@shopify/cli-kit 4.0.0 → 4.2.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 (76) hide show
  1. package/README.md +2 -2
  2. package/assets/graphiql/favicon.ico +0 -0
  3. package/assets/graphiql/style.css +58 -0
  4. package/dist/private/common/array.js +2 -1
  5. package/dist/private/common/array.js.map +1 -1
  6. package/dist/private/node/api/headers.js +6 -3
  7. package/dist/private/node/api/headers.js.map +1 -1
  8. package/dist/private/node/constants.d.ts +0 -1
  9. package/dist/private/node/constants.js +0 -1
  10. package/dist/private/node/constants.js.map +1 -1
  11. package/dist/private/node/session/device-authorization.js +4 -16
  12. package/dist/private/node/session/device-authorization.js.map +1 -1
  13. package/dist/private/node/ui.js +4 -1
  14. package/dist/private/node/ui.js.map +1 -1
  15. package/dist/public/common/gid.d.ts +24 -0
  16. package/dist/public/common/gid.js +32 -0
  17. package/dist/public/common/gid.js.map +1 -0
  18. package/dist/public/common/string.js +7 -6
  19. package/dist/public/common/string.js.map +1 -1
  20. package/dist/public/common/url.d.ts +16 -0
  21. package/dist/public/common/url.js +30 -0
  22. package/dist/public/common/url.js.map +1 -1
  23. package/dist/public/common/version.d.ts +1 -1
  24. package/dist/public/common/version.js +1 -1
  25. package/dist/public/common/version.js.map +1 -1
  26. package/dist/public/node/analytics.js +3 -5
  27. package/dist/public/node/analytics.js.map +1 -1
  28. package/dist/public/node/cli.d.ts +13 -0
  29. package/dist/public/node/cli.js +12 -0
  30. package/dist/public/node/cli.js.map +1 -1
  31. package/dist/public/node/context/local.d.ts +0 -7
  32. package/dist/public/node/context/local.js +18 -9
  33. package/dist/public/node/context/local.js.map +1 -1
  34. package/dist/public/node/error-handler.js +1 -1
  35. package/dist/public/node/error-handler.js.map +1 -1
  36. package/dist/public/node/git.js +8 -1
  37. package/dist/public/node/git.js.map +1 -1
  38. package/dist/public/node/graphiql/server.d.ts +80 -0
  39. package/dist/public/node/graphiql/server.js +234 -0
  40. package/dist/public/node/graphiql/server.js.map +1 -0
  41. package/dist/public/node/graphiql/templates/graphiql.d.ts +12 -0
  42. package/dist/public/node/graphiql/templates/graphiql.js +314 -0
  43. package/dist/public/node/graphiql/templates/graphiql.js.map +1 -0
  44. package/dist/public/node/graphiql/templates/unauthorized.d.ts +5 -0
  45. package/dist/public/node/graphiql/templates/unauthorized.js +111 -0
  46. package/dist/public/node/graphiql/templates/unauthorized.js.map +1 -0
  47. package/dist/public/node/graphiql/utilities.d.ts +12 -0
  48. package/dist/public/node/graphiql/utilities.js +44 -0
  49. package/dist/public/node/graphiql/utilities.js.map +1 -0
  50. package/dist/public/node/graphql.d.ts +19 -0
  51. package/dist/public/node/graphql.js +41 -0
  52. package/dist/public/node/graphql.js.map +1 -0
  53. package/dist/public/node/hooks/postrun.js +12 -2
  54. package/dist/public/node/hooks/postrun.js.map +1 -1
  55. package/dist/public/node/http.js +27 -31
  56. package/dist/public/node/http.js.map +1 -1
  57. package/dist/public/node/import-extractor.js +4 -3
  58. package/dist/public/node/import-extractor.js.map +1 -1
  59. package/dist/public/node/metadata.d.ts +3 -0
  60. package/dist/public/node/metadata.js.map +1 -1
  61. package/dist/public/node/monorail.d.ts +2 -1
  62. package/dist/public/node/monorail.js +1 -1
  63. package/dist/public/node/monorail.js.map +1 -1
  64. package/dist/public/node/output.js +22 -11
  65. package/dist/public/node/output.js.map +1 -1
  66. package/dist/public/node/system.js +5 -42
  67. package/dist/public/node/system.js.map +1 -1
  68. package/dist/public/node/tcp.js +11 -3
  69. package/dist/public/node/tcp.js.map +1 -1
  70. package/dist/public/node/themes/api.js +76 -4
  71. package/dist/public/node/themes/api.js.map +1 -1
  72. package/dist/public/node/toml/toml-file.d.ts +3 -2
  73. package/dist/public/node/toml/toml-file.js +3 -2
  74. package/dist/public/node/toml/toml-file.js.map +1 -1
  75. package/dist/tsconfig.tsbuildinfo +1 -1
  76. package/package.json +34 -29
