@shopify/cli-kit 3.79.2 → 3.80.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/private/node/session/exchange.d.ts +4 -0
  2. package/dist/private/node/session/exchange.js +7 -7
  3. package/dist/private/node/session/exchange.js.map +1 -1
  4. package/dist/public/common/version.d.ts +1 -1
  5. package/dist/public/common/version.js +1 -1
  6. package/dist/public/common/version.js.map +1 -1
  7. package/dist/public/node/api/admin.js +2 -2
  8. package/dist/public/node/api/admin.js.map +1 -1
  9. package/dist/public/node/api/app-management.d.ts +3 -2
  10. package/dist/public/node/api/app-management.js +3 -1
  11. package/dist/public/node/api/app-management.js.map +1 -1
  12. package/dist/public/node/api/graphql.d.ts +15 -2
  13. package/dist/public/node/api/graphql.js +52 -9
  14. package/dist/public/node/api/graphql.js.map +1 -1
  15. package/dist/public/node/api/partners.d.ts +5 -3
  16. package/dist/public/node/api/partners.js +7 -3
  17. package/dist/public/node/api/partners.js.map +1 -1
  18. package/dist/public/node/archiver.d.ts +39 -0
  19. package/dist/public/node/archiver.js +59 -2
  20. package/dist/public/node/archiver.js.map +1 -1
  21. package/dist/public/node/fs.d.ts +6 -0
  22. package/dist/public/node/fs.js +9 -1
  23. package/dist/public/node/fs.js.map +1 -1
  24. package/dist/public/node/git.d.ts +7 -0
  25. package/dist/public/node/git.js +12 -0
  26. package/dist/public/node/git.js.map +1 -1
  27. package/dist/public/node/hooks/prerun.js +2 -1
  28. package/dist/public/node/hooks/prerun.js.map +1 -1
  29. package/dist/public/node/http.js +2 -2
  30. package/dist/public/node/http.js.map +1 -1
  31. package/dist/public/node/tcp.js +8 -3
  32. package/dist/public/node/tcp.js.map +1 -1
  33. package/dist/public/node/ui/components.d.ts +1 -0
  34. package/dist/public/node/ui/components.js +1 -0
  35. package/dist/public/node/ui/components.js.map +1 -1
  36. package/dist/public/node/version.d.ts +8 -0
  37. package/dist/public/node/version.js +11 -1
  38. package/dist/public/node/version.js.map +1 -1
  39. package/dist/tsconfig.tsbuildinfo +1 -1
  40. package/package.json +3 -1
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/public/node/http.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AACjC,OAAO,EAAC,qBAAqB,EAAE,cAAc,EAAE,SAAS,EAAE,cAAc,EAAC,MAAM,SAAS,CAAA;AACxF,OAAO,EAAC,YAAY,EAAC,MAAM,eAAe,CAAA;AAC1C,OAAO,EAAC,+BAA+B,EAAE,qBAAqB,EAAC,MAAM,kBAAkB,CAAA;AACvF,OAAO,EAAC,UAAU,EAAE,sBAAsB,EAAC,MAAM,mCAAmC,CAAA;AACpF,OAAO,EAAC,WAAW,EAAC,MAAM,gCAAgC,CAAA;AAC1D,OAAO,EAAC,aAAa,EAAE,WAAW,EAAE,WAAW,EAAC,MAAM,6BAA6B,CAAA;AACnF,OAAO,EAAwB,yBAAyB,EAAC,MAAM,2BAA2B,CAAA;AAC1F,OAAO,EAAC,mBAAmB,EAAC,MAAM,0CAA0C,CAAA;AAC5E,OAAO,QAAQ,MAAM,WAAW,CAAA;AAChC,OAAO,SAA+C,MAAM,YAAY,CAAA;AAExE,OAAO,EAAC,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAC,MAAM,YAAY,CAAA;AAExD;;;;GAIG;AACH,MAAM,UAAU,QAAQ;IACtB,OAAO,IAAI,QAAQ,EAAE,CAAA;AACvB,CAAC;AAsBD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,WAAW,CACzB,SAA2B,SAAS,EACpC,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,4BAA4B,GAAG,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAA;IAChE,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,SAAS;YACZ,OAAO;gBACL,oBAAoB,EAAE,4BAA4B;gBAClD,cAAc,EAAE,mBAAmB;gBACnC,cAAc,EAAE,IAAI;gBACpB,SAAS,EAAE,+BAA+B,CAAC,GAAG,CAAC;aAChD,CAAA;QACH,KAAK,cAAc;YACjB,OAAO;gBACL,oBAAoB,EAAE,KAAK;gBAC3B,cAAc,EAAE,IAAI;gBACpB,SAAS,EAAE,+BAA+B,CAAC,GAAG,CAAC;aAChD,CAAA;QACH,KAAK,cAAc;YACjB,OAAO;gBACL,oBAAoB,EAAE,KAAK;gBAC3B,cAAc,EAAE,KAAK;aACtB,CAAA;IACL,CAAC;IACD,OAAO;QACL,GAAG,MAAM;QACT,oBAAoB,EAAE,4BAA4B,IAAI,MAAM,CAAC,oBAAoB;KAC9D,CAAA;AACvB,CAAC;AAUD;;;;;GAKG;AACH,MAAM,UAAU,+BAA+B,CAAC,SAA2B;IACzE,IAAI,MAAmB,CAAA;IACvB,IAAI,SAAS,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;QACtC,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,CAAA;IACnD,CAAC;SAAM,IAAI,SAAS,CAAC,cAAc,IAAI,OAAO,SAAS,CAAC,cAAc,KAAK,UAAU,EAAE,CAAC;QACtF,MAAM,GAAG,SAAS,CAAC,cAAc,EAAE,CAAA;IACrC,CAAC;SAAM,IAAI,SAAS,CAAC,cAAc,EAAE,CAAC;QACpC,MAAM,GAAG,SAAS,CAAC,cAAc,CAAA;IACnC,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,EAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,aAAa,EAAe;IACvF,IAAI,UAAU,EAAE,CAAC;QACf,WAAW,CAAC,aAAa,CAAA,WAAW,IAAI,EAAE,MAAM,IAAI,KAAK,mBAAmB,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;;EAEzG,sBAAsB,CAAC,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,CAA+B,CAAC;CAC5E,CAAC,CAAA;IACA,CAAC;IAED,IAAI,KAA2B,CAAA;IAC/B,IAAI,aAAa,EAAE,CAAC;QAClB,KAAK,GAAG,MAAM,UAAU,EAAE,CAAA;IAC5B,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;QACzB,8GAA8G;QAC9G,mCAAmC;QACnC,IAAI,MAAM,GAAG,+BAA+B,CAAC,SAAS,CAAC,CAAA;QAEvD,0EAA0E;QAC1E,IAAI,IAAI,EAAE,MAAM,EAAE,CAAC;YACjB,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QACtB,CAAC;QAED,OAAO,SAAS,CAAC,GAAG,EAAE,EAAC,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,EAAC,CAAC,CAAA;IACjD,CAAC,CAAA;IAED,OAAO,YAAY,CAAC,2BAA2B,CAAC,CAAC,KAAK,IAAI,EAAE;QAC1D,OAAO,yBAAyB,CAAC;YAC/B,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE;YACnB,OAAO;YACP,GAAG,SAAS;SACb,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CACzB,GAAgB,EAChB,IAAkB,EAClB,kBAAqC;IAErC,MAAM,OAAO,GAAG;QACd,GAAG;QACH,IAAI;QACJ,UAAU,EAAE,KAAK;QACjB,aAAa,EAAE,KAAK;QACpB,iDAAiD;QACjD,SAAS,EAAE,kBAAkB,CAAC,CAAC,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,cAAc,CAAC;KACrF,CAAA;IAEV,OAAO,UAAU,CAAC,OAAO,CAAC,CAAA;AAC5B,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,GAAgB,EAChB,IAAkB,EAClB,kBAAqC;IAErC,MAAM,OAAO,GAAG;QACd,GAAG;QACH,IAAI;QACJ,UAAU,EAAE,IAAI;QAChB,aAAa,EAAE,IAAI;QACnB,wCAAwC;QACxC,SAAS,EAAE,kBAAkB,CAAC,CAAC,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;KAChF,CAAA;IAED,OAAO,UAAU,CAAC,OAAO,CAAC,CAAA;AAC5B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,EAAU;IAClD,MAAM,YAAY,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;IACrC,WAAW,CAAC,eAAe,YAAY,OAAO,EAAE,EAAE,CAAC,CAAA;IAEnD,OAAO,YAAY,CAAC,2BAA2B,CAAC,CAAC,GAAG,EAAE;QACpD,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC7C,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;gBACjC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAA;YACxB,CAAC;YAED,MAAM,IAAI,GAAG,qBAAqB,CAAC,EAAE,CAAC,CAAA;YAEtC,4GAA4G;YAC5G,MAAM,eAAe,GAAG,GAAG,EAAE;gBAC3B,IAAI,CAAC;oBACH,cAAc,CAAC,EAAE,CAAC,CAAA;oBAClB,yFAAyF;gBAC3F,CAAC;gBAAC,OAAO,GAAQ,EAAE,CAAC;oBAClB,WAAW,CAAC,aAAa,CAAA,yBAAyB,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC,CAAA;gBACnF,CAAC;YACH,CAAC,CAAA;YAED,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;gBACrB,IAAI,CAAC,KAAK,EAAE,CAAA;gBACZ,OAAO,CAAC,EAAE,CAAC,CAAA;YACb,CAAC,CAAC,CAAA;YAEF,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACvB,eAAe,EAAE,CAAA;gBACjB,MAAM,CAAC,GAAG,CAAC,CAAA;YACb,CAAC,CAAC,CAAA;YAEF,SAAS,CAAC,GAAG,EAAE,EAAC,QAAQ,EAAE,QAAQ,EAAC,CAAC;iBACjC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;gBACZ,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;YACtB,CAAC,CAAC;iBACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBACb,eAAe,EAAE,CAAA;gBACjB,MAAM,CAAC,GAAG,CAAC,CAAA;YACb,CAAC,CAAC,CAAA;QACN,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["/* eslint-disable @typescript-eslint/no-base-to-string */\nimport {dirname} from './path.js'\nimport {createFileWriteStream, fileExistsSync, mkdirSync, unlinkFileSync} from './fs.js'\nimport {runWithTimer} from './metadata.js'\nimport {maxRequestTimeForNetworkCallsMs, skipNetworkLevelRetry} from './environment.js'\nimport {httpsAgent, sanitizedHeadersOutput} from '../../private/node/api/headers.js'\nimport {sanitizeURL} from '../../private/node/api/urls.js'\nimport {outputContent, outputDebug, outputToken} from '../../public/node/output.js'\nimport {NetworkRetryBehaviour, simpleRequestWithDebugLog} from '../../private/node/api.js'\nimport {DEFAULT_MAX_TIME_MS} from '../../private/node/sleep-with-backoff.js'\nimport FormData from 'form-data'\nimport nodeFetch, {RequestInfo, RequestInit, Response} from 'node-fetch'\n\nexport {FetchError, Request, Response} from 'node-fetch'\n\n/**\n * Create a new FormData object.\n *\n * @returns A FormData object.\n */\nexport function formData(): FormData {\n return new FormData()\n}\n\ntype AbortSignal = RequestInit['signal']\n\ntype PresetFetchBehaviour = 'default' | 'non-blocking' | 'slow-request'\n\ntype AutomaticCancellationBehaviour =\n | {\n useAbortSignal: true\n timeoutMs: number\n }\n | {\n useAbortSignal: false\n }\n | {\n useAbortSignal: AbortSignal | (() => AbortSignal)\n }\n\ntype RequestBehaviour = NetworkRetryBehaviour & AutomaticCancellationBehaviour\n\nexport type RequestModeInput = PresetFetchBehaviour | RequestBehaviour\n\n/**\n * Specify the behaviour of a network request.\n *\n * - default: Requests are automatically retried, and are subject to automatic cancellation if they're taking too long.\n * This is generally desirable.\n * - non-blocking: Requests are not retried if they fail with a network error, and are automatically cancelled if\n * they're taking too long. This is good for throwaway requests, like polling or tracking.\n * - slow-request: Requests are not retried if they fail with a network error, and are not automatically cancelled.\n * This is good for slow requests that should be give the chance to complete, and are unlikely to be safe to retry.\n *\n * Some request behaviours may be de-activated by the environment, and this function takes care of that concern. You\n * can also provide a customised request behaviour.\n *\n * @param preset - The preset to use.\n * @param env - Process environment variables.\n * @returns A request behaviour object.\n */\nexport function requestMode(\n preset: RequestModeInput = 'default',\n env: NodeJS.ProcessEnv = process.env,\n): RequestBehaviour {\n const networkLevelRetryIsSupported = !skipNetworkLevelRetry(env)\n switch (preset) {\n case 'default':\n return {\n useNetworkLevelRetry: networkLevelRetryIsSupported,\n maxRetryTimeMs: DEFAULT_MAX_TIME_MS,\n useAbortSignal: true,\n timeoutMs: maxRequestTimeForNetworkCallsMs(env),\n }\n case 'non-blocking':\n return {\n useNetworkLevelRetry: false,\n useAbortSignal: true,\n timeoutMs: maxRequestTimeForNetworkCallsMs(env),\n }\n case 'slow-request':\n return {\n useNetworkLevelRetry: false,\n useAbortSignal: false,\n }\n }\n return {\n ...preset,\n useNetworkLevelRetry: networkLevelRetryIsSupported && preset.useNetworkLevelRetry,\n } as RequestBehaviour\n}\n\ninterface FetchOptions {\n url: RequestInfo\n behaviour: RequestBehaviour\n init?: RequestInit\n logRequest: boolean\n useHttpsAgent: boolean\n}\n\n/**\n * Create an AbortSignal for automatic request cancellation, from a request behaviour.\n *\n * @param behaviour - The request behaviour.\n * @returns An AbortSignal.\n */\nexport function abortSignalFromRequestBehaviour(behaviour: RequestBehaviour): AbortSignal {\n let signal: AbortSignal\n if (behaviour.useAbortSignal === true) {\n signal = AbortSignal.timeout(behaviour.timeoutMs)\n } else if (behaviour.useAbortSignal && typeof behaviour.useAbortSignal === 'function') {\n signal = behaviour.useAbortSignal()\n } else if (behaviour.useAbortSignal) {\n signal = behaviour.useAbortSignal\n }\n return signal\n}\n\nasync function innerFetch({url, behaviour, init, logRequest, useHttpsAgent}: FetchOptions): Promise<Response> {\n if (logRequest) {\n outputDebug(outputContent`Sending ${init?.method ?? 'GET'} request to URL ${sanitizeURL(url.toString())}\nWith request headers:\n${sanitizedHeadersOutput((init?.headers ?? {}) as {[header: string]: string})}\n`)\n }\n\n let agent: RequestInit['agent']\n if (useHttpsAgent) {\n agent = await httpsAgent()\n }\n\n const request = async () => {\n // each time we make the request, we need to potentially reset the abort signal, as the request logic may make\n // the same request multiple times.\n let signal = abortSignalFromRequestBehaviour(behaviour)\n\n // it's possible to provide a signal through the request's init structure.\n if (init?.signal) {\n signal = init.signal\n }\n\n return nodeFetch(url, {...init, agent, signal})\n }\n\n return runWithTimer('cmd_all_timing_network_ms')(async () => {\n return simpleRequestWithDebugLog({\n url: url.toString(),\n request,\n ...behaviour,\n })\n })\n}\n\n/**\n * An interface that abstracts way node-fetch. When Node has built-in\n * support for \"fetch\" in the standard library, we can drop the node-fetch\n * dependency from here.\n * Note that we are exposing types from \"node-fetch\". The reason being is that\n * they are consistent with the Web API so if we drop node-fetch in the future\n * it won't require changes from the callers.\n *\n * The CLI's fetch function supports special behaviours, like automatic retries. These are disabled by default through\n * this function.\n *\n * @param url - This defines the resource that you wish to fetch.\n * @param init - An object containing any custom settings that you want to apply to the request.\n * @param preferredBehaviour - A request behaviour object that overrides the default behaviour.\n * @returns A promise that resolves with the response.\n */\nexport async function fetch(\n url: RequestInfo,\n init?: RequestInit,\n preferredBehaviour?: RequestModeInput,\n): Promise<Response> {\n const options = {\n url,\n init,\n logRequest: false,\n useHttpsAgent: false,\n // all special behaviours are disabled by default\n behaviour: preferredBehaviour ? requestMode(preferredBehaviour) : requestMode('non-blocking'),\n } as const\n\n return innerFetch(options)\n}\n\n/**\n * A fetch function to use with Shopify services. The function ensures the right\n * TLS configuragion is used based on the environment in which the service is running\n * (e.g. Spin). NB: headers/auth are the responsibility of the caller.\n *\n * By default, the CLI's fetch function's special behaviours, like automatic retries, are enabled.\n *\n * @param url - This defines the resource that you wish to fetch.\n * @param init - An object containing any custom settings that you want to apply to the request.\n * @param preferredBehaviour - A request behaviour object that overrides the default behaviour.\n * @returns A promise that resolves with the response.\n */\nexport async function shopifyFetch(\n url: RequestInfo,\n init?: RequestInit,\n preferredBehaviour?: RequestModeInput,\n): Promise<Response> {\n const options = {\n url,\n init,\n logRequest: true,\n useHttpsAgent: true,\n // special behaviours enabled by default\n behaviour: preferredBehaviour ? requestMode(preferredBehaviour) : requestMode(),\n }\n\n return innerFetch(options)\n}\n\n/**\n * Download a file from a URL to a local path.\n *\n * @param url - The URL to download from.\n * @param to - The local path to download to.\n * @returns - A promise that resolves with the local path.\n */\nexport function downloadFile(url: string, to: string): Promise<string> {\n const sanitizedUrl = sanitizeURL(url)\n outputDebug(`Downloading ${sanitizedUrl} to ${to}`)\n\n return runWithTimer('cmd_all_timing_network_ms')(() => {\n return new Promise<string>((resolve, reject) => {\n if (!fileExistsSync(dirname(to))) {\n mkdirSync(dirname(to))\n }\n\n const file = createFileWriteStream(to)\n\n // if we can't remove the file for some reason (seen on windows), that's ok -- it's in a temporary directory\n const tryToRemoveFile = () => {\n try {\n unlinkFileSync(to)\n // eslint-disable-next-line no-catch-all/no-catch-all, @typescript-eslint/no-explicit-any\n } catch (err: any) {\n outputDebug(outputContent`Failed to remove file ${outputToken.path(to)}: ${err}`)\n }\n }\n\n file.on('finish', () => {\n file.close()\n resolve(to)\n })\n\n file.on('error', (err) => {\n tryToRemoveFile()\n reject(err)\n })\n\n nodeFetch(url, {redirect: 'follow'})\n .then((res) => {\n res.body?.pipe(file)\n })\n .catch((err) => {\n tryToRemoveFile()\n reject(err)\n })\n })\n })\n}\n"]}
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/public/node/http.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-base-to-string */\nimport {dirname} from './path.js'\nimport {createFileWriteStream, fileExistsSync, mkdirSync, unlinkFileSync} from './fs.js'\nimport {runWithTimer} from './metadata.js'\nimport {maxRequestTimeForNetworkCallsMs, skipNetworkLevelRetry} from './environment.js'\nimport {httpsAgent, sanitizedHeadersOutput} from '../../private/node/api/headers.js'\nimport {sanitizeURL} from '../../private/node/api/urls.js'\nimport {outputContent, outputDebug, outputToken} from '../../public/node/output.js'\nimport {NetworkRetryBehaviour, simpleRequestWithDebugLog} from '../../private/node/api.js'\nimport {DEFAULT_MAX_TIME_MS} from '../../private/node/sleep-with-backoff.js'\nimport FormData from 'form-data'\nimport nodeFetch, {RequestInfo, RequestInit, Response} from 'node-fetch'\n\nexport {FetchError, Request, Response} from 'node-fetch'\n\n/**\n * Create a new FormData object.\n *\n * @returns A FormData object.\n */\nexport function formData(): FormData {\n return new FormData()\n}\n\ntype AbortSignal = RequestInit['signal']\n\ntype PresetFetchBehaviour = 'default' | 'non-blocking' | 'slow-request'\n\ntype AutomaticCancellationBehaviour =\n | {\n useAbortSignal: true\n timeoutMs: number\n }\n | {\n useAbortSignal: false\n }\n | {\n useAbortSignal: AbortSignal | (() => AbortSignal)\n }\n\ntype RequestBehaviour = NetworkRetryBehaviour & AutomaticCancellationBehaviour\n\nexport type RequestModeInput = PresetFetchBehaviour | RequestBehaviour\n\n/**\n * Specify the behaviour of a network request.\n *\n * - default: Requests are automatically retried, and are subject to automatic cancellation if they're taking too long.\n * This is generally desirable.\n * - non-blocking: Requests are not retried if they fail with a network error, and are automatically cancelled if\n * they're taking too long. This is good for throwaway requests, like polling or tracking.\n * - slow-request: Requests are not retried if they fail with a network error, and are not automatically cancelled.\n * This is good for slow requests that should be give the chance to complete, and are unlikely to be safe to retry.\n *\n * Some request behaviours may be de-activated by the environment, and this function takes care of that concern. You\n * can also provide a customised request behaviour.\n *\n * @param preset - The preset to use.\n * @param env - Process environment variables.\n * @returns A request behaviour object.\n */\nexport function requestMode(\n preset: RequestModeInput = 'default',\n env: NodeJS.ProcessEnv = process.env,\n): RequestBehaviour {\n const networkLevelRetryIsSupported = !skipNetworkLevelRetry(env)\n switch (preset) {\n case 'default':\n return {\n useNetworkLevelRetry: networkLevelRetryIsSupported,\n maxRetryTimeMs: DEFAULT_MAX_TIME_MS,\n useAbortSignal: true,\n timeoutMs: maxRequestTimeForNetworkCallsMs(env),\n }\n case 'non-blocking':\n return {\n useNetworkLevelRetry: false,\n useAbortSignal: true,\n timeoutMs: maxRequestTimeForNetworkCallsMs(env),\n }\n case 'slow-request':\n return {\n useNetworkLevelRetry: false,\n useAbortSignal: false,\n }\n }\n return {\n ...preset,\n useNetworkLevelRetry: networkLevelRetryIsSupported && preset.useNetworkLevelRetry,\n } as RequestBehaviour\n}\n\ninterface FetchOptions {\n url: RequestInfo\n behaviour: RequestBehaviour\n init?: RequestInit\n logRequest: boolean\n useHttpsAgent: boolean\n}\n\n/**\n * Create an AbortSignal for automatic request cancellation, from a request behaviour.\n *\n * @param behaviour - The request behaviour.\n * @returns An AbortSignal.\n */\nexport function abortSignalFromRequestBehaviour(behaviour: RequestBehaviour): AbortSignal {\n let signal: AbortSignal\n if (behaviour.useAbortSignal === true) {\n signal = AbortSignal.timeout(behaviour.timeoutMs)\n } else if (behaviour.useAbortSignal && typeof behaviour.useAbortSignal === 'function') {\n signal = behaviour.useAbortSignal()\n } else if (behaviour.useAbortSignal) {\n signal = behaviour.useAbortSignal\n }\n return signal\n}\n\nasync function innerFetch({url, behaviour, init, logRequest, useHttpsAgent}: FetchOptions): Promise<Response> {\n if (logRequest) {\n outputDebug(outputContent`Sending ${init?.method ?? 'GET'} request to URL ${sanitizeURL(url.toString())}\nWith request headers:\n${sanitizedHeadersOutput((init?.headers ?? {}) as {[header: string]: string})}\n`)\n }\n\n let agent: RequestInit['agent']\n if (useHttpsAgent) {\n agent = await httpsAgent()\n }\n\n const request = async () => {\n // each time we make the request, we need to potentially reset the abort signal, as the request logic may make\n // the same request multiple times.\n let signal = abortSignalFromRequestBehaviour(behaviour)\n\n // it's possible to provide a signal through the request's init structure.\n if (init?.signal) {\n signal = init.signal\n }\n\n return nodeFetch(url, {...init, agent, signal})\n }\n\n return runWithTimer('cmd_all_timing_network_ms')(async () => {\n return simpleRequestWithDebugLog({\n url: url.toString(),\n request,\n ...behaviour,\n })\n })\n}\n\n/**\n * An interface that abstracts way node-fetch. When Node has built-in\n * support for \"fetch\" in the standard library, we can drop the node-fetch\n * dependency from here.\n * Note that we are exposing types from \"node-fetch\". The reason being is that\n * they are consistent with the Web API so if we drop node-fetch in the future\n * it won't require changes from the callers.\n *\n * The CLI's fetch function supports special behaviours, like automatic retries. These are disabled by default through\n * this function.\n *\n * @param url - This defines the resource that you wish to fetch.\n * @param init - An object containing any custom settings that you want to apply to the request.\n * @param preferredBehaviour - A request behaviour object that overrides the default behaviour.\n * @returns A promise that resolves with the response.\n */\nexport async function fetch(\n url: RequestInfo,\n init?: RequestInit,\n preferredBehaviour?: RequestModeInput,\n): Promise<Response> {\n const options = {\n url,\n init,\n logRequest: false,\n useHttpsAgent: false,\n // all special behaviours are disabled by default\n behaviour: preferredBehaviour ? requestMode(preferredBehaviour) : requestMode('non-blocking'),\n } as const\n\n return innerFetch(options)\n}\n\n/**\n * A fetch function to use with Shopify services. The function ensures the right\n * TLS configuragion is used based on the environment in which the service is running\n * (e.g. Spin). NB: headers/auth are the responsibility of the caller.\n *\n * By default, the CLI's fetch function's special behaviours, like automatic retries, are enabled.\n *\n * @param url - This defines the resource that you wish to fetch.\n * @param init - An object containing any custom settings that you want to apply to the request.\n * @param preferredBehaviour - A request behaviour object that overrides the default behaviour.\n * @returns A promise that resolves with the response.\n */\nexport async function shopifyFetch(\n url: RequestInfo,\n init?: RequestInit,\n preferredBehaviour?: RequestModeInput,\n): Promise<Response> {\n const options = {\n url,\n init,\n logRequest: true,\n useHttpsAgent: true,\n // special behaviours enabled by default\n behaviour: preferredBehaviour ? requestMode(preferredBehaviour) : requestMode(),\n }\n\n return innerFetch(options)\n}\n\n/**\n * Download a file from a URL to a local path.\n *\n * @param url - The URL to download from.\n * @param to - The local path to download to.\n * @returns - A promise that resolves with the local path.\n */\nexport function downloadFile(url: string, to: string): Promise<string> {\n const sanitizedUrl = sanitizeURL(url)\n outputDebug(`Downloading ${sanitizedUrl} to ${to}`)\n\n return runWithTimer('cmd_all_timing_network_ms')(() => {\n return new Promise<string>((resolve, reject) => {\n if (!fileExistsSync(dirname(to))) {\n mkdirSync(dirname(to))\n }\n\n const file = createFileWriteStream(to)\n\n // if we can't remove the file for some reason (seen on windows), that's ok -- it's in a temporary directory\n const tryToRemoveFile = () => {\n try {\n unlinkFileSync(to)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (err: unknown) {\n outputDebug(outputContent`Failed to remove file ${outputToken.path(to)}: ${outputToken.raw(String(err))}`)\n }\n }\n\n file.on('finish', () => {\n file.close()\n resolve(to)\n })\n\n file.on('error', (err) => {\n tryToRemoveFile()\n reject(err)\n })\n\n nodeFetch(url, {redirect: 'follow'})\n .then((res) => {\n res.body?.pipe(file)\n })\n .catch((err) => {\n tryToRemoveFile()\n reject(err)\n })\n })\n })\n}\n"]}
@@ -16,13 +16,13 @@ export async function getAvailableTCPPort(preferredPort, options) {
16
16
  return preferredPort;
17
17
  }
18
18
  outputDebug(outputContent `Getting a random port...`);
19
- let randomPort = await retryOnError(() => port.getRandomPort('localhost'), options?.maxTries, options?.waitTimeInSeconds);
19
+ let randomPort = await retryOnError(() => port.getRandomPort(host()), options?.maxTries, options?.waitTimeInSeconds);
20
20
  for (let i = 0; i < (options?.maxTries ?? 5); i++) {
21
21
  if (!obtainedRandomPorts.has(randomPort)) {
22
22
  break;
23
23
  }
24
24
  // eslint-disable-next-line no-await-in-loop
25
- randomPort = await retryOnError(() => port.getRandomPort('localhost'), options?.maxTries, options?.waitTimeInSeconds);
25
+ randomPort = await retryOnError(() => port.getRandomPort(host()), options?.maxTries, options?.waitTimeInSeconds);
26
26
  }
27
27
  outputDebug(outputContent `Random port obtained: ${outputToken.raw(`${randomPort}`)}`);
28
28
  obtainedRandomPorts.add(randomPort);
@@ -35,7 +35,12 @@ export async function getAvailableTCPPort(preferredPort, options) {
35
35
  * @returns A promise that resolves with a boolean indicating if the port is available.
36
36
  */
37
37
  export async function checkPortAvailability(portNumber) {
38
- return (await port.checkPort(portNumber)) === portNumber;
38
+ return (await port.checkPort(portNumber, host())) === portNumber;
39
+ }
40
+ function host() {
41
+ // The get-port-please library does not work as expected when HOST env var is defined,
42
+ // so explicitly set the host to 0.0.0.0 to avoid conflicts
43
+ return process.env.HOST ? '0.0.0.0' : undefined;
39
44
  }
40
45
  /**
41
46
  * Given a function, it runs it and retries in case of failiure up to the provided number of times.
@@ -1 +1 @@
1
- {"version":3,"file":"tcp.js","sourceRoot":"","sources":["../../../src/public/node/tcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,aAAa,CAAA;AACjC,OAAO,EAAC,UAAU,EAAC,MAAM,YAAY,CAAA;AACrC,OAAO,EAAC,WAAW,EAAE,aAAa,EAAE,WAAW,EAAC,MAAM,6BAA6B,CAAA;AACnF,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAA;AAOvC,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAU,CAAA;AAE7C;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,aAAsB,EAAE,OAA2B;IAC3F,IAAI,aAAa,IAAI,CAAC,MAAM,qBAAqB,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC;QAClE,WAAW,CAAC,aAAa,CAAA,QAAQ,aAAa,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QACpE,OAAO,aAAa,CAAA;IACtB,CAAC;IACD,WAAW,CAAC,aAAa,CAAA,0BAA0B,CAAC,CAAA;IACpD,IAAI,UAAU,GAAG,MAAM,YAAY,CACjC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,EACrC,OAAO,EAAE,QAAQ,EACjB,OAAO,EAAE,iBAAiB,CAC3B,CAAA;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAClD,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YACzC,MAAK;QACP,CAAC;QACD,4CAA4C;QAC5C,UAAU,GAAG,MAAM,YAAY,CAC7B,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,EACrC,OAAO,EAAE,QAAQ,EACjB,OAAO,EAAE,iBAAiB,CAC3B,CAAA;IACH,CAAC;IAED,WAAW,CAAC,aAAa,CAAA,yBAAyB,WAAW,CAAC,GAAG,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,CAAC,CAAA;IACrF,mBAAmB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;IACnC,OAAO,UAAU,CAAA;AACnB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,UAAkB;IAC5D,OAAO,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,KAAK,UAAU,CAAA;AAC1D,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,YAAY,CAAI,OAAgB,EAAE,QAAQ,GAAG,CAAC,EAAE,iBAAiB,GAAG,CAAC;IAClF,IAAI,UAAU,GAAG,CAAC,CAAA;IAClB,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,CAAC;YACH,4CAA4C;YAC5C,OAAO,MAAM,OAAO,EAAE,CAAA;YACtB,8DAA8D;QAChE,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,IAAI,UAAU,EAAE,GAAG,QAAQ,EAAE,CAAC;gBAC5B,WAAW,CAAC,aAAa,CAAA,0CAA0C,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;gBACnF,4CAA4C;gBAC5C,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAA;YAChC,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YACrC,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import {sleep} from './system.js'\nimport {AbortError} from './error.js'\nimport {outputDebug, outputContent, outputToken} from '../../public/node/output.js'\nimport * as port from 'get-port-please'\n\ninterface GetTCPPortOptions {\n waitTimeInSeconds?: number\n maxTries?: number\n}\n\nconst obtainedRandomPorts = new Set<number>()\n\n/**\n * Returns an available port in the current environment.\n *\n * @param preferredPort - Number of the preferred port to be used if available.\n * @param options - Extra configuration for getting TCP ports.\n * @returns A promise that resolves with an availabe port.\n */\nexport async function getAvailableTCPPort(preferredPort?: number, options?: GetTCPPortOptions): Promise<number> {\n if (preferredPort && (await checkPortAvailability(preferredPort))) {\n outputDebug(outputContent`Port ${preferredPort.toString()} is free`)\n return preferredPort\n }\n outputDebug(outputContent`Getting a random port...`)\n let randomPort = await retryOnError(\n () => port.getRandomPort('localhost'),\n options?.maxTries,\n options?.waitTimeInSeconds,\n )\n\n for (let i = 0; i < (options?.maxTries ?? 5); i++) {\n if (!obtainedRandomPorts.has(randomPort)) {\n break\n }\n // eslint-disable-next-line no-await-in-loop\n randomPort = await retryOnError(\n () => port.getRandomPort('localhost'),\n options?.maxTries,\n options?.waitTimeInSeconds,\n )\n }\n\n outputDebug(outputContent`Random port obtained: ${outputToken.raw(`${randomPort}`)}`)\n obtainedRandomPorts.add(randomPort)\n return randomPort\n}\n\n/**\n * Checks if a port is available.\n *\n * @param portNumber - The port number to check.\n * @returns A promise that resolves with a boolean indicating if the port is available.\n */\nexport async function checkPortAvailability(portNumber: number): Promise<boolean> {\n return (await port.checkPort(portNumber)) === portNumber\n}\n\n/**\n * Given a function, it runs it and retries in case of failiure up to the provided number of times.\n *\n * @param execute - The function to execute.\n * @param maxTries - The maximum retries.\n * @param waitTimeInSeconds - The time to wait between retries.\n */\nasync function retryOnError<T>(execute: () => T, maxTries = 5, waitTimeInSeconds = 1) {\n let retryCount = 1\n while (true) {\n try {\n // eslint-disable-next-line no-await-in-loop\n return await execute()\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n if (retryCount++ < maxTries) {\n outputDebug(outputContent`Unknown problem getting a random port: ${error.message}`)\n // eslint-disable-next-line no-await-in-loop\n await sleep(waitTimeInSeconds)\n } else {\n throw new AbortError(error.message)\n }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"tcp.js","sourceRoot":"","sources":["../../../src/public/node/tcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,aAAa,CAAA;AACjC,OAAO,EAAC,UAAU,EAAC,MAAM,YAAY,CAAA;AACrC,OAAO,EAAC,WAAW,EAAE,aAAa,EAAE,WAAW,EAAC,MAAM,6BAA6B,CAAA;AACnF,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAA;AAOvC,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAU,CAAA;AAE7C;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,aAAsB,EAAE,OAA2B;IAC3F,IAAI,aAAa,IAAI,CAAC,MAAM,qBAAqB,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC;QAClE,WAAW,CAAC,aAAa,CAAA,QAAQ,aAAa,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QACpE,OAAO,aAAa,CAAA;IACtB,CAAC;IACD,WAAW,CAAC,aAAa,CAAA,0BAA0B,CAAC,CAAA;IACpD,IAAI,UAAU,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,CAAC,CAAA;IAEpH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAClD,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YACzC,MAAK;QACP,CAAC;QACD,4CAA4C;QAC5C,UAAU,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,CAAC,CAAA;IAClH,CAAC;IAED,WAAW,CAAC,aAAa,CAAA,yBAAyB,WAAW,CAAC,GAAG,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,CAAC,CAAA;IACrF,mBAAmB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;IACnC,OAAO,UAAU,CAAA;AACnB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,UAAkB;IAC5D,OAAO,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,UAAU,CAAA;AAClE,CAAC;AAED,SAAS,IAAI;IACX,sFAAsF;IACtF,2DAA2D;IAC3D,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAA;AACjD,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,YAAY,CAAI,OAAgB,EAAE,QAAQ,GAAG,CAAC,EAAE,iBAAiB,GAAG,CAAC;IAClF,IAAI,UAAU,GAAG,CAAC,CAAA;IAClB,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,CAAC;YACH,4CAA4C;YAC5C,OAAO,MAAM,OAAO,EAAE,CAAA;YACtB,8DAA8D;QAChE,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,IAAI,UAAU,EAAE,GAAG,QAAQ,EAAE,CAAC;gBAC5B,WAAW,CAAC,aAAa,CAAA,0CAA0C,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;gBACnF,4CAA4C;gBAC5C,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAA;YAChC,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YACrC,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import {sleep} from './system.js'\nimport {AbortError} from './error.js'\nimport {outputDebug, outputContent, outputToken} from '../../public/node/output.js'\nimport * as port from 'get-port-please'\n\ninterface GetTCPPortOptions {\n waitTimeInSeconds?: number\n maxTries?: number\n}\n\nconst obtainedRandomPorts = new Set<number>()\n\n/**\n * Returns an available port in the current environment.\n *\n * @param preferredPort - Number of the preferred port to be used if available.\n * @param options - Extra configuration for getting TCP ports.\n * @returns A promise that resolves with an availabe port.\n */\nexport async function getAvailableTCPPort(preferredPort?: number, options?: GetTCPPortOptions): Promise<number> {\n if (preferredPort && (await checkPortAvailability(preferredPort))) {\n outputDebug(outputContent`Port ${preferredPort.toString()} is free`)\n return preferredPort\n }\n outputDebug(outputContent`Getting a random port...`)\n let randomPort = await retryOnError(() => port.getRandomPort(host()), options?.maxTries, options?.waitTimeInSeconds)\n\n for (let i = 0; i < (options?.maxTries ?? 5); i++) {\n if (!obtainedRandomPorts.has(randomPort)) {\n break\n }\n // eslint-disable-next-line no-await-in-loop\n randomPort = await retryOnError(() => port.getRandomPort(host()), options?.maxTries, options?.waitTimeInSeconds)\n }\n\n outputDebug(outputContent`Random port obtained: ${outputToken.raw(`${randomPort}`)}`)\n obtainedRandomPorts.add(randomPort)\n return randomPort\n}\n\n/**\n * Checks if a port is available.\n *\n * @param portNumber - The port number to check.\n * @returns A promise that resolves with a boolean indicating if the port is available.\n */\nexport async function checkPortAvailability(portNumber: number): Promise<boolean> {\n return (await port.checkPort(portNumber, host())) === portNumber\n}\n\nfunction host(): string | undefined {\n // The get-port-please library does not work as expected when HOST env var is defined,\n // so explicitly set the host to 0.0.0.0 to avoid conflicts\n return process.env.HOST ? '0.0.0.0' : undefined\n}\n\n/**\n * Given a function, it runs it and retries in case of failiure up to the provided number of times.\n *\n * @param execute - The function to execute.\n * @param maxTries - The maximum retries.\n * @param waitTimeInSeconds - The time to wait between retries.\n */\nasync function retryOnError<T>(execute: () => T, maxTries = 5, waitTimeInSeconds = 1) {\n let retryCount = 1\n while (true) {\n try {\n // eslint-disable-next-line no-await-in-loop\n return await execute()\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n if (retryCount++ < maxTries) {\n outputDebug(outputContent`Unknown problem getting a random port: ${error.message}`)\n // eslint-disable-next-line no-await-in-loop\n await sleep(waitTimeInSeconds)\n } else {\n throw new AbortError(error.message)\n }\n }\n }\n}\n"]}
@@ -1,2 +1,3 @@
1
1
  export { ConcurrentOutput, ConcurrentOutputContext, useConcurrentOutputContext, } from '../../../private/node/ui/components/ConcurrentOutput.js';
2
2
  export { Alert } from '../../../private/node/ui/components/Alert.js';
3
+ export { Link } from '../../../private/node/ui/components/Link.js';
@@ -1,3 +1,4 @@
1
1
  export { ConcurrentOutput, useConcurrentOutputContext, } from '../../../private/node/ui/components/ConcurrentOutput.js';
2
2
  export { Alert } from '../../../private/node/ui/components/Alert.js';
3
+ export { Link } from '../../../private/node/ui/components/Link.js';
3
4
  //# sourceMappingURL=components.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"components.js","sourceRoot":"","sources":["../../../../src/public/node/ui/components.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAEhB,0BAA0B,GAC3B,MAAM,yDAAyD,CAAA;AAChE,OAAO,EAAC,KAAK,EAAC,MAAM,8CAA8C,CAAA","sourcesContent":["export {\n ConcurrentOutput,\n ConcurrentOutputContext,\n useConcurrentOutputContext,\n} from '../../../private/node/ui/components/ConcurrentOutput.js'\nexport {Alert} from '../../../private/node/ui/components/Alert.js'\n"]}
1
+ {"version":3,"file":"components.js","sourceRoot":"","sources":["../../../../src/public/node/ui/components.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAEhB,0BAA0B,GAC3B,MAAM,yDAAyD,CAAA;AAChE,OAAO,EAAC,KAAK,EAAC,MAAM,8CAA8C,CAAA;AAClE,OAAO,EAAC,IAAI,EAAC,MAAM,6CAA6C,CAAA","sourcesContent":["export {\n ConcurrentOutput,\n ConcurrentOutputContext,\n useConcurrentOutputContext,\n} from '../../../private/node/ui/components/ConcurrentOutput.js'\nexport {Alert} from '../../../private/node/ui/components/Alert.js'\nexport {Link} from '../../../private/node/ui/components/Link.js'\n"]}
@@ -11,3 +11,11 @@ export declare function localCLIVersion(directory: string): Promise<string | und
11
11
  * @returns The version of the CLI if it is globally installed or undefined.
12
12
  */
13
13
  export declare function globalCLIVersion(): Promise<string | undefined>;
14
+ /**
15
+ * Returns true if the given version is a pre-release version.
16
+ * Meaning is a `nightly`, `snapshot`, or `experimental` version.
17
+ *
18
+ * @param version - The version to check.
19
+ * @returns True if the version is a pre-release version.
20
+ */
21
+ export declare function isPreReleaseVersion(version: string): boolean;
@@ -33,7 +33,7 @@ export async function globalCLIVersion() {
33
33
  const versionMatch = output.match(/@shopify\/cli\/([^\s]+)/);
34
34
  if (versionMatch && versionMatch[1]) {
35
35
  const version = versionMatch[1];
36
- if (satisfies(version, `>=3.59.0`) || version.startsWith('0.0.0')) {
36
+ if (satisfies(version, `>=3.59.0`) || isPreReleaseVersion(version)) {
37
37
  return version;
38
38
  }
39
39
  }
@@ -44,4 +44,14 @@ export async function globalCLIVersion() {
44
44
  return undefined;
45
45
  }
46
46
  }
47
+ /**
48
+ * Returns true if the given version is a pre-release version.
49
+ * Meaning is a `nightly`, `snapshot`, or `experimental` version.
50
+ *
51
+ * @param version - The version to check.
52
+ * @returns True if the version is a pre-release version.
53
+ */
54
+ export function isPreReleaseVersion(version) {
55
+ return version.startsWith('0.0.0');
56
+ }
47
57
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/public/node/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,mBAAmB,CAAA;AAC/C,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAC,SAAS,EAAC,MAAM,QAAQ,CAAA;AAEhC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,SAAiB;IACrD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,EAAC,GAAG,EAAE,SAAS,EAAC,CAAC,CAAA;QACrF,OAAO,MAAM,CAAC,KAAK,CAAC,yBAAyB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACnD,qDAAqD;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAC,GAAG,OAAO,CAAC,GAAG,EAAE,wBAAwB,EAAE,GAAG,EAAC,CAAA;QAC3D,2EAA2E;QAC3E,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,EAAC,GAAG,EAAE,IAAI,EAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAA;QAC3G,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;YAAE,OAAO,SAAS,CAAA;QACzC,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAC,GAAG,EAAC,CAAC,CAAA;QACjE,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAA;QAC5D,IAAI,YAAY,IAAI,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;YACpC,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,CAAA;YAC/B,IAAI,SAAS,CAAC,OAAO,EAAE,UAAU,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAClE,OAAO,OAAO,CAAA;YAChB,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAA;QAChB,qDAAqD;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC","sourcesContent":["import {captureOutput} from '../node/system.js'\nimport which from 'which'\nimport {satisfies} from 'semver'\n\n/**\n * Returns the version of the local dependency of the CLI if it's installed in the provided directory.\n *\n * @param directory - Path of the project to look for the dependency.\n * @returns The CLI version or undefined if the dependency is not installed.\n */\nexport async function localCLIVersion(directory: string): Promise<string | undefined> {\n try {\n const output = await captureOutput('npm', ['list', '@shopify/cli'], {cwd: directory})\n return output.match(/@shopify\\/cli@([\\w.-]*)/)?.[1]\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return undefined\n }\n}\n\n/**\n * Returns the version of the globally installed CLI, only if it's greater than 3.59.0 (when the global CLI was introduced).\n *\n * @returns The version of the CLI if it is globally installed or undefined.\n */\nexport async function globalCLIVersion(): Promise<string | undefined> {\n try {\n const env = {...process.env, SHOPIFY_CLI_NO_ANALYTICS: '1'}\n // Both execa and which find the project dependency. We need to exclude it.\n const shopifyBinaries = which.sync('shopify', {all: true}).filter((path) => !path.includes('node_modules'))\n if (!shopifyBinaries[0]) return undefined\n const output = await captureOutput(shopifyBinaries[0], [], {env})\n const versionMatch = output.match(/@shopify\\/cli\\/([^\\s]+)/)\n if (versionMatch && versionMatch[1]) {\n const version = versionMatch[1]\n if (satisfies(version, `>=3.59.0`) || version.startsWith('0.0.0')) {\n return version\n }\n }\n return undefined\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return undefined\n }\n}\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/public/node/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,mBAAmB,CAAA;AAC/C,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAC,SAAS,EAAC,MAAM,QAAQ,CAAA;AAChC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,SAAiB;IACrD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,EAAC,GAAG,EAAE,SAAS,EAAC,CAAC,CAAA;QACrF,OAAO,MAAM,CAAC,KAAK,CAAC,yBAAyB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACnD,qDAAqD;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAC,GAAG,OAAO,CAAC,GAAG,EAAE,wBAAwB,EAAE,GAAG,EAAC,CAAA;QAC3D,2EAA2E;QAC3E,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,EAAC,GAAG,EAAE,IAAI,EAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAA;QAC3G,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;YAAE,OAAO,SAAS,CAAA;QACzC,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAC,GAAG,EAAC,CAAC,CAAA;QACjE,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAA;QAC5D,IAAI,YAAY,IAAI,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;YACpC,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,CAAA;YAC/B,IAAI,SAAS,CAAC,OAAO,EAAE,UAAU,CAAC,IAAI,mBAAmB,CAAC,OAAO,CAAC,EAAE,CAAC;gBACnE,OAAO,OAAO,CAAA;YAChB,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAA;QAChB,qDAAqD;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,OAAO,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;AACpC,CAAC","sourcesContent":["import {captureOutput} from '../node/system.js'\nimport which from 'which'\nimport {satisfies} from 'semver'\n/**\n * Returns the version of the local dependency of the CLI if it's installed in the provided directory.\n *\n * @param directory - Path of the project to look for the dependency.\n * @returns The CLI version or undefined if the dependency is not installed.\n */\nexport async function localCLIVersion(directory: string): Promise<string | undefined> {\n try {\n const output = await captureOutput('npm', ['list', '@shopify/cli'], {cwd: directory})\n return output.match(/@shopify\\/cli@([\\w.-]*)/)?.[1]\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return undefined\n }\n}\n\n/**\n * Returns the version of the globally installed CLI, only if it's greater than 3.59.0 (when the global CLI was introduced).\n *\n * @returns The version of the CLI if it is globally installed or undefined.\n */\nexport async function globalCLIVersion(): Promise<string | undefined> {\n try {\n const env = {...process.env, SHOPIFY_CLI_NO_ANALYTICS: '1'}\n // Both execa and which find the project dependency. We need to exclude it.\n const shopifyBinaries = which.sync('shopify', {all: true}).filter((path) => !path.includes('node_modules'))\n if (!shopifyBinaries[0]) return undefined\n const output = await captureOutput(shopifyBinaries[0], [], {env})\n const versionMatch = output.match(/@shopify\\/cli\\/([^\\s]+)/)\n if (versionMatch && versionMatch[1]) {\n const version = versionMatch[1]\n if (satisfies(version, `>=3.59.0`) || isPreReleaseVersion(version)) {\n return version\n }\n }\n return undefined\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return undefined\n }\n}\n\n/**\n * Returns true if the given version is a pre-release version.\n * Meaning is a `nightly`, `snapshot`, or `experimental` version.\n *\n * @param version - The version to check.\n * @returns True if the version is a pre-release version.\n */\nexport function isPreReleaseVersion(version: string): boolean {\n return version.startsWith('0.0.0')\n}\n"]}