Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions packages/app/src/cli/services/bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {AssetUrlSchema, DeveloperPlatformClient} from '../utilities/developer-pl
import {MinimalAppIdentifiers} from '../models/organization.js'
import {joinPath} from '@shopify/cli-kit/node/path'
import {brotliCompress, zip} from '@shopify/cli-kit/node/archiver'
import {formData, fetch} from '@shopify/cli-kit/node/http'
import {fetch} from '@shopify/cli-kit/node/http'
import {readFileSync} from '@shopify/cli-kit/node/fs'
import {AbortError} from '@shopify/cli-kit/node/error'
import {writeFile} from 'fs/promises'
Expand All @@ -29,10 +29,8 @@ export async function compressBundle(inputDirectory: string, outputPath: string,
* @param filePath - The path to the file
*/
export async function uploadToGCS(signedURL: string, filePath: string) {
const form = formData()
const buffer = readFileSync(filePath)
form.append('my_upload', buffer)
await fetch(signedURL, {method: 'put', body: buffer, headers: form.getHeaders()}, 'slow-request')
await fetch(signedURL, {method: 'put', body: buffer}, 'slow-request')
}

/**
Expand Down
11 changes: 0 additions & 11 deletions packages/app/src/cli/services/deploy/upload.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {testApp, testDeveloperPlatformClient} from '../../models/app/app.test-da
import {AppDeploySchema, AppDeployVariables} from '../../api/graphql/app_deploy.js'
import {describe, expect, test, vi} from 'vitest'
import {inTemporaryDirectory, writeFile} from '@shopify/cli-kit/node/fs'
import {formData} from '@shopify/cli-kit/node/http'
import {joinPath} from '@shopify/cli-kit/node/path'

vi.mock('@shopify/cli-kit/node/http')
Expand All @@ -16,8 +15,6 @@ describe('uploadExtensionsBundle', () => {
test('calls a mutation on partners', async () => {
await inTemporaryDirectory(async (tmpDir) => {
// Given
const mockedFormData = {append: vi.fn(), getHeaders: vi.fn()}
vi.mocked<any>(formData).mockReturnValue(mockedFormData)
const developerPlatformClient = testDeveloperPlatformClient()

// When
Expand Down Expand Up @@ -62,8 +59,6 @@ describe('uploadExtensionsBundle', () => {
test('calls a mutation on partners with a message and a version', async () => {
await inTemporaryDirectory(async (tmpDir) => {
// Given
const mockedFormData = {append: vi.fn(), getHeaders: vi.fn()}
vi.mocked<any>(formData).mockReturnValue(mockedFormData)
const developerPlatformClient = testDeveloperPlatformClient()

// When
Expand Down Expand Up @@ -111,8 +106,6 @@ describe('uploadExtensionsBundle', () => {

test('calls a mutation on partners when there are no extensions', async () => {
const developerPlatformClient = testDeveloperPlatformClient()
const mockedFormData = {append: vi.fn(), getHeaders: vi.fn()}
vi.mocked<any>(formData).mockReturnValue(mockedFormData)
// When
await uploadExtensionsBundle({
appManifest,
Expand Down Expand Up @@ -222,8 +215,6 @@ describe('uploadExtensionsBundle', () => {
deploy: (_input: AppDeployVariables) => Promise.resolve(errorResponse),
})

const mockedFormData = {append: vi.fn(), getHeaders: vi.fn()}
vi.mocked<any>(formData).mockReturnValue(mockedFormData)
// When
await writeFile(joinPath(tmpDir, 'test.zip'), '')

Expand Down Expand Up @@ -327,8 +318,6 @@ describe('uploadExtensionsBundle', () => {
const developerPlatformClient = testDeveloperPlatformClient({
deploy: (_input: AppDeployVariables) => Promise.resolve(errorResponse),
})
const mockedFormData = {append: vi.fn(), getHeaders: vi.fn()}
vi.mocked<any>(formData).mockReturnValue(mockedFormData)
await writeFile(joinPath(tmpDir, 'test.zip'), '')

// When
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
testWebhookExtensions,
} from '../../../../models/app/app.test-data.js'
import {getUploadURL} from '../../../bundle.js'
import {formData} from '@shopify/cli-kit/node/http'
import {describe, expect, test, vi, beforeEach, afterEach} from 'vitest'
import {AbortSignal, AbortController} from '@shopify/cli-kit/node/abort'
import {flushPromises} from '@shopify/cli-kit/node/promises'
Expand Down Expand Up @@ -81,7 +80,6 @@ describe('pushUpdatesForDevSession', () => {
let devSessionStatusManager: DevSessionStatusManager

beforeEach(() => {
vi.mocked(formData).mockReturnValue({append: vi.fn(), getHeaders: vi.fn()} as any)
stdout = {write: vi.fn()}
stderr = {write: vi.fn()}
developerPlatformClient = testDeveloperPlatformClient()
Expand Down Expand Up @@ -425,7 +423,6 @@ describe('pushUpdatesForDevSession', () => {

test('assetsURL is only generated if affected extensions have assets', async () => {
// Given
vi.mocked(formData).mockReturnValue({append: vi.fn(), getHeaders: vi.fn()} as any)
// Mock readdir to return that a folder for the extension assets exists
vi.mocked(readdir).mockResolvedValue(['other-folders', 'ui-extension-uid'])
vi.mocked(getUploadURL).mockResolvedValue('https://gcs.url')
Expand Down Expand Up @@ -456,7 +453,6 @@ describe('pushUpdatesForDevSession', () => {

test('assetsURL is always generated for create, even if there are no assets', async () => {
// Given
vi.mocked(formData).mockReturnValue({append: vi.fn(), getHeaders: vi.fn()} as any)
vi.mocked(getUploadURL).mockResolvedValue('https://gcs.url')

// When
Expand Down
1 change: 0 additions & 1 deletion packages/cli-kit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@
"fast-glob": "3.3.3",
"figures": "5.0.0",
"find-up": "6.3.0",
"form-data": "4.0.4",
"fs-extra": "11.1.0",
"get-port-please": "3.1.2",
"gradient-string": "2.0.2",
Expand Down
14 changes: 9 additions & 5 deletions packages/cli-kit/src/private/node/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ import {sanitizeURL} from './api/urls.js'
import {sleepWithBackoffUntil} from './sleep-with-backoff.js'
import {outputDebug} from '../../public/node/output.js'
import {recordRetry} from '../../public/node/analytics.js'
import {Headers} from 'form-data'
import {ClientError} from 'graphql-request'
import {performance} from 'perf_hooks'

interface ResponseHeaders {
forEach(callback: (value: string, key: string) => void): void
get?(key: string): string | null
}

export type API = 'admin' | 'storefront-renderer' | 'partners' | 'business-platform' | 'app-management'

export const allAPIs: API[] = ['admin', 'storefront-renderer', 'partners', 'business-platform', 'app-management']
Expand Down Expand Up @@ -135,7 +139,7 @@ export function isNetworkError(error: unknown): boolean {
return false
}

async function runRequestWithNetworkLevelRetry<T extends {headers: Headers; status: number}>(
async function runRequestWithNetworkLevelRetry<T extends {headers: ResponseHeaders; status: number}>(
requestOptions: RequestOptions<T>,
): Promise<T> {
if (!requestOptions.useNetworkLevelRetry) {
Expand Down Expand Up @@ -164,7 +168,7 @@ async function runRequestWithNetworkLevelRetry<T extends {headers: Headers; stat
throw lastSeenError
}

async function makeVerboseRequest<T extends {headers: Headers; status: number}>(
async function makeVerboseRequest<T extends {headers: ResponseHeaders; status: number}>(
requestOptions: RequestOptions<T>,
): Promise<VerboseResponse<T>> {
const t0 = performance.now()
Expand Down Expand Up @@ -264,7 +268,7 @@ function errorsIncludeStatus429(error: ClientError): boolean {
return error.response.errors?.some((error) => error.extensions?.code === '429') ?? false
}

export async function simpleRequestWithDebugLog<T extends {headers: Headers; status: number}>(
export async function simpleRequestWithDebugLog<T extends {headers: ResponseHeaders; status: number}>(
requestOptions: RequestOptions<T>,
errorHandler?: (error: unknown, requestId: string | undefined) => unknown,
): Promise<T> {
Expand Down Expand Up @@ -327,7 +331,7 @@ ${result.sanitizedHeaders}
* @param retryOptions - Options for the retry
* @returns The response from the request
*/
export async function retryAwareRequest<T extends {headers: Headers; status: number}>(
export async function retryAwareRequest<T extends {headers: ResponseHeaders; status: number}>(
requestOptions: RequestOptions<T>,
errorHandler?: (error: unknown, requestId: string | undefined) => unknown,
retryOptions: {
Expand Down
11 changes: 1 addition & 10 deletions packages/cli-kit/src/public/node/http.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {downloadFile, shopifyFetch, formData, requestMode, fetch} from './http.js'
import {downloadFile, shopifyFetch, requestMode, fetch} from './http.js'
import {mockAndCaptureOutput} from './testing/output.js'
import {fileExists, inTemporaryDirectory, readFile} from './fs.js'
import {joinPath} from './path.js'
Expand All @@ -7,7 +7,6 @@ import {platformAndArch} from './os.js'
import {afterAll, afterEach, beforeAll, beforeEach, describe, expect, test, vi} from 'vitest'
import {setupServer} from 'msw/node'
import {delay, http, HttpResponse} from 'msw'
import FormData from 'form-data'

const DURATION_UNTIL_ABORT_IS_SEEN = 100

Expand Down Expand Up @@ -76,14 +75,6 @@ afterEach(() => {
vi.useRealTimers()
})

describe('formData', () => {
test('make an empty form data object', () => {
const res = formData()
expect(res).toBeInstanceOf(FormData)
expect(res.getLengthSync()).toBe(0)
})
})

describe('shopifyFetch', () => {
test('make a successful request', async () => {
const mockOutput = mockAndCaptureOutput()
Expand Down
10 changes: 0 additions & 10 deletions packages/cli-kit/src/public/node/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,10 @@ import {sanitizeURL} from '../../private/node/api/urls.js'
import {outputContent, outputDebug, outputToken} from '../../public/node/output.js'
import {NetworkRetryBehaviour, simpleRequestWithDebugLog} from '../../private/node/api.js'
import {DEFAULT_MAX_TIME_MS} from '../../private/node/sleep-with-backoff.js'
import FormData from 'form-data'
import nodeFetch, {RequestInfo, RequestInit, Response} from 'node-fetch'

export {FetchError, Request, Response} from 'node-fetch'

/**
* Create a new FormData object.
*
* @returns A FormData object.
*/
export function formData(): FormData {
return new FormData()
}

type AbortSignal = RequestInit['signal']

type PresetFetchBehaviour = 'default' | 'non-blocking' | 'slow-request'
Expand Down
Loading