@@ -1 +1 @@
1
- {"version":3,"file":"output.js","sourceRoot":"","sources":["../../../src/public/node/output.ts"],"names":[],"mappings":"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","sourcesContent":["import {isUnitTest, isVerbose} from './context/local.js'\nimport {PackageManager} from './node-package-manager.js'\nimport {currentProcessIsGlobal} from './is-global.js'\nimport {AbortSignal} from './abort.js'\nimport colors from './colors.js'\nimport {isTruthy} from './context/utilities.js'\nimport {TokenItem} from './ui.js'\nimport {\n ColorContentToken,\n CommandContentToken,\n ContentToken,\n ErrorContentToken,\n HeadingContentToken,\n ItalicContentToken,\n JsonContentToken,\n LinesDiffContentToken,\n LinkContentToken,\n PathContentToken,\n RawContentToken,\n SubHeadingContentToken,\n} from '../../private/node/content-tokens.js'\nimport {tokenItemToString} from '../../private/node/ui/components/TokenizedText.js'\nimport {consoleLog, consoleWarn, output} from '../../private/node/output.js'\nimport stripAnsi from 'strip-ansi'\nimport {Writable} from 'stream'\n\nimport type {Change} from 'diff'\n\nexport type Logger = Writable | ((message: string, logLevel?: LogLevel) => void)\n\nexport class TokenizedString {\n value: string\n constructor(value: string) {\n this.value = value\n }\n}\n\nexport type OutputMessage = string | TokenizedString\n\nexport const outputToken = {\n raw(value: string): RawContentToken {\n return new RawContentToken(value)\n },\n genericShellCommand(value: OutputMessage): CommandContentToken {\n return new CommandContentToken(value)\n },\n json(value: unknown): JsonContentToken {\n return new JsonContentToken(value)\n },\n path(value: OutputMessage): PathContentToken {\n return new PathContentToken(value)\n },\n link(value: OutputMessage, link?: string, fallback?: string | undefined): LinkContentToken {\n return new LinkContentToken(value, link, fallback)\n },\n heading(value: OutputMessage): HeadingContentToken {\n return new HeadingContentToken(value)\n },\n subheading(value: OutputMessage): SubHeadingContentToken {\n return new SubHeadingContentToken(value)\n },\n italic(value: OutputMessage): ItalicContentToken {\n return new ItalicContentToken(value)\n },\n errorText(value: OutputMessage): ErrorContentToken {\n return new ErrorContentToken(value)\n },\n cyan(value: OutputMessage): ColorContentToken {\n return new ColorContentToken(value, colors.cyan)\n },\n yellow(value: OutputMessage): ColorContentToken {\n return new ColorContentToken(value, colors.yellow)\n },\n magenta(value: OutputMessage): ColorContentToken {\n return new ColorContentToken(value, colors.magenta)\n },\n green(value: OutputMessage): ColorContentToken {\n return new ColorContentToken(value, colors.green)\n },\n gray(value: OutputMessage): ColorContentToken {\n return new ColorContentToken(value, colors.gray)\n },\n packagejsonScript(packageManager: PackageManager, scriptName: string, ...scriptArgs: string[]): CommandContentToken {\n return new CommandContentToken(formatPackageManagerCommand(packageManager, scriptName, ...scriptArgs))\n },\n successIcon(): ColorContentToken {\n return new ColorContentToken('✔', colors.green)\n },\n failIcon(): ErrorContentToken {\n return new ErrorContentToken('✖')\n },\n linesDiff(value: Change[]): LinesDiffContentToken {\n return new LinesDiffContentToken(value)\n },\n}\n\n/**\n * Given a command and its arguments, it formats it depending on the package manager.\n *\n * @param packageManager - The package manager to use (pnpm, npm, yarn).\n * @param scriptName - The name of the script to run.\n * @param scriptArgs - The arguments to pass to the script.\n * @returns The formatted command.\n */\nexport function formatPackageManagerCommand(\n packageManager: PackageManager,\n scriptName: string,\n ...scriptArgs: string[]\n): string {\n if (currentProcessIsGlobal()) {\n return [scriptName, ...scriptArgs].join(' ')\n }\n switch (packageManager) {\n case 'pnpm':\n case 'bun':\n case 'yarn': {\n const pieces = [packageManager, scriptName, ...scriptArgs]\n return pieces.join(' ')\n }\n case 'npm': {\n const pieces = ['npm', 'run', scriptName]\n if (scriptArgs.length > 0) {\n pieces.push('--')\n pieces.push(...scriptArgs)\n }\n return pieces.join(' ')\n }\n case 'homebrew':\n case 'unknown': {\n const pieces = [scriptName, ...scriptArgs]\n return pieces.join(' ')\n }\n }\n}\n\n/**\n * Creates a tokenized string from an array of strings and tokens.\n *\n * @param strings - The strings to join.\n * @param keys - Array of tokens or strings to join.\n * @returns The tokenized string.\n */\nexport function outputContent(\n strings: TemplateStringsArray,\n ...keys: (ContentToken<unknown> | string)[]\n): TokenizedString {\n let output = ``\n strings.forEach((string, i) => {\n output += string\n if (i >= keys.length) {\n return\n }\n\n const token = keys[i]!\n\n if (typeof token === 'string') {\n output += token\n } else if (token) {\n const enumTokenOutput = token.output()\n\n if (Array.isArray(enumTokenOutput)) {\n enumTokenOutput.forEach((line: string) => {\n output += line\n })\n } else {\n output += enumTokenOutput\n }\n }\n })\n return new TokenizedString(output)\n}\n\n/** Log levels. */\nexport type LogLevel = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace' | 'silent'\n\n/**\n * It maps a level to a numeric value.\n *\n * @param level - The level for which we'll return its numeric value.\n * @returns The numeric value of the level.\n */\nfunction logLevelValue(level: LogLevel): number {\n switch (level) {\n case 'trace':\n return 10\n case 'debug':\n return 20\n case 'info':\n return 30\n case 'warn':\n return 40\n case 'error':\n return 50\n case 'fatal':\n return 60\n case 'silent':\n return 70\n }\n}\n\n/**\n * It returns the current log level (debug or info).\n *\n * @returns The log level set by the user.\n */\nfunction currentLogLevel(): LogLevel {\n if (isVerbose()) {\n return 'debug'\n } else {\n return 'info'\n }\n}\n\n/**\n * It checks if the message should be outputted or not.\n *\n * @param logLevel - The desired log level for the message.\n * @returns True if the message should be outputted, false otherwise.\n */\nfunction shouldOutput(logLevel: LogLevel): boolean {\n if (isUnitTest()) {\n return false\n }\n const currentLogLevelValue = logLevelValue(currentLogLevel())\n const messageLogLevelValue = logLevelValue(logLevel)\n return messageLogLevelValue >= currentLogLevelValue\n}\n\n// eslint-disable-next-line import-x/no-mutable-exports\nexport let collectedLogs: Record<string, string[]> = {}\n\n/**\n * This is only used during UnitTesting.\n * If we are in a testing context, instead of printing the logs to the console,\n * we will store them in a variable that can be accessed from the tests.\n *\n * @param key - The key of the log.\n * @param content - The content of the log.\n */\nexport function collectLog(key: string, content: OutputMessage): void {\n const output = collectedLogs.output ?? []\n const data = collectedLogs[key] ?? []\n data.push(stripAnsi(stringifyMessage(content) ?? ''))\n output.push(stripAnsi(stringifyMessage(content) ?? ''))\n collectedLogs[key] = data\n collectedLogs.output = output\n}\n\nexport const clearCollectedLogs = (): void => {\n collectedLogs = {}\n}\n\n/**\n * Outputs command result information to the user.\n * Result messages don't get additional formatting.\n * The messages are logged at info level to stdout.\n *\n * @param content - The content to be output to the user.\n */\nexport function outputResult(content: OutputMessage): void {\n output(content, 'info', consoleLog)\n}\n\n/**\n * Logs information at the info level.\n * Info messages don't get additional formatting.\n * Note: By default, info messages are sent through the standard error.\n *\n * @param content - The content to be output to the user.\n * @param logger - The logging function to use to output to the user.\n */\nexport function outputInfo(content: OutputMessage, logger: Logger = consoleWarn): void {\n const message = stringifyMessage(content)\n if (isUnitTest()) collectLog('info', content)\n outputWhereAppropriate('info', logger, message)\n}\n\n/**\n * Outputs a success message to the user.\n * Success messages receive a special formatting to make them stand out in the console.\n * Note: Success messages are sent through the standard error.\n *\n * @param content - The content to be output to the user.\n * @param logger - The logging function to use to output to the user.\n */\nexport function outputSuccess(content: OutputMessage, logger: Logger = consoleWarn): void {\n const message = colors.bold(`✅ Success! ${stringifyMessage(content)}.`)\n if (isUnitTest()) collectLog('success', content)\n outputWhereAppropriate('info', logger, message)\n}\n\n/**\n * Outputs a completed message to the user.\n * Completed message receive a special formatting to make them stand out in the console.\n * Note: Completed messages are sent through the standard error.\n *\n * @param content - The content to be output to the user.\n * @param logger - The logging function to use to output to the user.\n */\nexport function outputCompleted(content: OutputMessage, logger: Logger = consoleWarn): void {\n const message = `${colors.green('✔')} ${stringifyMessage(content)}`\n if (isUnitTest()) collectLog('completed', content)\n outputWhereAppropriate('info', logger, message)\n}\n\n/**\n * Logs a message at the debug level. By default these output is hidden unless the user calls the CLI with --verbose.\n * Debug messages don't get additional formatting.\n * Note: By default, debug messages are sent through the standard error.\n *\n * @param content - The content to be output to the user.\n * @param logger - The logging function to use to output to the user.\n */\nexport function outputDebug(content: OutputMessage, logger: Logger = consoleWarn): void {\n if (isUnitTest()) collectLog('debug', content)\n const message = colors.gray(stringifyMessage(content))\n outputWhereAppropriate('debug', logger, `${new Date().toISOString()}: ${message}`)\n}\n\n/**\n * Logs a message at the warning level.\n * Warning messages receive a special formatting to make them stand out in the console.\n * Note: By default, warning messages are sent through the standard error.\n *\n * @param content - The content to be output to the user.\n * @param logger - The logging function to use to output to the user.\n */\nexport function outputWarn(content: OutputMessage, logger: Logger = consoleWarn): void {\n if (isUnitTest()) collectLog('warn', content)\n const message = colors.yellow(stringifyMessage(content))\n outputWhereAppropriate('warn', logger, message)\n}\n\n/**\n * Prints a new line in the terminal.\n */\nexport function outputNewline(): void {\n consoleWarn('')\n}\n\n/**\n * Converts a Message to string.\n *\n * @param message - The message to convert to string.\n * @returns The string representation of the message.\n */\nexport function stringifyMessage(message: OutputMessage): string {\n if (message instanceof TokenizedString) {\n return message.value\n } else {\n return message\n }\n}\n\n/**\n * Convert a TokenItem to string.\n *\n * @param item - The item to convert to string.\n * @returns The string representation of the item.\n */\nexport function itemToString(item: TokenItem): string {\n return tokenItemToString(item)\n}\n\nexport interface OutputProcess {\n /**\n * The prefix to include in the logs\n * [vite] Output coming from Vite.\n */\n prefix: string\n /**\n * A callback to invoke the process. Stdout and stderr should be used\n * to send standard output and error data that gets formatted with the\n * right prefix.\n */\n action: (stdout: Writable, stderr: Writable, signal: AbortSignal) => Promise<void>\n}\n\n/**\n * Writes a message to the appropiated logger.\n *\n * @param logLevel - The log level to use to determine if the message should be output.\n * @param logger - The logger to use to output the message.\n * @param message - The message to output.\n */\nexport function outputWhereAppropriate(logLevel: LogLevel, logger: Logger, message: string): void {\n if (shouldOutput(logLevel)) {\n if (logger instanceof Writable) {\n logger.write(message)\n } else {\n logger(message, logLevel)\n }\n }\n}\n\n/**\n * Returns a message without styles (colors or any ANSI escape codes).\n *\n * @param message - The message to remove styles from.\n * @returns The message without styles.\n */\nexport function unstyled(message: string): string {\n return stripAnsi(message)\n}\n\n/**\n * Checks if the console outputs should display colors or not.\n *\n * @param _process - Optional, the process-like object to use to check if the console should display colors. Defaults to the global process.\n * @returns True if the console outputs should display colors, false otherwise.\n */\nexport function shouldDisplayColors(_process = process): boolean {\n const {env, stdout} = _process\n if (Object.hasOwnProperty.call(env, 'FORCE_COLOR')) {\n return isTruthy(env.FORCE_COLOR)\n } else {\n return Boolean(stdout.isTTY)\n }\n}\n\n/**\n * Parse title and body to be a single formatted string.\n *\n * @param title - The title of the message. Will be formatted as a heading.\n * @param body - The body of the message. Will respect the original formatting.\n * @returns The formatted message.\n */\nexport function formatSection(title: string, body: string): string {\n const formattedTitle = `${title.toUpperCase()}${' '.repeat(35 - title.length)}`\n return outputContent`${outputToken.heading(formattedTitle)}\\n${body}`.value\n}\n"]}
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../../src/public/node/output.ts"],"names":[],"mappings":"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","sourcesContent":["import {isUnitTest, isVerbose} from './context/local.js'\nimport {PackageManager} from './node-package-manager.js'\nimport {currentProcessIsGlobal} from './is-global.js'\nimport {AbortSignal} from './abort.js'\nimport colors from './colors.js'\nimport {isTruthy} from './context/utilities.js'\nimport {TokenItem} from './ui.js'\nimport {\n ColorContentToken,\n CommandContentToken,\n ContentToken,\n ErrorContentToken,\n HeadingContentToken,\n ItalicContentToken,\n JsonContentToken,\n LinesDiffContentToken,\n LinkContentToken,\n PathContentToken,\n RawContentToken,\n SubHeadingContentToken,\n} from '../../private/node/content-tokens.js'\nimport {tokenItemToString} from '../../private/node/ui/components/TokenizedText.js'\nimport {consoleLog, consoleWarn, output} from '../../private/node/output.js'\nimport stripAnsi from 'strip-ansi'\nimport {Writable} from 'stream'\n\nimport type {Change} from 'diff'\n\nexport type Logger = Writable | ((message: string, logLevel?: LogLevel) => void)\n\nexport class TokenizedString {\n value: string\n constructor(value: string) {\n this.value = value\n }\n}\n\nexport type OutputMessage = string | TokenizedString\n\nexport const outputToken = {\n raw(value: string): RawContentToken {\n return new RawContentToken(value)\n },\n genericShellCommand(value: OutputMessage): CommandContentToken {\n return new CommandContentToken(value)\n },\n json(value: unknown): JsonContentToken {\n return new JsonContentToken(value)\n },\n path(value: OutputMessage): PathContentToken {\n return new PathContentToken(value)\n },\n link(value: OutputMessage, link?: string, fallback?: string | undefined): LinkContentToken {\n return new LinkContentToken(value, link, fallback)\n },\n heading(value: OutputMessage): HeadingContentToken {\n return new HeadingContentToken(value)\n },\n subheading(value: OutputMessage): SubHeadingContentToken {\n return new SubHeadingContentToken(value)\n },\n italic(value: OutputMessage): ItalicContentToken {\n return new ItalicContentToken(value)\n },\n errorText(value: OutputMessage): ErrorContentToken {\n return new ErrorContentToken(value)\n },\n cyan(value: OutputMessage): ColorContentToken {\n return new ColorContentToken(value, colors.cyan)\n },\n yellow(value: OutputMessage): ColorContentToken {\n return new ColorContentToken(value, colors.yellow)\n },\n magenta(value: OutputMessage): ColorContentToken {\n return new ColorContentToken(value, colors.magenta)\n },\n green(value: OutputMessage): ColorContentToken {\n return new ColorContentToken(value, colors.green)\n },\n gray(value: OutputMessage): ColorContentToken {\n return new ColorContentToken(value, colors.gray)\n },\n packagejsonScript(packageManager: PackageManager, scriptName: string, ...scriptArgs: string[]): CommandContentToken {\n return new CommandContentToken(formatPackageManagerCommand(packageManager, scriptName, ...scriptArgs))\n },\n successIcon(): ColorContentToken {\n return new ColorContentToken('✔', colors.green)\n },\n failIcon(): ErrorContentToken {\n return new ErrorContentToken('✖')\n },\n linesDiff(value: Change[]): LinesDiffContentToken {\n return new LinesDiffContentToken(value)\n },\n}\n\n/**\n * Given a command and its arguments, it formats it depending on the package manager.\n *\n * @param packageManager - The package manager to use (pnpm, npm, yarn).\n * @param scriptName - The name of the script to run.\n * @param scriptArgs - The arguments to pass to the script.\n * @returns The formatted command.\n */\nexport function formatPackageManagerCommand(\n packageManager: PackageManager,\n scriptName: string,\n ...scriptArgs: string[]\n): string {\n if (currentProcessIsGlobal()) {\n return [scriptName, ...scriptArgs].join(' ')\n }\n switch (packageManager) {\n case 'pnpm':\n case 'bun':\n case 'yarn': {\n const pieces = [packageManager, scriptName, ...scriptArgs]\n return pieces.join(' ')\n }\n case 'npm': {\n const pieces = ['npm', 'run', scriptName]\n if (scriptArgs.length > 0) {\n pieces.push('--')\n pieces.push(...scriptArgs)\n }\n return pieces.join(' ')\n }\n case 'homebrew':\n case 'unknown': {\n const pieces = [scriptName, ...scriptArgs]\n return pieces.join(' ')\n }\n }\n}\n\n/**\n * Creates a tokenized string from an array of strings and tokens.\n *\n * @param strings - The strings to join.\n * @param keys - Array of tokens or strings to join.\n * @returns The tokenized string.\n */\nexport function outputContent(\n strings: TemplateStringsArray,\n ...keys: (ContentToken<unknown> | string)[]\n): TokenizedString {\n let output = ``\n strings.forEach((string, i) => {\n output += string\n if (i >= keys.length) {\n return\n }\n\n const token = keys[i]!\n\n if (typeof token === 'string') {\n output += token\n } else if (token) {\n const enumTokenOutput = token.output()\n\n if (Array.isArray(enumTokenOutput)) {\n enumTokenOutput.forEach((line: string) => {\n output += line\n })\n } else {\n output += enumTokenOutput\n }\n }\n })\n return new TokenizedString(output)\n}\n\n/** Log levels. */\nexport type LogLevel = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace' | 'silent'\n\n/**\n * It maps a level to a numeric value.\n *\n * @param level - The level for which we'll return its numeric value.\n * @returns The numeric value of the level.\n */\nfunction logLevelValue(level: LogLevel): number {\n switch (level) {\n case 'trace':\n return 10\n case 'debug':\n return 20\n case 'info':\n return 30\n case 'warn':\n return 40\n case 'error':\n return 50\n case 'fatal':\n return 60\n case 'silent':\n return 70\n }\n}\n\n/**\n * It returns the current log level (debug or info).\n *\n * @returns The log level set by the user.\n */\nfunction currentLogLevel(): LogLevel {\n if (isVerbose()) {\n return 'debug'\n } else {\n return 'info'\n }\n}\n\n/**\n * It checks if the message should be outputted or not.\n *\n * @param logLevel - The desired log level for the message.\n * @returns True if the message should be outputted, false otherwise.\n */\nfunction shouldOutput(logLevel: LogLevel): boolean {\n if (isUnitTest()) {\n return false\n }\n const currentLogLevelValue = logLevelValue(currentLogLevel())\n const messageLogLevelValue = logLevelValue(logLevel)\n return messageLogLevelValue >= currentLogLevelValue\n}\n\n// eslint-disable-next-line import-x/no-mutable-exports\nexport let collectedLogs: Record<string, string[]> = {}\n\n/**\n * Memoized value for the color check.\n */\nlet memoizedShouldDisplayColors: boolean | undefined\n\n/**\n * This is only used during UnitTesting.\n * If we are in a testing context, instead of printing the logs to the console,\n * we will store them in a variable that can be accessed from the tests.\n *\n * @param key - The key of the log.\n * @param content - The content of the log.\n */\nexport function collectLog(key: string, content: OutputMessage): void {\n const message = stripAnsi(stringifyMessage(content))\n collectedLogs.output ??= []\n collectedLogs[key] ??= []\n collectedLogs.output.push(message)\n collectedLogs[key].push(message)\n}\n\nexport const clearCollectedLogs = (): void => {\n collectedLogs = {}\n}\n\n/**\n * Outputs command result information to the user.\n * Result messages don't get additional formatting.\n * The messages are logged at info level to stdout.\n *\n * @param content - The content to be output to the user.\n */\nexport function outputResult(content: OutputMessage): void {\n output(content, 'info', consoleLog)\n}\n\n/**\n * Logs information at the info level.\n * Info messages don't get additional formatting.\n * Note: By default, info messages are sent through the standard error.\n *\n * @param content - The content to be output to the user.\n * @param logger - The logging function to use to output to the user.\n */\nexport function outputInfo(content: OutputMessage, logger: Logger = consoleWarn): void {\n const message = stringifyMessage(content)\n if (isUnitTest()) collectLog('info', content)\n outputWhereAppropriate('info', logger, message)\n}\n\n/**\n * Outputs a success message to the user.\n * Success messages receive a special formatting to make them stand out in the console.\n * Note: Success messages are sent through the standard error.\n *\n * @param content - The content to be output to the user.\n * @param logger - The logging function to use to output to the user.\n */\nexport function outputSuccess(content: OutputMessage, logger: Logger = consoleWarn): void {\n const message = colors.bold(`✅ Success! ${stringifyMessage(content)}.`)\n if (isUnitTest()) collectLog('success', content)\n outputWhereAppropriate('info', logger, message)\n}\n\n/**\n * Outputs a completed message to the user.\n * Completed message receive a special formatting to make them stand out in the console.\n * Note: Completed messages are sent through the standard error.\n *\n * @param content - The content to be output to the user.\n * @param logger - The logging function to use to output to the user.\n */\nexport function outputCompleted(content: OutputMessage, logger: Logger = consoleWarn): void {\n const message = `${colors.green('✔')} ${stringifyMessage(content)}`\n if (isUnitTest()) collectLog('completed', content)\n outputWhereAppropriate('info', logger, message)\n}\n\n/**\n * Logs a message at the debug level. By default these output is hidden unless the user calls the CLI with --verbose.\n * Debug messages don't get additional formatting.\n * Note: By default, debug messages are sent through the standard error.\n *\n * @param content - The content to be output to the user.\n * @param logger - The logging function to use to output to the user.\n */\nexport function outputDebug(content: OutputMessage, logger: Logger = consoleWarn): void {\n if (isUnitTest()) collectLog('debug', content)\n if (!shouldOutput('debug')) return\n\n const message = colors.gray(stringifyMessage(content))\n outputWhereAppropriate('debug', logger, `${new Date().toISOString()}: ${message}`)\n}\n\n/**\n * Logs a message at the warning level.\n * Warning messages receive a special formatting to make them stand out in the console.\n * Note: By default, warning messages are sent through the standard error.\n *\n * @param content - The content to be output to the user.\n * @param logger - The logging function to use to output to the user.\n */\nexport function outputWarn(content: OutputMessage, logger: Logger = consoleWarn): void {\n if (isUnitTest()) collectLog('warn', content)\n const message = colors.yellow(stringifyMessage(content))\n outputWhereAppropriate('warn', logger, message)\n}\n\n/**\n * Prints a new line in the terminal.\n */\nexport function outputNewline(): void {\n consoleWarn('')\n}\n\n/**\n * Converts a Message to string.\n *\n * @param message - The message to convert to string.\n * @returns The string representation of the message.\n */\nexport function stringifyMessage(message: OutputMessage): string {\n if (message instanceof TokenizedString) {\n return message.value\n } else {\n return message\n }\n}\n\n/**\n * Convert a TokenItem to string.\n *\n * @param item - The item to convert to string.\n * @returns The string representation of the item.\n */\nexport function itemToString(item: TokenItem): string {\n return tokenItemToString(item)\n}\n\nexport interface OutputProcess {\n /**\n * The prefix to include in the logs\n * [vite] Output coming from Vite.\n */\n prefix: string\n /**\n * A callback to invoke the process. Stdout and stderr should be used\n * to send standard output and error data that gets formatted with the\n * right prefix.\n */\n action: (stdout: Writable, stderr: Writable, signal: AbortSignal) => Promise<void>\n}\n\n/**\n * Writes a message to the appropiated logger.\n *\n * @param logLevel - The log level to use to determine if the message should be output.\n * @param logger - The logger to use to output the message.\n * @param message - The message to output.\n */\nexport function outputWhereAppropriate(logLevel: LogLevel, logger: Logger, message: string): void {\n if (shouldOutput(logLevel)) {\n if (logger instanceof Writable) {\n logger.write(message)\n } else {\n logger(message, logLevel)\n }\n }\n}\n\n/**\n * Returns a message without styles (colors or any ANSI escape codes).\n *\n * @param message - The message to remove styles from.\n * @returns The message without styles.\n */\nexport function unstyled(message: string): string {\n // Optimization: skip regex execution for strings that don't have ANSI escape codes.\n // In high-frequency paths like terminal layout calculations, this can save significant CPU time.\n if (!message.includes('\\u001b')) return message\n\n return stripAnsi(message)\n}\n\n/**\n * Checks if the console outputs should display colors or not.\n *\n * @param _process - Optional, the process-like object to use to check if the console should display colors. Defaults to the global process.\n * @returns True if the console outputs should display colors, false otherwise.\n */\nexport function shouldDisplayColors(_process = process): boolean {\n if (_process === process && memoizedShouldDisplayColors !== undefined) {\n return memoizedShouldDisplayColors\n }\n\n const {env, stdout} = _process\n const result = Object.hasOwnProperty.call(env, 'FORCE_COLOR') ? isTruthy(env.FORCE_COLOR) : Boolean(stdout.isTTY)\n\n if (_process === process) {\n memoizedShouldDisplayColors = result\n }\n\n return result\n}\n\n/**\n * Parse title and body to be a single formatted string.\n *\n * @param title - The title of the message. Will be formatted as a heading.\n * @param body - The body of the message. Will respect the original formatting.\n * @returns The formatted message.\n */\nexport function formatSection(title: string, body: string): string {\n const formattedTitle = `${title.toUpperCase()}${' '.repeat(35 - title.length)}`\n return outputContent`${outputToken.heading(formattedTitle)}\\n${body}`.value\n}\n"]}
@@ -5,6 +5,7 @@ import { isTruthy } from './context/utilities.js';
5
5
  import { renderWarning } from './ui.js';
