@shopify/cli-kit 4.5.1 → 4.6.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 (64) hide show
  1. package/dist/private/node/analytics/error-grouping.d.ts +57 -0
  2. package/dist/private/node/analytics/error-grouping.js +191 -0
  3. package/dist/private/node/analytics/error-grouping.js.map +1 -0
  4. package/dist/private/node/analytics/graphql-error-codes.d.ts +39 -0
  5. package/dist/private/node/analytics/graphql-error-codes.js +73 -0
  6. package/dist/private/node/analytics/graphql-error-codes.js.map +1 -0
  7. package/dist/private/node/api/headers.js +1 -2
  8. package/dist/private/node/api/headers.js.map +1 -1
  9. package/dist/private/node/constants.d.ts +0 -2
  10. package/dist/private/node/constants.js +0 -2
  11. package/dist/private/node/constants.js.map +1 -1
  12. package/dist/private/node/content-tokens.js +2 -4
  13. package/dist/private/node/content-tokens.js.map +1 -1
  14. package/dist/private/node/session/scopes.js +6 -5
  15. package/dist/private/node/session/scopes.js.map +1 -1
  16. package/dist/private/node/session/validate.js +1 -2
  17. package/dist/private/node/session/validate.js.map +1 -1
  18. package/dist/private/node/session.d.ts +1 -0
  19. package/dist/private/node/session.js +9 -8
  20. package/dist/private/node/session.js.map +1 -1
  21. package/dist/public/common/object.d.ts +8 -0
  22. package/dist/public/common/object.js +24 -0
  23. package/dist/public/common/object.js.map +1 -1
  24. package/dist/public/common/version.d.ts +1 -1
  25. package/dist/public/common/version.js +1 -1
  26. package/dist/public/common/version.js.map +1 -1
  27. package/dist/public/node/analytics.js +4 -1
  28. package/dist/public/node/analytics.js.map +1 -1
  29. package/dist/public/node/api/partners.d.ts +0 -17
  30. package/dist/public/node/api/partners.js +1 -48
  31. package/dist/public/node/api/partners.js.map +1 -1
  32. package/dist/public/node/base-command.d.ts +1 -0
  33. package/dist/public/node/base-command.js +2 -0
  34. package/dist/public/node/base-command.js.map +1 -1
  35. package/dist/public/node/cli.d.ts +3 -0
  36. package/dist/public/node/cli.js +6 -0
  37. package/dist/public/node/cli.js.map +1 -1
  38. package/dist/public/node/context/local.d.ts +0 -7
  39. package/dist/public/node/context/local.js +0 -9
  40. package/dist/public/node/context/local.js.map +1 -1
  41. package/dist/public/node/environment.d.ts +0 -6
  42. package/dist/public/node/environment.js +0 -8
  43. package/dist/public/node/environment.js.map +1 -1
  44. package/dist/public/node/error-handler.js +35 -14
  45. package/dist/public/node/error-handler.js.map +1 -1
  46. package/dist/public/node/error.js +34 -0
  47. package/dist/public/node/error.js.map +1 -1
  48. package/dist/public/node/graphiql/server.js +2 -2
  49. package/dist/public/node/graphiql/server.js.map +1 -1
  50. package/dist/public/node/local-storage.js +10 -1
  51. package/dist/public/node/local-storage.js.map +1 -1
  52. package/dist/public/node/node-package-manager.js +2 -13
  53. package/dist/public/node/node-package-manager.js.map +1 -1
  54. package/dist/public/node/session.d.ts +13 -0
  55. package/dist/public/node/session.js +26 -1
  56. package/dist/public/node/session.js.map +1 -1
  57. package/dist/public/node/system.js +2 -3
  58. package/dist/public/node/system.js.map +1 -1
  59. package/dist/public/node/themes/api.js +9 -2
  60. package/dist/public/node/themes/api.js.map +1 -1
  61. package/dist/public/node/tree-kill.js +12 -25
  62. package/dist/public/node/tree-kill.js.map +1 -1
  63. package/dist/tsconfig.tsbuildinfo +1 -1
  64. package/package.json +4 -4
@@ -1,7 +1,9 @@
1
1
  import { normalizePath } from './path.js';
2
2
  import { stringifyMessage, TokenizedString } from './output.js';
3
3
  import { tokenItemToString } from '../../private/node/ui/components/TokenizedText.js';
4
+ import { hasRateLimitCode } from '../../private/node/analytics/graphql-error-codes.js';
4
5
  import { Errors } from '@oclif/core';
6
+ import { ClientError } from 'graphql-request';
5
7
  export { ExtendableError } from 'ts-error';
6
8
  export var FatalErrorType;
