@shopify/cli-kit 3.11.0 → 3.12.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @shopify/cli-kit
2
2
 
3
+ ## 3.12.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 454641be: Allow running shopify installed globally instead of npm/yarn/pnpm shopify
8
+
3
9
  ## 3.11.0
4
10
 
5
11
  ### Minor Changes
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  With the Shopify command line interface (Shopify CLI 3.0), you can:
9
9
  - build custom storefronts and manage their hosting
10
- - initialize, build, dev, and deploy Shopify apps — and scaffold app extensions
10
+ - initialize, build, dev, and deploy Shopify apps — and generate app extensions
11
11
 
12
12
  <p>&nbsp;</p>
13
13
 
@@ -1,9 +1,10 @@
1
+ import BaseCommand from './node/base-command.js';
1
2
  import { Interfaces } from '@oclif/core';
2
3
  interface StartOptions {
3
4
  command: string;
4
5
  args: string[];
5
6
  currentTime?: number;
6
- commandClass?: Interfaces.Command.Class;
7
+ commandClass?: Interfaces.Command.Class | typeof BaseCommand;
7
8
  }
8
9
  export declare const start: ({ command, args, currentTime, commandClass }: StartOptions) => Promise<void>;
9
10
  interface ReportEventOptions {
package/dist/analytics.js CHANGED
@@ -8,10 +8,14 @@ import { publishEvent, MONORAIL_COMMAND_TOPIC } from './monorail.js';
8
8
  import { fanoutHooks } from './plugins.js';
9
9
  import { packageManagerUsedForCreating } from './node/node-package-manager.js';
10
10
  export const start = async ({ command, args, currentTime = new Date().getTime(), commandClass }) => {
11
+ let startCommand = command;
12
+ if (commandClass && Object.prototype.hasOwnProperty.call(command, 'analyticsNameOverride')) {
13
+ startCommand = commandClass.analyticsNameOverride() ?? command;
14
+ }
11
15
  await metadata.addSensitive(() => ({
12
16
  commandStartOptions: {
13
17
  startTime: currentTime,
14
- startCommand: command,
18
+ startCommand,
15
19
  startArgs: args,
16
20
  },
17
21
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"analytics.js","sourceRoot":"","sources":["../src/analytics.ts"],"names":[],"mappings":"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","sourcesContent":["import * as environment from './environment.js'\nimport {platformAndArch} from './os.js'\nimport {version as rubyVersion} from './node/ruby.js'\nimport {content, debug, token} from './output.js'\nimport constants from './constants.js'\nimport * as metadata from './metadata.js'\nimport {publishEvent, MONORAIL_COMMAND_TOPIC} from './monorail.js'\nimport {fanoutHooks} from './plugins.js'\nimport {packageManagerUsedForCreating} from './node/node-package-manager.js'\nimport {Interfaces} from '@oclif/core'\n\ninterface StartOptions {\n command: string\n args: string[]\n currentTime?: number\n commandClass?: Interfaces.Command.Class\n}\n\nexport const start = async ({command, args, currentTime = new Date().getTime(), commandClass}: StartOptions) => {\n await metadata.addSensitive(() => ({\n commandStartOptions: {\n startTime: currentTime,\n startCommand: command,\n startArgs: args,\n },\n }))\n\n await metadata.addPublic(() => ({\n cmd_all_launcher: packageManagerUsedForCreating(),\n cmd_all_plugin: commandClass?.plugin?.name,\n }))\n}\n\ninterface ReportEventOptions {\n config: Interfaces.Config\n errorMessage?: string\n}\n\n/**\n * Report an analytics event, sending it off to Monorail -- Shopify's internal analytics service.\n *\n * The payload for an event includes both generic data, and data gathered from installed plug-ins.\n *\n */\nexport async function reportEvent(options: ReportEventOptions) {\n try {\n const payload = await buildPayload(options)\n if (payload === undefined) {\n // Nothing to log\n return\n }\n if (!environment.local.alwaysLogAnalytics() && environment.local.analyticsDisabled()) {\n debug(content`Skipping command analytics, payload: ${token.json(payload)}`)\n return\n }\n const response = await publishEvent(MONORAIL_COMMAND_TOPIC, payload.public, payload.sensitive)\n if (response.type === 'error') {\n debug(response.message)\n }\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n let message = 'Failed to report usage analytics'\n if (error instanceof Error) {\n message = message.concat(`: ${error.message}`)\n }\n debug(message)\n }\n}\n\nconst buildPayload = async ({config, errorMessage}: ReportEventOptions) => {\n const {commandStartOptions, ...sensitiveMetadata} = metadata.getAllSensitive()\n if (commandStartOptions === undefined) {\n debug('Unable to log analytics event - no information on executed command')\n return\n }\n const {startCommand, startArgs, startTime} = commandStartOptions\n const currentTime = new Date().getTime()\n\n const {'@shopify/app': appPublic, ...otherPluginsPublic} = await fanoutHooks(config, 'public_command_metadata', {})\n const sensitivePluginData = await fanoutHooks(config, 'sensitive_command_metadata', {})\n\n const environmentData = getEnvironmentData(config)\n\n return {\n public: {\n command: startCommand,\n time_start: startTime,\n time_end: currentTime,\n total_time: currentTime - startTime,\n success: errorMessage === undefined,\n cli_version: await constants.versions.cliKit(),\n ruby_version: (await rubyVersion()) || '',\n node_version: process.version.replace('v', ''),\n is_employee: await environment.local.isShopify(),\n ...environmentData,\n ...appPublic,\n ...metadata.getAllPublic(),\n },\n sensitive: {\n args: startArgs.join(' '),\n error_message: errorMessage,\n metadata: JSON.stringify({\n ...sensitiveMetadata,\n extraPublic: {\n ...otherPluginsPublic,\n },\n extraSensitive: sensitivePluginData,\n }),\n },\n }\n}\n\nexport function getEnvironmentData(config: Interfaces.Config) {\n const ciPlatform = environment.local.ciPlatform()\n\n const pluginNames = config.plugins\n .map((plugin) => plugin.name)\n .sort()\n .filter((plugin) => !plugin.startsWith('@oclif/'))\n const shopifyPlugins = pluginNames.filter((plugin) => plugin.startsWith('@shopify/'))\n\n const {platform, arch} = platformAndArch()\n\n return {\n uname: `${platform} ${arch}`,\n env_ci: ciPlatform.isCI,\n env_ci_platform: ciPlatform.name,\n env_plugin_installed_any_custom: pluginNames.length !== shopifyPlugins.length,\n env_plugin_installed_shopify: JSON.stringify(shopifyPlugins),\n env_shell: config.shell,\n env_web_ide: environment.local.webIDEPlatform(),\n }\n}\n"]}
1
+ {"version":3,"file":"analytics.js","sourceRoot":"","sources":["../src/analytics.ts"],"names":[],"mappings":"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","sourcesContent":["import * as environment from './environment.js'\nimport {platformAndArch} from './os.js'\nimport {version as rubyVersion} from './node/ruby.js'\nimport {content, debug, token} from './output.js'\nimport constants from './constants.js'\nimport * as metadata from './metadata.js'\nimport {publishEvent, MONORAIL_COMMAND_TOPIC} from './monorail.js'\nimport {fanoutHooks} from './plugins.js'\nimport {packageManagerUsedForCreating} from './node/node-package-manager.js'\nimport BaseCommand from './node/base-command.js'\nimport {Interfaces} from '@oclif/core'\n\ninterface StartOptions {\n command: string\n args: string[]\n currentTime?: number\n commandClass?: Interfaces.Command.Class | typeof BaseCommand\n}\n\nexport const start = async ({command, args, currentTime = new Date().getTime(), commandClass}: StartOptions) => {\n let startCommand: string = command\n if (commandClass && Object.prototype.hasOwnProperty.call(command, 'analyticsNameOverride')) {\n startCommand = (commandClass as typeof BaseCommand).analyticsNameOverride() ?? command\n }\n\n await metadata.addSensitive(() => ({\n commandStartOptions: {\n startTime: currentTime,\n startCommand,\n startArgs: args,\n },\n }))\n\n await metadata.addPublic(() => ({\n cmd_all_launcher: packageManagerUsedForCreating(),\n cmd_all_plugin: commandClass?.plugin?.name,\n }))\n}\n\ninterface ReportEventOptions {\n config: Interfaces.Config\n errorMessage?: string\n}\n\n/**\n * Report an analytics event, sending it off to Monorail -- Shopify's internal analytics service.\n *\n * The payload for an event includes both generic data, and data gathered from installed plug-ins.\n *\n */\nexport async function reportEvent(options: ReportEventOptions) {\n try {\n const payload = await buildPayload(options)\n if (payload === undefined) {\n // Nothing to log\n return\n }\n if (!environment.local.alwaysLogAnalytics() && environment.local.analyticsDisabled()) {\n debug(content`Skipping command analytics, payload: ${token.json(payload)}`)\n return\n }\n const response = await publishEvent(MONORAIL_COMMAND_TOPIC, payload.public, payload.sensitive)\n if (response.type === 'error') {\n debug(response.message)\n }\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n let message = 'Failed to report usage analytics'\n if (error instanceof Error) {\n message = message.concat(`: ${error.message}`)\n }\n debug(message)\n }\n}\n\nconst buildPayload = async ({config, errorMessage}: ReportEventOptions) => {\n const {commandStartOptions, ...sensitiveMetadata} = metadata.getAllSensitive()\n if (commandStartOptions === undefined) {\n debug('Unable to log analytics event - no information on executed command')\n return\n }\n const {startCommand, startArgs, startTime} = commandStartOptions\n const currentTime = new Date().getTime()\n\n const {'@shopify/app': appPublic, ...otherPluginsPublic} = await fanoutHooks(config, 'public_command_metadata', {})\n const sensitivePluginData = await fanoutHooks(config, 'sensitive_command_metadata', {})\n\n const environmentData = getEnvironmentData(config)\n\n return {\n public: {\n command: startCommand,\n time_start: startTime,\n time_end: currentTime,\n total_time: currentTime - startTime,\n success: errorMessage === undefined,\n cli_version: await constants.versions.cliKit(),\n ruby_version: (await rubyVersion()) || '',\n node_version: process.version.replace('v', ''),\n is_employee: await environment.local.isShopify(),\n ...environmentData,\n ...appPublic,\n ...metadata.getAllPublic(),\n },\n sensitive: {\n args: startArgs.join(' '),\n error_message: errorMessage,\n metadata: JSON.stringify({\n ...sensitiveMetadata,\n extraPublic: {\n ...otherPluginsPublic,\n },\n extraSensitive: sensitivePluginData,\n }),\n },\n }\n}\n\nexport function getEnvironmentData(config: Interfaces.Config) {\n const ciPlatform = environment.local.ciPlatform()\n\n const pluginNames = config.plugins\n .map((plugin) => plugin.name)\n .sort()\n .filter((plugin) => !plugin.startsWith('@oclif/'))\n const shopifyPlugins = pluginNames.filter((plugin) => plugin.startsWith('@shopify/'))\n\n const {platform, arch} = platformAndArch()\n\n return {\n uname: `${platform} ${arch}`,\n env_ci: ciPlatform.isCI,\n env_ci_platform: ciPlatform.name,\n env_plugin_installed_any_custom: pluginNames.length !== shopifyPlugins.length,\n env_plugin_installed_shopify: JSON.stringify(shopifyPlugins),\n env_shell: config.shell,\n env_web_ide: environment.local.webIDEPlatform(),\n }\n}\n"]}
@@ -13,10 +13,13 @@ declare const constants: {
13
13
  noAnalytics: string;
14
14
  alwaysLogAnalytics: string;
15
15
  firstPartyDev: string;
16
+ enableCliRedirect: string;
17
+ skipCliRedirect: string;
16
18
  debugGoBinary: string;
17
19
  deviceAuth: string;
18
20
  spin: string;
19
21
  codespaces: string;
22
+ codespaceName: string;
20
23
  gitpod: string;
21
24
  };
22
25
  paths: {
package/dist/constants.js CHANGED
@@ -22,12 +22,15 @@ const constants = {
22
22
  noAnalytics: 'SHOPIFY_CLI_NO_ANALYTICS',
23
23
  alwaysLogAnalytics: 'SHOPIFY_CLI_ALWAYS_LOG_ANALYTICS',
24
24
  firstPartyDev: 'SHOPIFY_CLI_1P_DEV',
25
+ enableCliRedirect: 'SHOPIFY_CLI_ENABLE_CLI_REDIRECT',
26
+ skipCliRedirect: 'SHOPIFY_CLI_SKIP_CLI_REDIRECT',
25
27
  debugGoBinary: 'SHOPIFY_DEBUG_GO_BINARY',
26
28
  deviceAuth: 'SHOPIFY_CLI_DEVICE_AUTH',
27
29
  // Variables to detect if the CLI is running in a cloud environment
28
30
  spin: 'SPIN',
29
31
  codespaces: 'CODESPACES',
30
- gitpod: 'GITPOD_WORKSPACE_ID',
32
+ codespaceName: 'CODESPACE_NAME',
33
+ gitpod: 'GITPOD_WORKSPACE_URL',
31
34
  },
32
35
  paths: {
33
36
  executables: {
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,IAAI,QAAQ,EAAC,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAC,oBAAoB,EAAC,MAAM,cAAc,CAAA;AACjD,OAAO,QAAQ,MAAM,WAAW,CAAA;AAEhC,MAAM,UAAU,GAAG,aAAa,CAAA;AAEhC,MAAM,WAAW,GAAG,GAAG,EAAE;IACvB,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,CAAA;IACjE,OAAO,QAAQ,CAAC,UAAU,CAAC,CAAC,KAAK,CAAA;AACnC,CAAC,CAAA;AAED,MAAM,SAAS,GAAG;IAChB,oBAAoB,EAAE;QACpB,QAAQ,EAAE,mBAAmB;QAC7B,GAAG,EAAE,aAAa;QAClB,UAAU,EAAE,qBAAqB;QACjC,SAAS,EAAE,qBAAqB;QAChC,YAAY,EAAE,eAAe;QAC7B,aAAa,EAAE,gBAAgB;QAC/B,aAAa,EAAE,gBAAgB;QAC/B,QAAQ,EAAE,WAAW;QACrB,aAAa,EAAE,4BAA4B;QAC3C,OAAO,EAAE,sBAAsB;QAC/B,WAAW,EAAE,0BAA0B;QACvC,kBAAkB,EAAE,kCAAkC;QACtD,aAAa,EAAE,oBAAoB;QACnC,aAAa,EAAE,yBAAyB;QACxC,UAAU,EAAE,yBAAyB;QACrC,mEAAmE;QACnE,IAAI,EAAE,MAAM;QACZ,UAAU,EAAE,YAAY;QACxB,MAAM,EAAE,qBAAqB;KAC9B;IACD,KAAK,EAAE;QACL,WAAW,EAAE;YACX,GAAG,EAAE,kBAAkB;SACxB;QACD,WAAW,EAAE;YACX,KAAK,EAAE;gBACL,IAAI,EAAE,GAAG,EAAE;oBACT,OAAO,WAAW,EAAE,CAAA;gBACtB,CAAC;gBACD,MAAM,EAAE;oBACN,IAAI,EAAE,GAAG,EAAE;wBACT,OAAO,QAAQ,CAAC,WAAW,EAAE,EAAE,QAAQ,CAAC,CAAA;oBAC1C,CAAC;oBACD,QAAQ,EAAE,GAAG,EAAE;wBACb,OAAO,QAAQ,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAA;oBACtD,CAAC;iBACF;aACF;SACF;KACF;IACD,QAAQ,EAAE;QACR,MAAM,EAAE,KAAK,IAAI,EAAE;YACjB,OAAO,oBAAoB,CAAC,EAAC,aAAa,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAC,CAAC,CAAA;QAC/D,CAAC;KACF;IACD,QAAQ,EAAE;QACR,OAAO,EAAE,aAAa;KACvB;IACD,OAAO,EAAE;QACP,6BAA6B,EAAE,CAAC;KACjC;CACF,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,kCAAkC,CAAA;AAE/D,eAAe,SAAS,CAAA","sourcesContent":["import {join as pathJoin} from './path.js'\nimport {findPackageVersionUp} from './version.js'\nimport envPaths from 'env-paths'\n\nconst identifier = 'shopify-cli'\n\nconst cacheFolder = () => {\n if (process.env.XDG_CACHE_HOME) return process.env.XDG_CACHE_HOME\n return envPaths(identifier).cache\n}\n\nconst constants = {\n environmentVariables: {\n unitTest: 'SHOPIFY_UNIT_TEST',\n env: 'SHOPIFY_ENV',\n serviceEnv: 'SHOPIFY_SERVICE_ENV',\n runAsUser: 'SHOPIFY_RUN_AS_USER',\n spinInstance: 'SPIN_INSTANCE',\n spinWorkspace: 'SPIN_WORKSPACE',\n spinNamespace: 'SPIN_NAMESPACE',\n spinHost: 'SPIN_HOST',\n partnersToken: 'SHOPIFY_CLI_PARTNERS_TOKEN',\n verbose: 'SHOPIFY_FLAG_VERBOSE',\n noAnalytics: 'SHOPIFY_CLI_NO_ANALYTICS',\n alwaysLogAnalytics: 'SHOPIFY_CLI_ALWAYS_LOG_ANALYTICS',\n firstPartyDev: 'SHOPIFY_CLI_1P_DEV',\n debugGoBinary: 'SHOPIFY_DEBUG_GO_BINARY',\n deviceAuth: 'SHOPIFY_CLI_DEVICE_AUTH',\n // Variables to detect if the CLI is running in a cloud environment\n spin: 'SPIN',\n codespaces: 'CODESPACES',\n gitpod: 'GITPOD_WORKSPACE_ID',\n },\n paths: {\n executables: {\n dev: '/opt/dev/bin/dev',\n },\n directories: {\n cache: {\n path: () => {\n return cacheFolder()\n },\n vendor: {\n path: () => {\n return pathJoin(cacheFolder(), 'vendor')\n },\n binaries: () => {\n return pathJoin(cacheFolder(), 'vendor', 'binaries')\n },\n },\n },\n },\n },\n versions: {\n cliKit: async () => {\n return findPackageVersionUp({fromModuleURL: import.meta.url})\n },\n },\n keychain: {\n service: 'shopify-cli',\n },\n session: {\n expirationTimeMarginInMinutes: 4,\n },\n}\n\nexport const bugsnagApiKey = '9e1e6889176fd0c795d5c659225e0fae'\n\nexport default constants\n"]}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,IAAI,QAAQ,EAAC,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAC,oBAAoB,EAAC,MAAM,cAAc,CAAA;AACjD,OAAO,QAAQ,MAAM,WAAW,CAAA;AAEhC,MAAM,UAAU,GAAG,aAAa,CAAA;AAEhC,MAAM,WAAW,GAAG,GAAG,EAAE;IACvB,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,CAAA;IACjE,OAAO,QAAQ,CAAC,UAAU,CAAC,CAAC,KAAK,CAAA;AACnC,CAAC,CAAA;AAED,MAAM,SAAS,GAAG;IAChB,oBAAoB,EAAE;QACpB,QAAQ,EAAE,mBAAmB;QAC7B,GAAG,EAAE,aAAa;QAClB,UAAU,EAAE,qBAAqB;QACjC,SAAS,EAAE,qBAAqB;QAChC,YAAY,EAAE,eAAe;QAC7B,aAAa,EAAE,gBAAgB;QAC/B,aAAa,EAAE,gBAAgB;QAC/B,QAAQ,EAAE,WAAW;QACrB,aAAa,EAAE,4BAA4B;QAC3C,OAAO,EAAE,sBAAsB;QAC/B,WAAW,EAAE,0BAA0B;QACvC,kBAAkB,EAAE,kCAAkC;QACtD,aAAa,EAAE,oBAAoB;QACnC,iBAAiB,EAAE,iCAAiC;QACpD,eAAe,EAAE,+BAA+B;QAChD,aAAa,EAAE,yBAAyB;QACxC,UAAU,EAAE,yBAAyB;QACrC,mEAAmE;QACnE,IAAI,EAAE,MAAM;QACZ,UAAU,EAAE,YAAY;QACxB,aAAa,EAAE,gBAAgB;QAC/B,MAAM,EAAE,sBAAsB;KAC/B;IACD,KAAK,EAAE;QACL,WAAW,EAAE;YACX,GAAG,EAAE,kBAAkB;SACxB;QACD,WAAW,EAAE;YACX,KAAK,EAAE;gBACL,IAAI,EAAE,GAAG,EAAE;oBACT,OAAO,WAAW,EAAE,CAAA;gBACtB,CAAC;gBACD,MAAM,EAAE;oBACN,IAAI,EAAE,GAAG,EAAE;wBACT,OAAO,QAAQ,CAAC,WAAW,EAAE,EAAE,QAAQ,CAAC,CAAA;oBAC1C,CAAC;oBACD,QAAQ,EAAE,GAAG,EAAE;wBACb,OAAO,QAAQ,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAA;oBACtD,CAAC;iBACF;aACF;SACF;KACF;IACD,QAAQ,EAAE;QACR,MAAM,EAAE,KAAK,IAAI,EAAE;YACjB,OAAO,oBAAoB,CAAC,EAAC,aAAa,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAC,CAAC,CAAA;QAC/D,CAAC;KACF;IACD,QAAQ,EAAE;QACR,OAAO,EAAE,aAAa;KACvB;IACD,OAAO,EAAE;QACP,6BAA6B,EAAE,CAAC;KACjC;CACF,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,kCAAkC,CAAA;AAE/D,eAAe,SAAS,CAAA","sourcesContent":["import {join as pathJoin} from './path.js'\nimport {findPackageVersionUp} from './version.js'\nimport envPaths from 'env-paths'\n\nconst identifier = 'shopify-cli'\n\nconst cacheFolder = () => {\n if (process.env.XDG_CACHE_HOME) return process.env.XDG_CACHE_HOME\n return envPaths(identifier).cache\n}\n\nconst constants = {\n environmentVariables: {\n unitTest: 'SHOPIFY_UNIT_TEST',\n env: 'SHOPIFY_ENV',\n serviceEnv: 'SHOPIFY_SERVICE_ENV',\n runAsUser: 'SHOPIFY_RUN_AS_USER',\n spinInstance: 'SPIN_INSTANCE',\n spinWorkspace: 'SPIN_WORKSPACE',\n spinNamespace: 'SPIN_NAMESPACE',\n spinHost: 'SPIN_HOST',\n partnersToken: 'SHOPIFY_CLI_PARTNERS_TOKEN',\n verbose: 'SHOPIFY_FLAG_VERBOSE',\n noAnalytics: 'SHOPIFY_CLI_NO_ANALYTICS',\n alwaysLogAnalytics: 'SHOPIFY_CLI_ALWAYS_LOG_ANALYTICS',\n firstPartyDev: 'SHOPIFY_CLI_1P_DEV',\n enableCliRedirect: 'SHOPIFY_CLI_ENABLE_CLI_REDIRECT',\n skipCliRedirect: 'SHOPIFY_CLI_SKIP_CLI_REDIRECT',\n debugGoBinary: 'SHOPIFY_DEBUG_GO_BINARY',\n deviceAuth: 'SHOPIFY_CLI_DEVICE_AUTH',\n // Variables to detect if the CLI is running in a cloud environment\n spin: 'SPIN',\n codespaces: 'CODESPACES',\n codespaceName: 'CODESPACE_NAME',\n gitpod: 'GITPOD_WORKSPACE_URL',\n },\n paths: {\n executables: {\n dev: '/opt/dev/bin/dev',\n },\n directories: {\n cache: {\n path: () => {\n return cacheFolder()\n },\n vendor: {\n path: () => {\n return pathJoin(cacheFolder(), 'vendor')\n },\n binaries: () => {\n return pathJoin(cacheFolder(), 'vendor', 'binaries')\n },\n },\n },\n },\n },\n versions: {\n cliKit: async () => {\n return findPackageVersionUp({fromModuleURL: import.meta.url})\n },\n },\n keychain: {\n service: 'shopify-cli',\n },\n session: {\n expirationTimeMarginInMinutes: 4,\n },\n}\n\nexport const bugsnagApiKey = '9e1e6889176fd0c795d5c659225e0fae'\n\nexport default constants\n"]}
@@ -46,6 +46,8 @@ export declare function alwaysLogAnalytics(env?: NodeJS.ProcessEnv): boolean;
46
46
  export declare function firstPartyDev(env?: NodeJS.ProcessEnv): boolean;
47
47
  export declare function isDebugGoBinary(env?: NodeJS.ProcessEnv): boolean;
48
48
  export declare function useDeviceAuth(env?: NodeJS.ProcessEnv): boolean;
49
+ export declare function gitpodURL(env?: NodeJS.ProcessEnv): string | undefined;
50
+ export declare function codespaceURL(env?: NodeJS.ProcessEnv): string | undefined;
49
51
  export declare function isCloudEnvironment(env?: NodeJS.ProcessEnv): boolean;
50
52
  /**
51
53
  * Returns whether the environment has Git available.
@@ -65,4 +67,4 @@ export declare function ciPlatform(env?: NodeJS.ProcessEnv): {
65
67
  /**
66
68
  * Gets info on the Web IDE platform the CLI is running on, if applicable
67
69
  */
68
- export declare function webIDEPlatform(env?: NodeJS.ProcessEnv): "codespaces" | undefined;
70
+ export declare function webIDEPlatform(env?: NodeJS.ProcessEnv): "codespaces" | "gitpod" | undefined;
@@ -45,7 +45,7 @@ export async function isShopify(env = process.env) {
45
45
  return !isTruthy(env[constants.environmentVariables.runAsUser]);
46
46
  }
47
47
  const devInstalled = await fileExists(constants.paths.executables.dev);
48
- return devInstalled || isSpin();
48
+ return devInstalled || isSpin(env);
49
49
  }
50
50
  /**
51
51
  * This variable is used when running unit tests to indicate that the CLI's business logic
@@ -78,11 +78,22 @@ export function isDebugGoBinary(env = process.env) {
78
78
  export function useDeviceAuth(env = process.env) {
79
79
  return isTruthy(env[constants.environmentVariables.deviceAuth]) || isCloudEnvironment(env);
80
80
  }
81
+ // https://www.gitpod.io/docs/environment-variables#default-environment-variables
82
+ export function gitpodURL(env = process.env) {
83
+ return env[constants.environmentVariables.gitpod];
84
+ }
85
+ // https://docs.github.com/en/codespaces/developing-in-codespaces/default-environment-variables-for-your-codespace#list-of-default-environment-variables
86
+ export function codespaceURL(env = process.env) {
87
+ return env[constants.environmentVariables.codespaceName];
88
+ }
81
89
  export function isCloudEnvironment(env = process.env) {
82
- const isCodespaces = isTruthy(env[constants.environmentVariables.codespaces]);
83
- const isGitpod = isSet(env[constants.environmentVariables.gitpod]);
84
- const isSpin = isTruthy(env[constants.environmentVariables.spin]);
85
- return isCodespaces || isGitpod || isSpin;
90
+ return isCodespaces(env) || isGitpod(env) || isSpin(env);
91
+ }
92
+ function isCodespaces(env = process.env) {
93
+ return isTruthy(env[constants.environmentVariables.codespaces]);
94
+ }
95
+ function isGitpod(env = process.env) {
96
+ return isSet(env[constants.environmentVariables.gitpod]);
86
97
  }
87
98
  /**
88
99
  * Returns whether the environment has Git available.
@@ -126,9 +137,10 @@ export function ciPlatform(env = process.env) {
126
137
  * Gets info on the Web IDE platform the CLI is running on, if applicable
127
138
  */
128
139
  export function webIDEPlatform(env = process.env) {
129
- if (isTruthy(env.CODESPACES)) {
140
+ if (isCodespaces(env))
130
141
  return 'codespaces';
131
- }
142
+ if (isGitpod(env))
143
+ return 'gitpod';
132
144
  return undefined;
133
145
  }
134
146
  //# sourceMappingURL=local.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"local.js","sourceRoot":"","sources":["../../src/environment/local.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,gBAAgB,CAAA;AAC9C,OAAO,EAAC,MAAM,EAAC,MAAM,WAAW,CAAA;AAChC,OAAO,SAAS,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAC,MAAM,IAAI,UAAU,EAAC,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAC,IAAI,EAAC,MAAM,cAAc,CAAA;AACjC,OAAO,aAAa,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAC,OAAO,EAAC,MAAM,SAAS,CAAA;AAE/B;;;GAGG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO,aAAa,EAAE,CAAA;AACxB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,EAAE,CAAA;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IAC7C,OAAO,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,GAAG,CAAC,KAAK,aAAa,CAAA;AAClE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IACzC,OAAO,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;AACpG,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IAC/C,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,oBAAoB,CAAC,SAAS,CAAC,EAAE;QACvF,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC,CAAA;KAChE;IACD,MAAM,YAAY,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;IACtE,OAAO,YAAY,IAAI,MAAM,EAAE,CAAA;AACjC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IAC1C,OAAO,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAA;AAC/D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IACjD,OAAO,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,CAAA;AACxF,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,kBAAkB,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IAClD,OAAO,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,CAAC,CAAA;AACzE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IAC7C,OAAO,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC,CAAA;AACpE,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IAC/C,OAAO,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC,CAAA;AACpE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IAC7C,OAAO,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC,IAAI,kBAAkB,CAAC,GAAG,CAAC,CAAA;AAC5F,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IAClD,MAAM,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC,CAAA;IAC7E,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAA;IAClE,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAA;IACjE,OAAO,YAAY,IAAI,QAAQ,IAAI,MAAM,CAAA;AAC3C,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM;IAC1B,IAAI;QACF,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,WAAW,CAAC,CAAC,CAAA;QAChC,OAAO,IAAI,CAAA;QACX,qDAAqD;KACtD;IAAC,MAAM;QACN,OAAO,KAAK,CAAA;KACb;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IAC1C,IAAI,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;QACpB,IAAI,IAAI,GAAG,SAAS,CAAA;QACpB,IAAI,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;YAC1B,IAAI,GAAG,UAAU,CAAA;SAClB;aAAM,IAAI,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE;YACnC,IAAI,GAAG,QAAQ,CAAA;SAChB;aAAM,IAAI,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE;YAClC,IAAI,GAAG,QAAQ,CAAA;SAChB;QAED,OAAO;YACL,IAAI,EAAE,IAAI;YACV,IAAI;SACL,CAAA;KACF;IACD,OAAO;QACL,IAAI,EAAE,KAAK;KACZ,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IAC9C,IAAI,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;QAC5B,OAAO,YAAY,CAAA;KACpB;IACD,OAAO,SAAS,CAAA;AAClB,CAAC","sourcesContent":["import {isTruthy, isSet} from './utilities.js'\nimport {isSpin} from './spin.js'\nimport constants from '../constants.js'\nimport {exists as fileExists} from '../file.js'\nimport {exec} from '../system.js'\nimport isInteractive from 'is-interactive'\nimport {homedir} from 'node:os'\n\n/**\n * It returns true if the terminal is interactive.\n * @returns {boolean} True if the terminal is interactive.\n */\nexport function isTerminalInteractive(): boolean {\n return isInteractive()\n}\n\n/**\n * Returns the path to the user's home directory.\n * @returns {string} The path to the user's home directory.\n */\nexport function homeDirectory(): string {\n return homedir()\n}\n\n/**\n * Returns true if the CLI is running in debug mode.\n * @param env The environment variables from the environment of the current process.\n * @returns true if SHOPIFY_ENV is development\n */\nexport function isDevelopment(env = process.env): boolean {\n return env[constants.environmentVariables.env] === 'development'\n}\n\n/**\n * Returns true if the CLI is running in verbose mode.\n * @param env The environment variables from the environment of the current process.\n * @returns true if SHOPIFY_FLAG_VERBOSE is truthy or the flag --verbose has been passed\n */\nexport function isVerbose(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.verbose]) || process.argv.includes('--verbose')\n}\n\n/**\n * Returns true if the environment in which the CLI is running is either\n * a local environment (where dev is present) or a cloud environment (spin).\n * @returns {boolean} True if the CLI is used in a Shopify environment.\n */\nexport async function isShopify(env = process.env): Promise<boolean> {\n if (Object.prototype.hasOwnProperty.call(env, constants.environmentVariables.runAsUser)) {\n return !isTruthy(env[constants.environmentVariables.runAsUser])\n }\n const devInstalled = await fileExists(constants.paths.executables.dev)\n return devInstalled || isSpin()\n}\n\n/**\n * This variable is used when running unit tests to indicate that the CLI's business logic\n * is run as a subject of a unit test. We can use this variable to disable output through\n * the standard streams.\n * @param env The environment variables from the environment of the current process.\n * @returns True if the SHOPIFY_UNIT_TEST environment variable is truthy.\n */\nexport function isUnitTest(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.unitTest])\n}\n\n/**\n * Returns true if reporting analytics is enabled.\n * @param env The environment variables from the environment of the current process.\n * @returns true unless SHOPIFY_CLI_NO_ANALYTICS is truthy or debug mode is enabled.\n */\nexport function analyticsDisabled(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.noAnalytics]) || isDevelopment(env)\n}\n\n/** Returns true if reporting analytics should always happen, regardless of DEBUG mode etc. */\nexport function alwaysLogAnalytics(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.alwaysLogAnalytics])\n}\n\nexport function firstPartyDev(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.firstPartyDev])\n}\n\nexport function isDebugGoBinary(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.debugGoBinary])\n}\n\nexport function useDeviceAuth(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.deviceAuth]) || isCloudEnvironment(env)\n}\n\nexport function isCloudEnvironment(env = process.env): boolean {\n const isCodespaces = isTruthy(env[constants.environmentVariables.codespaces])\n const isGitpod = isSet(env[constants.environmentVariables.gitpod])\n const isSpin = isTruthy(env[constants.environmentVariables.spin])\n return isCodespaces || isGitpod || isSpin\n}\n\n/**\n * Returns whether the environment has Git available.\n * @returns {Promise<boolean>} A promise that resolves with the value.\n */\nexport async function hasGit(): Promise<boolean> {\n try {\n await exec('git', ['--version'])\n return true\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return false\n }\n}\n\n/**\n * Gets info on the CI platform the CLI is running on, if applicable\n */\nexport function ciPlatform(env = process.env): {isCI: true; name: string} | {isCI: false; name?: undefined} {\n if (isTruthy(env.CI)) {\n let name = 'unknown'\n if (isTruthy(env.CIRCLECI)) {\n name = 'circleci'\n } else if (isSet(env.GITHUB_ACTION)) {\n name = 'github'\n } else if (isTruthy(env.GITLAB_CI)) {\n name = 'gitlab'\n }\n\n return {\n isCI: true,\n name,\n }\n }\n return {\n isCI: false,\n }\n}\n\n/**\n * Gets info on the Web IDE platform the CLI is running on, if applicable\n */\nexport function webIDEPlatform(env = process.env) {\n if (isTruthy(env.CODESPACES)) {\n return 'codespaces'\n }\n return undefined\n}\n"]}
1
+ {"version":3,"file":"local.js","sourceRoot":"","sources":["../../src/environment/local.ts"],"names":[],"mappings":"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","sourcesContent":["import {isTruthy, isSet} from './utilities.js'\nimport {isSpin} from './spin.js'\nimport constants from '../constants.js'\nimport {exists as fileExists} from '../file.js'\nimport {exec} from '../system.js'\nimport isInteractive from 'is-interactive'\nimport {homedir} from 'node:os'\n\n/**\n * It returns true if the terminal is interactive.\n * @returns {boolean} True if the terminal is interactive.\n */\nexport function isTerminalInteractive(): boolean {\n return isInteractive()\n}\n\n/**\n * Returns the path to the user's home directory.\n * @returns {string} The path to the user's home directory.\n */\nexport function homeDirectory(): string {\n return homedir()\n}\n\n/**\n * Returns true if the CLI is running in debug mode.\n * @param env The environment variables from the environment of the current process.\n * @returns true if SHOPIFY_ENV is development\n */\nexport function isDevelopment(env = process.env): boolean {\n return env[constants.environmentVariables.env] === 'development'\n}\n\n/**\n * Returns true if the CLI is running in verbose mode.\n * @param env The environment variables from the environment of the current process.\n * @returns true if SHOPIFY_FLAG_VERBOSE is truthy or the flag --verbose has been passed\n */\nexport function isVerbose(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.verbose]) || process.argv.includes('--verbose')\n}\n\n/**\n * Returns true if the environment in which the CLI is running is either\n * a local environment (where dev is present) or a cloud environment (spin).\n * @returns {boolean} True if the CLI is used in a Shopify environment.\n */\nexport async function isShopify(env = process.env): Promise<boolean> {\n if (Object.prototype.hasOwnProperty.call(env, constants.environmentVariables.runAsUser)) {\n return !isTruthy(env[constants.environmentVariables.runAsUser])\n }\n const devInstalled = await fileExists(constants.paths.executables.dev)\n return devInstalled || isSpin(env)\n}\n\n/**\n * This variable is used when running unit tests to indicate that the CLI's business logic\n * is run as a subject of a unit test. We can use this variable to disable output through\n * the standard streams.\n * @param env The environment variables from the environment of the current process.\n * @returns True if the SHOPIFY_UNIT_TEST environment variable is truthy.\n */\nexport function isUnitTest(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.unitTest])\n}\n\n/**\n * Returns true if reporting analytics is enabled.\n * @param env The environment variables from the environment of the current process.\n * @returns true unless SHOPIFY_CLI_NO_ANALYTICS is truthy or debug mode is enabled.\n */\nexport function analyticsDisabled(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.noAnalytics]) || isDevelopment(env)\n}\n\n/** Returns true if reporting analytics should always happen, regardless of DEBUG mode etc. */\nexport function alwaysLogAnalytics(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.alwaysLogAnalytics])\n}\n\nexport function firstPartyDev(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.firstPartyDev])\n}\n\nexport function isDebugGoBinary(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.debugGoBinary])\n}\n\nexport function useDeviceAuth(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.deviceAuth]) || isCloudEnvironment(env)\n}\n\n// https://www.gitpod.io/docs/environment-variables#default-environment-variables\nexport function gitpodURL(env = process.env): string | undefined {\n return env[constants.environmentVariables.gitpod]\n}\n\n// https://docs.github.com/en/codespaces/developing-in-codespaces/default-environment-variables-for-your-codespace#list-of-default-environment-variables\nexport function codespaceURL(env = process.env): string | undefined {\n return env[constants.environmentVariables.codespaceName]\n}\n\nexport function isCloudEnvironment(env = process.env): boolean {\n return isCodespaces(env) || isGitpod(env) || isSpin(env)\n}\n\nfunction isCodespaces(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.codespaces])\n}\n\nfunction isGitpod(env = process.env): boolean {\n return isSet(env[constants.environmentVariables.gitpod])\n}\n\n/**\n * Returns whether the environment has Git available.\n * @returns {Promise<boolean>} A promise that resolves with the value.\n */\nexport async function hasGit(): Promise<boolean> {\n try {\n await exec('git', ['--version'])\n return true\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return false\n }\n}\n\n/**\n * Gets info on the CI platform the CLI is running on, if applicable\n */\nexport function ciPlatform(env = process.env): {isCI: true; name: string} | {isCI: false; name?: undefined} {\n if (isTruthy(env.CI)) {\n let name = 'unknown'\n if (isTruthy(env.CIRCLECI)) {\n name = 'circleci'\n } else if (isSet(env.GITHUB_ACTION)) {\n name = 'github'\n } else if (isTruthy(env.GITLAB_CI)) {\n name = 'gitlab'\n }\n\n return {\n isCI: true,\n name,\n }\n }\n return {\n isCI: false,\n }\n}\n\n/**\n * Gets info on the Web IDE platform the CLI is running on, if applicable\n */\nexport function webIDEPlatform(env = process.env) {\n if (isCodespaces(env)) return 'codespaces'\n if (isGitpod(env)) return 'gitpod'\n return undefined\n}\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spin.js","sourceRoot":"","sources":["../../src/environment/spin.ts"],"names":[],"mappings":"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","sourcesContent":["import {isTruthy} from './utilities.js'\nimport {getCachedSpinFqdn, setCachedSpinFqdn} from './spin-cache.js'\nimport constants from '../constants.js'\nimport {captureOutput} from '../system.js'\nimport {Abort} from '../error.js'\nimport {content, token} from '../output.js'\nimport {exists, readSync} from '../file.js'\n\nexport const SpinInstanceNotFound = (spinInstance: string | undefined, error: string) => {\n const errorMessage = content`${token.genericShellCommand(\n `spin`,\n )} yielded the following error trying to obtain the fully qualified domain name of the Spin instance:\n${error}\n `\n let nextSteps: string | undefined\n if (spinInstance) {\n nextSteps = `Make sure ${spinInstance} is the instance name and not a fully qualified domain name`\n }\n return new Abort(errorMessage, nextSteps)\n}\n\nconst spinFqdnFilePath = '/etc/spin/machine/fqdn'\n\n/**\n * When ran in a Spin environment, it returns the fqdn of the instance.\n *\n * Will cache the value of the Spin FQDN during the execution of the CLI.\n * To avoid multiple calls to `readSync` or `show`\n * @returns {string} fqdn of the Spin environment.\n */\nexport async function fqdn(env = process.env): Promise<string> {\n let spinFqdn = getCachedSpinFqdn()\n if (spinFqdn) return spinFqdn\n\n if (await exists(spinFqdnFilePath)) {\n spinFqdn = await readSync(spinFqdnFilePath).toString()\n } else {\n const spinInstance = await instance(env)\n const showResponse = await show(spinInstance, env)\n\n spinFqdn = showResponse.fqdn\n }\n setCachedSpinFqdn(spinFqdn)\n return spinFqdn\n}\n\n/**\n * Runs \"spin show\" and returns the JSON-parsed output.\n * @param {latest} Whether to pass --latest when running the command.\n * @returns The JSON-parsed output of the Spin CLI.\n * @throws Any error raised from the underlying Spin CLI.\n */\nexport async function show(spinInstance: string | undefined, env = process.env): Promise<{fqdn: string}> {\n const latest = spinInstance === undefined\n const args = latest ? ['show', '--latest', '--json'] : ['show', '--json']\n const output = await captureOutput('spin', args, {env})\n const json = JSON.parse(output)\n if (json.error) {\n throw SpinInstanceNotFound(spinInstance, json.error)\n } else {\n return json\n }\n}\n\n/**\n * Returns true if the CLI is running in a Spin environment.\n * @param env {[key: string]: string} Environment variables\n * @returns {boolean} True if the CLI is running in a Spin environment.\n */\nexport function isSpin(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.spin])\n}\n\n/**\n * Returns the value of the SPIN_INSTANCE environment variable.\n * @param env {[key: string]: string} Environment variables\n * @returns {string | undefined} The value of the SPIN_INSTANCE environment variable.\n */\nexport function instance(env = process.env): string | undefined {\n return env[constants.environmentVariables.spinInstance]\n}\n\n/**\n * Returns the value of the SPIN_WORKSPACE environment variable.\n * @param env {[key: string]: string} Environment variables\n * @returns {string | undefined} The value of the SPIN_WORKSPACE environment variable.\n */\nexport function workspace(env = process.env): string | undefined {\n return env[constants.environmentVariables.spinWorkspace]\n}\n\n/**\n * Returns the value of the SPIN_NAMESPACE environment variable.\n * @param env {[key: string]: string} Environment variables\n * @returns {string | undefined} The value of the SPIN_NAMESPACE environment variable.\n */\nexport function namespace(env = process.env): string | undefined {\n return env[constants.environmentVariables.spinNamespace]\n}\n\n/**\n * Returns the value of the SPIN_HOST environment variable.\n * @param env {[key: string]: string} Environment variables\n * @returns {string | undefined} The value of the SPIN_HOST environment variable.\n */\nexport function host(env = process.env): string | undefined {\n return env[constants.environmentVariables.spinHost]\n}\n"]}
@@ -1,5 +1,6 @@
1
1
  import { Command, Interfaces } from '@oclif/core';
2
- export default abstract class extends Command {
2
+ declare abstract class BaseCommand extends Command {
3
+ static analyticsNameOverride(): string | undefined;
3
4
  catch(error: Error & {
4
5
  exitCode?: number | undefined;
5
6
  }): Promise<void>;
@@ -11,6 +12,7 @@ export default abstract class extends Command {
11
12
  [name: string]: any;
12
13
  }>(options?: Interfaces.Input<TFlags> | undefined, argv?: string[] | undefined): Promise<Interfaces.ParserOutput<TFlags, TArgs>>;
13
14
  }
15
+ export default BaseCommand;
14
16
  export declare function addFromParsedFlags(flags: {
15
17
  path?: string;
16
18
  verbose?: boolean;
@@ -3,8 +3,10 @@ import { isDevelopment } from '../environment/local.js';
3
3
  import { addPublic } from '../metadata.js';
4
4
  import { hashString } from '../string.js';
5
5
  import { Command } from '@oclif/core';
6
- // eslint-disable-next-line import/no-anonymous-default-export
7
- export default class extends Command {
6
+ class BaseCommand extends Command {
7
+ static analyticsNameOverride() {
8
+ return undefined;
9
+ }
8
10
  async catch(error) {
9
11
  await errorHandler(error, this.config);
10
12
  }
@@ -23,6 +25,7 @@ export default class extends Command {
23
25
  return result;
24
26
  }
25
27
  }
28
+ export default BaseCommand;
26
29
  export async function addFromParsedFlags(flags) {
27
30
  await addPublic(() => ({
28
31
  cmd_all_verbose: flags.verbose,
@@ -1 +1 @@
1
- {"version":3,"file":"base-command.js","sourceRoot":"","sources":["../../src/node/base-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,2CAA2C,EAAC,MAAM,oBAAoB,CAAA;AAC5F,OAAO,EAAC,aAAa,EAAC,MAAM,yBAAyB,CAAA;AACrD,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAA;AACxC,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAA;AACvC,OAAO,EAAC,OAAO,EAAa,MAAM,aAAa,CAAA;AAE/C,8DAA8D;AAC9D,MAAM,CAAC,OAAO,MAAgB,SAAQ,OAAO;IAC3C,KAAK,CAAC,KAAK,CAAC,KAA8C;QACxD,MAAM,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IACxC,CAAC;IAED,8DAA8D;IACpD,KAAK,CAAC,IAAI;QAClB,IAAI,CAAC,aAAa,EAAE,EAAE;YACpB,yCAAyC;YACzC,MAAM,2CAA2C,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;SAC/D;QACD,OAAO,KAAK,CAAC,IAAI,EAAE,CAAA;IACrB,CAAC;IAED,8DAA8D;IACpD,KAAK,CAAC,KAAK,CACnB,OAA8C,EAC9C,IAA2B;QAE3B,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,KAAK,CAAgB,OAAO,EAAE,IAAI,CAAC,CAAA;QAC9D,MAAM,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACtC,OAAO,MAAM,CAAA;IACf,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,KAAyC;IAChF,MAAM,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC;QACrB,eAAe,EAAE,KAAK,CAAC,OAAO;QAC9B,qBAAqB,EAAE,KAAK,CAAC,IAAI,KAAK,SAAS;QAC/C,0BAA0B,EAAE,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC;KAC1F,CAAC,CAAC,CAAA;AACL,CAAC","sourcesContent":["import {errorHandler, registerCleanBugsnagErrorsFromWithinPlugins} from './error-handler.js'\nimport {isDevelopment} from '../environment/local.js'\nimport {addPublic} from '../metadata.js'\nimport {hashString} from '../string.js'\nimport {Command, Interfaces} from '@oclif/core'\n\n// eslint-disable-next-line import/no-anonymous-default-export\nexport default abstract class extends Command {\n async catch(error: Error & {exitCode?: number | undefined}) {\n await errorHandler(error, this.config)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected async init(): Promise<any> {\n if (!isDevelopment()) {\n // This function runs just prior to `run`\n await registerCleanBugsnagErrorsFromWithinPlugins(this.config)\n }\n return super.init()\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected async parse<TFlags extends {path?: string; verbose?: boolean}, TArgs extends {[name: string]: any}>(\n options?: Interfaces.Input<TFlags> | undefined,\n argv?: string[] | undefined,\n ): Promise<Interfaces.ParserOutput<TFlags, TArgs>> {\n const result = await super.parse<TFlags, TArgs>(options, argv)\n await addFromParsedFlags(result.flags)\n return result\n }\n}\n\nexport async function addFromParsedFlags(flags: {path?: string; verbose?: boolean}) {\n await addPublic(() => ({\n cmd_all_verbose: flags.verbose,\n cmd_all_path_override: flags.path !== undefined,\n cmd_all_path_override_hash: flags.path === undefined ? undefined : hashString(flags.path),\n }))\n}\n"]}
1
+ {"version":3,"file":"base-command.js","sourceRoot":"","sources":["../../src/node/base-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,2CAA2C,EAAC,MAAM,oBAAoB,CAAA;AAC5F,OAAO,EAAC,aAAa,EAAC,MAAM,yBAAyB,CAAA;AACrD,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAA;AACxC,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAA;AACvC,OAAO,EAAC,OAAO,EAAa,MAAM,aAAa,CAAA;AAE/C,MAAe,WAAY,SAAQ,OAAO;IACjC,MAAM,CAAC,qBAAqB;QACjC,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,KAA8C;QACxD,MAAM,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IACxC,CAAC;IAED,8DAA8D;IACpD,KAAK,CAAC,IAAI;QAClB,IAAI,CAAC,aAAa,EAAE,EAAE;YACpB,yCAAyC;YACzC,MAAM,2CAA2C,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;SAC/D;QACD,OAAO,KAAK,CAAC,IAAI,EAAE,CAAA;IACrB,CAAC;IAED,8DAA8D;IACpD,KAAK,CAAC,KAAK,CACnB,OAA8C,EAC9C,IAA2B;QAE3B,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,KAAK,CAAgB,OAAO,EAAE,IAAI,CAAC,CAAA;QAC9D,MAAM,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACtC,OAAO,MAAM,CAAA;IACf,CAAC;CACF;AAED,eAAe,WAAW,CAAA;AAE1B,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,KAAyC;IAChF,MAAM,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC;QACrB,eAAe,EAAE,KAAK,CAAC,OAAO;QAC9B,qBAAqB,EAAE,KAAK,CAAC,IAAI,KAAK,SAAS;QAC/C,0BAA0B,EAAE,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC;KAC1F,CAAC,CAAC,CAAA;AACL,CAAC","sourcesContent":["import {errorHandler, registerCleanBugsnagErrorsFromWithinPlugins} from './error-handler.js'\nimport {isDevelopment} from '../environment/local.js'\nimport {addPublic} from '../metadata.js'\nimport {hashString} from '../string.js'\nimport {Command, Interfaces} from '@oclif/core'\n\nabstract class BaseCommand extends Command {\n public static analyticsNameOverride(): string | undefined {\n return undefined\n }\n\n async catch(error: Error & {exitCode?: number | undefined}) {\n await errorHandler(error, this.config)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected async init(): Promise<any> {\n if (!isDevelopment()) {\n // This function runs just prior to `run`\n await registerCleanBugsnagErrorsFromWithinPlugins(this.config)\n }\n return super.init()\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected async parse<TFlags extends {path?: string; verbose?: boolean}, TArgs extends {[name: string]: any}>(\n options?: Interfaces.Input<TFlags> | undefined,\n argv?: string[] | undefined,\n ): Promise<Interfaces.ParserOutput<TFlags, TArgs>> {\n const result = await super.parse<TFlags, TArgs>(options, argv)\n await addFromParsedFlags(result.flags)\n return result\n }\n}\n\nexport default BaseCommand\n\nexport async function addFromParsedFlags(flags: {path?: string; verbose?: boolean}) {\n await addPublic(() => ({\n cmd_all_verbose: flags.verbose,\n cmd_all_path_override: flags.path !== undefined,\n cmd_all_path_override_hash: flags.path === undefined ? undefined : hashString(flags.path),\n }))\n}\n"]}
@@ -5,7 +5,7 @@ interface RunCLIOptions {
5
5
  /**
6
6
  * A function that abstracts away setting up the environment and running
7
7
  * a CLI
8
- * @param module {RunCLIOptions} Options.
8
+ * @param options {RunCLIOptions} Options.
9
9
  */
10
10
  export declare function runCLI(options: RunCLIOptions): Promise<void>;
11
11
  /**
@@ -13,4 +13,5 @@ export declare function runCLI(options: RunCLIOptions): Promise<void>;
13
13
  * @param options
14
14
  */
15
15
  export declare function runCreateCLI(options: RunCLIOptions): Promise<void>;
16
+ export declare function useLocalCLIIfDetected(filepath: string): Promise<boolean>;
16
17
  export default runCLI;
package/dist/node/cli.js CHANGED
@@ -2,12 +2,15 @@
2
2
  import { findUpAndReadPackageJson } from './node-package-manager.js';
3
3
  import { errorHandler } from './error-handler.js';
4
4
  import { isDevelopment } from '../environment/local.js';
5
- import { moduleDirectory } from '../path.js';
5
+ import { isTruthy } from '../environment/utilities.js';
6
+ import constants from '../constants.js';
7
+ import { join, moduleDirectory } from '../path.js';
8
+ import { captureOutput, exec } from '../system.js';
6
9
  import { run, settings, flush } from '@oclif/core';
7
10
  /**
8
11
  * A function that abstracts away setting up the environment and running
9
12
  * a CLI
10
- * @param module {RunCLIOptions} Options.
13
+ * @param options {RunCLIOptions} Options.
11
14
  */
12
15
  export async function runCLI(options) {
13
16
  if (isDevelopment()) {
@@ -31,5 +34,51 @@ export async function runCreateCLI(options) {
31
34
  }
32
35
  await runCLI(options);
33
36
  }
37
+ export async function useLocalCLIIfDetected(filepath) {
38
+ // Temporary flag while we test out this feature and ensure it won't break anything!
39
+ if (!isTruthy(process.env[constants.environmentVariables.enableCliRedirect]))
40
+ return false;
41
+ // Setting an env variable in the child process prevents accidental recursion.
42
+ if (isTruthy(process.env[constants.environmentVariables.skipCliRedirect]))
43
+ return false;
44
+ // If already running via package manager, we can assume it's running correctly already.
45
+ if (process.env.npm_config_user_agent)
46
+ return false;
47
+ const cliPackage = await localCliPackage();
48
+ if (!cliPackage)
49
+ return false;
50
+ const correctExecutablePath = join(cliPackage.path, cliPackage.bin.shopify);
51
+ if (correctExecutablePath === filepath)
52
+ return false;
53
+ try {
54
+ await exec(correctExecutablePath, process.argv.slice(2, process.argv.length), {
55
+ stdio: 'inherit',
56
+ env: { [constants.environmentVariables.skipCliRedirect]: '1' },
57
+ });
58
+ // eslint-disable-next-line no-catch-all/no-catch-all, @typescript-eslint/no-explicit-any
59
+ }
60
+ catch (processError) {
61
+ process.exit(processError.exitCode);
62
+ }
63
+ return true;
64
+ }
65
+ async function localCliPackage() {
66
+ let npmListOutput = '';
67
+ let localShopifyCLI = {};
68
+ try {
69
+ npmListOutput = await captureOutput('npm', ['list', '@shopify/cli', '--json', '-l']);
70
+ localShopifyCLI = JSON.parse(npmListOutput);
71
+ // eslint-disable-next-line no-catch-all/no-catch-all
72
+ }
73
+ catch (err) {
74
+ return;
75
+ }
76
+ const dependenciesList = {
77
+ ...localShopifyCLI.peerDependencies,
78
+ ...localShopifyCLI.devDependencies,
79
+ ...localShopifyCLI.dependencies,
80
+ };
81
+ return dependenciesList['@shopify/cli'];
82
+ }
34
83
  export default runCLI;
35
84
  //# sourceMappingURL=cli.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/node/cli.ts"],"names":[],"mappings":"AAAA,MAAM;AACN,OAAO,EAAC,wBAAwB,EAAC,MAAM,2BAA2B,CAAA;AAClE,OAAO,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAC,aAAa,EAAC,MAAM,yBAAyB,CAAA;AACrD,OAAO,EAAC,eAAe,EAAC,MAAM,YAAY,CAAA;AAC1C,OAAO,EAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAC,MAAM,aAAa,CAAA;AAOhD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,OAAsB;IACjD,IAAI,aAAa,EAAE,EAAE;QACnB,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAA;KACtB;IAED,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;AACnE,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAsB;IACvD,MAAM,WAAW,GAAG,MAAM,wBAAwB,CAAC,eAAe,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAA;IACtF,8DAA8D;IAC9D,MAAM,WAAW,GAAI,WAAW,CAAC,OAAe,CAAC,IAAc,CAAA;IAC/D,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAA;IACxD,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAA;IACvE,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE;QACpB,MAAM,SAAS,GACb,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,yBAAyB,IAAI,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QACtG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,EAAE,MAAM,CAAC,CAAA;KAC1C;IACD,MAAM,MAAM,CAAC,OAAO,CAAC,CAAA;AACvB,CAAC;AAED,eAAe,MAAM,CAAA","sourcesContent":["// CLI\nimport {findUpAndReadPackageJson} from './node-package-manager.js'\nimport {errorHandler} from './error-handler.js'\nimport {isDevelopment} from '../environment/local.js'\nimport {moduleDirectory} from '../path.js'\nimport {run, settings, flush} from '@oclif/core'\n\ninterface RunCLIOptions {\n /** The value of import.meta.url of the CLI executable module */\n moduleURL: string\n}\n\n/**\n * A function that abstracts away setting up the environment and running\n * a CLI\n * @param module {RunCLIOptions} Options.\n */\nexport async function runCLI(options: RunCLIOptions) {\n if (isDevelopment()) {\n settings.debug = true\n }\n\n run(undefined, options.moduleURL).then(flush).catch(errorHandler)\n}\n\n/**\n * A function for create-x CLIs that automatically runs the \"init\" command.\n * @param options\n */\nexport async function runCreateCLI(options: RunCLIOptions) {\n const packageJson = await findUpAndReadPackageJson(moduleDirectory(options.moduleURL))\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const packageName = (packageJson.content as any).name as string\n const name = packageName.replace('@shopify/create-', '')\n const initIndex = process.argv.findIndex((arg) => arg.includes('init'))\n if (initIndex === -1) {\n const initIndex =\n process.argv.findIndex((arg) => arg.match(new RegExp(`bin(\\\\/|\\\\\\\\)+(create-${name}|dev|run)`))) + 1\n process.argv.splice(initIndex, 0, 'init')\n }\n await runCLI(options)\n}\n\nexport default runCLI\n"]}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/node/cli.ts"],"names":[],"mappings":"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","sourcesContent":["// CLI\nimport {findUpAndReadPackageJson} from './node-package-manager.js'\nimport {errorHandler} from './error-handler.js'\nimport {isDevelopment} from '../environment/local.js'\nimport {isTruthy} from '../environment/utilities.js'\nimport constants from '../constants.js'\nimport {join, moduleDirectory} from '../path.js'\nimport {captureOutput, exec} from '../system.js'\nimport {run, settings, flush} from '@oclif/core'\n\ninterface RunCLIOptions {\n /** The value of import.meta.url of the CLI executable module */\n moduleURL: string\n}\n\n/**\n * A function that abstracts away setting up the environment and running\n * a CLI\n * @param options {RunCLIOptions} Options.\n */\nexport async function runCLI(options: RunCLIOptions) {\n if (isDevelopment()) {\n settings.debug = true\n }\n\n run(undefined, options.moduleURL).then(flush).catch(errorHandler)\n}\n\n/**\n * A function for create-x CLIs that automatically runs the \"init\" command.\n * @param options\n */\nexport async function runCreateCLI(options: RunCLIOptions) {\n const packageJson = await findUpAndReadPackageJson(moduleDirectory(options.moduleURL))\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const packageName = (packageJson.content as any).name as string\n const name = packageName.replace('@shopify/create-', '')\n const initIndex = process.argv.findIndex((arg) => arg.includes('init'))\n if (initIndex === -1) {\n const initIndex =\n process.argv.findIndex((arg) => arg.match(new RegExp(`bin(\\\\/|\\\\\\\\)+(create-${name}|dev|run)`))) + 1\n process.argv.splice(initIndex, 0, 'init')\n }\n await runCLI(options)\n}\n\nexport async function useLocalCLIIfDetected(filepath: string): Promise<boolean> {\n // Temporary flag while we test out this feature and ensure it won't break anything!\n if (!isTruthy(process.env[constants.environmentVariables.enableCliRedirect])) return false\n\n // Setting an env variable in the child process prevents accidental recursion.\n if (isTruthy(process.env[constants.environmentVariables.skipCliRedirect])) return false\n\n // If already running via package manager, we can assume it's running correctly already.\n if (process.env.npm_config_user_agent) return false\n\n const cliPackage = await localCliPackage()\n if (!cliPackage) return false\n\n const correctExecutablePath = join(cliPackage.path, cliPackage.bin.shopify)\n if (correctExecutablePath === filepath) return false\n try {\n await exec(correctExecutablePath, process.argv.slice(2, process.argv.length), {\n stdio: 'inherit',\n env: {[constants.environmentVariables.skipCliRedirect]: '1'},\n })\n // eslint-disable-next-line no-catch-all/no-catch-all, @typescript-eslint/no-explicit-any\n } catch (processError: any) {\n process.exit(processError.exitCode)\n }\n return true\n}\n\ninterface CliPackageInfo {\n path: string\n bin: {shopify: string}\n}\n\ninterface PackageJSON {\n dependencies?: {[packageName: string]: CliPackageInfo}\n devDependencies?: {[packageName: string]: CliPackageInfo}\n peerDependencies?: {[packageName: string]: CliPackageInfo}\n}\n\nasync function localCliPackage(): Promise<CliPackageInfo | undefined> {\n let npmListOutput = ''\n let localShopifyCLI: PackageJSON = {}\n try {\n npmListOutput = await captureOutput('npm', ['list', '@shopify/cli', '--json', '-l'])\n localShopifyCLI = JSON.parse(npmListOutput)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (err) {\n return\n }\n const dependenciesList = {\n ...localShopifyCLI.peerDependencies,\n ...localShopifyCLI.devDependencies,\n ...localShopifyCLI.dependencies,\n }\n return dependenciesList['@shopify/cli']\n}\n\nexport default runCLI\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"prerun.js","sourceRoot":"","sources":["../../../src/node/hooks/prerun.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,oBAAoB,CAAA;AACxC,OAAO,EAAC,KAAK,EAAC,MAAM,iBAAiB,CAAA;AAGrC,sFAAsF;AACtF,MAAM,CAAC,MAAM,IAAI,GAAgB,KAAK,EAAE,OAAO,EAAE,EAAE;IACjD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAE,CAAA;IACnG,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IACtC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;IACzB,KAAK,CAAC,mBAAmB,OAAO,EAAE,CAAC,CAAA;IACnC,MAAM,KAAK,CAAC,EAAC,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,CAAC,OAAO,EAAC,CAAC,CAAA;AAC7D,CAAC,CAAA","sourcesContent":["import {start} from '../../analytics.js'\nimport {debug} from '../../output.js'\nimport {Hook} from '@oclif/core'\n\n// This hook is called before each command run. More info: https://oclif.io/docs/hooks\nexport const hook: Hook.Prerun = async (options) => {\n const cmd = options.Command.aliases.length === 0 ? options.Command.id : options.Command.aliases[0]!\n const command = cmd.replace(/:/g, ' ')\n const args = options.argv\n debug(`Running command ${command}`)\n await start({command, args, commandClass: options.Command})\n}\n"]}
1
+ {"version":3,"file":"prerun.js","sourceRoot":"","sources":["../../../src/node/hooks/prerun.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,oBAAoB,CAAA;AACxC,OAAO,EAAC,KAAK,EAAC,MAAM,iBAAiB,CAAA;AAIrC,sFAAsF;AACtF,MAAM,CAAC,MAAM,IAAI,GAAgB,KAAK,EAAE,OAAO,EAAE,EAAE;IACjD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAE,CAAA;IACnG,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IACtC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;IACzB,KAAK,CAAC,mBAAmB,OAAO,EAAE,CAAC,CAAA;IACnC,MAAM,KAAK,CAAC,EAAC,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,CAAC,OAAoC,EAAC,CAAC,CAAA;AAC1F,CAAC,CAAA","sourcesContent":["import {start} from '../../analytics.js'\nimport {debug} from '../../output.js'\nimport Command from '../base-command.js'\nimport {Hook} from '@oclif/core'\n\n// This hook is called before each command run. More info: https://oclif.io/docs/hooks\nexport const hook: Hook.Prerun = async (options) => {\n const cmd = options.Command.aliases.length === 0 ? options.Command.id : options.Command.aliases[0]!\n const command = cmd.replace(/:/g, ' ')\n const args = options.argv\n debug(`Running command ${command}`)\n await start({command, args, commandClass: options.Command as unknown as typeof Command})\n}\n"]}
@@ -3,6 +3,10 @@ import { exchangeDeviceCodeForAccessToken } from './exchange.js';
3
3
  import { identity as identityFqdn } from '../environment/fqdn.js';
4
4
  import { shopifyFetch } from '../http.js';
5
5
  import { content, debug, info, token } from '../output.js';
6
+ import { Bug } from '../error.js';
7
+ const DeviceAuthError = () => {
8
+ return new Bug('Failed to start authorization process');
9
+ };
6
10
  /**
7
11
  * Initiate a device authorization flow.
8
12
  * This will return a DeviceAuthorizationResponse containing the URL where user
@@ -26,9 +30,11 @@ export async function requestDeviceAuthorization(scopes) {
26
30
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
27
31
  const jsonResult = await response.json();
28
32
  debug(content `Received device authorization code: ${token.json(jsonResult)}`);
33
+ if (!jsonResult.device_code || !jsonResult.verification_uri_complete)
34
+ throw DeviceAuthError();
29
35
  info('\nTo run this command, log in to Shopify Partners.');
30
36
  info(content `User verification code: ${jsonResult.user_code}`);
31
- info(content `👉 Open ${token.link('this Link', jsonResult.verification_uri_complete)} to start the auth process`);
37
+ info(content `👉 Open this link to start the auth process: ${token.green(jsonResult.verification_uri_complete)}`);
32
38
  return {
33
39
  deviceCode: jsonResult.device_code,
34
40
  userCode: jsonResult.user_code,
@@ -54,8 +60,8 @@ export async function pollForDeviceAuthorization(code, interval = 5) {
54
60
  return new Promise((resolve, reject) => {
55
61
  const onPoll = async () => {
56
62
  const result = await exchangeDeviceCodeForAccessToken(code);
57
- if (result.token)
58
- return resolve(result.token);
63
+ if (!result.isErr())
64
+ return resolve(result.value);
59
65
  const error = result.error ?? 'unknown_failure';
60
66
  debug(content `Polling for device authorization... status: ${error}`);
61
67
  switch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"device-authorization.js","sourceRoot":"","sources":["../../src/session/device-authorization.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,eAAe,CAAA;AACtC,OAAO,EAAC,gCAAgC,EAAC,MAAM,eAAe,CAAA;AAE9D,OAAO,EAAC,QAAQ,IAAI,YAAY,EAAC,MAAM,wBAAwB,CAAA;AAC/D,OAAO,EAAC,YAAY,EAAC,MAAM,YAAY,CAAA;AACvC,OAAO,EAAC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAC,MAAM,cAAc,CAAA;AAWxD;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,MAAgB;IAC/D,MAAM,IAAI,GAAG,MAAM,YAAY,EAAE,CAAA;IACjC,MAAM,gBAAgB,GAAG,MAAM,QAAQ,EAAE,CAAA;IACzC,MAAM,WAAW,GAAG,EAAC,SAAS,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAC,CAAA;IAC1E,MAAM,GAAG,GAAG,WAAW,IAAI,6BAA6B,CAAA;IAExD,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE;QACvC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAC,cAAc,EAAE,mCAAmC,EAAC;QAC9D,IAAI,EAAE,sBAAsB,CAAC,WAAW,CAAC;KAC1C,CAAC,CAAA;IAEF,8DAA8D;IAC9D,MAAM,UAAU,GAAQ,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;IAE7C,KAAK,CAAC,OAAO,CAAA,uCAAuC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;IAE7E,IAAI,CAAC,oDAAoD,CAAC,CAAA;IAC1D,IAAI,CAAC,OAAO,CAAA,2BAA2B,UAAU,CAAC,SAAS,EAAE,CAAC,CAAA;IAC9D,IAAI,CAAC,OAAO,CAAA,WAAW,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,yBAAyB,CAAC,4BAA4B,CAAC,CAAA;IAEjH,OAAO;QACL,UAAU,EAAE,UAAU,CAAC,WAAW;QAClC,QAAQ,EAAE,UAAU,CAAC,SAAS;QAC9B,eAAe,EAAE,UAAU,CAAC,gBAAgB;QAC5C,SAAS,EAAE,UAAU,CAAC,UAAU;QAChC,uBAAuB,EAAE,UAAU,CAAC,yBAAyB;QAC7D,QAAQ,EAAE,UAAU,CAAC,QAAQ;KAC9B,CAAA;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,IAAY,EAAE,QAAQ,GAAG,CAAC;IACzE,IAAI,wBAAwB,GAAG,QAAQ,CAAA;IAEvC,OAAO,IAAI,OAAO,CAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACpD,MAAM,MAAM,GAAG,KAAK,IAAI,EAAE;YACxB,MAAM,MAAM,GAAG,MAAM,gCAAgC,CAAC,IAAI,CAAC,CAAA;YAC3D,IAAI,MAAM,CAAC,KAAK;gBAAE,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YAC9C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,iBAAiB,CAAA;YAE/C,KAAK,CAAC,OAAO,CAAA,+CAA+C,KAAK,EAAE,CAAC,CAAA;YACpE,QAAQ,KAAK,EAAE;gBACb,KAAK,uBAAuB;oBAC1B,OAAO,YAAY,EAAE,CAAA;gBACvB,KAAK,WAAW;oBACd,wBAAwB,IAAI,CAAC,CAAA;oBAC7B,OAAO,YAAY,EAAE,CAAA;gBACvB,KAAK,eAAe,CAAC;gBACrB,KAAK,eAAe,CAAC;gBACrB,KAAK,iBAAiB;oBACpB,OAAO,MAAM,CAAC,MAAM,CAAC,CAAA;aACxB;QACH,CAAC,CAAA;QAED,MAAM,YAAY,GAAG,GAAG,EAAE;YACxB,kEAAkE;YAClE,UAAU,CAAC,MAAM,EAAE,wBAAwB,GAAG,IAAI,CAAC,CAAA;QACrD,CAAC,CAAA;QAED,YAAY,EAAE,CAAA;IAChB,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,sBAAsB,CAAC,WAA+C;IAC7E,OAAO,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;SAC/B,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,IAAI,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC;SACjD,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;SACvC,IAAI,CAAC,GAAG,CAAC,CAAA;AACd,CAAC","sourcesContent":["import {clientId} from './identity.js'\nimport {exchangeDeviceCodeForAccessToken} from './exchange.js'\nimport {IdentityToken} from './schema.js'\nimport {identity as identityFqdn} from '../environment/fqdn.js'\nimport {shopifyFetch} from '../http.js'\nimport {content, debug, info, token} from '../output.js'\n\nexport interface DeviceAuthorizationResponse {\n deviceCode: string\n userCode: string\n verificationUri: string\n expiresIn: number\n verificationUriComplete?: string\n interval?: number\n}\n\n/**\n * Initiate a device authorization flow.\n * This will return a DeviceAuthorizationResponse containing the URL where user\n * should go to authorize the device without the need of a callback to the CLI.\n *\n * Also returns a `deviceCode` used for polling the token endpoint in the next step.\n *\n * @param scopes The scopes to request\n * @returns {Promise<DeviceAuthorizationResponse>} An object with the device authorization response.\n */\nexport async function requestDeviceAuthorization(scopes: string[]): Promise<DeviceAuthorizationResponse> {\n const fqdn = await identityFqdn()\n const identityClientId = await clientId()\n const queryParams = {client_id: identityClientId, scope: scopes.join(' ')}\n const url = `https://${fqdn}/oauth/device_authorization`\n\n const response = await shopifyFetch(url, {\n method: 'POST',\n headers: {'Content-type': 'application/x-www-form-urlencoded'},\n body: convertRequestToParams(queryParams),\n })\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const jsonResult: any = await response.json()\n\n debug(content`Received device authorization code: ${token.json(jsonResult)}`)\n\n info('\\nTo run this command, log in to Shopify Partners.')\n info(content`User verification code: ${jsonResult.user_code}`)\n info(content`👉 Open ${token.link('this Link', jsonResult.verification_uri_complete)} to start the auth process`)\n\n return {\n deviceCode: jsonResult.device_code,\n userCode: jsonResult.user_code,\n verificationUri: jsonResult.verification_uri,\n expiresIn: jsonResult.expires_in,\n verificationUriComplete: jsonResult.verification_uri_complete,\n interval: jsonResult.interval,\n }\n}\n\n/**\n * Poll the Oauth token endpoint with the device code obtained from a DeviceAuthorizationResponse.\n * The endpoint will return `authorization_pending` until the user completes the auth flow in the browser.\n * Once the user completes the auth flow, the endpoint will return the identity token.\n *\n * Timeout for the polling is defined by the server and is around 600 seconds.\n *\n * @param code The device code obtained after starting a device identity flow\n * @param interval The interval to poll the token endpoint\n * @returns {Promise<IdentityToken>} The identity token\n */\nexport async function pollForDeviceAuthorization(code: string, interval = 5): Promise<IdentityToken> {\n let currentIntervalInSeconds = interval\n\n return new Promise<IdentityToken>((resolve, reject) => {\n const onPoll = async () => {\n const result = await exchangeDeviceCodeForAccessToken(code)\n if (result.token) return resolve(result.token)\n const error = result.error ?? 'unknown_failure'\n\n debug(content`Polling for device authorization... status: ${error}`)\n switch (error) {\n case 'authorization_pending':\n return startPolling()\n case 'slow_down':\n currentIntervalInSeconds += 5\n return startPolling()\n case 'access_denied':\n case 'expired_token':\n case 'unknown_failure':\n return reject(result)\n }\n }\n\n const startPolling = () => {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n setTimeout(onPoll, currentIntervalInSeconds * 1000)\n }\n\n startPolling()\n })\n}\n\nfunction convertRequestToParams(queryParams: {client_id: string; scope: string}): string {\n return Object.entries(queryParams)\n .map(([key, value]) => value && `${key}=${value}`)\n .filter((hasValue) => Boolean(hasValue))\n .join('&')\n}\n"]}
1
+ {"version":3,"file":"device-authorization.js","sourceRoot":"","sources":["../../src/session/device-authorization.ts"],"names":[],"mappings":"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","sourcesContent":["import {clientId} from './identity.js'\nimport {exchangeDeviceCodeForAccessToken} from './exchange.js'\nimport {IdentityToken} from './schema.js'\nimport {identity as identityFqdn} from '../environment/fqdn.js'\nimport {shopifyFetch} from '../http.js'\nimport {content, debug, info, token} from '../output.js'\nimport {Bug} from '../error.js'\n\nexport interface DeviceAuthorizationResponse {\n deviceCode: string\n userCode: string\n verificationUri: string\n expiresIn: number\n verificationUriComplete?: string\n interval?: number\n}\n\nconst DeviceAuthError = () => {\n return new Bug('Failed to start authorization process')\n}\n\n/**\n * Initiate a device authorization flow.\n * This will return a DeviceAuthorizationResponse containing the URL where user\n * should go to authorize the device without the need of a callback to the CLI.\n *\n * Also returns a `deviceCode` used for polling the token endpoint in the next step.\n *\n * @param scopes The scopes to request\n * @returns {Promise<DeviceAuthorizationResponse>} An object with the device authorization response.\n */\nexport async function requestDeviceAuthorization(scopes: string[]): Promise<DeviceAuthorizationResponse> {\n const fqdn = await identityFqdn()\n const identityClientId = await clientId()\n const queryParams = {client_id: identityClientId, scope: scopes.join(' ')}\n const url = `https://${fqdn}/oauth/device_authorization`\n\n const response = await shopifyFetch(url, {\n method: 'POST',\n headers: {'Content-type': 'application/x-www-form-urlencoded'},\n body: convertRequestToParams(queryParams),\n })\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const jsonResult: any = await response.json()\n\n debug(content`Received device authorization code: ${token.json(jsonResult)}`)\n if (!jsonResult.device_code || !jsonResult.verification_uri_complete) throw DeviceAuthError()\n\n info('\\nTo run this command, log in to Shopify Partners.')\n info(content`User verification code: ${jsonResult.user_code}`)\n info(content`👉 Open this link to start the auth process: ${token.green(jsonResult.verification_uri_complete)}`)\n\n return {\n deviceCode: jsonResult.device_code,\n userCode: jsonResult.user_code,\n verificationUri: jsonResult.verification_uri,\n expiresIn: jsonResult.expires_in,\n verificationUriComplete: jsonResult.verification_uri_complete,\n interval: jsonResult.interval,\n }\n}\n\n/**\n * Poll the Oauth token endpoint with the device code obtained from a DeviceAuthorizationResponse.\n * The endpoint will return `authorization_pending` until the user completes the auth flow in the browser.\n * Once the user completes the auth flow, the endpoint will return the identity token.\n *\n * Timeout for the polling is defined by the server and is around 600 seconds.\n *\n * @param code The device code obtained after starting a device identity flow\n * @param interval The interval to poll the token endpoint\n * @returns {Promise<IdentityToken>} The identity token\n */\nexport async function pollForDeviceAuthorization(code: string, interval = 5): Promise<IdentityToken> {\n let currentIntervalInSeconds = interval\n\n return new Promise<IdentityToken>((resolve, reject) => {\n const onPoll = async () => {\n const result = await exchangeDeviceCodeForAccessToken(code)\n if (!result.isErr()) return resolve(result.value)\n\n const error = result.error ?? 'unknown_failure'\n\n debug(content`Polling for device authorization... status: ${error}`)\n switch (error) {\n case 'authorization_pending':\n return startPolling()\n case 'slow_down':\n currentIntervalInSeconds += 5\n return startPolling()\n case 'access_denied':\n case 'expired_token':\n case 'unknown_failure':\n return reject(result)\n }\n }\n\n const startPolling = () => {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n setTimeout(onPoll, currentIntervalInSeconds * 1000)\n }\n\n startPolling()\n })\n}\n\nfunction convertRequestToParams(queryParams: {client_id: string; scope: string}): string {\n return Object.entries(queryParams)\n .map(([key, value]) => value && `${key}=${value}`)\n .filter((hasValue) => Boolean(hasValue))\n .join('&')\n}\n"]}
@@ -1,5 +1,6 @@
1
1
  import { ApplicationToken, IdentityToken } from './schema.js';
2
2
  import { CodeAuthResult } from './authorize.js';
3
+ import { Result } from '../common/result.js';
3
4
  export declare class InvalidGrantError extends Error {
4
5
  }
5
6
  export interface ExchangeScopes {
@@ -47,7 +48,4 @@ export declare type IdentityDeviceError = 'authorization_pending' | 'access_deni
47
48
  * @param scopes The scopes to request
48
49
  * @returns {Promise<IdentityToken>} An instance with the identity access tokens.
49
50
  */
50
- export declare function exchangeDeviceCodeForAccessToken(deviceCode: string): Promise<{
51
- token?: IdentityToken;
52
- error?: IdentityDeviceError;
53
- }>;
51
+ export declare function exchangeDeviceCodeForAccessToken(deviceCode: string): Promise<Result<IdentityToken, IdentityDeviceError>>;