6
6
  import { platformAndArch } from './os.js';
7
7
  import { shouldDisplayColors, outputDebug } from './output.js';
8
+ import { isCloudEnvironment } from './context/local.js';
8
9
  import { execa } from 'execa';
9
10
  import supportsHyperlinks from 'supports-hyperlinks';
10
11
  import which from 'which';
@@ -23,6 +24,8 @@ const MAX_STDIN_SIZE = 10 * 1024 * 1024;
23
24
  * @returns A promise that resolves true if the URL was opened successfully, false otherwise.
24
25
  */
25
26
  export async function openURL(url) {
27
+ if (isCloudEnvironment())
28
+ return false;
26
29
  const externalOpen = await import('open');
27
30
  try {
28
31
  await externalOpen.default(url);
@@ -133,26 +136,11 @@ function parseCommand(command) {
133
136
  * ```
134
137
  */
135
138
  export async function captureCommandWithExitCode(command, options) {
136
- const env = options?.env ?? process.env;
137
- if (shouldDisplayColors()) {
138
- env.FORCE_COLOR = '1';
139
- }
140
- const executionCwd = options?.cwd ?? cwd();
141
139
  const [cmd, ...args] = parseCommand(command);
142
140
  if (!cmd) {
143
141
  return { stdout: '', stderr: 'Empty command', exitCode: 1 };
144
142
  }
145
- checkCommandSafety(cmd, { cwd: executionCwd });
146
- const result = await execa(cmd, args, {
147
- env,
148
- cwd: executionCwd,
149
- reject: false,
150
- });
151
- return {
152
- stdout: result.stdout,
153
- stderr: result.stderr,
154
- exitCode: result.exitCode ?? 0,
155
- };
143
+ return captureOutputWithExitCode(cmd, args, options);
156
144
  }
157
145
  /**
158
146
  * Runs a command string asynchronously (parses command and arguments from the string).
@@ -161,36 +149,11 @@ export async function captureCommandWithExitCode(command, options) {
161
149
  * @param options - Optional settings for how to run the command.
162
150
  */
163
151
  export async function execCommand(command, options) {
164
- const env = options?.env ?? process.env;
165
- if (shouldDisplayColors()) {
166
- env.FORCE_COLOR = '1';
167
- }
168
- const executionCwd = options?.cwd ?? cwd();
169
152
  const [cmd, ...args] = parseCommand(command);
170
153
  if (!cmd) {
171
154
  throw new AbortError('Empty command');
172
155
  }
173
- checkCommandSafety(cmd, { cwd: executionCwd });
174
- try {
175
- await execa(cmd, args, {
176
- env,
177
- cwd: executionCwd,
178
- stdin: options?.stdin,
179
- stdout: options?.stdout === 'inherit' ? 'inherit' : undefined,
180
- stderr: options?.stderr === 'inherit' ? 'inherit' : undefined,
181
- });
182
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
183
- }
184
- catch (processError) {
185
- if (options?.externalErrorHandler) {
186
- await options.externalErrorHandler(processError);
187
- }
188
- else {
189
- const abortError = new ExternalError(processError.message, command, []);
190
- abortError.stack = processError.stack;
191
- throw abortError;
192
- }
193
- }
156
+ await exec(cmd, args, options);
194
157
  }
195
158
  /**
196
159
  * Runs a command asynchronously.
@@ -1 +1 @@
1
- {"version":3,"file":"system.js","sourceRoot":"","sources":["../../../src/public/node/system.ts"],"names":[],"mappings":"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","sourcesContent":["import {AbortSignal} from './abort.js'\nimport {AbortError, ExternalError} from './error.js'\nimport {cwd, dirname} from './path.js'\nimport {treeKill} from './tree-kill.js'\nimport {isTruthy} from './context/utilities.js'\nimport {renderWarning} from './ui.js'\nimport {platformAndArch} from './os.js'\nimport {shouldDisplayColors, outputDebug} from './output.js'\nimport {execa, ExecaChildProcess} from 'execa'\nimport supportsHyperlinks from 'supports-hyperlinks'\nimport which from 'which'\nimport {delimiter} from 'pathe'\n\nimport {fstatSync} from 'fs'\nimport type {Writable, Readable} from 'stream'\n\n/**\n * The maximum size of data that can be read from stdin in bytes.\n * This is to prevent memory exhaustion when reading from stdin.\n * 10MB.\n */\nconst MAX_STDIN_SIZE = 10 * 1024 * 1024\n\nexport interface ExecOptions {\n cwd?: string\n env?: Record<string, string | undefined>\n stdin?: Readable | 'inherit'\n stdout?: Writable | 'inherit'\n stderr?: Writable | 'inherit'\n stdio?: 'inherit'\n input?: string\n signal?: AbortSignal\n // Custom handler if process exits with a non-zero code\n externalErrorHandler?: (error: unknown) => Promise<void>\n // Ignored on Windows\n background?: boolean\n}\n\n/**\n * Options passed directly to execa.\n */\ninterface BuildExecOptions {\n /** Whether to throw on non-zero exit codes (default: true). */\n reject?: boolean\n}\n\n/**\n * Opens a URL in the user's default browser.\n *\n * @param url - URL to open.\n * @returns A promise that resolves true if the URL was opened successfully, false otherwise.\n */\nexport async function openURL(url: string): Promise<boolean> {\n const externalOpen = await import('open')\n try {\n await externalOpen.default(url)\n return true\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n return false\n }\n}\n\n/**\n * Runs a command asynchronously, aggregates the stdout data, and returns it.\n *\n * @param command - Command to be executed.\n * @param args - Arguments to pass to the command.\n * @param options - Optional settings for how to run the command.\n * @returns A promise that resolves with the aggregatted stdout of the command.\n */\nexport async function captureOutput(command: string, args: string[], options?: ExecOptions): Promise<string> {\n const result = await buildExec(command, args, options)\n return result.stdout\n}\n\n/**\n * Result from running a command with captureOutputWithExitCode.\n */\nexport interface CaptureOutputResult {\n /** Standard output. */\n stdout: string\n /** Standard error. */\n stderr: string\n /** Exit code (0 = success). */\n exitCode: number\n}\n\n/**\n * Runs a command asynchronously and returns stdout, stderr, and exit code.\n * Unlike captureOutput, this function does NOT throw on non-zero exit codes.\n *\n * @param command - Command to be executed.\n * @param args - Arguments to pass to the command.\n * @param options - Optional settings for how to run the command.\n * @returns A promise that resolves with stdout, stderr, and exitCode.\n *\n * @example\n * ```typescript\n * const result = await captureOutputWithExitCode('ls', ['-la'])\n * if (result.exitCode !== 0) \\{\n * console.error('Command failed:', result.stderr)\n * \\}\n * ```\n */\nexport async function captureOutputWithExitCode(\n command: string,\n args: string[],\n options?: ExecOptions,\n): Promise<CaptureOutputResult> {\n const result = await buildExec(command, args, options, {reject: false})\n return {\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode ?? 0,\n }\n}\n\n/**\n * Parse a command string into an array of arguments, respecting quoted strings.\n * Handles both single and double quotes, preserving spaces within quoted sections.\n *\n * @param command - The command string to parse (e.g., 'ls -la \"my folder\"').\n * @returns An array of command parts with quotes removed.\n *\n * @example\n * parseCommand('shopify theme push --theme \"My Theme Name\"') // ['shopify', 'theme', 'push', '--theme', 'My Theme Name']\n */\nfunction parseCommand(command: string): string[] {\n const result: string[] = []\n let current = ''\n let inQuote: string | null = null\n\n for (const char of command) {\n if (inQuote) {\n if (char === inQuote) {\n // End of quoted section\n inQuote = null\n } else {\n current += char\n }\n } else if (char === '\"' || char === \"'\") {\n // Start of quoted section\n inQuote = char\n } else if (char === ' ' || char === '\\t') {\n // Whitespace outside quotes - end current token\n if (current) {\n result.push(current)\n current = ''\n }\n } else {\n current += char\n }\n }\n\n // Don't forget the last token\n if (current) {\n result.push(current)\n }\n\n return result\n}\n\n/**\n * Runs a command string asynchronously and returns stdout, stderr, and exit code.\n * Parses the command string into command and arguments (handles quoted strings).\n * Unlike captureOutput, this function does NOT throw on non-zero exit codes.\n *\n * @param command - Full command string to be executed (e.g., 'ls -la \"my folder\"').\n * @param options - Optional settings for how to run the command.\n * @returns A promise that resolves with stdout, stderr, and exitCode.\n *\n * @example\n * ```typescript\n * const result = await captureCommandWithExitCode('shopify theme push --theme \"My Theme\"')\n * if (result.exitCode !== 0) {\n * console.error('Command failed:', result.stderr)\n * }\n * ```\n */\nexport async function captureCommandWithExitCode(command: string, options?: ExecOptions): Promise<CaptureOutputResult> {\n const env = options?.env ?? process.env\n if (shouldDisplayColors()) {\n env.FORCE_COLOR = '1'\n }\n const executionCwd = options?.cwd ?? cwd()\n const [cmd, ...args] = parseCommand(command)\n if (!cmd) {\n return {stdout: '', stderr: 'Empty command', exitCode: 1}\n }\n checkCommandSafety(cmd, {cwd: executionCwd})\n const result = await execa(cmd, args, {\n env,\n cwd: executionCwd,\n reject: false,\n })\n return {\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode ?? 0,\n }\n}\n\n/**\n * Runs a command string asynchronously (parses command and arguments from the string).\n *\n * @param command - Full command string to be executed (e.g., 'ls -la \"my folder\"').\n * @param options - Optional settings for how to run the command.\n */\nexport async function execCommand(command: string, options?: ExecOptions): Promise<void> {\n const env = options?.env ?? process.env\n if (shouldDisplayColors()) {\n env.FORCE_COLOR = '1'\n }\n const executionCwd = options?.cwd ?? cwd()\n const [cmd, ...args] = parseCommand(command)\n if (!cmd) {\n throw new AbortError('Empty command')\n }\n checkCommandSafety(cmd, {cwd: executionCwd})\n try {\n await execa(cmd, args, {\n env,\n cwd: executionCwd,\n stdin: options?.stdin,\n stdout: options?.stdout === 'inherit' ? 'inherit' : undefined,\n stderr: options?.stderr === 'inherit' ? 'inherit' : undefined,\n })\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (processError: any) {\n if (options?.externalErrorHandler) {\n await options.externalErrorHandler(processError)\n } else {\n const abortError = new ExternalError(processError.message, command, [])\n abortError.stack = processError.stack\n throw abortError\n }\n }\n}\n\n/**\n * Runs a command asynchronously.\n *\n * @param command - Command to be executed.\n * @param args - Arguments to pass to the command.\n * @param options - Optional settings for how to run the command.\n */\nexport async function exec(command: string, args: string[], options?: ExecOptions): Promise<void> {\n if (options) {\n // Windows opens a new console window when running a command in the background, so we disable it.\n const runningOnWindows = platformAndArch().platform === 'windows'\n options.background = runningOnWindows ? false : options.background\n }\n\n const commandProcess = buildExec(command, args, options)\n\n if (options?.background) {\n commandProcess.unref()\n }\n\n if (options?.stderr && options.stderr !== 'inherit') {\n commandProcess.stderr?.pipe(options.stderr, {end: false})\n }\n if (options?.stdout && options.stdout !== 'inherit') {\n commandProcess.stdout?.pipe(options.stdout, {end: false})\n }\n let aborted = false\n options?.signal?.addEventListener('abort', () => {\n const pid = commandProcess.pid\n if (pid) {\n outputDebug(`Killing process ${pid}: ${command} ${args.join(' ')}`)\n aborted = true\n treeKill(pid, 'SIGTERM')\n }\n })\n try {\n await commandProcess\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (processError: any) {\n // Windows will throw an error whenever the process is killed, no matter the reason.\n // The aborted flag tell use that we killed it, so we can ignore the error.\n if (aborted) return\n if (options?.externalErrorHandler) {\n await options.externalErrorHandler(processError)\n } else {\n const abortError = new ExternalError(processError.message, command, args)\n abortError.stack = processError.stack\n throw abortError\n }\n }\n}\n\n/**\n * Runs a command asynchronously.\n *\n * @param command - Command to be executed.\n * @param args - Arguments to pass to the command.\n * @param options - Optional settings for how to run the command.\n * @param execaOptions - Options passed directly to execa.\n * @returns A promise for a result with stdout and stderr properties.\n */\nfunction buildExec(\n command: string,\n args: string[],\n options?: ExecOptions,\n execaOptions?: BuildExecOptions,\n): ExecaChildProcess {\n const env = options?.env ?? process.env\n if (shouldDisplayColors()) {\n env.FORCE_COLOR = '1'\n }\n const executionCwd = options?.cwd ?? cwd()\n checkCommandSafety(command, {cwd: executionCwd})\n const commandProcess = execa(command, args, {\n env,\n cwd: executionCwd,\n input: options?.input,\n stdio: options?.background ? 'ignore' : options?.stdio,\n stdin: options?.stdin,\n stdout: options?.stdout === 'inherit' ? 'inherit' : undefined,\n stderr: options?.stderr === 'inherit' ? 'inherit' : undefined,\n // Setting this to false makes it possible to kill the main process\n // and all its sub-processes with Ctrl+C on Windows\n windowsHide: false,\n detached: options?.background,\n cleanup: !options?.background,\n ...execaOptions,\n })\n outputDebug(`Running system process${options?.background ? ' in background' : ''}:\n · Command: ${command} ${args.join(' ')}\n · Working directory: ${executionCwd}\n`)\n return commandProcess\n}\n\nfunction checkCommandSafety(command: string, _options: {cwd: string}): void {\n const pathIncludingLocal = `${_options.cwd}${delimiter}${process.env.PATH}`\n const commandPath = which.sync(command, {\n nothrow: true,\n path: pathIncludingLocal,\n })\n if (commandPath && dirname(commandPath) === _options.cwd) {\n const headline = ['Skipped run of unsecure binary', {command}, 'found in the current directory.']\n const body = 'Please remove that file or review your current PATH.'\n renderWarning({headline, body})\n throw new AbortError(headline, body)\n }\n}\n\n/**\n * Waits for a given number of seconds.\n *\n * @param seconds - Number of seconds to wait.\n * @returns A Promise resolving after the number of seconds.\n */\nexport async function sleep(seconds: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, 1000 * seconds)\n })\n}\n\n/**\n * Check if the terminal supports OSC 8 hyperlinks.\n *\n * @returns True if the terminal supports hyperlinks.\n */\nexport function terminalSupportsHyperlinks(): boolean {\n return supportsHyperlinks.stdout\n}\n\n/**\n * Check if the standard input and output streams support prompting.\n *\n * @returns True if the standard input and output streams support prompting.\n */\nexport function terminalSupportsPrompting(): boolean {\n if (isTruthy(process.env.CI)) {\n return false\n }\n return Boolean(process.stdin.isTTY && process.stdout.isTTY)\n}\n\n/**\n * Check if the current environment is a CI environment.\n *\n * @returns True if the current environment is a CI environment.\n */\nexport function isCI(): boolean {\n return isTruthy(process.env.CI)\n}\n\n/**\n * Check if the current environment is a WSL environment.\n *\n * @returns True if the current environment is a WSL environment.\n */\nexport async function isWsl(): Promise<boolean> {\n const wsl = await import('is-wsl')\n return wsl.default\n}\n\n/**\n * Check if stdin has piped data available.\n * This distinguishes between actual piped input (e.g., `echo \"query\" | cmd`)\n * and non-TTY environments without input (e.g., CI).\n *\n * @returns True if stdin is receiving piped data or file redirect, false otherwise.\n */\nexport function isStdinPiped(): boolean {\n try {\n const stats = fstatSync(0)\n return stats.isFIFO() || stats.isFile()\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return false\n }\n}\n\n/**\n * Reads all data from stdin and returns it as a string.\n * This is useful for commands that accept input via piping.\n *\n * @example\n * // Usage: echo \"your query\" | shopify app execute\n * const query = await readStdin()\n *\n * @returns A promise that resolves with the stdin content, or undefined if stdin is a TTY.\n */\nexport async function readStdinString(): Promise<string | undefined> {\n if (!isStdinPiped()) {\n return undefined\n }\n\n let data = ''\n let totalSize = 0\n process.stdin.setEncoding('utf8')\n for await (const chunk of process.stdin) {\n const chunkString = String(chunk)\n totalSize += Buffer.byteLength(chunkString, 'utf8')\n if (totalSize > MAX_STDIN_SIZE) {\n throw new AbortError('Stdin input exceeded the maximum allowed size.')\n }\n data += chunkString\n }\n return data.trim()\n}\n"]}
1
+ {"version":3,"file":"system.js","sourceRoot":"","sources":["../../../src/public/node/system.ts"],"names":[],"mappings":"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","sourcesContent":["import {AbortSignal} from './abort.js'\nimport {AbortError, ExternalError} from './error.js'\nimport {cwd, dirname} from './path.js'\nimport {treeKill} from './tree-kill.js'\nimport {isTruthy} from './context/utilities.js'\nimport {renderWarning} from './ui.js'\nimport {platformAndArch} from './os.js'\nimport {shouldDisplayColors, outputDebug} from './output.js'\nimport {isCloudEnvironment} from './context/local.js'\nimport {execa, ExecaChildProcess} from 'execa'\nimport supportsHyperlinks from 'supports-hyperlinks'\nimport which from 'which'\nimport {delimiter} from 'pathe'\n\nimport {fstatSync} from 'fs'\nimport type {Writable, Readable} from 'stream'\n\n/**\n * The maximum size of data that can be read from stdin in bytes.\n * This is to prevent memory exhaustion when reading from stdin.\n * 10MB.\n */\nconst MAX_STDIN_SIZE = 10 * 1024 * 1024\n\nexport interface ExecOptions {\n cwd?: string\n env?: Record<string, string | undefined>\n stdin?: Readable | 'inherit'\n stdout?: Writable | 'inherit'\n stderr?: Writable | 'inherit'\n stdio?: 'inherit'\n input?: string\n signal?: AbortSignal\n // Custom handler if process exits with a non-zero code\n externalErrorHandler?: (error: unknown) => Promise<void>\n // Ignored on Windows\n background?: boolean\n}\n\n/**\n * Options passed directly to execa.\n */\ninterface BuildExecOptions {\n /** Whether to throw on non-zero exit codes (default: true). */\n reject?: boolean\n}\n\n/**\n * Opens a URL in the user's default browser.\n *\n * @param url - URL to open.\n * @returns A promise that resolves true if the URL was opened successfully, false otherwise.\n */\nexport async function openURL(url: string): Promise<boolean> {\n if (isCloudEnvironment()) return false\n\n const externalOpen = await import('open')\n try {\n await externalOpen.default(url)\n return true\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n return false\n }\n}\n\n/**\n * Runs a command asynchronously, aggregates the stdout data, and returns it.\n *\n * @param command - Command to be executed.\n * @param args - Arguments to pass to the command.\n * @param options - Optional settings for how to run the command.\n * @returns A promise that resolves with the aggregatted stdout of the command.\n */\nexport async function captureOutput(command: string, args: string[], options?: ExecOptions): Promise<string> {\n const result = await buildExec(command, args, options)\n return result.stdout\n}\n\n/**\n * Result from running a command with captureOutputWithExitCode.\n */\nexport interface CaptureOutputResult {\n /** Standard output. */\n stdout: string\n /** Standard error. */\n stderr: string\n /** Exit code (0 = success). */\n exitCode: number\n}\n\n/**\n * Runs a command asynchronously and returns stdout, stderr, and exit code.\n * Unlike captureOutput, this function does NOT throw on non-zero exit codes.\n *\n * @param command - Command to be executed.\n * @param args - Arguments to pass to the command.\n * @param options - Optional settings for how to run the command.\n * @returns A promise that resolves with stdout, stderr, and exitCode.\n *\n * @example\n * ```typescript\n * const result = await captureOutputWithExitCode('ls', ['-la'])\n * if (result.exitCode !== 0) \\{\n * console.error('Command failed:', result.stderr)\n * \\}\n * ```\n */\nexport async function captureOutputWithExitCode(\n command: string,\n args: string[],\n options?: ExecOptions,\n): Promise<CaptureOutputResult> {\n const result = await buildExec(command, args, options, {reject: false})\n return {\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode ?? 0,\n }\n}\n\n/**\n * Parse a command string into an array of arguments, respecting quoted strings.\n * Handles both single and double quotes, preserving spaces within quoted sections.\n *\n * @param command - The command string to parse (e.g., 'ls -la \"my folder\"').\n * @returns An array of command parts with quotes removed.\n *\n * @example\n * parseCommand('shopify theme push --theme \"My Theme Name\"') // ['shopify', 'theme', 'push', '--theme', 'My Theme Name']\n */\nfunction parseCommand(command: string): string[] {\n const result: string[] = []\n let current = ''\n let inQuote: string | null = null\n\n for (const char of command) {\n if (inQuote) {\n if (char === inQuote) {\n // End of quoted section\n inQuote = null\n } else {\n current += char\n }\n } else if (char === '\"' || char === \"'\") {\n // Start of quoted section\n inQuote = char\n } else if (char === ' ' || char === '\\t') {\n // Whitespace outside quotes - end current token\n if (current) {\n result.push(current)\n current = ''\n }\n } else {\n current += char\n }\n }\n\n // Don't forget the last token\n if (current) {\n result.push(current)\n }\n\n return result\n}\n\n/**\n * Runs a command string asynchronously and returns stdout, stderr, and exit code.\n * Parses the command string into command and arguments (handles quoted strings).\n * Unlike captureOutput, this function does NOT throw on non-zero exit codes.\n *\n * @param command - Full command string to be executed (e.g., 'ls -la \"my folder\"').\n * @param options - Optional settings for how to run the command.\n * @returns A promise that resolves with stdout, stderr, and exitCode.\n *\n * @example\n * ```typescript\n * const result = await captureCommandWithExitCode('shopify theme push --theme \"My Theme\"')\n * if (result.exitCode !== 0) {\n * console.error('Command failed:', result.stderr)\n * }\n * ```\n */\nexport async function captureCommandWithExitCode(command: string, options?: ExecOptions): Promise<CaptureOutputResult> {\n const [cmd, ...args] = parseCommand(command)\n if (!cmd) {\n return {stdout: '', stderr: 'Empty command', exitCode: 1}\n }\n return captureOutputWithExitCode(cmd, args, options)\n}\n\n/**\n * Runs a command string asynchronously (parses command and arguments from the string).\n *\n * @param command - Full command string to be executed (e.g., 'ls -la \"my folder\"').\n * @param options - Optional settings for how to run the command.\n */\nexport async function execCommand(command: string, options?: ExecOptions): Promise<void> {\n const [cmd, ...args] = parseCommand(command)\n if (!cmd) {\n throw new AbortError('Empty command')\n }\n await exec(cmd, args, options)\n}\n\n/**\n * Runs a command asynchronously.\n *\n * @param command - Command to be executed.\n * @param args - Arguments to pass to the command.\n * @param options - Optional settings for how to run the command.\n */\nexport async function exec(command: string, args: string[], options?: ExecOptions): Promise<void> {\n if (options) {\n // Windows opens a new console window when running a command in the background, so we disable it.\n const runningOnWindows = platformAndArch().platform === 'windows'\n options.background = runningOnWindows ? false : options.background\n }\n\n const commandProcess = buildExec(command, args, options)\n\n if (options?.background) {\n commandProcess.unref()\n }\n\n if (options?.stderr && options.stderr !== 'inherit') {\n commandProcess.stderr?.pipe(options.stderr, {end: false})\n }\n if (options?.stdout && options.stdout !== 'inherit') {\n commandProcess.stdout?.pipe(options.stdout, {end: false})\n }\n let aborted = false\n options?.signal?.addEventListener('abort', () => {\n const pid = commandProcess.pid\n if (pid) {\n outputDebug(`Killing process ${pid}: ${command} ${args.join(' ')}`)\n aborted = true\n treeKill(pid, 'SIGTERM')\n }\n })\n try {\n await commandProcess\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (processError: any) {\n // Windows will throw an error whenever the process is killed, no matter the reason.\n // The aborted flag tell use that we killed it, so we can ignore the error.\n if (aborted) return\n if (options?.externalErrorHandler) {\n await options.externalErrorHandler(processError)\n } else {\n const abortError = new ExternalError(processError.message, command, args)\n abortError.stack = processError.stack\n throw abortError\n }\n }\n}\n\n/**\n * Runs a command asynchronously.\n *\n * @param command - Command to be executed.\n * @param args - Arguments to pass to the command.\n * @param options - Optional settings for how to run the command.\n * @param execaOptions - Options passed directly to execa.\n * @returns A promise for a result with stdout and stderr properties.\n */\nfunction buildExec(\n command: string,\n args: string[],\n options?: ExecOptions,\n execaOptions?: BuildExecOptions,\n): ExecaChildProcess {\n const env = options?.env ?? process.env\n if (shouldDisplayColors()) {\n env.FORCE_COLOR = '1'\n }\n const executionCwd = options?.cwd ?? cwd()\n checkCommandSafety(command, {cwd: executionCwd})\n const commandProcess = execa(command, args, {\n env,\n cwd: executionCwd,\n input: options?.input,\n stdio: options?.background ? 'ignore' : options?.stdio,\n stdin: options?.stdin,\n stdout: options?.stdout === 'inherit' ? 'inherit' : undefined,\n stderr: options?.stderr === 'inherit' ? 'inherit' : undefined,\n // Setting this to false makes it possible to kill the main process\n // and all its sub-processes with Ctrl+C on Windows\n windowsHide: false,\n detached: options?.background,\n cleanup: !options?.background,\n ...execaOptions,\n })\n outputDebug(`Running system process${options?.background ? ' in background' : ''}:\n · Command: ${command} ${args.join(' ')}\n · Working directory: ${executionCwd}\n`)\n return commandProcess\n}\n\nfunction checkCommandSafety(command: string, _options: {cwd: string}): void {\n const pathIncludingLocal = `${_options.cwd}${delimiter}${process.env.PATH}`\n const commandPath = which.sync(command, {\n nothrow: true,\n path: pathIncludingLocal,\n })\n if (commandPath && dirname(commandPath) === _options.cwd) {\n const headline = ['Skipped run of unsecure binary', {command}, 'found in the current directory.']\n const body = 'Please remove that file or review your current PATH.'\n renderWarning({headline, body})\n throw new AbortError(headline, body)\n }\n}\n\n/**\n * Waits for a given number of seconds.\n *\n * @param seconds - Number of seconds to wait.\n * @returns A Promise resolving after the number of seconds.\n */\nexport async function sleep(seconds: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, 1000 * seconds)\n })\n}\n\n/**\n * Check if the terminal supports OSC 8 hyperlinks.\n *\n * @returns True if the terminal supports hyperlinks.\n */\nexport function terminalSupportsHyperlinks(): boolean {\n return supportsHyperlinks.stdout\n}\n\n/**\n * Check if the standard input and output streams support prompting.\n *\n * @returns True if the standard input and output streams support prompting.\n */\nexport function terminalSupportsPrompting(): boolean {\n if (isTruthy(process.env.CI)) {\n return false\n }\n return Boolean(process.stdin.isTTY && process.stdout.isTTY)\n}\n\n/**\n * Check if the current environment is a CI environment.\n *\n * @returns True if the current environment is a CI environment.\n */\nexport function isCI(): boolean {\n return isTruthy(process.env.CI)\n}\n\n/**\n * Check if the current environment is a WSL environment.\n *\n * @returns True if the current environment is a WSL environment.\n */\nexport async function isWsl(): Promise<boolean> {\n const wsl = await import('is-wsl')\n return wsl.default\n}\n\n/**\n * Check if stdin has piped data available.\n * This distinguishes between actual piped input (e.g., `echo \"query\" | cmd`)\n * and non-TTY environments without input (e.g., CI).\n *\n * @returns True if stdin is receiving piped data or file redirect, false otherwise.\n */\nexport function isStdinPiped(): boolean {\n try {\n const stats = fstatSync(0)\n return stats.isFIFO() || stats.isFile()\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return false\n }\n}\n\n/**\n * Reads all data from stdin and returns it as a string.\n * This is useful for commands that accept input via piping.\n *\n * @example\n * // Usage: echo \"your query\" | shopify app execute\n * const query = await readStdin()\n *\n * @returns A promise that resolves with the stdin content, or undefined if stdin is a TTY.\n */\nexport async function readStdinString(): Promise<string | undefined> {\n if (!isStdinPiped()) {\n return undefined\n }\n\n let data = ''\n let totalSize = 0\n process.stdin.setEncoding('utf8')\n for await (const chunk of process.stdin) {\n const chunkString = String(chunk)\n totalSize += Buffer.byteLength(chunkString, 'utf8')\n if (totalSize > MAX_STDIN_SIZE) {\n throw new AbortError('Stdin input exceeded the maximum allowed size.')\n }\n data += chunkString\n }\n return data.trim()\n}\n"]}
@@ -39,9 +39,17 @@ export async function checkPortAvailability(portNumber) {
39
39
  const server = createServer();
40
40
  server.unref();
41
41
  server.once('error', () => resolve(false));
42
- server.listen(portNumber, 'localhost', () => {
43
- server.close(() => resolve(true));
44
- });
42
+ try {
43
+ server.listen(portNumber, 'localhost', () => {
44
+ server.close(() => resolve(true));
45
+ });
46
+ }
47
+ catch (error) {
48
+ if (!(error instanceof RangeError)) {
49
+ throw error;
50
+ }
51
+ resolve(false);
52
+ }
45
53
  });