7
9
  (function (FatalErrorType) {
@@ -155,6 +157,12 @@ export function shouldReportErrorAsUnexpected(error) {
155
157
  if (!isFatal(error)) {
156
158
  // this means its not one of the CLI wrapped errors
157
159
  if (error instanceof Error) {
160
+ // Raw API errors that slip through unwrapped (e.g. the handleErrors:false path) are expected
161
+ // environmental conditions, not CLI bugs. Treat them as expected so they don't pollute crash
162
+ // reporting.
163
+ if (isExpectedApiError(error)) {
164
+ return false;
165
+ }
158
166
  const message = error.message;
159
167
  return !errorMessageImpliesEnvironmentIssue(message);
160
168
  }
@@ -165,6 +173,32 @@ export function shouldReportErrorAsUnexpected(error) {
165
173
  }
166
174
  return false;
167
175
  }
176
+ /**
177
+ * Detects raw graphql-request `ClientError`s that are expected environmental conditions rather than
178
+ * CLI bugs. These reach the reporter as plain `Error`s (not `FatalError`s) and would otherwise be
179
+ * reported as unexpected. Two distinct cases, both kept out of crash reporting:
180
+ *
181
+ * HTTP 401 (unauthenticated) is not "transient" in the retry sense — it means the user's session
182
+ * token is expired or invalid, a credential/environment condition (see issue #7891). Rate limiting
183
+ * (HTTP 429, or a `THROTTLED`/`429` GraphQL code on any error in the response) matches the shape
184
+ * detected by `errorsIncludeStatus429` in `private/node/api.ts`.
185
+ *
186
+ * Scoped to the external `ClientError` type only — importing the cli-kit `GraphQLClientError`
187
+ * wrapper here would create an `error.ts → headers.ts → error.ts` import cycle.
188
+ *
189
+ * @param error - Error to be checked.
190
+ * @returns A boolean indicating if the error is a known expected API error.
191
+ */
192
+ function isExpectedApiError(error) {
193
+ if (!(error instanceof ClientError)) {
194
+ return false;
195
+ }
196
+ const status = error.response?.status;
197
+ if (status === 401 || status === 429) {
198
+ return true;
199
+ }
200
+ return hasRateLimitCode(error.response?.errors);
201
+ }
168
202
  /**
169
203
  * Stack traces usually have file:// - we strip that and also remove the Windows drive designation.
170
204
  *
@@ -1 +1 @@
1
- {"version":3,"file":"error.js","sourceRoot":"","sources":["../../../src/public/node/error.ts"],"names":[],"mappings":"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","sourcesContent":["import {normalizePath} from './path.js'\nimport {OutputMessage, stringifyMessage, TokenizedString} from './output.js'\nimport {InlineToken, TokenItem, tokenItemToString} from '../../private/node/ui/components/TokenizedText.js'\n\nimport {Errors} from '@oclif/core'\n\nimport type {AlertCustomSection} from './ui.js'\n\nexport {ExtendableError} from 'ts-error'\n\nexport enum FatalErrorType {\n Abort,\n AbortSilent,\n Bug,\n}\n\nexport class CancelExecution extends Error {}\n\n/**\n * A fatal error represents an error shouldn't be rescued and that causes the execution to terminate.\n * There shouldn't be code that catches fatal errors.\n */\nexport abstract class FatalError extends Error {\n tryMessage: TokenItem | null\n type: FatalErrorType\n nextSteps?: TokenItem<InlineToken>[]\n formattedMessage?: TokenItem\n customSections?: AlertCustomSection[]\n skipOclifErrorHandling: boolean\n /**\n * Creates a new FatalError error.\n *\n * @param message - The error message.\n * @param type - The type of fatal error.\n * @param tryMessage - The message that recommends next steps to the user.\n * You can pass a string a {@link TokenizedString} or a {@link TokenItem}\n * if you need to style the message inside the error Banner component.\n * @param nextSteps - Message to show as \"next steps\" with suggestions to solve the issue.\n * @param customSections - Custom sections to show in the error banner. To be used if nextSteps is not enough.\n */\n constructor(\n message: TokenItem | OutputMessage,\n type: FatalErrorType,\n tryMessage: TokenItem | OutputMessage | null = null,\n nextSteps?: TokenItem<InlineToken>[],\n customSections?: AlertCustomSection[],\n ) {\n const messageIsOutputMessage = typeof message === 'string' || 'value' in message\n super(messageIsOutputMessage ? stringifyMessage(message) : tokenItemToString(message))\n\n if (tryMessage) {\n if (tryMessage instanceof TokenizedString) {\n this.tryMessage = stringifyMessage(tryMessage)\n } else {\n this.tryMessage = tryMessage\n }\n } else {\n this.tryMessage = null\n }\n\n this.type = type\n this.nextSteps = nextSteps\n this.customSections = customSections\n this.skipOclifErrorHandling = true\n\n if (!messageIsOutputMessage) {\n this.formattedMessage = message\n }\n }\n}\n\n/**\n * An abort error is a fatal error that shouldn't be reported as a bug.\n * Those usually represent unexpected scenarios that we can't handle and that usually require some action from the developer.\n */\nexport class AbortError extends FatalError {\n nextSteps?: TokenItem<InlineToken>[]\n customSections?: AlertCustomSection[]\n\n constructor(\n message: TokenItem | OutputMessage,\n tryMessage: TokenItem | OutputMessage | null = null,\n nextSteps?: TokenItem<InlineToken>[],\n customSections?: AlertCustomSection[],\n ) {\n super(message, FatalErrorType.Abort, tryMessage, nextSteps, customSections)\n }\n}\n\n/**\n * An external error is similar to Abort but has extra command and args attributes.\n * This is useful to represent errors coming from external commands, usually executed by execa.\n */\nexport class ExternalError extends FatalError {\n command: string\n args: string[]\n\n constructor(\n message: OutputMessage,\n command: string,\n args: string[],\n tryMessage: TokenItem | OutputMessage | null = null,\n ) {\n super(message, FatalErrorType.Abort, tryMessage)\n this.command = command\n this.args = args\n }\n}\n\nexport class AbortSilentError extends FatalError {\n constructor() {\n super('', FatalErrorType.AbortSilent)\n }\n}\n\n/**\n * A bug error is an error that represents a bug and therefore should be reported.\n */\nexport class BugError extends FatalError {\n constructor(message: TokenItem | OutputMessage, tryMessage: TokenItem | OutputMessage | null = null) {\n super(message, FatalErrorType.Bug, tryMessage)\n }\n}\n\n/**\n * A function that handles errors that blow up in the CLI.\n *\n * @param error - Error to be handled.\n * @returns A promise that resolves with the error passed.\n */\nexport async function handler(error: unknown): Promise<unknown> {\n let fatal: FatalError\n if (isFatal(error)) {\n fatal = error\n } else if (typeof error === 'string') {\n fatal = new BugError(error)\n } else if (error instanceof Error) {\n fatal = new BugError(error.message)\n fatal.stack = error.stack\n } else {\n // errors can come in all shapes and sizes...\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const maybeError = error as any\n fatal = new BugError(maybeError?.message ?? 'Unknown error')\n if (maybeError?.stack) {\n fatal.stack = maybeError?.stack\n }\n }\n\n const {renderFatalError} = await import('./ui.js')\n renderFatalError(fatal)\n return Promise.resolve(error)\n}\n\n/**\n * A function that maps an error to an Abort with the stack trace when coming from the CLI.\n *\n * @param error - Error to be mapped.\n * @returns A promise that resolves with the new error object.\n */\nexport function errorMapper(error: unknown): Promise<unknown> {\n if (error instanceof Errors.CLIError) {\n const mappedError = new AbortError(error.message)\n mappedError.stack = error.stack\n return Promise.resolve(mappedError)\n } else {\n return Promise.resolve(error)\n }\n}\n\n/**\n * A function that checks if an error is a fatal one.\n *\n * @param error - Error to be checked.\n * @returns A boolean indicating if the error is a fatal one.\n */\nfunction isFatal(error: unknown): error is FatalError {\n try {\n return Object.prototype.hasOwnProperty.call(error, 'type')\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return false\n }\n}\n\n/**\n * A function that checks if an error should be reported as unexpected.\n *\n * @param error - Error to be checked.\n * @returns A boolean indicating if the error should be reported as unexpected.\n */\nexport function shouldReportErrorAsUnexpected(error: unknown): boolean {\n if (!isFatal(error)) {\n // this means its not one of the CLI wrapped errors\n if (error instanceof Error) {\n const message = error.message\n return !errorMessageImpliesEnvironmentIssue(message)\n }\n return true\n }\n if (error.type === FatalErrorType.Bug) {\n return true\n }\n return false\n}\n\n/**\n * Stack traces usually have file:// - we strip that and also remove the Windows drive designation.\n *\n * @param filePath - Path to be cleaned.\n * @returns The cleaned path.\n */\nexport function cleanSingleStackTracePath(filePath: string): string {\n return normalizePath(filePath)\n .replace('file:/', '/')\n .replace(/^\\/?[A-Z]:/, '')\n}\n\n/**\n * There are certain errors that we know are not due to a CLI bug, but are environmental/user error.\n *\n * @param message - The error message to check.\n * @returns A boolean indicating if the error message implies an environment issue.\n */\nfunction errorMessageImpliesEnvironmentIssue(message: string): boolean {\n const environmentIssueMessages = [\n 'EPERM: operation not permitted, scandir',\n 'EPERM: operation not permitted, rename',\n 'EACCES: permission denied',\n 'EPERM: operation not permitted, symlink',\n 'This version of npm supports the following node versions',\n 'EBUSY: resource busy or locked',\n 'ENOTEMPTY: directory not empty',\n 'getaddrinfo ENOTFOUND',\n 'Client network socket disconnected before secure TLS connection was established',\n 'spawn EPERM',\n 'socket hang up',\n 'The user aborted a request.',\n 'write EPIPE',\n 'Unsupported platform',\n ]\n const anyMatches = environmentIssueMessages.some((issueMessage) => message.includes(issueMessage))\n return anyMatches\n}\n"]}
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../../../src/public/node/error.ts"],"names":[],"mappings":"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","sourcesContent":["import {normalizePath} from './path.js'\nimport {OutputMessage, stringifyMessage, TokenizedString} from './output.js'\nimport {InlineToken, TokenItem, tokenItemToString} from '../../private/node/ui/components/TokenizedText.js'\nimport {hasRateLimitCode} from '../../private/node/analytics/graphql-error-codes.js'\n\nimport {Errors} from '@oclif/core'\nimport {ClientError} from 'graphql-request'\n\nimport type {AlertCustomSection} from './ui.js'\n\nexport {ExtendableError} from 'ts-error'\n\nexport enum FatalErrorType {\n Abort,\n AbortSilent,\n Bug,\n}\n\nexport class CancelExecution extends Error {}\n\n/**\n * A fatal error represents an error shouldn't be rescued and that causes the execution to terminate.\n * There shouldn't be code that catches fatal errors.\n */\nexport abstract class FatalError extends Error {\n tryMessage: TokenItem | null\n type: FatalErrorType\n nextSteps?: TokenItem<InlineToken>[]\n formattedMessage?: TokenItem\n customSections?: AlertCustomSection[]\n skipOclifErrorHandling: boolean\n /**\n * Creates a new FatalError error.\n *\n * @param message - The error message.\n * @param type - The type of fatal error.\n * @param tryMessage - The message that recommends next steps to the user.\n * You can pass a string a {@link TokenizedString} or a {@link TokenItem}\n * if you need to style the message inside the error Banner component.\n * @param nextSteps - Message to show as \"next steps\" with suggestions to solve the issue.\n * @param customSections - Custom sections to show in the error banner. To be used if nextSteps is not enough.\n */\n constructor(\n message: TokenItem | OutputMessage,\n type: FatalErrorType,\n tryMessage: TokenItem | OutputMessage | null = null,\n nextSteps?: TokenItem<InlineToken>[],\n customSections?: AlertCustomSection[],\n ) {\n const messageIsOutputMessage = typeof message === 'string' || 'value' in message\n super(messageIsOutputMessage ? stringifyMessage(message) : tokenItemToString(message))\n\n if (tryMessage) {\n if (tryMessage instanceof TokenizedString) {\n this.tryMessage = stringifyMessage(tryMessage)\n } else {\n this.tryMessage = tryMessage\n }\n } else {\n this.tryMessage = null\n }\n\n this.type = type\n this.nextSteps = nextSteps\n this.customSections = customSections\n this.skipOclifErrorHandling = true\n\n if (!messageIsOutputMessage) {\n this.formattedMessage = message\n }\n }\n}\n\n/**\n * An abort error is a fatal error that shouldn't be reported as a bug.\n * Those usually represent unexpected scenarios that we can't handle and that usually require some action from the developer.\n */\nexport class AbortError extends FatalError {\n nextSteps?: TokenItem<InlineToken>[]\n customSections?: AlertCustomSection[]\n\n constructor(\n message: TokenItem | OutputMessage,\n tryMessage: TokenItem | OutputMessage | null = null,\n nextSteps?: TokenItem<InlineToken>[],\n customSections?: AlertCustomSection[],\n ) {\n super(message, FatalErrorType.Abort, tryMessage, nextSteps, customSections)\n }\n}\n\n/**\n * An external error is similar to Abort but has extra command and args attributes.\n * This is useful to represent errors coming from external commands, usually executed by execa.\n */\nexport class ExternalError extends FatalError {\n command: string\n args: string[]\n\n constructor(\n message: OutputMessage,\n command: string,\n args: string[],\n tryMessage: TokenItem | OutputMessage | null = null,\n ) {\n super(message, FatalErrorType.Abort, tryMessage)\n this.command = command\n this.args = args\n }\n}\n\nexport class AbortSilentError extends FatalError {\n constructor() {\n super('', FatalErrorType.AbortSilent)\n }\n}\n\n/**\n * A bug error is an error that represents a bug and therefore should be reported.\n */\nexport class BugError extends FatalError {\n constructor(message: TokenItem | OutputMessage, tryMessage: TokenItem | OutputMessage | null = null) {\n super(message, FatalErrorType.Bug, tryMessage)\n }\n}\n\n/**\n * A function that handles errors that blow up in the CLI.\n *\n * @param error - Error to be handled.\n * @returns A promise that resolves with the error passed.\n */\nexport async function handler(error: unknown): Promise<unknown> {\n let fatal: FatalError\n if (isFatal(error)) {\n fatal = error\n } else if (typeof error === 'string') {\n fatal = new BugError(error)\n } else if (error instanceof Error) {\n fatal = new BugError(error.message)\n fatal.stack = error.stack\n } else {\n // errors can come in all shapes and sizes...\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const maybeError = error as any\n fatal = new BugError(maybeError?.message ?? 'Unknown error')\n if (maybeError?.stack) {\n fatal.stack = maybeError?.stack\n }\n }\n\n const {renderFatalError} = await import('./ui.js')\n renderFatalError(fatal)\n return Promise.resolve(error)\n}\n\n/**\n * A function that maps an error to an Abort with the stack trace when coming from the CLI.\n *\n * @param error - Error to be mapped.\n * @returns A promise that resolves with the new error object.\n */\nexport function errorMapper(error: unknown): Promise<unknown> {\n if (error instanceof Errors.CLIError) {\n const mappedError = new AbortError(error.message)\n mappedError.stack = error.stack\n return Promise.resolve(mappedError)\n } else {\n return Promise.resolve(error)\n }\n}\n\n/**\n * A function that checks if an error is a fatal one.\n *\n * @param error - Error to be checked.\n * @returns A boolean indicating if the error is a fatal one.\n */\nfunction isFatal(error: unknown): error is FatalError {\n try {\n return Object.prototype.hasOwnProperty.call(error, 'type')\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return false\n }\n}\n\n/**\n * A function that checks if an error should be reported as unexpected.\n *\n * @param error - Error to be checked.\n * @returns A boolean indicating if the error should be reported as unexpected.\n */\nexport function shouldReportErrorAsUnexpected(error: unknown): boolean {\n if (!isFatal(error)) {\n // this means its not one of the CLI wrapped errors\n if (error instanceof Error) {\n // Raw API errors that slip through unwrapped (e.g. the handleErrors:false path) are expected\n // environmental conditions, not CLI bugs. Treat them as expected so they don't pollute crash\n // reporting.\n if (isExpectedApiError(error)) {\n return false\n }\n const message = error.message\n return !errorMessageImpliesEnvironmentIssue(message)\n }\n return true\n }\n if (error.type === FatalErrorType.Bug) {\n return true\n }\n return false\n}\n\n/**\n * Detects raw graphql-request `ClientError`s that are expected environmental conditions rather than\n * CLI bugs. These reach the reporter as plain `Error`s (not `FatalError`s) and would otherwise be\n * reported as unexpected. Two distinct cases, both kept out of crash reporting:\n *\n * HTTP 401 (unauthenticated) is not \"transient\" in the retry sense — it means the user's session\n * token is expired or invalid, a credential/environment condition (see issue #7891). Rate limiting\n * (HTTP 429, or a `THROTTLED`/`429` GraphQL code on any error in the response) matches the shape\n * detected by `errorsIncludeStatus429` in `private/node/api.ts`.\n *\n * Scoped to the external `ClientError` type only — importing the cli-kit `GraphQLClientError`\n * wrapper here would create an `error.ts → headers.ts → error.ts` import cycle.\n *\n * @param error - Error to be checked.\n * @returns A boolean indicating if the error is a known expected API error.\n */\nfunction isExpectedApiError(error: Error): boolean {\n if (!(error instanceof ClientError)) {\n return false\n }\n const status = error.response?.status\n if (status === 401 || status === 429) {\n return true\n }\n return hasRateLimitCode(error.response?.errors)\n}\n\n/**\n * Stack traces usually have file:// - we strip that and also remove the Windows drive designation.\n *\n * @param filePath - Path to be cleaned.\n * @returns The cleaned path.\n */\nexport function cleanSingleStackTracePath(filePath: string): string {\n return normalizePath(filePath)\n .replace('file:/', '/')\n .replace(/^\\/?[A-Z]:/, '')\n}\n\n/**\n * There are certain errors that we know are not due to a CLI bug, but are environmental/user error.\n *\n * @param message - The error message to check.\n * @returns A boolean indicating if the error message implies an environment issue.\n */\nfunction errorMessageImpliesEnvironmentIssue(message: string): boolean {\n const environmentIssueMessages = [\n 'EPERM: operation not permitted, scandir',\n 'EPERM: operation not permitted, rename',\n 'EACCES: permission denied',\n 'EPERM: operation not permitted, symlink',\n 'This version of npm supports the following node versions',\n 'EBUSY: resource busy or locked',\n 'ENOTEMPTY: directory not empty',\n 'getaddrinfo ENOTFOUND',\n 'Client network socket disconnected before secure TLS connection was established',\n 'spawn EPERM',\n 'socket hang up',\n 'The user aborted a request.',\n 'write EPIPE',\n 'Unsupported platform',\n ]\n const anyMatches = environmentIssueMessages.some((issueMessage) => message.includes(issueMessage))\n return anyMatches\n}\n"]}
@@ -82,9 +82,9 @@ export function setupGraphiQLServer(options) {
82
82
  async function fetchApiVersionsWithTokenRefresh() {
83
83
  return performActionWithRetryAfterRecovery(async () => supportedApiVersions({ storeFqdn, token: await currentToken() }), refreshUpstreamToken);
84
84
  }
85
- const faviconPath = require.resolve('@shopify/cli-kit/assets/graphiql/favicon.ico');
85
+ const faviconPath = require.resolve('../../../../assets/graphiql/favicon.ico');
86
86
  const faviconContent = readFileSync(faviconPath);
87
- const stylePath = require.resolve('@shopify/cli-kit/assets/graphiql/style.css');
87
+ const stylePath = require.resolve('../../../../assets/graphiql/style.css');
88
88
  const styleContent = readFileSync(stylePath, 'utf8');
89
89
  app.use(defineEventHandler((event) => {
90
90
  setResponseHeader(event, 'Access-Control-Allow-Origin', '*');
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../../src/public/node/graphiql/server.ts"],"names":[],"mappings":"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","sourcesContent":["import {defaultQuery, graphiqlTemplate} from './templates/graphiql.js'\nimport {unauthorizedTemplate} from './templates/unauthorized.js'\nimport {filterCustomHeaders} from './utilities.js'\nimport {performActionWithRetryAfterRecovery} from '../../common/retry.js'\nimport {CLI_KIT_VERSION} from '../../common/version.js'\nimport {AbortError} from '../error.js'\nimport {adminUrl, supportedApiVersions} from '../api/admin.js'\nimport {fetch} from '../http.js'\nimport {renderLiquidTemplate} from '../liquid.js'\nimport {outputDebug} from '../output.js'\nimport {containsMutation} from '../graphql.js'\nimport {\n createApp,\n createRouter,\n defineEventHandler,\n getQuery,\n getRequestHeader,\n getRequestHeaders,\n readBody,\n setResponseHeader,\n setResponseStatus,\n toNodeListener,\n} from 'h3'\nimport {createHmac, randomBytes} from 'crypto'\nimport {createServer, Server} from 'http'\nimport {readFileSync} from 'fs'\nimport {Writable} from 'stream'\nimport {createRequire} from 'module'\n\n/**\n * Derives a deterministic GraphiQL authentication key from the app's API secret and store FQDN.\n * The key is stable across dev server restarts (so browser tabs survive restarts)\n * but is not guessable without the app secret.\n *\n * @param apiSecret - The Partners app's client secret used as the HMAC key.\n * @param storeFqdn - The myshopify.com domain the GraphiQL session targets.\n * @returns A 64-character hex string suitable for use as the `?key=` query param.\n */\nexport function deriveGraphiQLKey(apiSecret: string, storeFqdn: string): string {\n return createHmac('sha256', apiSecret).update(`graphiql:${storeFqdn}`).digest('hex')\n}\n\n/**\n * Resolves the GraphiQL authentication key. Uses the explicitly provided key\n * if non-empty, otherwise derives one deterministically from the app secret.\n *\n * @param providedKey - An explicit key supplied by the caller; takes precedence when non-empty.\n * @param apiSecret - The Partners app's client secret, used to derive a stable key as a fallback.\n * @param storeFqdn - The myshopify.com domain the GraphiQL session targets.\n * @returns The resolved key.\n */\nexport function resolveGraphiQLKey(providedKey: string | undefined, apiSecret: string, storeFqdn: string): string {\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- intentional: empty string after trim should fall through to deriveGraphiQLKey\n return providedKey?.trim() || deriveGraphiQLKey(apiSecret, storeFqdn)\n}\n\nconst require = createRequire(import.meta.url)\n\nclass TokenRefreshError extends AbortError {\n constructor() {\n super('Failed to refresh credentials. Check that your app is installed, and try again.')\n }\n}\n\n/**\n * Pluggable strategy for obtaining and refreshing the Admin API access token\n * that the GraphiQL proxy injects into every request.\n *\n * - `getToken` may return a cached token; the proxy calls it for every request.\n * - `refreshToken` (optional) is invoked when the upstream Admin API returns 401.\n * When omitted, the proxy falls back to calling `getToken` again on 401.\n *\n * Implementations must throw `TokenRefreshError` (or any thrown error) when the\n * token cannot be obtained; the proxy renders the unauthorized template in that case.\n */\nexport interface TokenProvider {\n getToken: () => Promise<string>\n refreshToken?: () => Promise<string>\n}\n\n/**\n * Optional app-specific context, used to render the app pill and scopes note in the\n * GraphiQL header and to drive the deterministic key derivation. Pass when the GraphiQL\n * server is hosted as part of `shopify app dev`; omit for app-less use cases such as\n * `shopify store execute`.\n */\nexport interface GraphiQLAppContext {\n appName: string\n appUrl: string\n apiSecret: string\n}\n\nexport interface SetupGraphiQLServerOptions {\n stdout: Writable\n port: number\n storeFqdn: string\n tokenProvider: TokenProvider\n /**\n * Authentication key required as a `?key=` query string on every request. When omitted:\n * - if `appContext` is provided, derived deterministically from `apiSecret` + `storeFqdn`\n * so browser tabs survive dev server restarts.\n * - otherwise, generated randomly per process.\n */\n key?: string\n appContext?: GraphiQLAppContext\n /**\n * When true, the proxy rejects mutation operations with HTTP 400 before forwarding\n * them to the Admin API. Use this to mirror non-interactive safety guarantees in the\n * interactive UI.\n */\n protectMutations?: boolean\n}\n\nexport const MUTATIONS_BLOCKED_MESSAGE = 'Mutations are disabled. Re-run with --allow-mutations to enable mutations.'\n\n/**\n * Starts a local HTTP server that hosts the GraphiQL UI and proxies requests to the\n * Admin API for the configured store. Authentication is delegated to the supplied\n * `tokenProvider`, so the same server can serve both `shopify app dev` and stored-session\n * use cases.\n *\n * @param options - Configuration for the server, including the target store, the\n * pluggable token provider, and the local port to bind to.\n * @returns The underlying Node `http.Server` instance, already listening on `options.port`.\n */\nexport function setupGraphiQLServer(options: SetupGraphiQLServerOptions): Server {\n const {stdout, port, storeFqdn, tokenProvider, key: providedKey, appContext, protectMutations = false} = options\n const key = resolveGraphiQLServerKey(providedKey, appContext, storeFqdn)\n outputDebug(`Setting up GraphiQL HTTP server on port ${port}...`, stdout)\n\n const app = createApp()\n const router = createRouter()\n\n const refreshUpstreamToken = async (): Promise<string> => {\n try {\n outputDebug('refreshing token', stdout)\n return await (tokenProvider.refreshToken ?? tokenProvider.getToken)()\n } catch (_error) {\n throw new TokenRefreshError()\n }\n }\n\n const currentToken = async (): Promise<string> => {\n try {\n return await tokenProvider.getToken()\n } catch (_error) {\n throw new TokenRefreshError()\n }\n }\n\n async function fetchApiVersionsWithTokenRefresh(): Promise<string[]> {\n return performActionWithRetryAfterRecovery(\n async () => supportedApiVersions({storeFqdn, token: await currentToken()}),\n refreshUpstreamToken,\n )\n }\n\n const faviconPath = require.resolve('@shopify/cli-kit/assets/graphiql/favicon.ico')\n const faviconContent = readFileSync(faviconPath)\n const stylePath = require.resolve('@shopify/cli-kit/assets/graphiql/style.css')\n const styleContent = readFileSync(stylePath, 'utf8')\n\n app.use(\n defineEventHandler((event) => {\n setResponseHeader(event, 'Access-Control-Allow-Origin', '*')\n setResponseHeader(event, 'Access-Control-Allow-Methods', 'GET, OPTIONS')\n setResponseHeader(\n event,\n 'Access-Control-Allow-Headers',\n 'Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, ngrok-skip-browser-warning',\n )\n }),\n )\n\n router.get(\n '/graphiql/ping',\n defineEventHandler(() => 'pong'),\n )\n\n router.get(\n '/graphiql/favicon.ico',\n defineEventHandler((event) => {\n setResponseHeader(event, 'Content-Type', 'image/x-icon')\n return faviconContent\n }),\n )\n\n router.get(\n '/graphiql/simple.css',\n defineEventHandler((event) => {\n setResponseHeader(event, 'Content-Type', 'text/css')\n return styleContent\n }),\n )\n\n router.get(\n '/graphiql/status',\n defineEventHandler(async () => {\n try {\n await fetchApiVersionsWithTokenRefresh()\n return {status: 'OK', storeFqdn, appName: appContext?.appName, appUrl: appContext?.appUrl}\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return {status: 'UNAUTHENTICATED'}\n }\n }),\n )\n\n router.get(\n '/graphiql',\n defineEventHandler(async (event) => {\n outputDebug('Handling /graphiql request', stdout)\n\n const query = getQuery(event)\n\n if (key && query.key !== key) {\n setResponseStatus(event, 404)\n return `Invalid path ${event.path}`\n }\n\n const forwardedProto = getRequestHeader(event, 'x-forwarded-proto')\n const usesHttps = forwardedProto === 'https'\n const host = getRequestHeader(event, 'host')\n const url = `http${usesHttps ? 's' : ''}://${host}`\n\n let apiVersions: string[]\n try {\n apiVersions = await fetchApiVersionsWithTokenRefresh()\n } catch (err) {\n if (err instanceof TokenRefreshError) {\n return renderLiquidTemplate(unauthorizedTemplate({hasAppContext: Boolean(appContext)}), {\n previewUrl: appContext?.appUrl ?? '',\n storeFqdn,\n url,\n })\n }\n throw err\n }\n\n const apiVersion = apiVersions.sort().reverse()[0]!\n\n function decodeQueryString(input: string | undefined) {\n return input ? decodeURIComponent(input).replace(/\\n/g, '\\\\n') : undefined\n }\n\n const queryParam = decodeQueryString(query.query as string | undefined)\n const variables = decodeQueryString(query.variables as string | undefined)\n\n return renderLiquidTemplate(\n graphiqlTemplate({\n apiVersion,\n apiVersions: [...apiVersions, 'unstable'],\n appName: appContext?.appName,\n appUrl: appContext?.appUrl,\n key,\n storeFqdn,\n protectMutations,\n }),\n {\n url,\n defaultQueries: [{query: defaultQuery}],\n query: queryParam ? JSON.stringify(queryParam) : undefined,\n variables: variables ? JSON.stringify(variables) : undefined,\n },\n )\n }),\n )\n\n router.post(\n '/graphiql/graphql.json',\n defineEventHandler(async (event) => {\n outputDebug('Handling /graphiql/graphql.json request', stdout)\n\n const query = getQuery(event)\n\n if (key && query.key !== key) {\n setResponseStatus(event, 404)\n return `Invalid path ${event.path}`\n }\n\n const graphqlUrl = adminUrl(storeFqdn, query.api_version as string)\n try {\n const body = await readBody(event)\n\n if (protectMutations && isMutationRequestBody(body)) {\n setResponseStatus(event, 400)\n return {errors: [{message: MUTATIONS_BLOCKED_MESSAGE}]}\n }\n\n const reqBody = JSON.stringify(body)\n\n const reqHeaders = getRequestHeaders(event)\n const customHeaders = filterCustomHeaders(reqHeaders)\n\n const runRequest = async (token: string) => {\n const headers = {\n ...customHeaders,\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n 'X-Shopify-Access-Token': token,\n 'User-Agent': `ShopifyCLIGraphiQL/${CLI_KIT_VERSION}`,\n }\n\n return fetch(graphqlUrl, {\n method: 'POST',\n headers,\n body: reqBody,\n })\n }\n\n let result = await runRequest(await currentToken())\n if (result.status === 401) {\n outputDebug('Token expired, fetching new token', stdout)\n result = await runRequest(await refreshUpstreamToken())\n }\n\n setResponseHeader(event, 'Content-Type', 'application/json')\n setResponseStatus(event, result.status)\n return result.json()\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error: unknown) {\n setResponseStatus(event, 500)\n if (error instanceof Error) {\n return {errors: [error.message]}\n }\n return {errors: ['Unknown error']}\n }\n }),\n )\n\n app.use(router)\n\n const server = createServer(toNodeListener(app))\n server.listen(port, 'localhost', () => stdout.write(`GraphiQL server started on port ${port}`))\n return server\n}\n\n// Picks the right key based on what the caller supplied:\n// - explicit non-empty key → use it\n// - app context with apiSecret → derive deterministically (stable across restarts)\n// - otherwise → random per-process key (browser tabs won't survive restarts, which is\n// the right tradeoff when there's no stable secret to derive from).\nfunction resolveGraphiQLServerKey(\n providedKey: string | undefined,\n appContext: GraphiQLAppContext | undefined,\n storeFqdn: string,\n): string {\n const trimmed = providedKey?.trim()\n if (trimmed) return trimmed\n if (appContext) return deriveGraphiQLKey(appContext.apiSecret, storeFqdn)\n return randomBytes(32).toString('hex')\n}\n\nfunction isMutationRequestBody(body: unknown): boolean {\n if (typeof body !== 'object' || body === null) return false\n const {query, operationName} = body as {query?: unknown; operationName?: unknown}\n if (typeof query !== 'string') return false\n return containsMutation(query, typeof operationName === 'string' ? operationName : undefined)\n}\n"]}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../../src/public/node/graphiql/server.ts"],"names":[],"mappings":"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","sourcesContent":["import {defaultQuery, graphiqlTemplate} from './templates/graphiql.js'\nimport {unauthorizedTemplate} from './templates/unauthorized.js'\nimport {filterCustomHeaders} from './utilities.js'\nimport {performActionWithRetryAfterRecovery} from '../../common/retry.js'\nimport {CLI_KIT_VERSION} from '../../common/version.js'\nimport {AbortError} from '../error.js'\nimport {adminUrl, supportedApiVersions} from '../api/admin.js'\nimport {fetch} from '../http.js'\nimport {renderLiquidTemplate} from '../liquid.js'\nimport {outputDebug} from '../output.js'\nimport {containsMutation} from '../graphql.js'\nimport {\n createApp,\n createRouter,\n defineEventHandler,\n getQuery,\n getRequestHeader,\n getRequestHeaders,\n readBody,\n setResponseHeader,\n setResponseStatus,\n toNodeListener,\n} from 'h3'\nimport {createHmac, randomBytes} from 'crypto'\nimport {createServer, Server} from 'http'\nimport {readFileSync} from 'fs'\nimport {Writable} from 'stream'\nimport {createRequire} from 'module'\n\n/**\n * Derives a deterministic GraphiQL authentication key from the app's API secret and store FQDN.\n * The key is stable across dev server restarts (so browser tabs survive restarts)\n * but is not guessable without the app secret.\n *\n * @param apiSecret - The Partners app's client secret used as the HMAC key.\n * @param storeFqdn - The myshopify.com domain the GraphiQL session targets.\n * @returns A 64-character hex string suitable for use as the `?key=` query param.\n */\nexport function deriveGraphiQLKey(apiSecret: string, storeFqdn: string): string {\n return createHmac('sha256', apiSecret).update(`graphiql:${storeFqdn}`).digest('hex')\n}\n\n/**\n * Resolves the GraphiQL authentication key. Uses the explicitly provided key\n * if non-empty, otherwise derives one deterministically from the app secret.\n *\n * @param providedKey - An explicit key supplied by the caller; takes precedence when non-empty.\n * @param apiSecret - The Partners app's client secret, used to derive a stable key as a fallback.\n * @param storeFqdn - The myshopify.com domain the GraphiQL session targets.\n * @returns The resolved key.\n */\nexport function resolveGraphiQLKey(providedKey: string | undefined, apiSecret: string, storeFqdn: string): string {\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- intentional: empty string after trim should fall through to deriveGraphiQLKey\n return providedKey?.trim() || deriveGraphiQLKey(apiSecret, storeFqdn)\n}\n\nconst require = createRequire(import.meta.url)\n\nclass TokenRefreshError extends AbortError {\n constructor() {\n super('Failed to refresh credentials. Check that your app is installed, and try again.')\n }\n}\n\n/**\n * Pluggable strategy for obtaining and refreshing the Admin API access token\n * that the GraphiQL proxy injects into every request.\n *\n * - `getToken` may return a cached token; the proxy calls it for every request.\n * - `refreshToken` (optional) is invoked when the upstream Admin API returns 401.\n * When omitted, the proxy falls back to calling `getToken` again on 401.\n *\n * Implementations must throw `TokenRefreshError` (or any thrown error) when the\n * token cannot be obtained; the proxy renders the unauthorized template in that case.\n */\nexport interface TokenProvider {\n getToken: () => Promise<string>\n refreshToken?: () => Promise<string>\n}\n\n/**\n * Optional app-specific context, used to render the app pill and scopes note in the\n * GraphiQL header and to drive the deterministic key derivation. Pass when the GraphiQL\n * server is hosted as part of `shopify app dev`; omit for app-less use cases such as\n * `shopify store execute`.\n */\nexport interface GraphiQLAppContext {\n appName: string\n appUrl: string\n apiSecret: string\n}\n\nexport interface SetupGraphiQLServerOptions {\n stdout: Writable\n port: number\n storeFqdn: string\n tokenProvider: TokenProvider\n /**\n * Authentication key required as a `?key=` query string on every request. When omitted:\n * - if `appContext` is provided, derived deterministically from `apiSecret` + `storeFqdn`\n * so browser tabs survive dev server restarts.\n * - otherwise, generated randomly per process.\n */\n key?: string\n appContext?: GraphiQLAppContext\n /**\n * When true, the proxy rejects mutation operations with HTTP 400 before forwarding\n * them to the Admin API. Use this to mirror non-interactive safety guarantees in the\n * interactive UI.\n */\n protectMutations?: boolean\n}\n\nexport const MUTATIONS_BLOCKED_MESSAGE = 'Mutations are disabled. Re-run with --allow-mutations to enable mutations.'\n\n/**\n * Starts a local HTTP server that hosts the GraphiQL UI and proxies requests to the\n * Admin API for the configured store. Authentication is delegated to the supplied\n * `tokenProvider`, so the same server can serve both `shopify app dev` and stored-session\n * use cases.\n *\n * @param options - Configuration for the server, including the target store, the\n * pluggable token provider, and the local port to bind to.\n * @returns The underlying Node `http.Server` instance, already listening on `options.port`.\n */\nexport function setupGraphiQLServer(options: SetupGraphiQLServerOptions): Server {\n const {stdout, port, storeFqdn, tokenProvider, key: providedKey, appContext, protectMutations = false} = options\n const key = resolveGraphiQLServerKey(providedKey, appContext, storeFqdn)\n outputDebug(`Setting up GraphiQL HTTP server on port ${port}...`, stdout)\n\n const app = createApp()\n const router = createRouter()\n\n const refreshUpstreamToken = async (): Promise<string> => {\n try {\n outputDebug('refreshing token', stdout)\n return await (tokenProvider.refreshToken ?? tokenProvider.getToken)()\n } catch (_error) {\n throw new TokenRefreshError()\n }\n }\n\n const currentToken = async (): Promise<string> => {\n try {\n return await tokenProvider.getToken()\n } catch (_error) {\n throw new TokenRefreshError()\n }\n }\n\n async function fetchApiVersionsWithTokenRefresh(): Promise<string[]> {\n return performActionWithRetryAfterRecovery(\n async () => supportedApiVersions({storeFqdn, token: await currentToken()}),\n refreshUpstreamToken,\n )\n }\n\n const faviconPath = require.resolve('../../../../assets/graphiql/favicon.ico')\n const faviconContent = readFileSync(faviconPath)\n const stylePath = require.resolve('../../../../assets/graphiql/style.css')\n const styleContent = readFileSync(stylePath, 'utf8')\n\n app.use(\n defineEventHandler((event) => {\n setResponseHeader(event, 'Access-Control-Allow-Origin', '*')\n setResponseHeader(event, 'Access-Control-Allow-Methods', 'GET, OPTIONS')\n setResponseHeader(\n event,\n 'Access-Control-Allow-Headers',\n 'Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, ngrok-skip-browser-warning',\n )\n }),\n )\n\n router.get(\n '/graphiql/ping',\n defineEventHandler(() => 'pong'),\n )\n\n router.get(\n '/graphiql/favicon.ico',\n defineEventHandler((event) => {\n setResponseHeader(event, 'Content-Type', 'image/x-icon')\n return faviconContent\n }),\n )\n\n router.get(\n '/graphiql/simple.css',\n defineEventHandler((event) => {\n setResponseHeader(event, 'Content-Type', 'text/css')\n return styleContent\n }),\n )\n\n router.get(\n '/graphiql/status',\n defineEventHandler(async () => {\n try {\n await fetchApiVersionsWithTokenRefresh()\n return {status: 'OK', storeFqdn, appName: appContext?.appName, appUrl: appContext?.appUrl}\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return {status: 'UNAUTHENTICATED'}\n }\n }),\n )\n\n router.get(\n '/graphiql',\n defineEventHandler(async (event) => {\n outputDebug('Handling /graphiql request', stdout)\n\n const query = getQuery(event)\n\n if (key && query.key !== key) {\n setResponseStatus(event, 404)\n return `Invalid path ${event.path}`\n }\n\n const forwardedProto = getRequestHeader(event, 'x-forwarded-proto')\n const usesHttps = forwardedProto === 'https'\n const host = getRequestHeader(event, 'host')\n const url = `http${usesHttps ? 's' : ''}://${host}`\n\n let apiVersions: string[]\n try {\n apiVersions = await fetchApiVersionsWithTokenRefresh()\n } catch (err) {\n if (err instanceof TokenRefreshError) {\n return renderLiquidTemplate(unauthorizedTemplate({hasAppContext: Boolean(appContext)}), {\n previewUrl: appContext?.appUrl ?? '',\n storeFqdn,\n url,\n })\n }\n throw err\n }\n\n const apiVersion = apiVersions.sort().reverse()[0]!\n\n function decodeQueryString(input: string | undefined) {\n return input ? decodeURIComponent(input).replace(/\\n/g, '\\\\n') : undefined\n }\n\n const queryParam = decodeQueryString(query.query as string | undefined)\n const variables = decodeQueryString(query.variables as string | undefined)\n\n return renderLiquidTemplate(\n graphiqlTemplate({\n apiVersion,\n apiVersions: [...apiVersions, 'unstable'],\n appName: appContext?.appName,\n appUrl: appContext?.appUrl,\n key,\n storeFqdn,\n protectMutations,\n }),\n {\n url,\n defaultQueries: [{query: defaultQuery}],\n query: queryParam ? JSON.stringify(queryParam) : undefined,\n variables: variables ? JSON.stringify(variables) : undefined,\n },\n )\n }),\n )\n\n router.post(\n '/graphiql/graphql.json',\n defineEventHandler(async (event) => {\n outputDebug('Handling /graphiql/graphql.json request', stdout)\n\n const query = getQuery(event)\n\n if (key && query.key !== key) {\n setResponseStatus(event, 404)\n return `Invalid path ${event.path}`\n }\n\n const graphqlUrl = adminUrl(storeFqdn, query.api_version as string)\n try {\n const body = await readBody(event)\n\n if (protectMutations && isMutationRequestBody(body)) {\n setResponseStatus(event, 400)\n return {errors: [{message: MUTATIONS_BLOCKED_MESSAGE}]}\n }\n\n const reqBody = JSON.stringify(body)\n\n const reqHeaders = getRequestHeaders(event)\n const customHeaders = filterCustomHeaders(reqHeaders)\n\n const runRequest = async (token: string) => {\n const headers = {\n ...customHeaders,\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n 'X-Shopify-Access-Token': token,\n 'User-Agent': `ShopifyCLIGraphiQL/${CLI_KIT_VERSION}`,\n }\n\n return fetch(graphqlUrl, {\n method: 'POST',\n headers,\n body: reqBody,\n })\n }\n\n let result = await runRequest(await currentToken())\n if (result.status === 401) {\n outputDebug('Token expired, fetching new token', stdout)\n result = await runRequest(await refreshUpstreamToken())\n }\n\n setResponseHeader(event, 'Content-Type', 'application/json')\n setResponseStatus(event, result.status)\n return result.json()\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error: unknown) {\n setResponseStatus(event, 500)\n if (error instanceof Error) {\n return {errors: [error.message]}\n }\n return {errors: ['Unknown error']}\n }\n }),\n )\n\n app.use(router)\n\n const server = createServer(toNodeListener(app))\n server.listen(port, 'localhost', () => stdout.write(`GraphiQL server started on port ${port}`))\n return server\n}\n\n// Picks the right key based on what the caller supplied:\n// - explicit non-empty key → use it\n// - app context with apiSecret → derive deterministically (stable across restarts)\n// - otherwise → random per-process key (browser tabs won't survive restarts, which is\n// the right tradeoff when there's no stable secret to derive from).\nfunction resolveGraphiQLServerKey(\n providedKey: string | undefined,\n appContext: GraphiQLAppContext | undefined,\n storeFqdn: string,\n): string {\n const trimmed = providedKey?.trim()\n if (trimmed) return trimmed\n if (appContext) return deriveGraphiQLKey(appContext.apiSecret, storeFqdn)\n return randomBytes(32).toString('hex')\n}\n\nfunction isMutationRequestBody(body: unknown): boolean {\n if (typeof body !== 'object' || body === null) return false\n const {query, operationName} = body as {query?: unknown; operationName?: unknown}\n if (typeof query !== 'string') return false\n return containsMutation(query, typeof operationName === 'string' ? operationName : undefined)\n}\n"]}
@@ -2,6 +2,11 @@ import { AbortError, BugError } from './error.js';
2
2
  import { fileHasWritePermissions, unixFileIsOwnedByCurrentUser } from './fs.js';
3
3
  import { dirname } from './path.js';
4
4
  import Config from 'conf';
5
+ function deserializeJson(value) {
6
+ // Some Windows editors encode UTF-8 files with a byte order mark, which JSON.parse does not accept.
7
+ const valueWithoutByteOrderMark = value.replace(/^\uFEFF/, '');
8
+ return JSON.parse(valueWithoutByteOrderMark);
9
+ }
5
10
  /**
6
11
  * A wrapper around the `conf` package that provides a strongly-typed interface
7
12
  * for accessing the local storage.
@@ -9,7 +14,11 @@ import Config from 'conf';
9
14
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
15
  export class LocalStorage {
11
16
  constructor(options) {
12
- this.config = new Config(options);
17
+ this.config = new Config({
18
+ ...options,
19
+ clearInvalidConfig: true,
20
+ deserialize: (deserializeJson),
21
+ });
13
22
  }
14
23
  /**
15
24
  * Get a value from the local storage.
@@ -1 +1 @@
1
- {"version":3,"file":"local-storage.js","sourceRoot":"","sources":["../../../src/public/node/local-storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,QAAQ,EAAC,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAC,uBAAuB,EAAE,4BAA4B,EAAC,MAAM,SAAS,CAAA;AAC7E,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AAEjC,OAAO,MAAM,MAAM,MAAM,CAAA;AAEzB;;;GAGG;AACH,8DAA8D;AAC9D,MAAM,OAAO,YAAY;IAGvB,YAAY,OAA6C;QACvD,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAI,OAAO,CAAC,CAAA;IACtC,CAAC;IAED;;;;;;;OAOG;IACH,GAAG,CAAuB,GAAS;QACjC,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAC3B,qDAAqD;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;QAChC,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACH,GAAG,CAAuB,GAAS,EAAE,KAAe;QAClD,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;YAC3B,qDAAqD;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;QAChC,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAuB,GAAS;QACpC,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YACvB,qDAAqD;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;QACnC,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,KAAK;QACH,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAA;YACnB,qDAAqD;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;QAClC,CAAC;IACH,CAAC;IAED;;;;;;;;;OASG;IACK,WAAW,CAAC,KAAc,EAAE,SAAiB;QACnD,IAAI,IAAI,CAAC,iBAAiB,EAAE,EAAE,CAAC;YAC7B,MAAM,IAAI,UAAU,CAAC,mCAAmC,SAAS,MAAM,KAAK,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAA;QACpG,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,QAAQ,CAChB,qDAAqD,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,MAAM,KAAK,EAAE,CACjG,CAAA;QACH,CAAC;IACH,CAAC;IAEO,iBAAiB;QACvB,MAAM,aAAa,GAAG,uBAAuB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAC/D,MAAM,eAAe,GAAG,uBAAuB,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;QAC1E,MAAM,QAAQ,GAAG,4BAA4B,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAE/D,OAAO,CAAC,aAAa,IAAI,CAAC,eAAe,IAAI,QAAQ,KAAK,KAAK,CAAA;IACjE,CAAC;IAEO,UAAU;QAChB,MAAM,QAAQ,GAAG,4BAA4B,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAC/D,MAAM,UAAU,GAAG,4BAA4B,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;QAE1E,MAAM,OAAO,GAAc,CAAC,2CAA2C,EAAE,EAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAC,CAAC,CAAA;QACtG,IAAI,QAAQ,KAAK,KAAK,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;YAC/C,OAAO,CAAC,IAAI,CACV,6IAA6I,CAC9I,CAAA;QACH,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,iEAAiE,CAAC,CAAA;QAC/E,OAAO,CAAC,IAAI,CAAC,EAAC,OAAO,EAAE,UAAU,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAC,CAAC,CAAA;QAE9D,OAAO,OAAO,CAAA;IAChB,CAAC;CACF","sourcesContent":["import {AbortError, BugError} from './error.js'\nimport {fileHasWritePermissions, unixFileIsOwnedByCurrentUser} from './fs.js'\nimport {dirname} from './path.js'\nimport {TokenItem} from './ui.js'\nimport Config from 'conf'\n\n/**\n * A wrapper around the `conf` package that provides a strongly-typed interface\n * for accessing the local storage.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class LocalStorage<T extends Record<string, any>> {\n private readonly config: Config<T>\n\n constructor(options: {projectName?: string; cwd?: string}) {\n this.config = new Config<T>(options)\n }\n\n /**\n * Get a value from the local storage.\n *\n * @param key - The key to get.\n * @returns The value.\n * @throws AbortError if a permission error occurs.\n * @throws BugError if an unexpected error occurs.\n */\n get<TKey extends keyof T>(key: TKey): T[TKey] | undefined {\n try {\n return this.config.get(key)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n this.handleError(error, 'get')\n }\n }\n\n /**\n * Set a value in the local storage.\n *\n * @param key - The key to set.\n * @param value - The value to set.\n * @throws AbortError if a permission error occurs.\n * @throws BugError if an unexpected error occurs.\n */\n set<TKey extends keyof T>(key: TKey, value?: T[TKey]): void {\n try {\n this.config.set(key, value)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n this.handleError(error, 'set')\n }\n }\n\n /**\n * Delete a value from the local storage.\n *\n * @param key - The key to delete.\n * @throws AbortError if a permission error occurs.\n * @throws BugError if an unexpected error occurs.\n */\n delete<TKey extends keyof T>(key: TKey): void {\n try {\n this.config.delete(key)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n this.handleError(error, 'delete')\n }\n }\n\n /**\n * Clear the local storage (delete all values).\n *\n * @throws AbortError if a permission error occurs.\n * @throws BugError if an unexpected error occurs.\n */\n clear(): void {\n try {\n this.config.clear()\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n this.handleError(error, 'clear')\n }\n }\n\n /**\n * Handle errors from config operations.\n * If the error is permission-related, throw an AbortError with helpful hints.\n * Otherwise, throw a BugError.\n *\n * @param error - The error that occurred.\n * @param operation - The operation that failed.\n * @throws AbortError if the error is permission-related.\n * @throws BugError if the error is not permission-related.\n */\n private handleError(error: unknown, operation: string): never {\n if (this.isPermissionError()) {\n throw new AbortError(`Failed to access local storage (${operation}): ${error}`, this.tryMessage())\n } else {\n throw new BugError(\n `Unexpected error while accessing local storage at ${this.config.path} (${operation}): ${error}`,\n )\n }\n }\n\n private isPermissionError(): boolean {\n const canAccessFile = fileHasWritePermissions(this.config.path)\n const canAccessFolder = fileHasWritePermissions(dirname(this.config.path))\n const ownsFile = unixFileIsOwnedByCurrentUser(this.config.path)\n\n return !canAccessFile || !canAccessFolder || ownsFile === false\n }\n\n private tryMessage() {\n const ownsFile = unixFileIsOwnedByCurrentUser(this.config.path)\n const ownsFolder = unixFileIsOwnedByCurrentUser(dirname(this.config.path))\n\n const message: TokenItem = [`Check that you have write permissions for`, {filePath: this.config.path}]\n if (ownsFile === false || ownsFolder === false) {\n message.push(\n '- The file is owned by a different user. This typically happens when Shopify CLI was previously run with elevated permissions (e.g., sudo).',\n )\n }\n\n message.push('\\n\\nTo resolve this, remove the Shopify CLI preferences folder:')\n message.push({command: `rm -rf ${dirname(this.config.path)}`})\n\n return message\n }\n}\n"]}
1
+ {"version":3,"file":"local-storage.js","sourceRoot":"","sources":["../../../src/public/node/local-storage.ts"],"names":[],"mappings":"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","sourcesContent":["import {AbortError, BugError} from './error.js'\nimport {fileHasWritePermissions, unixFileIsOwnedByCurrentUser} from './fs.js'\nimport {dirname} from './path.js'\nimport {TokenItem} from './ui.js'\nimport Config from 'conf'\n\nfunction deserializeJson<T>(value: string): T {\n // Some Windows editors encode UTF-8 files with a byte order mark, which JSON.parse does not accept.\n const valueWithoutByteOrderMark = value.replace(/^\\uFEFF/, '')\n return JSON.parse(valueWithoutByteOrderMark) as T\n}\n\n/**\n * A wrapper around the `conf` package that provides a strongly-typed interface\n * for accessing the local storage.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class LocalStorage<T extends Record<string, any>> {\n private readonly config: Config<T>\n\n constructor(options: {projectName?: string; cwd?: string}) {\n this.config = new Config<T>({\n ...options,\n clearInvalidConfig: true,\n deserialize: deserializeJson<T>,\n })\n }\n\n /**\n * Get a value from the local storage.\n *\n * @param key - The key to get.\n * @returns The value.\n * @throws AbortError if a permission error occurs.\n * @throws BugError if an unexpected error occurs.\n */\n get<TKey extends keyof T>(key: TKey): T[TKey] | undefined {\n try {\n return this.config.get(key)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n this.handleError(error, 'get')\n }\n }\n\n /**\n * Set a value in the local storage.\n *\n * @param key - The key to set.\n * @param value - The value to set.\n * @throws AbortError if a permission error occurs.\n * @throws BugError if an unexpected error occurs.\n */\n set<TKey extends keyof T>(key: TKey, value?: T[TKey]): void {\n try {\n this.config.set(key, value)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n this.handleError(error, 'set')\n }\n }\n\n /**\n * Delete a value from the local storage.\n *\n * @param key - The key to delete.\n * @throws AbortError if a permission error occurs.\n * @throws BugError if an unexpected error occurs.\n */\n delete<TKey extends keyof T>(key: TKey): void {\n try {\n this.config.delete(key)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n this.handleError(error, 'delete')\n }\n }\n\n /**\n * Clear the local storage (delete all values).\n *\n * @throws AbortError if a permission error occurs.\n * @throws BugError if an unexpected error occurs.\n */\n clear(): void {\n try {\n this.config.clear()\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n this.handleError(error, 'clear')\n }\n }\n\n /**\n * Handle errors from config operations.\n * If the error is permission-related, throw an AbortError with helpful hints.\n * Otherwise, throw a BugError.\n *\n * @param error - The error that occurred.\n * @param operation - The operation that failed.\n * @throws AbortError if the error is permission-related.\n * @throws BugError if the error is not permission-related.\n */\n private handleError(error: unknown, operation: string): never {\n if (this.isPermissionError()) {\n throw new AbortError(`Failed to access local storage (${operation}): ${error}`, this.tryMessage())\n } else {\n throw new BugError(\n `Unexpected error while accessing local storage at ${this.config.path} (${operation}): ${error}`,\n )\n }\n }\n\n private isPermissionError(): boolean {\n const canAccessFile = fileHasWritePermissions(this.config.path)\n const canAccessFolder = fileHasWritePermissions(dirname(this.config.path))\n const ownsFile = unixFileIsOwnedByCurrentUser(this.config.path)\n\n return !canAccessFile || !canAccessFolder || ownsFile === false\n }\n\n private tryMessage() {\n const ownsFile = unixFileIsOwnedByCurrentUser(this.config.path)\n const ownsFolder = unixFileIsOwnedByCurrentUser(dirname(this.config.path))\n\n const message: TokenItem = [`Check that you have write permissions for`, {filePath: this.config.path}]\n if (ownsFile === false || ownsFolder === false) {\n message.push(\n '- The file is owned by a different user. This typically happens when Shopify CLI was previously run with elevated permissions (e.g., sudo).',\n )\n }\n\n message.push('\\n\\nTo resolve this, remove the Shopify CLI preferences folder:')\n message.push({command: `rm -rf ${dirname(this.config.path)}`})\n\n return message\n }\n}\n"]}
@@ -71,19 +71,8 @@ export class FindUpAndReadPackageJsonNotFoundError extends BugError {
71
71
  * @returns The dependency manager
72
72
  */
73
73
  export function packageManagerFromUserAgent(env = process.env) {
74
- if (env.npm_config_user_agent?.includes('yarn')) {
75
- return 'yarn';
76
- }
77
- else if (env.npm_config_user_agent?.includes('pnpm')) {
78
- return 'pnpm';
79
- }
80
- else if (env.npm_config_user_agent?.includes('bun')) {
81
- return 'bun';
82
- }
83
- else if (env.npm_config_user_agent?.includes('npm')) {
84
- return 'npm';
85
- }
86
- return 'unknown';
74
+ const userAgent = env.npm_config_user_agent;
75
+ return ['yarn', 'pnpm', 'bun', 'npm'].find((pm) => userAgent?.includes(pm)) ?? 'unknown';
87
76
  }
88
77
  function hasBunLockfileSync(directory) {
89
78
  return fileExistsSync(joinPath(directory, bunLockfile)) || fileExistsSync(joinPath(directory, modernBunLockfile));
@@ -1 +1 @@
1
- {"version":3,"file":"node-package-manager.js","sourceRoot":"","sources":["../../../src/public/node/node-package-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import {AbortError, BugError} from './error.js'\nimport {AbortController, AbortSignal} from './abort.js'\nimport {exec} from './system.js'\nimport {fileExists, readFile, writeFile, findPathUp, glob, fileExistsSync} from './fs.js'\nimport {dirname, joinPath} from './path.js'\nimport {runWithTimer} from './metadata.js'\nimport {inferPackageManagerForGlobalCLI} from './is-global.js'\nimport {outputToken, outputContent, outputDebug} from './output.js'\nimport {PackageVersionKey, cacheRetrieve, cacheRetrieveOrRepopulate} from '../../private/node/conf-store.js'\nimport {parseJSON} from '../common/json.js'\nimport {SemVer, satisfies as semverSatisfies} from 'semver'\nimport type {Writable} from 'stream'\nimport type {ExecOptions} from './system.js'\n\n/** The name of the Yarn lock file */\nexport const yarnLockfile = 'yarn.lock'\n\n/** The name of the npm lock file */\nexport const npmLockfile = 'package-lock.json'\n\n/** The name of the pnpm lock file */\nexport const pnpmLockfile = 'pnpm-lock.yaml'\n\n/** The name of the bun lock file */\nexport const bunLockfile = 'bun.lockb'\nconst modernBunLockfile = 'bun.lock'\n\n/** The name of the pnpm workspace file */\nexport const pnpmWorkspaceFile = 'pnpm-workspace.yaml'\n\n/** An array containing the lockfiles from all the package managers */\nexport const lockfiles: Lockfile[] = [yarnLockfile, pnpmLockfile, npmLockfile, bunLockfile, modernBunLockfile]\nexport const lockfilesByManager: Record<PackageManager, Lockfile[]> = {\n yarn: [yarnLockfile],\n npm: [npmLockfile],\n pnpm: [pnpmLockfile],\n bun: [bunLockfile, modernBunLockfile],\n homebrew: [],\n unknown: [],\n}\nexport type Lockfile = 'yarn.lock' | 'package-lock.json' | 'pnpm-lock.yaml' | 'bun.lockb' | 'bun.lock'\n\n/**\n * A union type that represents the type of dependencies in the package.json\n * - dev: devDependencies\n * - prod: dependencies\n * - peer: peerDependencies\n */\nexport type DependencyType = 'dev' | 'prod' | 'peer'\n\n/**\n * A union that represents the package managers available.\n */\nexport const packageManager = ['yarn', 'npm', 'pnpm', 'bun', 'homebrew', 'unknown'] as const\nexport type PackageManager = (typeof packageManager)[number]\ntype ProjectPackageManager = Extract<PackageManager, 'yarn' | 'npm' | 'pnpm' | 'bun'>\n\n/**\n * Returns an abort error that's thrown when the package manager can't be determined.\n * @returns An abort error.\n */\nexport class UnknownPackageManagerError extends AbortError {\n constructor() {\n super('Unknown package manager')\n }\n}\n\n/**\n * Returns an abort error that's thrown when a directory that's expected to have\n * a package.json doesn't have it.\n * @param directory - The path to the directory that should contain a package.json\n * @returns An abort error.\n */\nexport class PackageJsonNotFoundError extends AbortError {\n constructor(directory: string) {\n super(outputContent`The directory ${outputToken.path(directory)} doesn't have a package.json.`)\n }\n}\n\n/**\n * Returns a bug error that's thrown when the lookup of the package.json traversing the directory\n * hierarchy up can't find a package.json\n * @param directory - The directory from which the traverse has been done\n * @returns An abort error.\n */\nexport class FindUpAndReadPackageJsonNotFoundError extends BugError {\n constructor(directory: string) {\n super(outputContent`Couldn't find a a package.json traversing directories from ${outputToken.path(directory)}`)\n }\n}\n\n/**\n * Returns the dependency manager used to run the create workflow.\n * @param env - The environment variables of the process in which the CLI runs.\n * @returns The dependency manager\n */\nexport function packageManagerFromUserAgent(env = process.env): PackageManager {\n if (env.npm_config_user_agent?.includes('yarn')) {\n return 'yarn'\n } else if (env.npm_config_user_agent?.includes('pnpm')) {\n return 'pnpm'\n } else if (env.npm_config_user_agent?.includes('bun')) {\n return 'bun'\n } else if (env.npm_config_user_agent?.includes('npm')) {\n return 'npm'\n }\n return 'unknown'\n}\n\nfunction hasBunLockfileSync(directory: string): boolean {\n return fileExistsSync(joinPath(directory, bunLockfile)) || fileExistsSync(joinPath(directory, modernBunLockfile))\n}\n\nfunction normalizePackageManagerForProject(packageManager: PackageManager): ProjectPackageManager {\n switch (packageManager) {\n case 'yarn':\n case 'npm':\n case 'pnpm':\n case 'bun':\n return packageManager\n case 'homebrew':\n case 'unknown':\n return 'npm'\n }\n}\n\nfunction packageManagerBinaryCommand(\n packageManager: ProjectPackageManager,\n binary: string,\n ...binaryArgs: string[]\n): {command: string; args: string[]} {\n switch (packageManager) {\n case 'npm':\n return {command: 'npm', args: ['exec', '--', binary, ...binaryArgs]}\n case 'pnpm':\n return {command: 'pnpm', args: ['exec', binary, ...binaryArgs]}\n case 'yarn':\n return {command: 'yarn', args: ['run', binary, ...binaryArgs]}\n case 'bun':\n return {command: 'bun', args: ['x', binary, ...binaryArgs]}\n }\n}\n\n/**\n * Returns the dependency manager used in a directory.\n * Walks upward from `fromDirectory` so workspace packages (e.g. `extensions/my-fn/package.json`)\n * still resolve to the repo root lockfile (`pnpm-lock.yaml`).\n * If no lockfile is found, it falls back to the package manager from the user agent.\n * If the package manager from the user agent is unknown, it returns 'npm'.\n * @param fromDirectory - The starting directory\n * @returns The dependency manager\n */\nexport async function getPackageManager(fromDirectory: string): Promise<PackageManager> {\n let current = fromDirectory\n outputDebug(outputContent`Looking for a lockfile in ${outputToken.path(current)}...`)\n while (true) {\n if (fileExistsSync(joinPath(current, yarnLockfile))) return 'yarn'\n if (fileExistsSync(joinPath(current, pnpmLockfile)) || fileExistsSync(joinPath(current, pnpmWorkspaceFile))) {\n return 'pnpm'\n }\n if (hasBunLockfileSync(current)) return 'bun'\n if (fileExistsSync(joinPath(current, npmLockfile))) return 'npm'\n const parent = dirname(current)\n if (parent === current) break\n current = parent\n }\n\n const pm: PackageManager = packageManagerFromUserAgent()\n if (pm !== 'unknown') return pm\n\n return 'npm'\n}\n\n/**\n * Builds the command and argv needed to execute a local binary using the package manager\n * detected from the provided directory or its ancestors.\n */\nexport async function packageManagerBinaryCommandForDirectory(\n fromDirectory: string,\n binary: string,\n ...binaryArgs: string[]\n): Promise<{command: string; args: string[]}> {\n const packageManager = normalizePackageManagerForProject(await getPackageManager(fromDirectory))\n return packageManagerBinaryCommand(packageManager, binary, ...binaryArgs)\n}\n\ninterface InstallNPMDependenciesRecursivelyOptions {\n /**\n * The dependency manager to use to install the dependencies.\n */\n packageManager: PackageManager\n /**\n * The directory from where we'll find package.json's recursively\n */\n directory: string\n\n /**\n * Specifies the maximum depth of the glob search.\n */\n deep?: number\n}\n\n/**\n * This function traverses down a directory tree to find directories containing a package.json\n * and installs the dependencies if needed. To know if it's needed, it uses the \"check\" command\n * provided by dependency managers.\n * @param options - Options to install dependencies recursively.\n */\nexport async function installNPMDependenciesRecursively(\n options: InstallNPMDependenciesRecursivelyOptions,\n): Promise<void> {\n const packageJsons = await glob(joinPath(options.directory, '**/package.json'), {\n ignore: [joinPath(options.directory, 'node_modules/**/package.json')],\n cwd: options.directory,\n onlyFiles: true,\n deep: options.deep,\n })\n const abortController = new AbortController()\n try {\n await Promise.all(\n packageJsons.map(async (packageJsonPath) => {\n const directory = dirname(packageJsonPath)\n await installNodeModules({\n directory,\n packageManager: options.packageManager,\n stdout: undefined,\n stderr: undefined,\n signal: abortController.signal,\n args: [],\n })\n }),\n )\n } catch (error) {\n abortController.abort()\n throw error\n }\n}\n\ninterface InstallNodeModulesOptions {\n directory: string\n args?: string[]\n packageManager: PackageManager\n stdout?: Writable\n stderr?: Writable\n signal?: AbortSignal\n}\n\nexport async function installNodeModules(options: InstallNodeModulesOptions): Promise<void> {\n const execOptions: ExecOptions = {\n cwd: options.directory,\n stdin: undefined,\n stdout: options.stdout,\n stderr: options.stderr,\n signal: options.signal,\n }\n let args = ['install']\n if (options.args) {\n args = args.concat(options.args)\n }\n await runWithTimer('cmd_all_timing_network_ms')(async () => {\n await exec(options.packageManager, args, execOptions)\n })\n}\n\n/**\n * Returns the name of the package configured in its package.json\n * @param packageJsonPath - Path to the package.json file\n * @returns A promise that resolves with the name.\n */\nexport async function getPackageName(packageJsonPath: string): Promise<string | undefined> {\n const packageJsonContent = await readAndParsePackageJson(packageJsonPath)\n return packageJsonContent.name\n}\n/**\n * Returns the version of the package configured in its package.json\n * @param packageJsonPath - Path to the package.json file\n * @returns A promise that resolves with the version.\n */\nexport async function getPackageVersion(packageJsonPath: string): Promise<string | undefined> {\n const packageJsonContent = await readAndParsePackageJson(packageJsonPath)\n return packageJsonContent.version\n}\n\n/**\n * Returns the list of production and dev dependencies of a package.json\n * @param packageJsonPath - Path to the package.json file\n * @returns A promise that resolves with the list of dependencies.\n */\nexport async function getDependencies(packageJsonPath: string): Promise<Record<string, string>> {\n const packageJsonContent = await readAndParsePackageJson(packageJsonPath)\n const dependencies: Record<string, string> = packageJsonContent.dependencies ?? {}\n const devDependencies: Record<string, string> = packageJsonContent.devDependencies ?? {}\n\n return {...dependencies, ...devDependencies}\n}\n\n/**\n * Returns true if the app uses workspaces, false otherwise.\n * @param packageJsonPath - Path to the package.json file\n * @param pnpmWorkspacePath - Path to the pnpm-workspace.yaml file\n * @returns A promise that resolves with true if the app uses workspaces, false otherwise.\n */\nexport async function usesWorkspaces(appDirectory: string): Promise<boolean> {\n const packageJsonPath = joinPath(appDirectory, 'package.json')\n const packageJsonContent = await readAndParsePackageJson(packageJsonPath)\n const pnpmWorkspacePath = joinPath(appDirectory, pnpmWorkspaceFile)\n return Boolean(packageJsonContent.workspaces) || fileExists(pnpmWorkspacePath)\n}\n\n/**\n * Given an NPM dependency, it checks if there's a more recent version, and if there is, it returns its value.\n * @param dependency - The dependency name (e.g. react)\n * @param currentVersion - The current version.\n * @param cacheExpiryInHours - If the last check was done more than this amount of hours ago, it will\n * refresh the cache. Defaults to always refreshing.\n * @returns A promise that resolves with a more recent version or undefined if there's no more recent version.\n */\nexport async function checkForNewVersion(\n dependency: string,\n currentVersion: string,\n {cacheExpiryInHours = 0} = {},\n): Promise<string | undefined> {\n const getLatestVersion = async () => {\n outputDebug(outputContent`Checking if there's a version of ${dependency} newer than ${currentVersion}`)\n return getLatestNPMPackageVersion(dependency)\n }\n\n const cacheKey: PackageVersionKey = `npm-package-${dependency}`\n let lastVersion\n try {\n lastVersion = await cacheRetrieveOrRepopulate(cacheKey, getLatestVersion, cacheExpiryInHours * 3600 * 1000)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n return undefined\n }\n\n if (lastVersion && new SemVer(currentVersion).compare(lastVersion) < 0) {\n return lastVersion\n } else {\n return undefined\n }\n}\n\n/**\n * Given an NPM dependency, it checks if there's a cached more recent version, and if there is, it returns its value.\n * @param dependency - The dependency name (e.g. react)\n * @param currentVersion - The current version.\n * @returns A more recent version or undefined if there's no more recent version.\n */\nexport function checkForCachedNewVersion(dependency: string, currentVersion: string): string | undefined {\n const cacheKey: PackageVersionKey = `npm-package-${dependency}`\n const lastVersion = cacheRetrieve(cacheKey)?.value\n\n if (lastVersion && new SemVer(currentVersion).compare(lastVersion) < 0) {\n return lastVersion\n } else {\n return undefined\n }\n}\n\n/**\n * Utility function used to check whether a package version satisfies some requirements\n * @param version - The version to check\n * @param requirements - The requirements to check against, e.g. \"\\>=1.0.0\" - see https://www.npmjs.com/package/semver#ranges\n * @returns A boolean indicating whether the version satisfies the requirements\n */\nexport function versionSatisfies(version: string, requirements: string): boolean {\n return semverSatisfies(version, requirements)\n}\n\n/**\n * An interface that represents a package.json\n */\nexport interface PackageJson {\n /**\n * The name attribute of the package.json\n */\n name?: string\n\n /**\n * The author attribute of the package.json\n */\n author?: string\n\n /**\n * The version attribute of the package.json\n */\n version?: string\n\n /**\n * The scripts attribute of the package.json\n */\n scripts?: Record<string, string>\n\n /**\n * The dependencies attribute of the package.json\n */\n dependencies?: Record<string, string>\n\n /**\n * The devDependencies attribute of the package.json\n */\n devDependencies?: Record<string, string>\n\n /**\n * The peerDependencies attribute of the package.json\n */\n peerDependencies?: Record<string, string>\n\n /**\n * The optional oclif settings attribute of the package.json\n */\n oclif?: {\n plugins?: string[]\n }\n\n /**\n * The workspaces attribute of the package.json\n */\n workspaces?: string[]\n\n /**\n * The resolutions attribute of the package.json. Only useful when using yarn as package manager\n */\n resolutions?: Record<string, string>\n\n /**\n * The overrides attribute of the package.json. Only useful when using npm o npmn as package managers\n */\n overrides?: Record<string, string>\n\n /**\n * The prettier attribute of the package.json\n */\n prettier?: string\n\n /**\n * The private attribute of the package.json.\n * https://docs.npmjs.com/cli/v9/configuring-npm/package-json#private\n */\n private?: boolean\n}\n\n/**\n * Reads and parses a package.json\n * @param packageJsonPath - Path to the package.json\n * @returns An promise that resolves with an in-memory representation\n * of the package.json or rejects with an error if the file is not found or the content is\n * not decodable.\n */\nexport async function readAndParsePackageJson(packageJsonPath: string): Promise<PackageJson> {\n if (!(await fileExists(packageJsonPath))) {\n throw new PackageJsonNotFoundError(dirname(packageJsonPath))\n }\n return parseJSON(await readFile(packageJsonPath), packageJsonPath)\n}\n\ninterface AddNPMDependenciesIfNeededOptions {\n /** How dependencies should be added */\n type: DependencyType\n\n /** The dependency manager to use to add dependencies */\n packageManager: PackageManager\n\n /** The directory that contains the package.json where dependencies will be added */\n directory: string\n\n /** Standard output coming from the underlying installation process */\n stdout?: Writable\n\n /** Standard error coming from the underlying installation process */\n stderr?: Writable\n\n /** Abort signal to stop the process */\n signal?: AbortSignal\n\n /** Whether to add the dependencies to the root package.json or to the package.json of the directory */\n addToRootDirectory?: boolean\n}\n\n/**\n * An interface that represents a dependency name with its version\n */\nexport interface DependencyVersion {\n /**\n * The name of the NPM dependency as it's reflected in the package.json:\n *\n * @example\n * In the example below name would be \"react\"\n * ```\n * {\n * \"react\": \"1.2.3\"\n * }\n * ```\n */\n name: string\n\n /**\n * The version of the NPM dependency as it's reflected in the package.json:\n *\n * @example\n * In the example below version would be \"1.2.3\"\n * ```\n * {\n * \"react\": \"1.2.3\"\n * }\n * ```\n */\n version: string | undefined\n}\n\n/**\n * Adds dependencies to a Node project (i.e. a project that has a package.json)\n * @param dependencies - List of dependencies to be added.\n * @param options - Options for adding dependencies.\n */\nexport async function addNPMDependenciesIfNeeded(\n dependencies: DependencyVersion[],\n options: AddNPMDependenciesIfNeededOptions,\n): Promise<void> {\n outputDebug(outputContent`Adding the following dependencies if needed:\n${outputToken.json(dependencies)}\nWith options:\n${outputToken.json(options)}\n `)\n const packageJsonPath = joinPath(options.directory, 'package.json')\n if (!(await fileExists(packageJsonPath))) {\n throw new PackageJsonNotFoundError(options.directory)\n }\n const existingDependencies = Object.keys(await getDependencies(packageJsonPath))\n const dependenciesToAdd = dependencies.filter((dep) => {\n return !existingDependencies.includes(dep.name)\n })\n if (dependenciesToAdd.length === 0) {\n return\n }\n await addNPMDependencies(dependenciesToAdd, options)\n}\n\nexport async function addNPMDependencies(\n dependencies: DependencyVersion[],\n options: AddNPMDependenciesIfNeededOptions,\n): Promise<void> {\n const dependenciesWithVersion = dependencies.map((dep) => {\n return dep.version ? `${dep.name}@${dep.version}` : dep.name\n })\n options.stdout?.write(`Installing ${dependenciesWithVersion.join(' ')} with ${options.packageManager}`)\n switch (options.packageManager) {\n case 'npm':\n // npm isn't too smart when resolving the dependency tree. For example, admin ui extensions include react as\n // a peer dependency, but npm can't figure out the relationship and fails. Installing dependencies one by one\n // makes the task easier and npm can then proceed.\n for (const dep of dependenciesWithVersion) {\n // eslint-disable-next-line no-await-in-loop\n await installDependencies(options, argumentsToAddDependenciesWithNPM(dep, options.type))\n }\n break\n case 'yarn':\n await installDependencies(\n options,\n argumentsToAddDependenciesWithYarn(dependenciesWithVersion, options.type, Boolean(options.addToRootDirectory)),\n )\n break\n case 'pnpm':\n await installDependencies(\n options,\n argumentsToAddDependenciesWithPNPM(dependenciesWithVersion, options.type, Boolean(options.addToRootDirectory)),\n )\n break\n case 'bun':\n await installDependencies(options, argumentsToAddDependenciesWithBun(dependenciesWithVersion, options.type))\n await installDependencies(options, ['install'])\n break\n case 'homebrew':\n throw new AbortError(\"Homebrew can't be used to install project dependencies. Use npm, yarn, pnpm, or bun.\")\n case 'unknown':\n throw new UnknownPackageManagerError()\n }\n}\n\nasync function installDependencies(options: AddNPMDependenciesIfNeededOptions, args: string[]) {\n return runWithTimer('cmd_all_timing_network_ms')(async () => {\n return exec(options.packageManager, args, {\n cwd: options.directory,\n stdout: options.stdout,\n stderr: options.stderr,\n signal: options.signal,\n })\n })\n}\n\nexport async function addNPMDependenciesWithoutVersionIfNeeded(\n dependencies: string[],\n options: AddNPMDependenciesIfNeededOptions,\n): Promise<void> {\n await addNPMDependenciesIfNeeded(\n dependencies.map((dependency) => {\n return {name: dependency, version: undefined}\n }),\n options,\n )\n}\n\n/**\n * Returns the arguments to add dependencies using NPM.\n * @param dependencies - The list of dependencies to add\n * @param type - The dependency type.\n * @returns An array with the arguments.\n */\nfunction argumentsToAddDependenciesWithNPM(dependency: string, type: DependencyType): string[] {\n let command = ['install']\n command = command.concat(dependency)\n switch (type) {\n case 'dev':\n command.push('--save-dev')\n break\n case 'peer':\n command.push('--save-peer')\n break\n case 'prod':\n command.push('--save-prod')\n break\n }\n // NPM adds ^ to the installed version by default. We want to install exact versions unless specified otherwise.\n if (dependency.match(/@\\d/g)) {\n command.push('--save-exact')\n }\n return command\n}\n\n/**\n * Returns the arguments to add dependencies using Yarn.\n * @param dependencies - The list of dependencies to add\n * @param type - The dependency type.\n * @param addAtRoot - Force to install the dependencies in the workspace root (optional, default = false)\n * @returns An array with the arguments.\n */\nfunction argumentsToAddDependenciesWithYarn(dependencies: string[], type: DependencyType, addAtRoot = false): string[] {\n let command = ['add']\n\n if (addAtRoot) {\n command.push('-W')\n }\n\n command = command.concat(dependencies)\n switch (type) {\n case 'dev':\n command.push('--dev')\n break\n case 'peer':\n command.push('--peer')\n break\n case 'prod':\n command.push('--prod')\n break\n }\n return command\n}\n\n/**\n * Returns the arguments to add dependencies using PNPM.\n * @param dependencies - The list of dependencies to add\n * @param type - The dependency type.\n * @param addAtRoot - Force to install the dependencies in the workspace root (optional, default = false)\n * @returns An array with the arguments.\n */\nfunction argumentsToAddDependenciesWithPNPM(dependencies: string[], type: DependencyType, addAtRoot = false): string[] {\n let command = ['add']\n\n if (addAtRoot) {\n command.push('-w')\n }\n\n command = command.concat(dependencies)\n\n switch (type) {\n case 'dev':\n command.push('--save-dev')\n break\n case 'peer':\n command.push('--save-peer')\n break\n case 'prod':\n command.push('--save-prod')\n break\n }\n return command\n}\n\n/**\n * Returns the arguments to add dependencies using Bun.\n * @param dependencies - The list of dependencies to add\n * @param type - The dependency type.\n * @returns An array with the arguments.\n */\nfunction argumentsToAddDependenciesWithBun(dependencies: string[], type: DependencyType): string[] {\n let command = ['add']\n\n command = command.concat(dependencies)\n\n switch (type) {\n case 'dev':\n command.push('--development')\n break\n case 'peer':\n command.push('--optional')\n break\n case 'prod':\n break\n }\n return command\n}\n\n/**\n * Given a directory it traverses the directory up looking for a package.json and if found, it reads it\n * decodes the JSON, and returns its content as a Javascript object.\n * @param options - The directory from which traverse up.\n * @returns If found, the promise resolves with the path to the\n * package.json and its content. If not found, it throws a FindUpAndReadPackageJsonNotFoundError error.\n */\nexport async function findUpAndReadPackageJson(fromDirectory: string): Promise<{path: string; content: PackageJson}> {\n const packageJsonPath = await findPathUp('package.json', {cwd: fromDirectory, type: 'file'})\n if (packageJsonPath) {\n const packageJson = parseJSON<PackageJson>(await readFile(packageJsonPath), packageJsonPath)\n return {path: packageJsonPath, content: packageJson}\n } else {\n throw new FindUpAndReadPackageJsonNotFoundError(fromDirectory)\n }\n}\n\nexport async function addResolutionOrOverride(directory: string, dependencies: Record<string, string>): Promise<void> {\n const packageManager = await getPackageManager(directory)\n const packageJsonPath = joinPath(directory, 'package.json')\n const packageJsonContent = await readAndParsePackageJson(packageJsonPath)\n\n if (packageManager === 'yarn') {\n packageJsonContent.resolutions = packageJsonContent.resolutions\n ? {...packageJsonContent.resolutions, ...dependencies}\n : dependencies\n }\n if (packageManager === 'npm' || packageManager === 'pnpm' || packageManager === 'bun') {\n packageJsonContent.overrides = packageJsonContent.overrides\n ? {...packageJsonContent.overrides, ...dependencies}\n : dependencies\n }\n\n await writeFile(packageJsonPath, JSON.stringify(packageJsonContent, null, 2))\n}\n\n/**\n * Returns the latest available version of an NPM package.\n * @param name - The name of the NPM package.\n * @returns A promise to get the latest available version of a package.\n */\nasync function getLatestNPMPackageVersion(name: string) {\n outputDebug(outputContent`Getting the latest version of NPM package: ${outputToken.raw(name)}`)\n return runWithTimer('cmd_all_timing_network_ms')(async () => {\n const {default: latestVersion} = await import('latest-version')\n return latestVersion(name)\n })\n}\n\n/**\n * Writes the package.json file to the given directory.\n *\n * @param directory - Directory where the package.json file will be written.\n * @param packageJSON - Package.json file to write.\n */\nexport async function writePackageJSON(directory: string, packageJSON: PackageJson): Promise<void> {\n outputDebug(outputContent`JSON-encoding and writing content to package.json at ${outputToken.path(directory)}...`)\n const packagePath = joinPath(directory, 'package.json')\n await writeFile(packagePath, JSON.stringify(packageJSON, null, 2))\n}\n\n/**\n * Infers the package manager to be used based on the provided options and environment.\n *\n * This function determines the package manager in the following order of precedence:\n * 1. Uses the package manager specified in the options, if valid.\n * 2. Infers the package manager from the user agent string.\n * 3. Infers the package manager used for the global CLI installation.\n * 4. Defaults to 'npm' if no other method succeeds.\n *\n * @param optionsPackageManager - The package manager specified in the options (if any).\n * @returns The inferred package manager as a PackageManager type.\n */\nexport function inferPackageManager(optionsPackageManager: string | undefined, env = process.env): PackageManager {\n if (optionsPackageManager && packageManager.includes(optionsPackageManager as PackageManager)) {\n return optionsPackageManager as PackageManager\n }\n const usedPackageManager = packageManagerFromUserAgent(env)\n if (usedPackageManager !== 'unknown') return usedPackageManager\n\n const globalPackageManager = inferPackageManagerForGlobalCLI()\n if (globalPackageManager !== 'unknown') return globalPackageManager\n\n return 'npm'\n}\n"]}
1
+ {"version":3,"file":"node-package-manager.js","sourceRoot":"","sources":["../../../src/public/node/node-package-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import {AbortError, BugError} from './error.js'\nimport {AbortController, AbortSignal} from './abort.js'\nimport {exec} from './system.js'\nimport {fileExists, readFile, writeFile, findPathUp, glob, fileExistsSync} from './fs.js'\nimport {dirname, joinPath} from './path.js'\nimport {runWithTimer} from './metadata.js'\nimport {inferPackageManagerForGlobalCLI} from './is-global.js'\nimport {outputToken, outputContent, outputDebug} from './output.js'\nimport {PackageVersionKey, cacheRetrieve, cacheRetrieveOrRepopulate} from '../../private/node/conf-store.js'\nimport {parseJSON} from '../common/json.js'\nimport {SemVer, satisfies as semverSatisfies} from 'semver'\nimport type {Writable} from 'stream'\nimport type {ExecOptions} from './system.js'\n\n/** The name of the Yarn lock file */\nexport const yarnLockfile = 'yarn.lock'\n\n/** The name of the npm lock file */\nexport const npmLockfile = 'package-lock.json'\n\n/** The name of the pnpm lock file */\nexport const pnpmLockfile = 'pnpm-lock.yaml'\n\n/** The name of the bun lock file */\nexport const bunLockfile = 'bun.lockb'\nconst modernBunLockfile = 'bun.lock'\n\n/** The name of the pnpm workspace file */\nexport const pnpmWorkspaceFile = 'pnpm-workspace.yaml'\n\n/** An array containing the lockfiles from all the package managers */\nexport const lockfiles: Lockfile[] = [yarnLockfile, pnpmLockfile, npmLockfile, bunLockfile, modernBunLockfile]\nexport const lockfilesByManager: Record<PackageManager, Lockfile[]> = {\n yarn: [yarnLockfile],\n npm: [npmLockfile],\n pnpm: [pnpmLockfile],\n bun: [bunLockfile, modernBunLockfile],\n homebrew: [],\n unknown: [],\n}\nexport type Lockfile = 'yarn.lock' | 'package-lock.json' | 'pnpm-lock.yaml' | 'bun.lockb' | 'bun.lock'\n\n/**\n * A union type that represents the type of dependencies in the package.json\n * - dev: devDependencies\n * - prod: dependencies\n * - peer: peerDependencies\n */\nexport type DependencyType = 'dev' | 'prod' | 'peer'\n\n/**\n * A union that represents the package managers available.\n */\nexport const packageManager = ['yarn', 'npm', 'pnpm', 'bun', 'homebrew', 'unknown'] as const\nexport type PackageManager = (typeof packageManager)[number]\ntype ProjectPackageManager = Extract<PackageManager, 'yarn' | 'npm' | 'pnpm' | 'bun'>\n\n/**\n * Returns an abort error that's thrown when the package manager can't be determined.\n * @returns An abort error.\n */\nexport class UnknownPackageManagerError extends AbortError {\n constructor() {\n super('Unknown package manager')\n }\n}\n\n/**\n * Returns an abort error that's thrown when a directory that's expected to have\n * a package.json doesn't have it.\n * @param directory - The path to the directory that should contain a package.json\n * @returns An abort error.\n */\nexport class PackageJsonNotFoundError extends AbortError {\n constructor(directory: string) {\n super(outputContent`The directory ${outputToken.path(directory)} doesn't have a package.json.`)\n }\n}\n\n/**\n * Returns a bug error that's thrown when the lookup of the package.json traversing the directory\n * hierarchy up can't find a package.json\n * @param directory - The directory from which the traverse has been done\n * @returns An abort error.\n */\nexport class FindUpAndReadPackageJsonNotFoundError extends BugError {\n constructor(directory: string) {\n super(outputContent`Couldn't find a a package.json traversing directories from ${outputToken.path(directory)}`)\n }\n}\n\n/**\n * Returns the dependency manager used to run the create workflow.\n * @param env - The environment variables of the process in which the CLI runs.\n * @returns The dependency manager\n */\nexport function packageManagerFromUserAgent(env = process.env): PackageManager {\n const userAgent = env.npm_config_user_agent\n return (['yarn', 'pnpm', 'bun', 'npm'] as const).find((pm) => userAgent?.includes(pm)) ?? 'unknown'\n}\n\nfunction hasBunLockfileSync(directory: string): boolean {\n return fileExistsSync(joinPath(directory, bunLockfile)) || fileExistsSync(joinPath(directory, modernBunLockfile))\n}\n\nfunction normalizePackageManagerForProject(packageManager: PackageManager): ProjectPackageManager {\n switch (packageManager) {\n case 'yarn':\n case 'npm':\n case 'pnpm':\n case 'bun':\n return packageManager\n case 'homebrew':\n case 'unknown':\n return 'npm'\n }\n}\n\nfunction packageManagerBinaryCommand(\n packageManager: ProjectPackageManager,\n binary: string,\n ...binaryArgs: string[]\n): {command: string; args: string[]} {\n switch (packageManager) {\n case 'npm':\n return {command: 'npm', args: ['exec', '--', binary, ...binaryArgs]}\n case 'pnpm':\n return {command: 'pnpm', args: ['exec', binary, ...binaryArgs]}\n case 'yarn':\n return {command: 'yarn', args: ['run', binary, ...binaryArgs]}\n case 'bun':\n return {command: 'bun', args: ['x', binary, ...binaryArgs]}\n }\n}\n\n/**\n * Returns the dependency manager used in a directory.\n * Walks upward from `fromDirectory` so workspace packages (e.g. `extensions/my-fn/package.json`)\n * still resolve to the repo root lockfile (`pnpm-lock.yaml`).\n * If no lockfile is found, it falls back to the package manager from the user agent.\n * If the package manager from the user agent is unknown, it returns 'npm'.\n * @param fromDirectory - The starting directory\n * @returns The dependency manager\n */\nexport async function getPackageManager(fromDirectory: string): Promise<PackageManager> {\n let current = fromDirectory\n outputDebug(outputContent`Looking for a lockfile in ${outputToken.path(current)}...`)\n while (true) {\n if (fileExistsSync(joinPath(current, yarnLockfile))) return 'yarn'\n if (fileExistsSync(joinPath(current, pnpmLockfile)) || fileExistsSync(joinPath(current, pnpmWorkspaceFile))) {\n return 'pnpm'\n }\n if (hasBunLockfileSync(current)) return 'bun'\n if (fileExistsSync(joinPath(current, npmLockfile))) return 'npm'\n const parent = dirname(current)\n if (parent === current) break\n current = parent\n }\n\n const pm: PackageManager = packageManagerFromUserAgent()\n if (pm !== 'unknown') return pm\n\n return 'npm'\n}\n\n/**\n * Builds the command and argv needed to execute a local binary using the package manager\n * detected from the provided directory or its ancestors.\n */\nexport async function packageManagerBinaryCommandForDirectory(\n fromDirectory: string,\n binary: string,\n ...binaryArgs: string[]\n): Promise<{command: string; args: string[]}> {\n const packageManager = normalizePackageManagerForProject(await getPackageManager(fromDirectory))\n return packageManagerBinaryCommand(packageManager, binary, ...binaryArgs)\n}\n\ninterface InstallNPMDependenciesRecursivelyOptions {\n /**\n * The dependency manager to use to install the dependencies.\n */\n packageManager: PackageManager\n /**\n * The directory from where we'll find package.json's recursively\n */\n directory: string\n\n /**\n * Specifies the maximum depth of the glob search.\n */\n deep?: number\n}\n\n/**\n * This function traverses down a directory tree to find directories containing a package.json\n * and installs the dependencies if needed. To know if it's needed, it uses the \"check\" command\n * provided by dependency managers.\n * @param options - Options to install dependencies recursively.\n */\nexport async function installNPMDependenciesRecursively(\n options: InstallNPMDependenciesRecursivelyOptions,\n): Promise<void> {\n const packageJsons = await glob(joinPath(options.directory, '**/package.json'), {\n ignore: [joinPath(options.directory, 'node_modules/**/package.json')],\n cwd: options.directory,\n onlyFiles: true,\n deep: options.deep,\n })\n const abortController = new AbortController()\n try {\n await Promise.all(\n packageJsons.map(async (packageJsonPath) => {\n const directory = dirname(packageJsonPath)\n await installNodeModules({\n directory,\n packageManager: options.packageManager,\n stdout: undefined,\n stderr: undefined,\n signal: abortController.signal,\n args: [],\n })\n }),\n )\n } catch (error) {\n abortController.abort()\n throw error\n }\n}\n\ninterface InstallNodeModulesOptions {\n directory: string\n args?: string[]\n packageManager: PackageManager\n stdout?: Writable\n stderr?: Writable\n signal?: AbortSignal\n}\n\nexport async function installNodeModules(options: InstallNodeModulesOptions): Promise<void> {\n const execOptions: ExecOptions = {\n cwd: options.directory,\n stdin: undefined,\n stdout: options.stdout,\n stderr: options.stderr,\n signal: options.signal,\n }\n let args = ['install']\n if (options.args) {\n args = args.concat(options.args)\n }\n await runWithTimer('cmd_all_timing_network_ms')(async () => {\n await exec(options.packageManager, args, execOptions)\n })\n}\n\n/**\n * Returns the name of the package configured in its package.json\n * @param packageJsonPath - Path to the package.json file\n * @returns A promise that resolves with the name.\n */\nexport async function getPackageName(packageJsonPath: string): Promise<string | undefined> {\n const packageJsonContent = await readAndParsePackageJson(packageJsonPath)\n return packageJsonContent.name\n}\n/**\n * Returns the version of the package configured in its package.json\n * @param packageJsonPath - Path to the package.json file\n * @returns A promise that resolves with the version.\n */\nexport async function getPackageVersion(packageJsonPath: string): Promise<string | undefined> {\n const packageJsonContent = await readAndParsePackageJson(packageJsonPath)\n return packageJsonContent.version\n}\n\n/**\n * Returns the list of production and dev dependencies of a package.json\n * @param packageJsonPath - Path to the package.json file\n * @returns A promise that resolves with the list of dependencies.\n */\nexport async function getDependencies(packageJsonPath: string): Promise<Record<string, string>> {\n const packageJsonContent = await readAndParsePackageJson(packageJsonPath)\n const dependencies: Record<string, string> = packageJsonContent.dependencies ?? {}\n const devDependencies: Record<string, string> = packageJsonContent.devDependencies ?? {}\n\n return {...dependencies, ...devDependencies}\n}\n\n/**\n * Returns true if the app uses workspaces, false otherwise.\n * @param packageJsonPath - Path to the package.json file\n * @param pnpmWorkspacePath - Path to the pnpm-workspace.yaml file\n * @returns A promise that resolves with true if the app uses workspaces, false otherwise.\n */\nexport async function usesWorkspaces(appDirectory: string): Promise<boolean> {\n const packageJsonPath = joinPath(appDirectory, 'package.json')\n const packageJsonContent = await readAndParsePackageJson(packageJsonPath)\n const pnpmWorkspacePath = joinPath(appDirectory, pnpmWorkspaceFile)\n return Boolean(packageJsonContent.workspaces) || fileExists(pnpmWorkspacePath)\n}\n\n/**\n * Given an NPM dependency, it checks if there's a more recent version, and if there is, it returns its value.\n * @param dependency - The dependency name (e.g. react)\n * @param currentVersion - The current version.\n * @param cacheExpiryInHours - If the last check was done more than this amount of hours ago, it will\n * refresh the cache. Defaults to always refreshing.\n * @returns A promise that resolves with a more recent version or undefined if there's no more recent version.\n */\nexport async function checkForNewVersion(\n dependency: string,\n currentVersion: string,\n {cacheExpiryInHours = 0} = {},\n): Promise<string | undefined> {\n const getLatestVersion = async () => {\n outputDebug(outputContent`Checking if there's a version of ${dependency} newer than ${currentVersion}`)\n return getLatestNPMPackageVersion(dependency)\n }\n\n const cacheKey: PackageVersionKey = `npm-package-${dependency}`\n let lastVersion\n try {\n lastVersion = await cacheRetrieveOrRepopulate(cacheKey, getLatestVersion, cacheExpiryInHours * 3600 * 1000)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n return undefined\n }\n\n if (lastVersion && new SemVer(currentVersion).compare(lastVersion) < 0) {\n return lastVersion\n } else {\n return undefined\n }\n}\n\n/**\n * Given an NPM dependency, it checks if there's a cached more recent version, and if there is, it returns its value.\n * @param dependency - The dependency name (e.g. react)\n * @param currentVersion - The current version.\n * @returns A more recent version or undefined if there's no more recent version.\n */\nexport function checkForCachedNewVersion(dependency: string, currentVersion: string): string | undefined {\n const cacheKey: PackageVersionKey = `npm-package-${dependency}`\n const lastVersion = cacheRetrieve(cacheKey)?.value\n\n if (lastVersion && new SemVer(currentVersion).compare(lastVersion) < 0) {\n return lastVersion\n } else {\n return undefined\n }\n}\n\n/**\n * Utility function used to check whether a package version satisfies some requirements\n * @param version - The version to check\n * @param requirements - The requirements to check against, e.g. \"\\>=1.0.0\" - see https://www.npmjs.com/package/semver#ranges\n * @returns A boolean indicating whether the version satisfies the requirements\n */\nexport function versionSatisfies(version: string, requirements: string): boolean {\n return semverSatisfies(version, requirements)\n}\n\n/**\n * An interface that represents a package.json\n */\nexport interface PackageJson {\n /**\n * The name attribute of the package.json\n */\n name?: string\n\n /**\n * The author attribute of the package.json\n */\n author?: string\n\n /**\n * The version attribute of the package.json\n */\n version?: string\n\n /**\n * The scripts attribute of the package.json\n */\n scripts?: Record<string, string>\n\n /**\n * The dependencies attribute of the package.json\n */\n dependencies?: Record<string, string>\n\n /**\n * The devDependencies attribute of the package.json\n */\n devDependencies?: Record<string, string>\n\n /**\n * The peerDependencies attribute of the package.json\n */\n peerDependencies?: Record<string, string>\n\n /**\n * The optional oclif settings attribute of the package.json\n */\n oclif?: {\n plugins?: string[]\n }\n\n /**\n * The workspaces attribute of the package.json\n */\n workspaces?: string[]\n\n /**\n * The resolutions attribute of the package.json. Only useful when using yarn as package manager\n */\n resolutions?: Record<string, string>\n\n /**\n * The overrides attribute of the package.json. Only useful when using npm o npmn as package managers\n */\n overrides?: Record<string, string>\n\n /**\n * The prettier attribute of the package.json\n */\n prettier?: string\n\n /**\n * The private attribute of the package.json.\n * https://docs.npmjs.com/cli/v9/configuring-npm/package-json#private\n */\n private?: boolean\n}\n\n/**\n * Reads and parses a package.json\n * @param packageJsonPath - Path to the package.json\n * @returns An promise that resolves with an in-memory representation\n * of the package.json or rejects with an error if the file is not found or the content is\n * not decodable.\n */\nexport async function readAndParsePackageJson(packageJsonPath: string): Promise<PackageJson> {\n if (!(await fileExists(packageJsonPath))) {\n throw new PackageJsonNotFoundError(dirname(packageJsonPath))\n }\n return parseJSON(await readFile(packageJsonPath), packageJsonPath)\n}\n\ninterface AddNPMDependenciesIfNeededOptions {\n /** How dependencies should be added */\n type: DependencyType\n\n /** The dependency manager to use to add dependencies */\n packageManager: PackageManager\n\n /** The directory that contains the package.json where dependencies will be added */\n directory: string\n\n /** Standard output coming from the underlying installation process */\n stdout?: Writable\n\n /** Standard error coming from the underlying installation process */\n stderr?: Writable\n\n /** Abort signal to stop the process */\n signal?: AbortSignal\n\n /** Whether to add the dependencies to the root package.json or to the package.json of the directory */\n addToRootDirectory?: boolean\n}\n\n/**\n * An interface that represents a dependency name with its version\n */\nexport interface DependencyVersion {\n /**\n * The name of the NPM dependency as it's reflected in the package.json:\n *\n * @example\n * In the example below name would be \"react\"\n * ```\n * {\n * \"react\": \"1.2.3\"\n * }\n * ```\n */\n name: string\n\n /**\n * The version of the NPM dependency as it's reflected in the package.json:\n *\n * @example\n * In the example below version would be \"1.2.3\"\n * ```\n * {\n * \"react\": \"1.2.3\"\n * }\n * ```\n */\n version: string | undefined\n}\n\n/**\n * Adds dependencies to a Node project (i.e. a project that has a package.json)\n * @param dependencies - List of dependencies to be added.\n * @param options - Options for adding dependencies.\n */\nexport async function addNPMDependenciesIfNeeded(\n dependencies: DependencyVersion[],\n options: AddNPMDependenciesIfNeededOptions,\n): Promise<void> {\n outputDebug(outputContent`Adding the following dependencies if needed:\n${outputToken.json(dependencies)}\nWith options:\n${outputToken.json(options)}\n `)\n const packageJsonPath = joinPath(options.directory, 'package.json')\n if (!(await fileExists(packageJsonPath))) {\n throw new PackageJsonNotFoundError(options.directory)\n }\n const existingDependencies = Object.keys(await getDependencies(packageJsonPath))\n const dependenciesToAdd = dependencies.filter((dep) => {\n return !existingDependencies.includes(dep.name)\n })\n if (dependenciesToAdd.length === 0) {\n return\n }\n await addNPMDependencies(dependenciesToAdd, options)\n}\n\nexport async function addNPMDependencies(\n dependencies: DependencyVersion[],\n options: AddNPMDependenciesIfNeededOptions,\n): Promise<void> {\n const dependenciesWithVersion = dependencies.map((dep) => {\n return dep.version ? `${dep.name}@${dep.version}` : dep.name\n })\n options.stdout?.write(`Installing ${dependenciesWithVersion.join(' ')} with ${options.packageManager}`)\n switch (options.packageManager) {\n case 'npm':\n // npm isn't too smart when resolving the dependency tree. For example, admin ui extensions include react as\n // a peer dependency, but npm can't figure out the relationship and fails. Installing dependencies one by one\n // makes the task easier and npm can then proceed.\n for (const dep of dependenciesWithVersion) {\n // eslint-disable-next-line no-await-in-loop\n await installDependencies(options, argumentsToAddDependenciesWithNPM(dep, options.type))\n }\n break\n case 'yarn':\n await installDependencies(\n options,\n argumentsToAddDependenciesWithYarn(dependenciesWithVersion, options.type, Boolean(options.addToRootDirectory)),\n )\n break\n case 'pnpm':\n await installDependencies(\n options,\n argumentsToAddDependenciesWithPNPM(dependenciesWithVersion, options.type, Boolean(options.addToRootDirectory)),\n )\n break\n case 'bun':\n await installDependencies(options, argumentsToAddDependenciesWithBun(dependenciesWithVersion, options.type))\n await installDependencies(options, ['install'])\n break\n case 'homebrew':\n throw new AbortError(\"Homebrew can't be used to install project dependencies. Use npm, yarn, pnpm, or bun.\")\n case 'unknown':\n throw new UnknownPackageManagerError()\n }\n}\n\nasync function installDependencies(options: AddNPMDependenciesIfNeededOptions, args: string[]) {\n return runWithTimer('cmd_all_timing_network_ms')(async () => {\n return exec(options.packageManager, args, {\n cwd: options.directory,\n stdout: options.stdout,\n stderr: options.stderr,\n signal: options.signal,\n })\n })\n}\n\nexport async function addNPMDependenciesWithoutVersionIfNeeded(\n dependencies: string[],\n options: AddNPMDependenciesIfNeededOptions,\n): Promise<void> {\n await addNPMDependenciesIfNeeded(\n dependencies.map((dependency) => {\n return {name: dependency, version: undefined}\n }),\n options,\n )\n}\n\n/**\n * Returns the arguments to add dependencies using NPM.\n * @param dependencies - The list of dependencies to add\n * @param type - The dependency type.\n * @returns An array with the arguments.\n */\nfunction argumentsToAddDependenciesWithNPM(dependency: string, type: DependencyType): string[] {\n let command = ['install']\n command = command.concat(dependency)\n switch (type) {\n case 'dev':\n command.push('--save-dev')\n break\n case 'peer':\n command.push('--save-peer')\n break\n case 'prod':\n command.push('--save-prod')\n break\n }\n // NPM adds ^ to the installed version by default. We want to install exact versions unless specified otherwise.\n if (dependency.match(/@\\d/g)) {\n command.push('--save-exact')\n }\n return command\n}\n\n/**\n * Returns the arguments to add dependencies using Yarn.\n * @param dependencies - The list of dependencies to add\n * @param type - The dependency type.\n * @param addAtRoot - Force to install the dependencies in the workspace root (optional, default = false)\n * @returns An array with the arguments.\n */\nfunction argumentsToAddDependenciesWithYarn(dependencies: string[], type: DependencyType, addAtRoot = false): string[] {\n let command = ['add']\n\n if (addAtRoot) {\n command.push('-W')\n }\n\n command = command.concat(dependencies)\n switch (type) {\n case 'dev':\n command.push('--dev')\n break\n case 'peer':\n command.push('--peer')\n break\n case 'prod':\n command.push('--prod')\n break\n }\n return command\n}\n\n/**\n * Returns the arguments to add dependencies using PNPM.\n * @param dependencies - The list of dependencies to add\n * @param type - The dependency type.\n * @param addAtRoot - Force to install the dependencies in the workspace root (optional, default = false)\n * @returns An array with the arguments.\n */\nfunction argumentsToAddDependenciesWithPNPM(dependencies: string[], type: DependencyType, addAtRoot = false): string[] {\n let command = ['add']\n\n if (addAtRoot) {\n command.push('-w')\n }\n\n command = command.concat(dependencies)\n\n switch (type) {\n case 'dev':\n command.push('--save-dev')\n break\n case 'peer':\n command.push('--save-peer')\n break\n case 'prod':\n command.push('--save-prod')\n break\n }\n return command\n}\n\n/**\n * Returns the arguments to add dependencies using Bun.\n * @param dependencies - The list of dependencies to add\n * @param type - The dependency type.\n * @returns An array with the arguments.\n */\nfunction argumentsToAddDependenciesWithBun(dependencies: string[], type: DependencyType): string[] {\n let command = ['add']\n\n command = command.concat(dependencies)\n\n switch (type) {\n case 'dev':\n command.push('--development')\n break\n case 'peer':\n command.push('--optional')\n break\n case 'prod':\n break\n }\n return command\n}\n\n/**\n * Given a directory it traverses the directory up looking for a package.json and if found, it reads it\n * decodes the JSON, and returns its content as a Javascript object.\n * @param options - The directory from which traverse up.\n * @returns If found, the promise resolves with the path to the\n * package.json and its content. If not found, it throws a FindUpAndReadPackageJsonNotFoundError error.\n */\nexport async function findUpAndReadPackageJson(fromDirectory: string): Promise<{path: string; content: PackageJson}> {\n const packageJsonPath = await findPathUp('package.json', {cwd: fromDirectory, type: 'file'})\n if (packageJsonPath) {\n const packageJson = parseJSON<PackageJson>(await readFile(packageJsonPath), packageJsonPath)\n return {path: packageJsonPath, content: packageJson}\n } else {\n throw new FindUpAndReadPackageJsonNotFoundError(fromDirectory)\n }\n}\n\nexport async function addResolutionOrOverride(directory: string, dependencies: Record<string, string>): Promise<void> {\n const packageManager = await getPackageManager(directory)\n const packageJsonPath = joinPath(directory, 'package.json')\n const packageJsonContent = await readAndParsePackageJson(packageJsonPath)\n\n if (packageManager === 'yarn') {\n packageJsonContent.resolutions = packageJsonContent.resolutions\n ? {...packageJsonContent.resolutions, ...dependencies}\n : dependencies\n }\n if (packageManager === 'npm' || packageManager === 'pnpm' || packageManager === 'bun') {\n packageJsonContent.overrides = packageJsonContent.overrides\n ? {...packageJsonContent.overrides, ...dependencies}\n : dependencies\n }\n\n await writeFile(packageJsonPath, JSON.stringify(packageJsonContent, null, 2))\n}\n\n/**\n * Returns the latest available version of an NPM package.\n * @param name - The name of the NPM package.\n * @returns A promise to get the latest available version of a package.\n */\nasync function getLatestNPMPackageVersion(name: string) {\n outputDebug(outputContent`Getting the latest version of NPM package: ${outputToken.raw(name)}`)\n return runWithTimer('cmd_all_timing_network_ms')(async () => {\n const {default: latestVersion} = await import('latest-version')\n return latestVersion(name)\n })\n}\n\n/**\n * Writes the package.json file to the given directory.\n *\n * @param directory - Directory where the package.json file will be written.\n * @param packageJSON - Package.json file to write.\n */\nexport async function writePackageJSON(directory: string, packageJSON: PackageJson): Promise<void> {\n outputDebug(outputContent`JSON-encoding and writing content to package.json at ${outputToken.path(directory)}...`)\n const packagePath = joinPath(directory, 'package.json')\n await writeFile(packagePath, JSON.stringify(packageJSON, null, 2))\n}\n\n/**\n * Infers the package manager to be used based on the provided options and environment.\n *\n * This function determines the package manager in the following order of precedence:\n * 1. Uses the package manager specified in the options, if valid.\n * 2. Infers the package manager from the user agent string.\n * 3. Infers the package manager used for the global CLI installation.\n * 4. Defaults to 'npm' if no other method succeeds.\n *\n * @param optionsPackageManager - The package manager specified in the options (if any).\n * @returns The inferred package manager as a PackageManager type.\n */\nexport function inferPackageManager(optionsPackageManager: string | undefined, env = process.env): PackageManager {\n if (optionsPackageManager && packageManager.includes(optionsPackageManager as PackageManager)) {\n return optionsPackageManager as PackageManager\n }\n const usedPackageManager = packageManagerFromUserAgent(env)\n if (usedPackageManager !== 'unknown') return usedPackageManager\n\n const globalPackageManager = inferPackageManagerForGlobalCLI()\n if (globalPackageManager !== 'unknown') return globalPackageManager\n\n return 'npm'\n}\n"]}
@@ -22,6 +22,19 @@ export type AccountInfo = UserAccountInfo | ServiceAccountInfo | UnknownAccountI
22
22
  * @param userId - User identifier to report on the command analytics event.
23
23
  */
24
24
  export declare function setLastSeenUserId(userId: string): void;
25
+ /**
26
+ * Finds a stored Shopify account session by alias without changing the current session.
27
+ *
28
+ * @param alias - The account alias to find.
29
+ * @returns The matching session ID, or undefined if no session matches.
30
+ */
31
+ export declare function findSessionIdByAlias(alias: string): Promise<string | undefined>;
32
+ /**
33
+ * Selects a stored Shopify account session by alias for the current command process.
34
+ *
35
+ * @param alias - The account alias to select. Passing undefined clears the command selection.
36
+ */
37
+ export declare function setCurrentSessionAlias(alias?: string): Promise<void>;
25
38
  interface UserAccountInfo {
26
39
  type: 'UserAccount';
27
40
  email: string;
@@ -5,7 +5,7 @@ import { AbortError, BugError } from './error.js';
5
5
  import { outputContent, outputToken, outputDebug } from './output.js';
6
6
  import * as sessionStore from '../../private/node/session/store.js';
7
7
  import { exchangeCustomPartnerToken, exchangeAppAutomationTokenForAppManagementAccessToken, exchangeAppAutomationTokenForBusinessPlatformAccessToken, } from '../../private/node/session/exchange.js';
8
- import { ensureAuthenticated, setLastSeenAuthMethod, setLastSeenUserIdAfterAuth, } from '../../private/node/session.js';
8
+ import { ensureAuthenticated, setCommandSessionId, setLastSeenAuthMethod, setLastSeenUserIdAfterAuth, } from '../../private/node/session.js';
9
9
  import { isThemeAccessSession } from '../../private/node/api/rest.js';
10
10
  /**
11
11
  * Records the user ID that should be attached to command analytics for this process.
@@ -15,6 +15,31 @@ import { isThemeAccessSession } from '../../private/node/api/rest.js';
15
15
  export function setLastSeenUserId(userId) {
16
16
  setLastSeenUserIdAfterAuth(userId);
17
17
  }
18
+ /**
19
+ * Finds a stored Shopify account session by alias without changing the current session.
20
+ *
21
+ * @param alias - The account alias to find.
22
+ * @returns The matching session ID, or undefined if no session matches.
23
+ */
24
+ export async function findSessionIdByAlias(alias) {
25
+ return sessionStore.findSessionByAlias(alias);
26
+ }
27
+ /**
28
+ * Selects a stored Shopify account session by alias for the current command process.
29
+ *
30
+ * @param alias - The account alias to select. Passing undefined clears the command selection.
31
+ */
32
+ export async function setCurrentSessionAlias(alias) {
33
+ if (!alias) {
34
+ setCommandSessionId(undefined);
35
+ return;
36
+ }
37
+ const sessionId = await findSessionIdByAlias(alias);
38
+ if (!sessionId) {
39
+ throw new AbortError(outputContent `No authenticated account found for alias ${outputToken.yellow(alias)}.`, outputContent `Run ${outputToken.genericShellCommand(`shopify auth login`)} first.`);
40
+ }
41
+ setCommandSessionId(sessionId);
42
+ }
18
43
  /**
19
44
  * Type guard to check if an account is a UserAccount.
20
45
  *