46
54
  }
47
55
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"tcp.js","sourceRoot":"","sources":["../../../src/public/node/tcp.ts"],"names":[],"mappings":"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","sourcesContent":["import {sleep} from './system.js'\nimport {AbortError} from './error.js'\nimport {outputDebug, outputContent, outputToken} from './output.js'\nimport {createServer} from 'net'\n\ninterface GetTCPPortOptions {\n waitTimeInSeconds?: number\n maxTries?: number\n}\n\nconst obtainedRandomPorts = new Set<number>()\n\n/**\n * Returns an available port in the current environment.\n *\n * @param preferredPort - Number of the preferred port to be used if available.\n * @param options - Extra configuration for getting TCP ports.\n * @returns A promise that resolves with an availabe port.\n */\nexport async function getAvailableTCPPort(preferredPort?: number, options?: GetTCPPortOptions): Promise<number> {\n if (preferredPort && (await checkPortAvailability(preferredPort))) {\n outputDebug(outputContent`Port ${preferredPort.toString()} is free`)\n return preferredPort\n }\n outputDebug(outputContent`Getting a random port...`)\n let randomPort = await retryOnError(() => getRandomPort(), options?.maxTries, options?.waitTimeInSeconds)\n\n for (let i = 0; i < (options?.maxTries ?? 5); i++) {\n if (!obtainedRandomPorts.has(randomPort)) {\n break\n }\n // eslint-disable-next-line no-await-in-loop\n randomPort = await retryOnError(() => getRandomPort(), options?.maxTries, options?.waitTimeInSeconds)\n }\n\n outputDebug(outputContent`Random port obtained: ${outputToken.raw(`${randomPort}`)}`)\n obtainedRandomPorts.add(randomPort)\n return randomPort\n}\n\n/**\n * Checks if a port is available.\n *\n * @param portNumber - The port number to check.\n * @returns A promise that resolves with a boolean indicating if the port is available.\n */\nexport async function checkPortAvailability(portNumber: number): Promise<boolean> {\n return new Promise((resolve) => {\n const server = createServer()\n server.unref()\n server.once('error', () => resolve(false))\n server.listen(portNumber, 'localhost', () => {\n server.close(() => resolve(true))\n })\n })\n}\n\n/**\n * Gets a random available port by binding to port 0 on localhost.\n *\n * @returns A promise that resolves with an available port number.\n */\nfunction getRandomPort(): Promise<number> {\n return new Promise((resolve, reject) => {\n const server = createServer()\n server.unref()\n server.once('error', reject)\n server.listen(0, 'localhost', () => {\n const address = server.address()\n if (address && typeof address === 'object') {\n const assignedPort = address.port\n server.close(() => resolve(assignedPort))\n } else {\n server.close(() => reject(new Error('Unable to determine assigned port')))\n }\n })\n })\n}\n\n/**\n * Given a function, it runs it and retries in case of failiure up to the provided number of times.\n *\n * @param execute - The function to execute.\n * @param maxTries - The maximum retries.\n * @param waitTimeInSeconds - The time to wait between retries.\n */\nasync function retryOnError<T>(execute: () => T, maxTries = 5, waitTimeInSeconds = 1) {\n let retryCount = 1\n while (true) {\n try {\n // eslint-disable-next-line no-await-in-loop\n return await execute()\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n if (retryCount++ < maxTries) {\n outputDebug(outputContent`Unknown problem getting a random port: ${error.message}`)\n // eslint-disable-next-line no-await-in-loop\n await sleep(waitTimeInSeconds)\n } else {\n throw new AbortError(error.message)\n }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"tcp.js","sourceRoot":"","sources":["../../../src/public/node/tcp.ts"],"names":[],"mappings":"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","sourcesContent":["import {sleep} from './system.js'\nimport {AbortError} from './error.js'\nimport {outputDebug, outputContent, outputToken} from './output.js'\nimport {createServer} from 'net'\n\ninterface GetTCPPortOptions {\n waitTimeInSeconds?: number\n maxTries?: number\n}\n\nconst obtainedRandomPorts = new Set<number>()\n\n/**\n * Returns an available port in the current environment.\n *\n * @param preferredPort - Number of the preferred port to be used if available.\n * @param options - Extra configuration for getting TCP ports.\n * @returns A promise that resolves with an availabe port.\n */\nexport async function getAvailableTCPPort(preferredPort?: number, options?: GetTCPPortOptions): Promise<number> {\n if (preferredPort && (await checkPortAvailability(preferredPort))) {\n outputDebug(outputContent`Port ${preferredPort.toString()} is free`)\n return preferredPort\n }\n outputDebug(outputContent`Getting a random port...`)\n let randomPort = await retryOnError(() => getRandomPort(), options?.maxTries, options?.waitTimeInSeconds)\n\n for (let i = 0; i < (options?.maxTries ?? 5); i++) {\n if (!obtainedRandomPorts.has(randomPort)) {\n break\n }\n // eslint-disable-next-line no-await-in-loop\n randomPort = await retryOnError(() => getRandomPort(), options?.maxTries, options?.waitTimeInSeconds)\n }\n\n outputDebug(outputContent`Random port obtained: ${outputToken.raw(`${randomPort}`)}`)\n obtainedRandomPorts.add(randomPort)\n return randomPort\n}\n\n/**\n * Checks if a port is available.\n *\n * @param portNumber - The port number to check.\n * @returns A promise that resolves with a boolean indicating if the port is available.\n */\nexport async function checkPortAvailability(portNumber: number): Promise<boolean> {\n return new Promise((resolve) => {\n const server = createServer()\n server.unref()\n server.once('error', () => resolve(false))\n try {\n server.listen(portNumber, 'localhost', () => {\n server.close(() => resolve(true))\n })\n } catch (error) {\n if (!(error instanceof RangeError)) {\n throw error\n }\n resolve(false)\n }\n })\n}\n\n/**\n * Gets a random available port by binding to port 0 on localhost.\n *\n * @returns A promise that resolves with an available port number.\n */\nfunction getRandomPort(): Promise<number> {\n return new Promise((resolve, reject) => {\n const server = createServer()\n server.unref()\n server.once('error', reject)\n server.listen(0, 'localhost', () => {\n const address = server.address()\n if (address && typeof address === 'object') {\n const assignedPort = address.port\n server.close(() => resolve(assignedPort))\n } else {\n server.close(() => reject(new Error('Unable to determine assigned port')))\n }\n })\n })\n}\n\n/**\n * Given a function, it runs it and retries in case of failiure up to the provided number of times.\n *\n * @param execute - The function to execute.\n * @param maxTries - The maximum retries.\n * @param waitTimeInSeconds - The time to wait between retries.\n */\nasync function retryOnError<T>(execute: () => T, maxTries = 5, waitTimeInSeconds = 1) {\n let retryCount = 1\n while (true) {\n try {\n // eslint-disable-next-line no-await-in-loop\n return await execute()\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n if (retryCount++ < maxTries) {\n outputDebug(outputContent`Unknown problem getting a random port: ${error.message}`)\n // eslint-disable-next-line no-await-in-loop\n await sleep(waitTimeInSeconds)\n } else {\n throw new AbortError(error.message)\n }\n }\n }\n}\n"]}
@@ -19,6 +19,7 @@ import { adminRequestDoc } from '../api/admin.js';
19
19
  import { AbortError } from '../error.js';
20
20
  import { outputDebug } from '../output.js';
21
21
  import { recordTiming, recordEvent, recordError } from '../analytics.js';
22
+ import { ClientError } from 'graphql-request';
22
23
  const SkeletonThemeCdn = 'https://cdn.shopify.com/static/online-store/theme-skeleton.zip';
23
24
  const THEME_API_NETWORK_BEHAVIOUR = {
24
25
  useNetworkLevelRetry: true,
@@ -26,6 +27,7 @@ const THEME_API_NETWORK_BEHAVIOUR = {
26
27
  maxRetryTimeMs: 90 * 1000,
27
28
  recordCommandRetries: true,
28
29
  };
30
+ const DEFAULT_THEME_ACCESS_REQUIREMENT = 'the required theme access scope';
29
31
  export async function fetchTheme(id, session) {
30
32
  const gid = composeThemeGid(id);
31
33
  recordEvent('theme-api:fetch-theme');
@@ -48,6 +50,7 @@ export async function fetchTheme(id, session) {
48
50
  // eslint-disable-next-line no-catch-all/no-catch-all
49
51
  }
50
52
  catch (error) {
53
+ abortIfMissingThemeAccessScope(error);
51
54
  /**
52
55
  * Consumers of this and other theme APIs in this file expect either a theme
53
56
  * or `undefined`.
@@ -65,7 +68,7 @@ export async function fetchThemes(session) {
65
68
  recordEvent('theme-api:fetch-themes');
66
69
  while (true) {
67
70
  // eslint-disable-next-line no-await-in-loop
68
- const response = await adminRequestDoc({
71
+ const response = await requestThemeAdminDoc({
69
72
  query: GetThemes,
70
73
  session,
71
74
  variables: { after },
@@ -95,7 +98,7 @@ export async function fetchThemes(session) {
95
98
  }
96
99
  export async function findDevelopmentThemeByName(name, session) {
97
100
  recordEvent('theme-api:find-development-theme-by-name');
98
- const { themes } = await adminRequestDoc({
101
+ const { themes } = await requestThemeAdminDoc({
99
102
  query: FindDevelopmentThemeByName,
100
103
  session,
101
104
  variables: { name },
@@ -155,7 +158,7 @@ export async function fetchThemeAssets(id, filenames, session) {
155
158
  recordEvent('theme-api:fetch-assets');
156
159
  while (true) {
157
160
  // eslint-disable-next-line no-await-in-loop
158
- const response = await adminRequestDoc({
161
+ const response = await requestThemeAdminDoc({
159
162
  query: GetThemeFileBodies,
160
163
  session,
161
164
  variables: { id: themeGid(id), filenames, after },
@@ -306,7 +309,7 @@ export async function fetchChecksums(id, session) {
306
309
  recordEvent('theme-api:fetch-checksums');
307
310
  while (true) {
308
311
  // eslint-disable-next-line no-await-in-loop
309
- const response = await adminRequestDoc({
312
+ const response = await requestThemeAdminDoc({
310
313
  query: GetThemeFileChecksums,
311
314
  session,
312
315
  variables: { id: themeGid(id), after },
@@ -493,6 +496,75 @@ export async function passwordProtected(session) {
493
496
  function unexpectedGraphQLError(message) {
494
497
  throw recordError(new AbortError(message));
495
498
  }
499
+ async function requestThemeAdminDoc(options) {
500
+ try {
501
+ const response = await adminRequestDoc(options);
502
+ return response;
503
+ }
504
+ catch (error) {
505
+ abortIfMissingThemeAccessScope(error);
506
+ throw error;
507
+ }
508
+ }
509
+ function abortIfMissingThemeAccessScope(error) {
510
+ if (!(error instanceof ClientError))
511
+ return;
512
+ const requiredAccess = getThemeAccessRequirementForAccessDeniedError(error);
513
+ if (!requiredAccess)
514
+ return;
515
+ const nextSteps = [
516
+ [
517
+ 'If you authenticated with an Admin API access token, update the app or integration that issued the token to include the required theme access scopes, then reauthorize it or generate a new token.',
518
+ ],
519
+ [
520
+ 'For',
521
+ { command: 'theme pull' },
522
+ { char: ',' },
523
+ { command: 'theme list' },
524
+ { char: ',' },
525
+ 'and',
526
+ { command: 'theme info' },
527
+ { char: ',' },
528
+ 'add the',
529
+ { command: 'read_themes' },
530
+ 'scope',
531
+ { char: '.' },
532
+ ],
533
+ [
534
+ 'For',
535
+ { command: 'theme push' },
536
+ 'and',
537
+ { command: 'theme dev' },
538
+ { char: ',' },
539
+ 'add both the',
540
+ { command: 'read_themes' },
541
+ 'and',
542
+ { command: 'write_themes' },
543
+ 'scopes',
544
+ { char: '.' },
545
+ ],
546
+ [
547
+ 'If you authenticated with your Shopify account, make sure your staff or collaborator account can access Online Store themes, then run',
548
+ { command: 'shopify auth logout' },
549
+ 'and try again',
550
+ { char: '.' },
551
+ ],
552
+ ['See', { link: { label: 'Shopify access scopes', url: 'https://shopify.dev/api/usage/access-scopes' } }, { char: '.' }],
553
+ ];
554
+ throw recordError(new AbortError(`The authenticated account or access token is missing ${requiredAccess}.`, undefined, nextSteps));
555
+ }
556
+ function getThemeAccessRequirementForAccessDeniedError(error) {
557
+ const graphQLErrors = error.response.errors;
558
+ if (!Array.isArray(graphQLErrors))
559
+ return undefined;
560
+ const accessDeniedError = graphQLErrors.find((graphQLError) => graphQLError.extensions?.code === 'ACCESS_DENIED');
561
+ if (!accessDeniedError)
562
+ return undefined;
563
+ const requiredAccess = accessDeniedError.extensions?.requiredAccess;
564
+ if (typeof requiredAccess !== 'string')
565
+ return DEFAULT_THEME_ACCESS_REQUIREMENT;
566
+ return requiredAccess.trim().replace(/\.$/, '') || DEFAULT_THEME_ACCESS_REQUIREMENT;
567
+ }
496
568
  function themeGid(id) {
497
569
  return `gid://shopify/OnlineStoreTheme/${id}`;
498
570
  }