@shopify/cli-kit 3.9.2 → 3.10.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.10.0
4
+
5
+ ### Patch Changes
6
+
7
+ - 4c8853f1: Use hooks to communicate with ngrok plugin
8
+
3
9
  ## 3.9.2
4
10
 
5
11
  ## 3.9.1
@@ -1,5 +1,4 @@
1
1
  export * from './all_app_extension_registrations.js';
2
- export * from './all_app_extension_registrations.js';
3
2
  export * from './all_orgs.js';
4
3
  export * from './all_stores_by_org.js';
5
4
  export * from './convert_dev_to_test_store.js';
@@ -14,14 +13,10 @@ export * from './find_store_by_domain.js';
14
13
  export * from './functions/app_function_set.js';
15
14
  export * from './functions/compile_module.js';
16
15
  export * from './functions/function_service_proxy.js';
17
- export * from './functions/function_service_proxy.js';
18
- export * from './functions/get_app_functions.js';
19
- export * from './functions/get_app_functions.js';
20
16
  export * from './functions/module_compilation_status.js';
21
17
  export * from './functions/upload_url_generate.js';
22
18
  export * from './generate_signed_upload_url.js';
23
19
  export * from './get_urls.js';
24
20
  export * from './get_variant_id.js';
25
- export * from './get_variant_id.js';
26
21
  export * from './update_draft.js';
27
22
  export * from './update_urls.js';
@@ -1,5 +1,4 @@
1
1
  export * from './all_app_extension_registrations.js';
2
- export * from './all_app_extension_registrations.js';
3
2
  export * from './all_orgs.js';
4
3
  export * from './all_stores_by_org.js';
5
4
  export * from './convert_dev_to_test_store.js';
@@ -14,15 +13,11 @@ export * from './find_store_by_domain.js';
14
13
  export * from './functions/app_function_set.js';
15
14
  export * from './functions/compile_module.js';
16
15
  export * from './functions/function_service_proxy.js';
17
- export * from './functions/function_service_proxy.js';
18
- export * from './functions/get_app_functions.js';
19
- export * from './functions/get_app_functions.js';
20
16
  export * from './functions/module_compilation_status.js';
21
17
  export * from './functions/upload_url_generate.js';
22
18
  export * from './generate_signed_upload_url.js';
23
19
  export * from './get_urls.js';
24
20
  export * from './get_variant_id.js';
25
- export * from './get_variant_id.js';
26
21
  export * from './update_draft.js';
27
22
  export * from './update_urls.js';
28
23
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/api/graphql/index.ts"],"names":[],"mappings":"AAAA,cAAc,sCAAsC,CAAA;AACpD,cAAc,sCAAsC,CAAA;AACpD,cAAc,eAAe,CAAA;AAC7B,cAAc,wBAAwB,CAAA;AACtC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,iBAAiB,CAAA;AAC/B,cAAc,wBAAwB,CAAA;AACtC,cAAc,uBAAuB,CAAA;AACrC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,eAAe,CAAA;AAC7B,cAAc,qBAAqB,CAAA;AACnC,cAAc,eAAe,CAAA;AAC7B,cAAc,2BAA2B,CAAA;AACzC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,+BAA+B,CAAA;AAC7C,cAAc,uCAAuC,CAAA;AACrD,cAAc,uCAAuC,CAAA;AACrD,cAAc,kCAAkC,CAAA;AAChD,cAAc,kCAAkC,CAAA;AAChD,cAAc,0CAA0C,CAAA;AACxD,cAAc,oCAAoC,CAAA;AAClD,cAAc,iCAAiC,CAAA;AAC/C,cAAc,eAAe,CAAA;AAC7B,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA;AACnC,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA","sourcesContent":["export * from './all_app_extension_registrations.js'\nexport * from './all_app_extension_registrations.js'\nexport * from './all_orgs.js'\nexport * from './all_stores_by_org.js'\nexport * from './convert_dev_to_test_store.js'\nexport * from './create_app.js'\nexport * from './create_deployment.js'\nexport * from './extension_create.js'\nexport * from './extension_specifications.js'\nexport * from './find_app.js'\nexport * from './find_org_basic.js'\nexport * from './find_org.js'\nexport * from './find_store_by_domain.js'\nexport * from './functions/app_function_set.js'\nexport * from './functions/compile_module.js'\nexport * from './functions/function_service_proxy.js'\nexport * from './functions/function_service_proxy.js'\nexport * from './functions/get_app_functions.js'\nexport * from './functions/get_app_functions.js'\nexport * from './functions/module_compilation_status.js'\nexport * from './functions/upload_url_generate.js'\nexport * from './generate_signed_upload_url.js'\nexport * from './get_urls.js'\nexport * from './get_variant_id.js'\nexport * from './get_variant_id.js'\nexport * from './update_draft.js'\nexport * from './update_urls.js'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/api/graphql/index.ts"],"names":[],"mappings":"AAAA,cAAc,sCAAsC,CAAA;AACpD,cAAc,eAAe,CAAA;AAC7B,cAAc,wBAAwB,CAAA;AACtC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,iBAAiB,CAAA;AAC/B,cAAc,wBAAwB,CAAA;AACtC,cAAc,uBAAuB,CAAA;AACrC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,eAAe,CAAA;AAC7B,cAAc,qBAAqB,CAAA;AACnC,cAAc,eAAe,CAAA;AAC7B,cAAc,2BAA2B,CAAA;AACzC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,+BAA+B,CAAA;AAC7C,cAAc,uCAAuC,CAAA;AACrD,cAAc,0CAA0C,CAAA;AACxD,cAAc,oCAAoC,CAAA;AAClD,cAAc,iCAAiC,CAAA;AAC/C,cAAc,eAAe,CAAA;AAC7B,cAAc,qBAAqB,CAAA;AACnC,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA","sourcesContent":["export * from './all_app_extension_registrations.js'\nexport * from './all_orgs.js'\nexport * from './all_stores_by_org.js'\nexport * from './convert_dev_to_test_store.js'\nexport * from './create_app.js'\nexport * from './create_deployment.js'\nexport * from './extension_create.js'\nexport * from './extension_specifications.js'\nexport * from './find_app.js'\nexport * from './find_org_basic.js'\nexport * from './find_org.js'\nexport * from './find_store_by_domain.js'\nexport * from './functions/app_function_set.js'\nexport * from './functions/compile_module.js'\nexport * from './functions/function_service_proxy.js'\nexport * from './functions/module_compilation_status.js'\nexport * from './functions/upload_url_generate.js'\nexport * from './generate_signed_upload_url.js'\nexport * from './get_urls.js'\nexport * from './get_variant_id.js'\nexport * from './update_draft.js'\nexport * from './update_urls.js'\n"]}
package/dist/array.d.ts CHANGED
@@ -1 +1,3 @@
1
1
  export declare function randomPick<T>(array: T[]): T | undefined;
2
+ export declare function filterUndefined<T>(array: T[]): Exclude<T, null | undefined>[];
3
+ export declare function containsDuplicates<T>(array: T[]): boolean;
package/dist/array.js CHANGED
@@ -1,4 +1,10 @@
1
1
  export function randomPick(array) {
2
2
  return array[Math.floor(Math.random() * array.length)];
3
3
  }
4
+ export function filterUndefined(array) {
5
+ return array.filter((item) => item !== undefined);
6
+ }
7
+ export function containsDuplicates(array) {
8
+ return array.length !== new Set(array).size;
9
+ }
4
10
  //# sourceMappingURL=array.js.map
package/dist/array.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"array.js","sourceRoot":"","sources":["../src/array.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,UAAU,CAAI,KAAU;IACtC,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAA;AACxD,CAAC","sourcesContent":["export function randomPick<T>(array: T[]) {\n return array[Math.floor(Math.random() * array.length)]\n}\n"]}
1
+ {"version":3,"file":"array.js","sourceRoot":"","sources":["../src/array.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,UAAU,CAAI,KAAU;IACtC,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAA;AACxD,CAAC;AAED,MAAM,UAAU,eAAe,CAAI,KAAU;IAC3C,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,CAAmC,CAAA;AACrF,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAI,KAAU;IAC9C,OAAO,KAAK,CAAC,MAAM,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAA;AAC7C,CAAC","sourcesContent":["export function randomPick<T>(array: T[]) {\n return array[Math.floor(Math.random() * array.length)]\n}\n\nexport function filterUndefined<T>(array: T[]) {\n return array.filter((item) => item !== undefined) as Exclude<T, null | undefined>[]\n}\n\nexport function containsDuplicates<T>(array: T[]) {\n return array.length !== new Set(array).size\n}\n"]}
package/dist/node/cli.js CHANGED
@@ -2,10 +2,8 @@
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 constants, { bugsnagApiKey } from '../constants.js';
6
5
  import { moduleDirectory } from '../path.js';
7
6
  import { run, settings, flush } from '@oclif/core';
8
- import Bugsnag from '@bugsnag/js';
9
7
  /**
10
8
  * A function that abstracts away setting up the environment and running
11
9
  * a CLI
@@ -15,16 +13,6 @@ export async function runCLI(options) {
15
13
  if (isDevelopment()) {
16
14
  settings.debug = true;
17
15
  }
18
- else {
19
- Bugsnag.start({
20
- appType: 'node',
21
- apiKey: bugsnagApiKey,
22
- logger: null,
23
- appVersion: await constants.versions.cliKit(),
24
- autoTrackSessions: false,
25
- autoDetectErrors: false,
26
- });
27
- }
28
16
  run(undefined, options.moduleURL).then(flush).catch(errorHandler);
29
17
  }
30
18
  /**
@@ -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,SAAS,EAAE,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAA;AACxD,OAAO,EAAC,eAAe,EAAC,MAAM,YAAY,CAAA;AAC1C,OAAO,EAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAC,MAAM,aAAa,CAAA;AAChD,OAAO,OAAO,MAAM,aAAa,CAAA;AAOjC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,OAAsB;IACjD,IAAI,aAAa,EAAE,EAAE;QACnB,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAA;KACtB;SAAM;QACL,OAAO,CAAC,KAAK,CAAC;YACZ,OAAO,EAAE,MAAM;YACf,MAAM,EAAE,aAAa;YACrB,MAAM,EAAE,IAAI;YACZ,UAAU,EAAE,MAAM,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE;YAC7C,iBAAiB,EAAE,KAAK;YACxB,gBAAgB,EAAE,KAAK;SACxB,CAAC,CAAA;KACH;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 constants, {bugsnagApiKey} from '../constants.js'\nimport {moduleDirectory} from '../path.js'\nimport {run, settings, flush} from '@oclif/core'\nimport Bugsnag from '@bugsnag/js'\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 } else {\n Bugsnag.start({\n appType: 'node',\n apiKey: bugsnagApiKey,\n logger: null,\n appVersion: await constants.versions.cliKit(),\n autoTrackSessions: false,\n autoDetectErrors: false,\n })\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":"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"]}
@@ -4,6 +4,7 @@ import { getEnvironmentData, reportEvent } from '../analytics.js';
4
4
  import * as path from '../path.js';
5
5
  import * as metadata from '../metadata.js';
6
6
  import { fanoutHooks } from '../plugins.js';
7
+ import constants, { bugsnagApiKey } from '../constants.js';
7
8
  import { settings } from '@oclif/core';
8
9
  import StackTracey from 'stacktracey';
9
10
  import Bugsnag from '@bugsnag/js';
@@ -76,6 +77,7 @@ export async function sendErrorToBugsnag(error) {
76
77
  .join('\n');
77
78
  reportableError.stack = `Error: ${reportableError.message}\n${formattedStacktrace}`;
78
79
  if (report) {
80
+ await initializeBugsnag();
79
81
  await new Promise((resolve, reject) => {
80
82
  Bugsnag.notify(reportableError, undefined, (error, event) => {
81
83
  if (error) {
@@ -117,6 +119,7 @@ export async function registerCleanBugsnagErrorsFromWithinPlugins(config) {
117
119
  const followSymlinks = await realpath(plugin.root);
118
120
  return { name: plugin.name, pluginPath: path.normalize(followSymlinks) };
119
121
  }));
122
+ await initializeBugsnag();
120
123
  Bugsnag.addOnError(async (event) => {
121
124
  event.errors.forEach((error) => {
122
125
  error.stacktrace.forEach((stackFrame) => {
@@ -177,4 +180,17 @@ export async function addBugsnagMetadata(event, config) {
177
180
  event.addMetadata(section, values);
178
181
  });
179
182
  }
183
+ async function initializeBugsnag() {
184
+ if (Bugsnag.isStarted()) {
185
+ return;
186
+ }
187
+ Bugsnag.start({
188
+ appType: 'node',
189
+ apiKey: bugsnagApiKey,
190
+ logger: null,
191
+ appVersion: await constants.versions.cliKit(),
192
+ autoTrackSessions: false,
193
+ autoDetectErrors: false,
194
+ });
195
+ }
180
196
  //# sourceMappingURL=error-handler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/node/error-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n AbortSilent,\n CancelExecution,\n mapper as errorMapper,\n shouldReport as shouldReportError,\n handler,\n cleanSingleStackTracePath,\n} from '../error.js'\nimport {debug, info} from '../output.js'\nimport {getEnvironmentData, reportEvent} from '../analytics.js'\nimport * as path from '../path.js'\nimport * as metadata from '../metadata.js'\nimport {fanoutHooks} from '../plugins.js'\nimport {settings, Interfaces} from '@oclif/core'\nimport StackTracey from 'stacktracey'\nimport Bugsnag, {Event} from '@bugsnag/js'\nimport {realpath} from 'fs/promises'\n\nexport function errorHandler(error: Error & {exitCode?: number | undefined}, config?: Interfaces.Config) {\n if (error instanceof CancelExecution) {\n if (error.message && error.message !== '') {\n info(`✨ ${error.message}`)\n }\n } else if (error instanceof AbortSilent) {\n process.exit(1)\n } else {\n return errorMapper(error)\n .then((error) => {\n return handler(error)\n })\n .then((mappedError) => reportError(mappedError, config))\n .then(() => {\n process.exit(1)\n })\n }\n}\n\nconst reportError = async (error: unknown, config?: Interfaces.Config): Promise<void> => {\n if (config !== undefined) {\n // Log an analytics event when there's an error\n await reportEvent({config, errorMessage: error instanceof Error ? error.message : undefined})\n }\n await sendErrorToBugsnag(error)\n}\n\n/**\n * Sends an error to Bugsnag. This is configured automatically for uncaught errors from CLI commands, but can also be used to manually record an error.\n *\n * @returns the reported error (this may have been tweaked for better reporting), and a bool to indicate if the error was actually submitted or not\n */\nexport async function sendErrorToBugsnag(\n error: unknown,\n): Promise<{reported: false; error: unknown} | {error: Error; reported: true}> {\n if (settings.debug || !shouldReportError(error)) return {reported: false, error}\n\n let reportableError: Error\n let stacktrace: string | undefined\n let report = false\n\n if (error instanceof Error) {\n report = true\n reportableError = new Error(error.message)\n stacktrace = error.stack\n\n /**\n * Some errors that reach this point have an empty string. For example:\n * https://app.bugsnag.com/shopify/cli/errors/62cd5d31fd5040000814086c?filters[event.since]=30d&filters[error.status]=new&filters[release.seen_in]=3.1.0\n *\n * Because at this point we have neither the error message nor a stack trace reporting them\n * to Bugsnag is pointless and adds noise.\n */\n } else if (typeof error === 'string' && error.trim().length !== 0) {\n report = true\n reportableError = new Error(error)\n stacktrace = reportableError.stack\n } else {\n report = false\n reportableError = new Error('Unknown error')\n }\n\n const formattedStacktrace = new StackTracey(stacktrace ?? '')\n .clean()\n .items.map((item) => {\n const filePath = cleanSingleStackTracePath(item.file)\n return ` at ${item.callee} (${filePath}:${item.line}:${item.column})`\n })\n .join('\\n')\n reportableError.stack = `Error: ${reportableError.message}\\n${formattedStacktrace}`\n\n if (report) {\n await new Promise((resolve, reject) => {\n Bugsnag.notify(reportableError, undefined, (error, event) => {\n if (error) {\n reject(error)\n } else {\n resolve(reportableError)\n }\n })\n })\n }\n return {error: reportableError, reported: report}\n}\n\n/**\n * If the given file path comes from within a plugin, return the relative path, plus the plugin name.\n *\n * This gives us very consistent paths for errors thrown from plugin code.\n *\n */\nexport function cleanStackFrameFilePath({\n currentFilePath,\n projectRoot,\n pluginLocations,\n}: {\n currentFilePath: string\n projectRoot: string\n pluginLocations: {name: string; pluginPath: string}[]\n}): string {\n const fullLocation = path.isAbsolute(currentFilePath) ? currentFilePath : path.join(projectRoot, currentFilePath)\n\n const matchingPluginPath = pluginLocations.filter(({pluginPath}) => fullLocation.indexOf(pluginPath) === 0)[0]\n\n if (matchingPluginPath !== undefined) {\n // the plugin name (e.g. @shopify/cli-kit), plus the relative path of the error line from within the plugin's code (e.g. dist/something.js )\n return path.join(matchingPluginPath.name, path.relative(matchingPluginPath.pluginPath, fullLocation))\n }\n return currentFilePath\n}\n\n/**\n * Register a Bugsnag error listener to clean up stack traces for errors within plugin code.\n *\n */\nexport async function registerCleanBugsnagErrorsFromWithinPlugins(config: Interfaces.Config) {\n // Bugsnag have their own plug-ins that use this private field\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const bugsnagConfigProjectRoot: string = (Bugsnag as any)?._client?._config?.projectRoot ?? process.cwd()\n const projectRoot = path.normalize(bugsnagConfigProjectRoot)\n const pluginLocations = await Promise.all(\n config.plugins.map(async (plugin) => {\n const followSymlinks = await realpath(plugin.root)\n return {name: plugin.name, pluginPath: path.normalize(followSymlinks)}\n }),\n )\n Bugsnag.addOnError(async (event) => {\n event.errors.forEach((error) => {\n error.stacktrace.forEach((stackFrame) => {\n stackFrame.file = cleanStackFrameFilePath({currentFilePath: stackFrame.file, projectRoot, pluginLocations})\n })\n })\n try {\n await addBugsnagMetadata(event, config)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (metadataError) {\n debug(`There was an error adding metadata to the Bugsnag report; Ignoring and carrying on ${metadataError}`)\n }\n })\n}\n\nexport async function addBugsnagMetadata(event: Event, config: Interfaces.Config) {\n const publicData = metadata.getAllPublic()\n const {commandStartOptions} = metadata.getAllSensitive()\n const {startCommand} = commandStartOptions ?? {}\n\n const {'@shopify/app': appPublic, ...otherPluginsPublic} = await fanoutHooks(config, 'public_command_metadata', {})\n\n const environment = getEnvironmentData(config)\n\n const allMetadata = {\n command: startCommand,\n ...appPublic,\n ...publicData,\n ...environment,\n pluginData: otherPluginsPublic,\n }\n\n const appData = {} as {[key: string]: unknown}\n const commandData = {} as {[key: string]: unknown}\n const environmentData = {} as {[key: string]: unknown}\n const miscData = {} as {[key: string]: unknown}\n const appKeys = ['api_key', 'partner_id', 'project_type']\n const commandKeys = ['command']\n const environmentKeys = ['cli_version', 'node_version', 'ruby_version', 'uname']\n\n Object.entries(allMetadata).forEach(([key, value]) => {\n if (key.startsWith('app_') || appKeys.includes(key)) {\n appData[key] = value\n } else if (key.startsWith('cmd_') || commandKeys.includes(key)) {\n commandData[key] = value\n } else if (key.startsWith('env_') || environmentKeys) {\n environmentData[key] = value\n } else {\n miscData[key] = value\n }\n })\n\n // app, command, environment, misc\n const bugsnagMetadata = {\n 'Shopify App': appData,\n Command: commandData,\n Environment: environmentData,\n Misc: miscData,\n }\n Object.entries(bugsnagMetadata).forEach(([section, values]) => {\n event.addMetadata(section, values)\n })\n}\n"]}
1
+ {"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/node/error-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n AbortSilent,\n CancelExecution,\n mapper as errorMapper,\n shouldReport as shouldReportError,\n handler,\n cleanSingleStackTracePath,\n} from '../error.js'\nimport {debug, info} from '../output.js'\nimport {getEnvironmentData, reportEvent} from '../analytics.js'\nimport * as path from '../path.js'\nimport * as metadata from '../metadata.js'\nimport {fanoutHooks} from '../plugins.js'\nimport constants, {bugsnagApiKey} from '../constants.js'\nimport {settings, Interfaces} from '@oclif/core'\nimport StackTracey from 'stacktracey'\nimport Bugsnag, {Event} from '@bugsnag/js'\nimport {realpath} from 'fs/promises'\n\nexport function errorHandler(error: Error & {exitCode?: number | undefined}, config?: Interfaces.Config) {\n if (error instanceof CancelExecution) {\n if (error.message && error.message !== '') {\n info(`✨ ${error.message}`)\n }\n } else if (error instanceof AbortSilent) {\n process.exit(1)\n } else {\n return errorMapper(error)\n .then((error) => {\n return handler(error)\n })\n .then((mappedError) => reportError(mappedError, config))\n .then(() => {\n process.exit(1)\n })\n }\n}\n\nconst reportError = async (error: unknown, config?: Interfaces.Config): Promise<void> => {\n if (config !== undefined) {\n // Log an analytics event when there's an error\n await reportEvent({config, errorMessage: error instanceof Error ? error.message : undefined})\n }\n await sendErrorToBugsnag(error)\n}\n\n/**\n * Sends an error to Bugsnag. This is configured automatically for uncaught errors from CLI commands, but can also be used to manually record an error.\n *\n * @returns the reported error (this may have been tweaked for better reporting), and a bool to indicate if the error was actually submitted or not\n */\nexport async function sendErrorToBugsnag(\n error: unknown,\n): Promise<{reported: false; error: unknown} | {error: Error; reported: true}> {\n if (settings.debug || !shouldReportError(error)) return {reported: false, error}\n\n let reportableError: Error\n let stacktrace: string | undefined\n let report = false\n\n if (error instanceof Error) {\n report = true\n reportableError = new Error(error.message)\n stacktrace = error.stack\n\n /**\n * Some errors that reach this point have an empty string. For example:\n * https://app.bugsnag.com/shopify/cli/errors/62cd5d31fd5040000814086c?filters[event.since]=30d&filters[error.status]=new&filters[release.seen_in]=3.1.0\n *\n * Because at this point we have neither the error message nor a stack trace reporting them\n * to Bugsnag is pointless and adds noise.\n */\n } else if (typeof error === 'string' && error.trim().length !== 0) {\n report = true\n reportableError = new Error(error)\n stacktrace = reportableError.stack\n } else {\n report = false\n reportableError = new Error('Unknown error')\n }\n\n const formattedStacktrace = new StackTracey(stacktrace ?? '')\n .clean()\n .items.map((item) => {\n const filePath = cleanSingleStackTracePath(item.file)\n return ` at ${item.callee} (${filePath}:${item.line}:${item.column})`\n })\n .join('\\n')\n reportableError.stack = `Error: ${reportableError.message}\\n${formattedStacktrace}`\n\n if (report) {\n await initializeBugsnag()\n await new Promise((resolve, reject) => {\n Bugsnag.notify(reportableError, undefined, (error, event) => {\n if (error) {\n reject(error)\n } else {\n resolve(reportableError)\n }\n })\n })\n }\n return {error: reportableError, reported: report}\n}\n\n/**\n * If the given file path comes from within a plugin, return the relative path, plus the plugin name.\n *\n * This gives us very consistent paths for errors thrown from plugin code.\n *\n */\nexport function cleanStackFrameFilePath({\n currentFilePath,\n projectRoot,\n pluginLocations,\n}: {\n currentFilePath: string\n projectRoot: string\n pluginLocations: {name: string; pluginPath: string}[]\n}): string {\n const fullLocation = path.isAbsolute(currentFilePath) ? currentFilePath : path.join(projectRoot, currentFilePath)\n\n const matchingPluginPath = pluginLocations.filter(({pluginPath}) => fullLocation.indexOf(pluginPath) === 0)[0]\n\n if (matchingPluginPath !== undefined) {\n // the plugin name (e.g. @shopify/cli-kit), plus the relative path of the error line from within the plugin's code (e.g. dist/something.js )\n return path.join(matchingPluginPath.name, path.relative(matchingPluginPath.pluginPath, fullLocation))\n }\n return currentFilePath\n}\n\n/**\n * Register a Bugsnag error listener to clean up stack traces for errors within plugin code.\n *\n */\nexport async function registerCleanBugsnagErrorsFromWithinPlugins(config: Interfaces.Config) {\n // Bugsnag have their own plug-ins that use this private field\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const bugsnagConfigProjectRoot: string = (Bugsnag as any)?._client?._config?.projectRoot ?? process.cwd()\n const projectRoot = path.normalize(bugsnagConfigProjectRoot)\n const pluginLocations = await Promise.all(\n config.plugins.map(async (plugin) => {\n const followSymlinks = await realpath(plugin.root)\n return {name: plugin.name, pluginPath: path.normalize(followSymlinks)}\n }),\n )\n await initializeBugsnag()\n Bugsnag.addOnError(async (event) => {\n event.errors.forEach((error) => {\n error.stacktrace.forEach((stackFrame) => {\n stackFrame.file = cleanStackFrameFilePath({currentFilePath: stackFrame.file, projectRoot, pluginLocations})\n })\n })\n try {\n await addBugsnagMetadata(event, config)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (metadataError) {\n debug(`There was an error adding metadata to the Bugsnag report; Ignoring and carrying on ${metadataError}`)\n }\n })\n}\n\nexport async function addBugsnagMetadata(event: Event, config: Interfaces.Config) {\n const publicData = metadata.getAllPublic()\n const {commandStartOptions} = metadata.getAllSensitive()\n const {startCommand} = commandStartOptions ?? {}\n\n const {'@shopify/app': appPublic, ...otherPluginsPublic} = await fanoutHooks(config, 'public_command_metadata', {})\n\n const environment = getEnvironmentData(config)\n\n const allMetadata = {\n command: startCommand,\n ...appPublic,\n ...publicData,\n ...environment,\n pluginData: otherPluginsPublic,\n }\n\n const appData = {} as {[key: string]: unknown}\n const commandData = {} as {[key: string]: unknown}\n const environmentData = {} as {[key: string]: unknown}\n const miscData = {} as {[key: string]: unknown}\n const appKeys = ['api_key', 'partner_id', 'project_type']\n const commandKeys = ['command']\n const environmentKeys = ['cli_version', 'node_version', 'ruby_version', 'uname']\n\n Object.entries(allMetadata).forEach(([key, value]) => {\n if (key.startsWith('app_') || appKeys.includes(key)) {\n appData[key] = value\n } else if (key.startsWith('cmd_') || commandKeys.includes(key)) {\n commandData[key] = value\n } else if (key.startsWith('env_') || environmentKeys) {\n environmentData[key] = value\n } else {\n miscData[key] = value\n }\n })\n\n // app, command, environment, misc\n const bugsnagMetadata = {\n 'Shopify App': appData,\n Command: commandData,\n Environment: environmentData,\n Misc: miscData,\n }\n Object.entries(bugsnagMetadata).forEach(([section, values]) => {\n event.addMetadata(section, values)\n })\n}\n\nasync function initializeBugsnag() {\n if (Bugsnag.isStarted()) {\n return\n }\n Bugsnag.start({\n appType: 'node',\n apiKey: bugsnagApiKey,\n logger: null,\n appVersion: await constants.versions.cliKit(),\n autoTrackSessions: false,\n autoDetectErrors: false,\n })\n}\n"]}
@@ -1,7 +1,5 @@
1
1
  import { initiateLogging } from '../../output.js';
2
- import { initializeCliKitStore } from '../../store.js';
3
2
  export const hook = async (options) => {
4
- await initializeCliKitStore();
5
3
  initiateLogging();
6
4
  };
7
5
  //# sourceMappingURL=init.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/node/hooks/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,iBAAiB,CAAA;AAC/C,OAAO,EAAC,qBAAqB,EAAC,MAAM,gBAAgB,CAAA;AAGpD,MAAM,CAAC,MAAM,IAAI,GAAc,KAAK,EAAE,OAAO,EAAE,EAAE;IAC/C,MAAM,qBAAqB,EAAE,CAAA;IAC7B,eAAe,EAAE,CAAA;AACnB,CAAC,CAAA","sourcesContent":["import {initiateLogging} from '../../output.js'\nimport {initializeCliKitStore} from '../../store.js'\nimport {Hook} from '@oclif/core'\n\nexport const hook: Hook.Init = async (options) => {\n await initializeCliKitStore()\n initiateLogging()\n}\n"]}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/node/hooks/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,iBAAiB,CAAA;AAG/C,MAAM,CAAC,MAAM,IAAI,GAAc,KAAK,EAAE,OAAO,EAAE,EAAE;IAC/C,eAAe,EAAE,CAAA;AACnB,CAAC,CAAA","sourcesContent":["import {initiateLogging} from '../../output.js'\nimport {Hook} from '@oclif/core'\n\nexport const hook: Hook.Init = async (options) => {\n initiateLogging()\n}\n"]}
package/dist/node/ruby.js CHANGED
@@ -11,7 +11,6 @@ const RubyCLIVersion = '2.23.0';
11
11
  const ThemeCheckVersion = '1.10.3';
12
12
  const MinBundlerVersion = '2.3.8';
13
13
  const MinRubyVersion = '2.7.5';
14
- const MinRubyGemVersion = '2.5.0';
15
14
  /**
16
15
  * Execute CLI 2.0 commands.
17
16
  * Installs a version of RubyCLI as a vendor dependency in a hidden folder in the system.
@@ -135,7 +134,6 @@ async function installCLIDependencies() {
135
134
  }
136
135
  async function validateRubyEnv() {
137
136
  await validateRuby();
138
- await validateRubyGems();
139
137
  await validateBundler();
140
138
  }
141
139
  async function validateRuby() {
@@ -152,14 +150,6 @@ async function validateRuby() {
152
150
  throw new Abort(`Ruby version ${content `${token.yellow(version.raw)}`.value} is not supported`, `Make sure you have at least Ruby ${content `${token.yellow(MinRubyVersion)}`.value} installed on your system. ${content `${token.link('Documentation.', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value}`);
153
151
  }
154
152
  }
155
- async function validateRubyGems() {
156
- const stdout = await system.captureOutput(gemExecutable(), ['-v']);
157
- const version = coerce(stdout);
158
- const isValid = version?.compare(MinRubyGemVersion);
159
- if (isValid === -1 || isValid === undefined) {
160
- throw new Abort(`RubyGems version ${content `${token.yellow(version.raw)}`.value} is not supported`, `To update to the latest version of RubyGems, run ${content `${token.genericShellCommand(`${gemExecutable()} update --system`)}`.value}`);
161
- }
162
- }
163
153
  async function validateBundler() {
164
154
  let version;
165
155
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"ruby.js","sourceRoot":"","sources":["../../src/node/ruby.ts"],"names":[],"mappings":"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","sourcesContent":["import * as file from '../file.js'\nimport * as ui from '../ui.js'\nimport * as system from '../system.js'\nimport {Abort, AbortSilent} from '../error.js'\nimport {glob, join} from '../path.js'\nimport constants from '../constants.js'\nimport {coerce} from '../semver.js'\nimport {AdminSession} from '../session.js'\nimport {content, token} from '../output.js'\nimport {Writable} from 'node:stream'\n\nconst RubyCLIVersion = '2.23.0'\nconst ThemeCheckVersion = '1.10.3'\nconst MinBundlerVersion = '2.3.8'\nconst MinRubyVersion = '2.7.5'\nconst MinRubyGemVersion = '2.5.0'\n\ninterface ExecCLI2Options {\n // Contains token and store to pass to CLI 2.0, which will be set as environment variables\n adminSession?: AdminSession\n // Contains token for storefront access to pass to CLI 2.0 as environment variable\n storefrontToken?: string\n // Directory in which to execute the command. Otherwise the current directory will be used.\n directory?: string\n}\n/**\n * Execute CLI 2.0 commands.\n * Installs a version of RubyCLI as a vendor dependency in a hidden folder in the system.\n * User must have a valid ruby+bundler environment to run any command.\n *\n * @param args {string[]} List of argumets to execute. (ex: ['theme', 'pull'])\n * @param options {ExecCLI2Options}\n */\nexport async function execCLI2(args: string[], {adminSession, storefrontToken, directory}: ExecCLI2Options = {}) {\n await installCLIDependencies()\n const env = {\n ...process.env,\n SHOPIFY_CLI_STOREFRONT_RENDERER_AUTH_TOKEN: storefrontToken,\n SHOPIFY_CLI_ADMIN_AUTH_TOKEN: adminSession?.token,\n SHOPIFY_CLI_STORE: adminSession?.storeFqdn,\n SHOPIFY_CLI_RUN_AS_SUBPROCESS: 'true',\n // Bundler uses this Gemfile to understand which gems are available in the\n // environment. We use this to specify our own Gemfile for CLI2, which exists\n // outside the user's project directory.\n BUNDLE_GEMFILE: join(shopifyCLIDirectory(), 'Gemfile'),\n }\n\n try {\n await system.exec(bundleExecutable(), ['exec', 'shopify'].concat(args), {\n stdio: 'inherit',\n cwd: directory ?? process.cwd(),\n env,\n })\n } catch (error) {\n // CLI2 will show it's own errors, we don't need to show an additional CLI3 error\n throw new AbortSilent()\n }\n}\n\ninterface ExecThemeCheckCLIOptions {\n /** A list of directories in which theme-check should run */\n directories: string[]\n /** Arguments to pass to the theme-check CLI */\n args?: string[]\n /** Writable to send standard output content through */\n stdout: Writable\n /** Writable to send standard error content through */\n stderr: Writable\n}\n\n/**\n * A function that installs (if needed) and runs the theme-check CLI.\n * @param options {ExecThemeCheckCLIOptions} Options to customize the execution of theme-check.\n * @returns {Promise<void>} A promise that resolves or rejects depending on the result of the underlying theme-check process.\n */\nexport async function execThemeCheckCLI({\n directories,\n args,\n stdout,\n stderr,\n}: ExecThemeCheckCLIOptions): Promise<void[]> {\n await installThemeCheckCLIDependencies(stdout)\n\n const processes = directories.map(async (directory): Promise<void> => {\n // Check that there are files aside from the extension TOML config file,\n // otherwise theme-check will return a false failure.\n const files = await glob(join(directory, '/**/*'))\n const fileCount = files.filter((file) => !file.match(/\\.toml$/)).length\n if (fileCount === 0) return\n\n const customStderr = new Writable({\n write(chunk, ...args) {\n // For some reason, theme-check reports this initial status line to stderr\n // See https://github.com/Shopify/theme-check/blob/1092737cfb58a73ca397ffb1371665dc55df2976/lib/theme_check/language_server/diagnostics_engine.rb#L31\n // which leads to https://github.com/Shopify/theme-check/blob/1092737cfb58a73ca397ffb1371665dc55df2976/lib/theme_check/language_server/io_messenger.rb#L65\n if (chunk.toString('ascii').match(/^Checking/)) {\n stdout.write(chunk, ...args)\n } else {\n stderr.write(chunk, ...args)\n }\n },\n })\n await system.exec(bundleExecutable(), ['exec', 'theme-check'].concat([directory, ...(args || [])]), {\n stdout,\n stderr: customStderr,\n cwd: themeCheckDirectory(),\n })\n })\n return Promise.all(processes)\n}\n\n/**\n * Validate Ruby Enviroment\n * Install Theme Check CLI and its dependencies\n * Shows a loading message if it's the first time installing dependencies\n * or if we are installing a new version of Theme Check CLI\n */\nasync function installThemeCheckCLIDependencies(stdout: Writable) {\n const exists = await file.exists(themeCheckDirectory())\n\n if (!exists) stdout.write('Installing theme dependencies...')\n const list = ui.newListr(\n [\n {\n title: 'Installing theme dependencies',\n task: async () => {\n await validateRubyEnv()\n await createThemeCheckCLIWorkingDirectory()\n await createThemeCheckGemfile()\n await bundleInstallThemeCheck()\n },\n },\n ],\n {renderer: 'silent'},\n )\n await list.run()\n if (!exists) stdout.write('Installed theme dependencies!')\n}\n\n/**\n * Validate Ruby Enviroment\n * Install RubyCLI and its dependencies\n * Shows a loading spinner if it's the first time installing dependencies\n * or if we are installing a new version of RubyCLI\n */\nasync function installCLIDependencies() {\n const exists = await file.exists(shopifyCLIDirectory())\n const renderer = exists ? 'silent' : 'default'\n\n const list = ui.newListr(\n [\n {\n title: 'Installing theme dependencies',\n task: async () => {\n const usingLocalCLI2 = Boolean(process.env.SHOPIFY_CLI_2_0_DIRECTORY)\n await validateRubyEnv()\n if (usingLocalCLI2) {\n await bundleInstallLocalShopifyCLI()\n } else {\n await createShopifyCLIWorkingDirectory()\n await createShopifyCLIGemfile()\n await bundleInstallShopifyCLI()\n }\n },\n },\n ],\n {renderer},\n )\n await list.run()\n}\n\nasync function validateRubyEnv() {\n await validateRuby()\n await validateRubyGems()\n await validateBundler()\n}\n\nasync function validateRuby() {\n let version\n try {\n const stdout = await system.captureOutput(rubyExecutable(), ['-v'])\n version = coerce(stdout)\n } catch {\n throw new Abort(\n 'Ruby environment not found',\n `Make sure you have Ruby installed on your system. ${\n content`${token.link('Documentation.', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value\n }`,\n )\n }\n\n const isValid = version?.compare(MinRubyVersion)\n if (isValid === -1 || isValid === undefined) {\n throw new Abort(\n `Ruby version ${content`${token.yellow(version.raw)}`.value} is not supported`,\n `Make sure you have at least Ruby ${content`${token.yellow(MinRubyVersion)}`.value} installed on your system. ${\n content`${token.link('Documentation.', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value\n }`,\n )\n }\n}\n\nasync function validateRubyGems() {\n const stdout = await system.captureOutput(gemExecutable(), ['-v'])\n const version = coerce(stdout)\n\n const isValid = version?.compare(MinRubyGemVersion)\n if (isValid === -1 || isValid === undefined) {\n throw new Abort(\n `RubyGems version ${content`${token.yellow(version.raw)}`.value} is not supported`,\n `To update to the latest version of RubyGems, run ${\n content`${token.genericShellCommand(`${gemExecutable()} update --system`)}`.value\n }`,\n )\n }\n}\n\nasync function validateBundler() {\n let version\n try {\n const stdout = await system.captureOutput(bundleExecutable(), ['-v'])\n version = coerce(stdout)\n } catch {\n throw new Abort(\n 'Bundler not found',\n `To install the latest version of Bundler, run ${\n content`${token.genericShellCommand(`${gemExecutable()} install bundler`)}`.value\n }`,\n )\n }\n\n const isValid = version?.compare(MinBundlerVersion)\n if (isValid === -1 || isValid === undefined) {\n throw new Abort(\n `Bundler version ${content`${token.yellow(version.raw)}`.value} is not supported`,\n `To update to the latest version of Bundler, run ${\n content`${token.genericShellCommand(`${gemExecutable()} install bundler`)}`.value\n }`,\n )\n }\n}\n\nfunction createShopifyCLIWorkingDirectory() {\n return file.mkdir(shopifyCLIDirectory())\n}\n\nfunction createThemeCheckCLIWorkingDirectory() {\n return file.mkdir(themeCheckDirectory())\n}\n\nasync function createShopifyCLIGemfile() {\n const gemPath = join(shopifyCLIDirectory(), 'Gemfile')\n await file.write(gemPath, `source 'https://rubygems.org'\\ngem 'shopify-cli', '${RubyCLIVersion}'`)\n}\n\nasync function createThemeCheckGemfile() {\n const gemPath = join(themeCheckDirectory(), 'Gemfile')\n await file.write(gemPath, `source 'https://rubygems.org'\\ngem 'theme-check', '${ThemeCheckVersion}'`)\n}\n\nasync function bundleInstallLocalShopifyCLI() {\n await system.exec(bundleExecutable(), ['install'], {cwd: shopifyCLIDirectory()})\n}\n\nasync function bundleInstallShopifyCLI() {\n await system.exec(bundleExecutable(), ['config', 'set', '--local', 'path', shopifyCLIDirectory()], {\n cwd: shopifyCLIDirectory(),\n })\n await system.exec(bundleExecutable(), ['install'], {cwd: shopifyCLIDirectory()})\n}\n\nasync function bundleInstallThemeCheck() {\n await system.exec(bundleExecutable(), ['config', 'set', '--local', 'path', themeCheckDirectory()], {\n cwd: themeCheckDirectory(),\n })\n await system.exec(bundleExecutable(), ['install'], {cwd: themeCheckDirectory()})\n}\n\nfunction shopifyCLIDirectory() {\n return (\n process.env.SHOPIFY_CLI_2_0_DIRECTORY ??\n join(constants.paths.directories.cache.vendor.path(), 'ruby-cli', RubyCLIVersion)\n )\n}\n\nfunction themeCheckDirectory() {\n return join(constants.paths.directories.cache.vendor.path(), 'theme-check', ThemeCheckVersion)\n}\n\nexport async function version(): Promise<string | undefined> {\n const parseOutput = (version: string) => version.match(/ruby (\\d+\\.\\d+\\.\\d+)/)?.[1]\n return system\n .captureOutput(rubyExecutable(), ['-v'])\n .then(parseOutput)\n .catch(() => undefined)\n}\n\nfunction getRubyBinDir(): string | undefined {\n return process.env.SHOPIFY_RUBY_BINDIR\n}\n\nfunction rubyExecutable(): string {\n const rubyBinDir = getRubyBinDir()\n return rubyBinDir ? join(rubyBinDir, 'ruby') : 'ruby'\n}\n\nfunction bundleExecutable(): string {\n const rubyBinDir = getRubyBinDir()\n return rubyBinDir ? join(rubyBinDir, 'bundle') : 'bundle'\n}\n\nfunction gemExecutable(): string {\n const rubyBinDir = getRubyBinDir()\n return rubyBinDir ? join(rubyBinDir, 'gem') : 'gem'\n}\n"]}
1
+ {"version":3,"file":"ruby.js","sourceRoot":"","sources":["../../src/node/ruby.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,YAAY,CAAA;AAClC,OAAO,KAAK,EAAE,MAAM,UAAU,CAAA;AAC9B,OAAO,KAAK,MAAM,MAAM,cAAc,CAAA;AACtC,OAAO,EAAC,KAAK,EAAE,WAAW,EAAC,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAC,IAAI,EAAE,IAAI,EAAC,MAAM,YAAY,CAAA;AACrC,OAAO,SAAS,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAC,MAAM,EAAC,MAAM,cAAc,CAAA;AAEnC,OAAO,EAAC,OAAO,EAAE,KAAK,EAAC,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAA;AAEpC,MAAM,cAAc,GAAG,QAAQ,CAAA;AAC/B,MAAM,iBAAiB,GAAG,QAAQ,CAAA;AAClC,MAAM,iBAAiB,GAAG,OAAO,CAAA;AACjC,MAAM,cAAc,GAAG,OAAO,CAAA;AAU9B;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAc,EAAE,EAAC,YAAY,EAAE,eAAe,EAAE,SAAS,KAAqB,EAAE;IAC7G,MAAM,sBAAsB,EAAE,CAAA;IAC9B,MAAM,GAAG,GAAG;QACV,GAAG,OAAO,CAAC,GAAG;QACd,0CAA0C,EAAE,eAAe;QAC3D,4BAA4B,EAAE,YAAY,EAAE,KAAK;QACjD,iBAAiB,EAAE,YAAY,EAAE,SAAS;QAC1C,6BAA6B,EAAE,MAAM;QACrC,0EAA0E;QAC1E,6EAA6E;QAC7E,wCAAwC;QACxC,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,EAAE,SAAS,CAAC;KACvD,CAAA;IAED,IAAI;QACF,MAAM,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;YACtE,KAAK,EAAE,SAAS;YAChB,GAAG,EAAE,SAAS,IAAI,OAAO,CAAC,GAAG,EAAE;YAC/B,GAAG;SACJ,CAAC,CAAA;KACH;IAAC,OAAO,KAAK,EAAE;QACd,iFAAiF;QACjF,MAAM,IAAI,WAAW,EAAE,CAAA;KACxB;AACH,CAAC;AAaD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,EACtC,WAAW,EACX,IAAI,EACJ,MAAM,EACN,MAAM,GACmB;IACzB,MAAM,gCAAgC,CAAC,MAAM,CAAC,CAAA;IAE9C,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,EAAiB,EAAE;QACnE,wEAAwE;QACxE,qDAAqD;QACrD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAA;QAClD,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAA;QACvE,IAAI,SAAS,KAAK,CAAC;YAAE,OAAM;QAE3B,MAAM,YAAY,GAAG,IAAI,QAAQ,CAAC;YAChC,KAAK,CAAC,KAAK,EAAE,GAAG,IAAI;gBAClB,0EAA0E;gBAC1E,qJAAqJ;gBACrJ,0JAA0J;gBAC1J,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE;oBAC9C,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,CAAA;iBAC7B;qBAAM;oBACL,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,CAAA;iBAC7B;YACH,CAAC;SACF,CAAC,CAAA;QACF,MAAM,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;YAClG,MAAM;YACN,MAAM,EAAE,YAAY;YACpB,GAAG,EAAE,mBAAmB,EAAE;SAC3B,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IACF,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;AAC/B,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,gCAAgC,CAAC,MAAgB;IAC9D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,CAAC,CAAA;IAEvD,IAAI,CAAC,MAAM;QAAE,MAAM,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAA;IAC7D,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CACtB;QACE;YACE,KAAK,EAAE,+BAA+B;YACtC,IAAI,EAAE,KAAK,IAAI,EAAE;gBACf,MAAM,eAAe,EAAE,CAAA;gBACvB,MAAM,mCAAmC,EAAE,CAAA;gBAC3C,MAAM,uBAAuB,EAAE,CAAA;gBAC/B,MAAM,uBAAuB,EAAE,CAAA;YACjC,CAAC;SACF;KACF,EACD,EAAC,QAAQ,EAAE,QAAQ,EAAC,CACrB,CAAA;IACD,MAAM,IAAI,CAAC,GAAG,EAAE,CAAA;IAChB,IAAI,CAAC,MAAM;QAAE,MAAM,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAA;AAC5D,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,sBAAsB;IACnC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,CAAC,CAAA;IACvD,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAA;IAE9C,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CACtB;QACE;YACE,KAAK,EAAE,+BAA+B;YACtC,IAAI,EAAE,KAAK,IAAI,EAAE;gBACf,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAA;gBACrE,MAAM,eAAe,EAAE,CAAA;gBACvB,IAAI,cAAc,EAAE;oBAClB,MAAM,4BAA4B,EAAE,CAAA;iBACrC;qBAAM;oBACL,MAAM,gCAAgC,EAAE,CAAA;oBACxC,MAAM,uBAAuB,EAAE,CAAA;oBAC/B,MAAM,uBAAuB,EAAE,CAAA;iBAChC;YACH,CAAC;SACF;KACF,EACD,EAAC,QAAQ,EAAC,CACX,CAAA;IACD,MAAM,IAAI,CAAC,GAAG,EAAE,CAAA;AAClB,CAAC;AAED,KAAK,UAAU,eAAe;IAC5B,MAAM,YAAY,EAAE,CAAA;IACpB,MAAM,eAAe,EAAE,CAAA;AACzB,CAAC;AAED,KAAK,UAAU,YAAY;IACzB,IAAI,OAAO,CAAA;IACX,IAAI;QACF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,cAAc,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;QACnE,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAA;KACzB;IAAC,MAAM;QACN,MAAM,IAAI,KAAK,CACb,4BAA4B,EAC5B,qDACE,OAAO,CAAA,GAAG,KAAK,CAAC,IAAI,CAAC,gBAAgB,EAAE,0DAA0D,CAAC,EAAE,CAAC,KACvG,EAAE,CACH,CAAA;KACF;IAED,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;IAChD,IAAI,OAAO,KAAK,CAAC,CAAC,IAAI,OAAO,KAAK,SAAS,EAAE;QAC3C,MAAM,IAAI,KAAK,CACb,gBAAgB,OAAO,CAAA,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,mBAAmB,EAC9E,oCAAoC,OAAO,CAAA,GAAG,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,KAAK,8BAChF,OAAO,CAAA,GAAG,KAAK,CAAC,IAAI,CAAC,gBAAgB,EAAE,0DAA0D,CAAC,EAAE,CAAC,KACvG,EAAE,CACH,CAAA;KACF;AACH,CAAC;AAED,KAAK,UAAU,eAAe;IAC5B,IAAI,OAAO,CAAA;IACX,IAAI;QACF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,gBAAgB,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;QACrE,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAA;KACzB;IAAC,MAAM;QACN,MAAM,IAAI,KAAK,CACb,mBAAmB,EACnB,iDACE,OAAO,CAAA,GAAG,KAAK,CAAC,mBAAmB,CAAC,GAAG,aAAa,EAAE,kBAAkB,CAAC,EAAE,CAAC,KAC9E,EAAE,CACH,CAAA;KACF;IAED,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAA;IACnD,IAAI,OAAO,KAAK,CAAC,CAAC,IAAI,OAAO,KAAK,SAAS,EAAE;QAC3C,MAAM,IAAI,KAAK,CACb,mBAAmB,OAAO,CAAA,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,mBAAmB,EACjF,mDACE,OAAO,CAAA,GAAG,KAAK,CAAC,mBAAmB,CAAC,GAAG,aAAa,EAAE,kBAAkB,CAAC,EAAE,CAAC,KAC9E,EAAE,CACH,CAAA;KACF;AACH,CAAC;AAED,SAAS,gCAAgC;IACvC,OAAO,IAAI,CAAC,KAAK,CAAC,mBAAmB,EAAE,CAAC,CAAA;AAC1C,CAAC;AAED,SAAS,mCAAmC;IAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,mBAAmB,EAAE,CAAC,CAAA;AAC1C,CAAC;AAED,KAAK,UAAU,uBAAuB;IACpC,MAAM,OAAO,GAAG,IAAI,CAAC,mBAAmB,EAAE,EAAE,SAAS,CAAC,CAAA;IACtD,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,sDAAsD,cAAc,GAAG,CAAC,CAAA;AACpG,CAAC;AAED,KAAK,UAAU,uBAAuB;IACpC,MAAM,OAAO,GAAG,IAAI,CAAC,mBAAmB,EAAE,EAAE,SAAS,CAAC,CAAA;IACtD,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,sDAAsD,iBAAiB,GAAG,CAAC,CAAA;AACvG,CAAC;AAED,KAAK,UAAU,4BAA4B;IACzC,MAAM,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,EAAC,GAAG,EAAE,mBAAmB,EAAE,EAAC,CAAC,CAAA;AAClF,CAAC;AAED,KAAK,UAAU,uBAAuB;IACpC,MAAM,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC,EAAE;QACjG,GAAG,EAAE,mBAAmB,EAAE;KAC3B,CAAC,CAAA;IACF,MAAM,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,EAAC,GAAG,EAAE,mBAAmB,EAAE,EAAC,CAAC,CAAA;AAClF,CAAC;AAED,KAAK,UAAU,uBAAuB;IACpC,MAAM,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC,EAAE;QACjG,GAAG,EAAE,mBAAmB,EAAE;KAC3B,CAAC,CAAA;IACF,MAAM,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,EAAC,GAAG,EAAE,mBAAmB,EAAE,EAAC,CAAC,CAAA;AAClF,CAAC;AAED,SAAS,mBAAmB;IAC1B,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,yBAAyB;QACrC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,cAAc,CAAC,CAClF,CAAA;AACH,CAAC;AAED,SAAS,mBAAmB;IAC1B,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,iBAAiB,CAAC,CAAA;AAChG,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO;IAC3B,MAAM,WAAW,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IACnF,OAAO,MAAM;SACV,aAAa,CAAC,cAAc,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;SACvC,IAAI,CAAC,WAAW,CAAC;SACjB,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;AAC3B,CAAC;AAED,SAAS,aAAa;IACpB,OAAO,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAA;AACxC,CAAC;AAED,SAAS,cAAc;IACrB,MAAM,UAAU,GAAG,aAAa,EAAE,CAAA;IAClC,OAAO,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;AACvD,CAAC;AAED,SAAS,gBAAgB;IACvB,MAAM,UAAU,GAAG,aAAa,EAAE,CAAA;IAClC,OAAO,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;AAC3D,CAAC;AAED,SAAS,aAAa;IACpB,MAAM,UAAU,GAAG,aAAa,EAAE,CAAA;IAClC,OAAO,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;AACrD,CAAC","sourcesContent":["import * as file from '../file.js'\nimport * as ui from '../ui.js'\nimport * as system from '../system.js'\nimport {Abort, AbortSilent} from '../error.js'\nimport {glob, join} from '../path.js'\nimport constants from '../constants.js'\nimport {coerce} from '../semver.js'\nimport {AdminSession} from '../session.js'\nimport {content, token} from '../output.js'\nimport {Writable} from 'node:stream'\n\nconst RubyCLIVersion = '2.23.0'\nconst ThemeCheckVersion = '1.10.3'\nconst MinBundlerVersion = '2.3.8'\nconst MinRubyVersion = '2.7.5'\n\ninterface ExecCLI2Options {\n // Contains token and store to pass to CLI 2.0, which will be set as environment variables\n adminSession?: AdminSession\n // Contains token for storefront access to pass to CLI 2.0 as environment variable\n storefrontToken?: string\n // Directory in which to execute the command. Otherwise the current directory will be used.\n directory?: string\n}\n/**\n * Execute CLI 2.0 commands.\n * Installs a version of RubyCLI as a vendor dependency in a hidden folder in the system.\n * User must have a valid ruby+bundler environment to run any command.\n *\n * @param args {string[]} List of argumets to execute. (ex: ['theme', 'pull'])\n * @param options {ExecCLI2Options}\n */\nexport async function execCLI2(args: string[], {adminSession, storefrontToken, directory}: ExecCLI2Options = {}) {\n await installCLIDependencies()\n const env = {\n ...process.env,\n SHOPIFY_CLI_STOREFRONT_RENDERER_AUTH_TOKEN: storefrontToken,\n SHOPIFY_CLI_ADMIN_AUTH_TOKEN: adminSession?.token,\n SHOPIFY_CLI_STORE: adminSession?.storeFqdn,\n SHOPIFY_CLI_RUN_AS_SUBPROCESS: 'true',\n // Bundler uses this Gemfile to understand which gems are available in the\n // environment. We use this to specify our own Gemfile for CLI2, which exists\n // outside the user's project directory.\n BUNDLE_GEMFILE: join(shopifyCLIDirectory(), 'Gemfile'),\n }\n\n try {\n await system.exec(bundleExecutable(), ['exec', 'shopify'].concat(args), {\n stdio: 'inherit',\n cwd: directory ?? process.cwd(),\n env,\n })\n } catch (error) {\n // CLI2 will show it's own errors, we don't need to show an additional CLI3 error\n throw new AbortSilent()\n }\n}\n\ninterface ExecThemeCheckCLIOptions {\n /** A list of directories in which theme-check should run */\n directories: string[]\n /** Arguments to pass to the theme-check CLI */\n args?: string[]\n /** Writable to send standard output content through */\n stdout: Writable\n /** Writable to send standard error content through */\n stderr: Writable\n}\n\n/**\n * A function that installs (if needed) and runs the theme-check CLI.\n * @param options {ExecThemeCheckCLIOptions} Options to customize the execution of theme-check.\n * @returns {Promise<void>} A promise that resolves or rejects depending on the result of the underlying theme-check process.\n */\nexport async function execThemeCheckCLI({\n directories,\n args,\n stdout,\n stderr,\n}: ExecThemeCheckCLIOptions): Promise<void[]> {\n await installThemeCheckCLIDependencies(stdout)\n\n const processes = directories.map(async (directory): Promise<void> => {\n // Check that there are files aside from the extension TOML config file,\n // otherwise theme-check will return a false failure.\n const files = await glob(join(directory, '/**/*'))\n const fileCount = files.filter((file) => !file.match(/\\.toml$/)).length\n if (fileCount === 0) return\n\n const customStderr = new Writable({\n write(chunk, ...args) {\n // For some reason, theme-check reports this initial status line to stderr\n // See https://github.com/Shopify/theme-check/blob/1092737cfb58a73ca397ffb1371665dc55df2976/lib/theme_check/language_server/diagnostics_engine.rb#L31\n // which leads to https://github.com/Shopify/theme-check/blob/1092737cfb58a73ca397ffb1371665dc55df2976/lib/theme_check/language_server/io_messenger.rb#L65\n if (chunk.toString('ascii').match(/^Checking/)) {\n stdout.write(chunk, ...args)\n } else {\n stderr.write(chunk, ...args)\n }\n },\n })\n await system.exec(bundleExecutable(), ['exec', 'theme-check'].concat([directory, ...(args || [])]), {\n stdout,\n stderr: customStderr,\n cwd: themeCheckDirectory(),\n })\n })\n return Promise.all(processes)\n}\n\n/**\n * Validate Ruby Enviroment\n * Install Theme Check CLI and its dependencies\n * Shows a loading message if it's the first time installing dependencies\n * or if we are installing a new version of Theme Check CLI\n */\nasync function installThemeCheckCLIDependencies(stdout: Writable) {\n const exists = await file.exists(themeCheckDirectory())\n\n if (!exists) stdout.write('Installing theme dependencies...')\n const list = ui.newListr(\n [\n {\n title: 'Installing theme dependencies',\n task: async () => {\n await validateRubyEnv()\n await createThemeCheckCLIWorkingDirectory()\n await createThemeCheckGemfile()\n await bundleInstallThemeCheck()\n },\n },\n ],\n {renderer: 'silent'},\n )\n await list.run()\n if (!exists) stdout.write('Installed theme dependencies!')\n}\n\n/**\n * Validate Ruby Enviroment\n * Install RubyCLI and its dependencies\n * Shows a loading spinner if it's the first time installing dependencies\n * or if we are installing a new version of RubyCLI\n */\nasync function installCLIDependencies() {\n const exists = await file.exists(shopifyCLIDirectory())\n const renderer = exists ? 'silent' : 'default'\n\n const list = ui.newListr(\n [\n {\n title: 'Installing theme dependencies',\n task: async () => {\n const usingLocalCLI2 = Boolean(process.env.SHOPIFY_CLI_2_0_DIRECTORY)\n await validateRubyEnv()\n if (usingLocalCLI2) {\n await bundleInstallLocalShopifyCLI()\n } else {\n await createShopifyCLIWorkingDirectory()\n await createShopifyCLIGemfile()\n await bundleInstallShopifyCLI()\n }\n },\n },\n ],\n {renderer},\n )\n await list.run()\n}\n\nasync function validateRubyEnv() {\n await validateRuby()\n await validateBundler()\n}\n\nasync function validateRuby() {\n let version\n try {\n const stdout = await system.captureOutput(rubyExecutable(), ['-v'])\n version = coerce(stdout)\n } catch {\n throw new Abort(\n 'Ruby environment not found',\n `Make sure you have Ruby installed on your system. ${\n content`${token.link('Documentation.', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value\n }`,\n )\n }\n\n const isValid = version?.compare(MinRubyVersion)\n if (isValid === -1 || isValid === undefined) {\n throw new Abort(\n `Ruby version ${content`${token.yellow(version.raw)}`.value} is not supported`,\n `Make sure you have at least Ruby ${content`${token.yellow(MinRubyVersion)}`.value} installed on your system. ${\n content`${token.link('Documentation.', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value\n }`,\n )\n }\n}\n\nasync function validateBundler() {\n let version\n try {\n const stdout = await system.captureOutput(bundleExecutable(), ['-v'])\n version = coerce(stdout)\n } catch {\n throw new Abort(\n 'Bundler not found',\n `To install the latest version of Bundler, run ${\n content`${token.genericShellCommand(`${gemExecutable()} install bundler`)}`.value\n }`,\n )\n }\n\n const isValid = version?.compare(MinBundlerVersion)\n if (isValid === -1 || isValid === undefined) {\n throw new Abort(\n `Bundler version ${content`${token.yellow(version.raw)}`.value} is not supported`,\n `To update to the latest version of Bundler, run ${\n content`${token.genericShellCommand(`${gemExecutable()} install bundler`)}`.value\n }`,\n )\n }\n}\n\nfunction createShopifyCLIWorkingDirectory() {\n return file.mkdir(shopifyCLIDirectory())\n}\n\nfunction createThemeCheckCLIWorkingDirectory() {\n return file.mkdir(themeCheckDirectory())\n}\n\nasync function createShopifyCLIGemfile() {\n const gemPath = join(shopifyCLIDirectory(), 'Gemfile')\n await file.write(gemPath, `source 'https://rubygems.org'\\ngem 'shopify-cli', '${RubyCLIVersion}'`)\n}\n\nasync function createThemeCheckGemfile() {\n const gemPath = join(themeCheckDirectory(), 'Gemfile')\n await file.write(gemPath, `source 'https://rubygems.org'\\ngem 'theme-check', '${ThemeCheckVersion}'`)\n}\n\nasync function bundleInstallLocalShopifyCLI() {\n await system.exec(bundleExecutable(), ['install'], {cwd: shopifyCLIDirectory()})\n}\n\nasync function bundleInstallShopifyCLI() {\n await system.exec(bundleExecutable(), ['config', 'set', '--local', 'path', shopifyCLIDirectory()], {\n cwd: shopifyCLIDirectory(),\n })\n await system.exec(bundleExecutable(), ['install'], {cwd: shopifyCLIDirectory()})\n}\n\nasync function bundleInstallThemeCheck() {\n await system.exec(bundleExecutable(), ['config', 'set', '--local', 'path', themeCheckDirectory()], {\n cwd: themeCheckDirectory(),\n })\n await system.exec(bundleExecutable(), ['install'], {cwd: themeCheckDirectory()})\n}\n\nfunction shopifyCLIDirectory() {\n return (\n process.env.SHOPIFY_CLI_2_0_DIRECTORY ??\n join(constants.paths.directories.cache.vendor.path(), 'ruby-cli', RubyCLIVersion)\n )\n}\n\nfunction themeCheckDirectory() {\n return join(constants.paths.directories.cache.vendor.path(), 'theme-check', ThemeCheckVersion)\n}\n\nexport async function version(): Promise<string | undefined> {\n const parseOutput = (version: string) => version.match(/ruby (\\d+\\.\\d+\\.\\d+)/)?.[1]\n return system\n .captureOutput(rubyExecutable(), ['-v'])\n .then(parseOutput)\n .catch(() => undefined)\n}\n\nfunction getRubyBinDir(): string | undefined {\n return process.env.SHOPIFY_RUBY_BINDIR\n}\n\nfunction rubyExecutable(): string {\n const rubyBinDir = getRubyBinDir()\n return rubyBinDir ? join(rubyBinDir, 'ruby') : 'ruby'\n}\n\nfunction bundleExecutable(): string {\n const rubyBinDir = getRubyBinDir()\n return rubyBinDir ? join(rubyBinDir, 'bundle') : 'bundle'\n}\n\nfunction gemExecutable(): string {\n const rubyBinDir = getRubyBinDir()\n return rubyBinDir ? join(rubyBinDir, 'gem') : 'gem'\n}\n"]}
package/dist/plugins.d.ts CHANGED
@@ -2,14 +2,7 @@ import { JsonMap } from './json.js';
2
2
  import { PickByPrefix } from './typing/pick-by-prefix.js';
3
3
  import { MonorailEventPublic } from './monorail.js';
4
4
  import { HookReturnPerTunnelPlugin } from './plugins/tunnel.js';
5
- import { Interfaces } from '@oclif/core';
6
- interface TunnelPlugin {
7
- start: (options: TunnelStartOptions) => Promise<string>;
8
- }
9
- interface TunnelStartOptions {
10
- port: number;
11
- }
12
- export declare function lookupTunnelPlugin(plugins: Interfaces.Plugin[]): Promise<TunnelPlugin | undefined>;
5
+ import { Config, Interfaces } from '@oclif/core';
13
6
  /**
14
7
  * Convenience function to trigger a hook, and gather any successful responses. Failures are ignored.
15
8
  *
@@ -40,4 +33,28 @@ export declare type PluginReturnsForHook<TEvent extends keyof TPluginMap, TPlugi
40
33
  export declare type FanoutHookFunction<TEvent extends keyof TPluginMap = string, TPluginName extends keyof TPluginMap[TEvent]['pluginReturns'] = string, TPluginMap extends HookReturnsPerPlugin = HookReturnsPerPlugin> = (this: Interfaces.Hook.Context, options: TPluginMap[TEvent]['options'] & {
41
34
  config: Interfaces.Config;
42
35
  }) => Promise<PluginReturnsForHook<TEvent, TPluginName, TPluginMap>>;
36
+ /**
37
+ * Execute the 'tunnel_provider' hook, and return the list of available tunnel providers.
38
+ * Fail if there are multiple plugins for the same provider
39
+ *
40
+ * @param config oclif config used to execute hooks
41
+ * @returns list of available tunnel plugins
42
+ */
43
+ export declare function getListOfTunnelPlugins(config: Config): Promise<{
44
+ plugins: string[];
45
+ error?: string;
46
+ }>;
47
+ /**
48
+ * Execute the 'tunnel_start' hook for the given provider.
49
+ * Fails if there aren't plugins for that provider or if there are more than one.
50
+ *
51
+ * @param config oclif config used to execute hooks
52
+ * @param port port where the tunnel will be started
53
+ * @param provider selected provider, must be unique
54
+ * @returns tunnel URL from the selected provider
55
+ */
56
+ export declare function runTunnelPlugin(config: Config, port: number, provider: string): Promise<{
57
+ url?: string;
58
+ error?: string;
59
+ }>;
43
60
  export {};
package/dist/plugins.js CHANGED
@@ -1,14 +1,4 @@
1
- import { join, pathToFileURL } from './path.js';
2
- import { debug, content } from './output.js';
3
- const TUNNEL_PLUGINS = ['@shopify/plugin-ngrok'];
4
- export async function lookupTunnelPlugin(plugins) {
5
- debug(content `Looking up the Ngrok tunnel plugin...`);
6
- const tunnelPlugin = plugins.find((plugin) => TUNNEL_PLUGINS.includes(plugin.name));
7
- if (!tunnelPlugin)
8
- return undefined;
9
- const tunnelPath = pathToFileURL(join(tunnelPlugin.root, 'dist/tunnel.js')).toString();
10
- return import(tunnelPath).catch(() => undefined);
11
- }
1
+ import { containsDuplicates, filterUndefined } from './array.js';
12
2
  /**
13
3
  * Convenience function to trigger a hook, and gather any successful responses. Failures are ignored.
14
4
  *
@@ -19,4 +9,36 @@ export async function fanoutHooks(config, event, options, timeout) {
19
9
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
10
  return Object.fromEntries(res.successes.map(({ result, plugin }) => [plugin.name, result]));
21
11
  }
12
+ /**
13
+ * Execute the 'tunnel_provider' hook, and return the list of available tunnel providers.
14
+ * Fail if there are multiple plugins for the same provider
15
+ *
16
+ * @param config oclif config used to execute hooks
17
+ * @returns list of available tunnel plugins
18
+ */
19
+ export async function getListOfTunnelPlugins(config) {
20
+ const hooks = await fanoutHooks(config, 'tunnel_provider', {});
21
+ const names = filterUndefined(Object.values(hooks).map((key) => key?.name));
22
+ if (containsDuplicates(names))
23
+ return { plugins: names, error: 'multiple-plugins-for-provider' };
24
+ return { plugins: names };
25
+ }
26
+ /**
27
+ * Execute the 'tunnel_start' hook for the given provider.
28
+ * Fails if there aren't plugins for that provider or if there are more than one.
29
+ *
30
+ * @param config oclif config used to execute hooks
31
+ * @param port port where the tunnel will be started
32
+ * @param provider selected provider, must be unique
33
+ * @returns tunnel URL from the selected provider
34
+ */
35
+ export async function runTunnelPlugin(config, port, provider) {
36
+ const hooks = await fanoutHooks(config, 'tunnel_start', { port, provider });
37
+ const urls = filterUndefined(Object.values(hooks).map((key) => key?.url));
38
+ if (urls.length > 1)
39
+ return { error: 'multiple-urls' };
40
+ if (urls.length === 0)
41
+ return { error: 'no-urls' };
42
+ return { url: urls[0] };
43
+ }
22
44
  //# sourceMappingURL=plugins.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugins.js","sourceRoot":"","sources":["../src/plugins.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAE,aAAa,EAAC,MAAM,WAAW,CAAA;AAC7C,OAAO,EAAC,KAAK,EAAE,OAAO,EAAC,MAAM,aAAa,CAAA;AAO1C,MAAM,cAAc,GAAG,CAAC,uBAAuB,CAAC,CAAA;AAUhD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAA4B;IACnE,KAAK,CAAC,OAAO,CAAA,uCAAuC,CAAC,CAAA;IACrD,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;IACnF,IAAI,CAAC,YAAY;QAAE,OAAO,SAAS,CAAA;IACnC,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;IACtF,OAAO,MAAM,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;AAClD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAyB,EACzB,KAAa,EACb,OAA4C,EAC5C,OAAgB;IAEhB,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACzD,8DAA8D;IAC9D,OAAO,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAC,MAAM,EAAE,MAAM,EAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAQ,CAAA;AAClG,CAAC","sourcesContent":["import {join, pathToFileURL} from './path.js'\nimport {debug, content} from './output.js'\nimport {JsonMap} from './json.js'\nimport {PickByPrefix} from './typing/pick-by-prefix.js'\nimport {MonorailEventPublic} from './monorail.js'\nimport {HookReturnPerTunnelPlugin} from './plugins/tunnel.js'\nimport {Interfaces} from '@oclif/core'\n\nconst TUNNEL_PLUGINS = ['@shopify/plugin-ngrok']\n\ninterface TunnelPlugin {\n start: (options: TunnelStartOptions) => Promise<string>\n}\n\ninterface TunnelStartOptions {\n port: number\n}\n\nexport async function lookupTunnelPlugin(plugins: Interfaces.Plugin[]): Promise<TunnelPlugin | undefined> {\n debug(content`Looking up the Ngrok tunnel plugin...`)\n const tunnelPlugin = plugins.find((plugin) => TUNNEL_PLUGINS.includes(plugin.name))\n if (!tunnelPlugin) return undefined\n const tunnelPath = pathToFileURL(join(tunnelPlugin.root, 'dist/tunnel.js')).toString()\n return import(tunnelPath).catch(() => undefined)\n}\n\n/**\n * Convenience function to trigger a hook, and gather any successful responses. Failures are ignored.\n *\n * Responses are organised into a dictionary, keyed by plug-in name. Only plug-ins that have hooks registered for the given event, and the hooks were run successfully, are included.\n */\nexport async function fanoutHooks<TPluginMap extends HookReturnsPerPlugin, TEvent extends string & keyof TPluginMap>(\n config: Interfaces.Config,\n event: TEvent,\n options: TPluginMap[typeof event]['options'],\n timeout?: number,\n): Promise<Partial<TPluginMap[typeof event]['pluginReturns']>> {\n const res = await config.runHook(event, options, timeout)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return Object.fromEntries(res.successes.map(({result, plugin}) => [plugin.name, result])) as any\n}\n\ntype AppSpecificMonorailFields = PickByPrefix<MonorailEventPublic, 'app_', 'project_type' | 'api_key' | 'partner_id'> &\n PickByPrefix<MonorailEventPublic, 'cmd_extensions_'> &\n PickByPrefix<MonorailEventPublic, 'cmd_scaffold_'>\n\ninterface HookReturnsPerPlugin extends HookReturnPerTunnelPlugin {\n public_command_metadata: {\n options: {[key: string]: never}\n pluginReturns: {\n '@shopify/app': Partial<AppSpecificMonorailFields>\n [pluginName: string]: JsonMap\n }\n }\n [hookName: string]: {\n options: {[key: string]: unknown}\n pluginReturns: {[key: string]: JsonMap}\n }\n}\n\nexport type PluginReturnsForHook<\n TEvent extends keyof TPluginMap,\n TPluginName extends keyof TPluginMap[TEvent]['pluginReturns'],\n TPluginMap extends HookReturnsPerPlugin = HookReturnsPerPlugin,\n> = TPluginMap[TEvent]['pluginReturns'][TPluginName]\n\nexport type FanoutHookFunction<\n TEvent extends keyof TPluginMap = string,\n TPluginName extends keyof TPluginMap[TEvent]['pluginReturns'] = string,\n TPluginMap extends HookReturnsPerPlugin = HookReturnsPerPlugin,\n> = (\n this: Interfaces.Hook.Context,\n options: TPluginMap[TEvent]['options'] & {config: Interfaces.Config},\n) => Promise<PluginReturnsForHook<TEvent, TPluginName, TPluginMap>>\n"]}
1
+ {"version":3,"file":"plugins.js","sourceRoot":"","sources":["../src/plugins.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,kBAAkB,EAAE,eAAe,EAAC,MAAM,YAAY,CAAA;AAG9D;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAyB,EACzB,KAAa,EACb,OAA4C,EAC5C,OAAgB;IAEhB,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACzD,8DAA8D;IAC9D,OAAO,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAC,MAAM,EAAE,MAAM,EAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAQ,CAAA;AAClG,CAAC;AAmCD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,MAAc;IACzD,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,iBAAiB,EAAE,EAAE,CAAC,CAAA;IAC9D,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAA;IAC3E,IAAI,kBAAkB,CAAC,KAAK,CAAC;QAAE,OAAO,EAAC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,+BAA+B,EAAC,CAAA;IAC9F,OAAO,EAAC,OAAO,EAAE,KAAK,EAAC,CAAA;AACzB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAc,EACd,IAAY,EACZ,QAAgB;IAEhB,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,cAAc,EAAE,EAAC,IAAI,EAAE,QAAQ,EAAC,CAAC,CAAA;IACzE,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;IACzE,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,EAAC,KAAK,EAAE,eAAe,EAAC,CAAA;IACpD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAC,KAAK,EAAE,SAAS,EAAC,CAAA;IAChD,OAAO,EAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,EAAC,CAAA;AACvB,CAAC","sourcesContent":["import {JsonMap} from './json.js'\nimport {PickByPrefix} from './typing/pick-by-prefix.js'\nimport {MonorailEventPublic} from './monorail.js'\nimport {HookReturnPerTunnelPlugin} from './plugins/tunnel.js'\nimport {containsDuplicates, filterUndefined} from './array.js'\nimport {Config, Interfaces} from '@oclif/core'\n\n/**\n * Convenience function to trigger a hook, and gather any successful responses. Failures are ignored.\n *\n * Responses are organised into a dictionary, keyed by plug-in name. Only plug-ins that have hooks registered for the given event, and the hooks were run successfully, are included.\n */\nexport async function fanoutHooks<TPluginMap extends HookReturnsPerPlugin, TEvent extends string & keyof TPluginMap>(\n config: Interfaces.Config,\n event: TEvent,\n options: TPluginMap[typeof event]['options'],\n timeout?: number,\n): Promise<Partial<TPluginMap[typeof event]['pluginReturns']>> {\n const res = await config.runHook(event, options, timeout)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return Object.fromEntries(res.successes.map(({result, plugin}) => [plugin.name, result])) as any\n}\n\ntype AppSpecificMonorailFields = PickByPrefix<MonorailEventPublic, 'app_', 'project_type' | 'api_key' | 'partner_id'> &\n PickByPrefix<MonorailEventPublic, 'cmd_extensions_'> &\n PickByPrefix<MonorailEventPublic, 'cmd_scaffold_'>\n\ninterface HookReturnsPerPlugin extends HookReturnPerTunnelPlugin {\n public_command_metadata: {\n options: {[key: string]: never}\n pluginReturns: {\n '@shopify/app': Partial<AppSpecificMonorailFields>\n [pluginName: string]: JsonMap\n }\n }\n [hookName: string]: {\n options: {[key: string]: unknown}\n pluginReturns: {[key: string]: JsonMap}\n }\n}\n\nexport type PluginReturnsForHook<\n TEvent extends keyof TPluginMap,\n TPluginName extends keyof TPluginMap[TEvent]['pluginReturns'],\n TPluginMap extends HookReturnsPerPlugin = HookReturnsPerPlugin,\n> = TPluginMap[TEvent]['pluginReturns'][TPluginName]\n\nexport type FanoutHookFunction<\n TEvent extends keyof TPluginMap = string,\n TPluginName extends keyof TPluginMap[TEvent]['pluginReturns'] = string,\n TPluginMap extends HookReturnsPerPlugin = HookReturnsPerPlugin,\n> = (\n this: Interfaces.Hook.Context,\n options: TPluginMap[TEvent]['options'] & {config: Interfaces.Config},\n) => Promise<PluginReturnsForHook<TEvent, TPluginName, TPluginMap>>\n\n/**\n * Execute the 'tunnel_provider' hook, and return the list of available tunnel providers.\n * Fail if there are multiple plugins for the same provider\n *\n * @param config oclif config used to execute hooks\n * @returns list of available tunnel plugins\n */\nexport async function getListOfTunnelPlugins(config: Config): Promise<{plugins: string[]; error?: string}> {\n const hooks = await fanoutHooks(config, 'tunnel_provider', {})\n const names = filterUndefined(Object.values(hooks).map((key) => key?.name))\n if (containsDuplicates(names)) return {plugins: names, error: 'multiple-plugins-for-provider'}\n return {plugins: names}\n}\n\n/**\n * Execute the 'tunnel_start' hook for the given provider.\n * Fails if there aren't plugins for that provider or if there are more than one.\n *\n * @param config oclif config used to execute hooks\n * @param port port where the tunnel will be started\n * @param provider selected provider, must be unique\n * @returns tunnel URL from the selected provider\n */\nexport async function runTunnelPlugin(\n config: Config,\n port: number,\n provider: string,\n): Promise<{url?: string; error?: string}> {\n const hooks = await fanoutHooks(config, 'tunnel_start', {port, provider})\n const urls = filterUndefined(Object.values(hooks).map((key) => key?.url))\n if (urls.length > 1) return {error: 'multiple-urls'}\n if (urls.length === 0) return {error: 'no-urls'}\n return {url: urls[0]}\n}\n"]}
package/dist/store.d.ts CHANGED
@@ -13,7 +13,6 @@ interface ConfSchema {
13
13
  session: string;
14
14
  }
15
15
  export declare function cliKitStore(): CLIKitStore;
16
- export declare function initializeCliKitStore(): Promise<void>;
17
16
  export declare class CLIKitStore extends Conf<ConfSchema> {
18
17
  getAppInfo(directory: string): CachedAppInfo | undefined;
19
18
  setAppInfo(options: {
package/dist/store.js CHANGED
@@ -1,6 +1,4 @@
1
1
  import { content, token, debug } from './output.js';
2
- import constants from './constants.js';
3
- import { Abort } from './error.js';
4
2
  import Conf from 'conf';
5
3
  const migrations = {};
6
4
  const schema = {
@@ -25,20 +23,13 @@ const schema = {
25
23
  let _instance;
26
24
  export function cliKitStore() {
27
25
  if (!_instance) {
28
- throw new Abort("The CLIKitStore instance hasn't been initialized");
29
- }
30
- return _instance;
31
- }
32
- export async function initializeCliKitStore() {
33
- if (!_instance) {
34
- // eslint-disable-next-line require-atomic-updates
35
26
  _instance = new CLIKitStore({
36
27
  schema,
37
28
  migrations,
38
29
  projectName: 'shopify-cli-kit',
39
- projectVersion: await constants.versions.cliKit(),
40
30
  });
41
31
  }
32
+ return _instance;
42
33
  }
43
34
  export class CLIKitStore extends Conf {
44
35
  getAppInfo(directory) {
package/dist/store.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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","sourcesContent":["import {content, token, debug} from './output.js'\nimport constants from './constants.js'\nimport {Abort} from './error.js'\nimport Conf, {Schema} from 'conf'\n\nconst migrations = {}\n\nexport interface CachedAppInfo {\n directory: string\n appId?: string\n title?: string\n orgId?: string\n storeFqdn?: string\n updateURLs?: boolean\n}\n\ninterface ConfSchema {\n appInfo: CachedAppInfo[]\n themeStore: string\n session: string\n}\n\nconst schema = {\n appInfo: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n appId: {\n type: 'string',\n },\n orgId: {\n type: 'string',\n },\n storeFqdn: {\n type: 'string',\n },\n },\n },\n },\n} as unknown as Schema<ConfSchema>\n\nlet _instance: CLIKitStore | undefined\n\nexport function cliKitStore() {\n if (!_instance) {\n throw new Abort(\"The CLIKitStore instance hasn't been initialized\")\n }\n return _instance\n}\n\nexport async function initializeCliKitStore() {\n if (!_instance) {\n // eslint-disable-next-line require-atomic-updates\n _instance = new CLIKitStore({\n schema,\n migrations,\n projectName: 'shopify-cli-kit',\n projectVersion: await constants.versions.cliKit(),\n })\n }\n}\n\nexport class CLIKitStore extends Conf<ConfSchema> {\n getAppInfo(directory: string): CachedAppInfo | undefined {\n debug(content`Reading cached app information for directory ${token.path(directory)}...`)\n const apps = this.get('appInfo') ?? []\n return apps.find((app: CachedAppInfo) => app.directory === directory)\n }\n\n setAppInfo(options: {\n directory: string\n appId?: string\n title?: string\n storeFqdn?: string\n orgId?: string\n updateURLs?: boolean\n }): void {\n debug(content`Storing app information for directory ${token.path(options.directory)}:${token.json(options)}`)\n const apps = this.get('appInfo') ?? []\n const index = apps.findIndex((saved: CachedAppInfo) => saved.directory === options.directory)\n if (index === -1) {\n apps.push(options)\n } else {\n const app: CachedAppInfo = apps[index]!\n apps[index] = {\n directory: options.directory,\n appId: options.appId ?? app.appId,\n title: options.title ?? app.title,\n storeFqdn: options.storeFqdn ?? app.storeFqdn,\n orgId: options.orgId ?? app.orgId,\n updateURLs: options.updateURLs ?? app.updateURLs,\n }\n }\n this.set('appInfo', apps)\n }\n\n clearAppInfo(directory: string): void {\n debug(content`Clearning app information for directory ${token.path(directory)}...`)\n const apps = this.get('appInfo') ?? []\n const index = apps.findIndex((saved: CachedAppInfo) => saved.directory === directory)\n if (index !== -1) {\n apps.splice(index, 1)\n }\n this.set('appInfo', apps)\n }\n\n getTheme(): string | undefined {\n debug(content`Getting theme store...`)\n return this.get('themeStore')\n }\n\n setTheme(store: string): void {\n debug(content`Setting theme store...`)\n this.set('themeStore', store)\n }\n\n getSession(): string | undefined {\n debug(content`Getting session store...`)\n return this.get('sessionStore')\n }\n\n setSession(store: string): void {\n debug(content`Setting session store...`)\n this.set('sessionStore', store)\n }\n\n removeSession(): void {\n debug(content`Removing session store...`)\n this.set('sessionStore', '')\n }\n}\n"]}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAC,MAAM,aAAa,CAAA;AACjD,OAAO,IAAc,MAAM,MAAM,CAAA;AAEjC,MAAM,UAAU,GAAG,EAAE,CAAA;AAiBrB,MAAM,MAAM,GAAG;IACb,OAAO,EAAE;QACP,IAAI,EAAE,OAAO;QACb,KAAK,EAAE;YACL,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;iBACf;gBACD,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;iBACf;gBACD,SAAS,EAAE;oBACT,IAAI,EAAE,QAAQ;iBACf;aACF;SACF;KACF;CAC+B,CAAA;AAElC,IAAI,SAAkC,CAAA;AAEtC,MAAM,UAAU,WAAW;IACzB,IAAI,CAAC,SAAS,EAAE;QACd,SAAS,GAAG,IAAI,WAAW,CAAC;YAC1B,MAAM;YACN,UAAU;YACV,WAAW,EAAE,iBAAiB;SAC/B,CAAC,CAAA;KACH;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,MAAM,OAAO,WAAY,SAAQ,IAAgB;IAC/C,UAAU,CAAC,SAAiB;QAC1B,KAAK,CAAC,OAAO,CAAA,gDAAgD,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;QACxF,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAA;QACtC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,GAAkB,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAA;IACvE,CAAC;IAED,UAAU,CAAC,OAOV;QACC,KAAK,CAAC,OAAO,CAAA,yCAAyC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAC7G,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAA;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,KAAoB,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,KAAK,OAAO,CAAC,SAAS,CAAC,CAAA;QAC7F,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE;YAChB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;SACnB;aAAM;YACL,MAAM,GAAG,GAAkB,IAAI,CAAC,KAAK,CAAE,CAAA;YACvC,IAAI,CAAC,KAAK,CAAC,GAAG;gBACZ,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK;gBACjC,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK;gBACjC,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,GAAG,CAAC,SAAS;gBAC7C,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK;gBACjC,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,GAAG,CAAC,UAAU;aACjD,CAAA;SACF;QACD,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;IAC3B,CAAC;IAED,YAAY,CAAC,SAAiB;QAC5B,KAAK,CAAC,OAAO,CAAA,2CAA2C,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;QACnF,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAA;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,KAAoB,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAA;QACrF,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE;YAChB,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;SACtB;QACD,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;IAC3B,CAAC;IAED,QAAQ;QACN,KAAK,CAAC,OAAO,CAAA,wBAAwB,CAAC,CAAA;QACtC,OAAO,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;IAC/B,CAAC;IAED,QAAQ,CAAC,KAAa;QACpB,KAAK,CAAC,OAAO,CAAA,wBAAwB,CAAC,CAAA;QACtC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,KAAK,CAAC,CAAA;IAC/B,CAAC;IAED,UAAU;QACR,KAAK,CAAC,OAAO,CAAA,0BAA0B,CAAC,CAAA;QACxC,OAAO,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;IACjC,CAAC;IAED,UAAU,CAAC,KAAa;QACtB,KAAK,CAAC,OAAO,CAAA,0BAA0B,CAAC,CAAA;QACxC,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,KAAK,CAAC,CAAA;IACjC,CAAC;IAED,aAAa;QACX,KAAK,CAAC,OAAO,CAAA,2BAA2B,CAAC,CAAA;QACzC,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,EAAE,CAAC,CAAA;IAC9B,CAAC;CACF","sourcesContent":["import {content, token, debug} from './output.js'\nimport Conf, {Schema} from 'conf'\n\nconst migrations = {}\n\nexport interface CachedAppInfo {\n directory: string\n appId?: string\n title?: string\n orgId?: string\n storeFqdn?: string\n updateURLs?: boolean\n}\n\ninterface ConfSchema {\n appInfo: CachedAppInfo[]\n themeStore: string\n session: string\n}\n\nconst schema = {\n appInfo: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n appId: {\n type: 'string',\n },\n orgId: {\n type: 'string',\n },\n storeFqdn: {\n type: 'string',\n },\n },\n },\n },\n} as unknown as Schema<ConfSchema>\n\nlet _instance: CLIKitStore | undefined\n\nexport function cliKitStore() {\n if (!_instance) {\n _instance = new CLIKitStore({\n schema,\n migrations,\n projectName: 'shopify-cli-kit',\n })\n }\n return _instance\n}\n\nexport class CLIKitStore extends Conf<ConfSchema> {\n getAppInfo(directory: string): CachedAppInfo | undefined {\n debug(content`Reading cached app information for directory ${token.path(directory)}...`)\n const apps = this.get('appInfo') ?? []\n return apps.find((app: CachedAppInfo) => app.directory === directory)\n }\n\n setAppInfo(options: {\n directory: string\n appId?: string\n title?: string\n storeFqdn?: string\n orgId?: string\n updateURLs?: boolean\n }): void {\n debug(content`Storing app information for directory ${token.path(options.directory)}:${token.json(options)}`)\n const apps = this.get('appInfo') ?? []\n const index = apps.findIndex((saved: CachedAppInfo) => saved.directory === options.directory)\n if (index === -1) {\n apps.push(options)\n } else {\n const app: CachedAppInfo = apps[index]!\n apps[index] = {\n directory: options.directory,\n appId: options.appId ?? app.appId,\n title: options.title ?? app.title,\n storeFqdn: options.storeFqdn ?? app.storeFqdn,\n orgId: options.orgId ?? app.orgId,\n updateURLs: options.updateURLs ?? app.updateURLs,\n }\n }\n this.set('appInfo', apps)\n }\n\n clearAppInfo(directory: string): void {\n debug(content`Clearning app information for directory ${token.path(directory)}...`)\n const apps = this.get('appInfo') ?? []\n const index = apps.findIndex((saved: CachedAppInfo) => saved.directory === directory)\n if (index !== -1) {\n apps.splice(index, 1)\n }\n this.set('appInfo', apps)\n }\n\n getTheme(): string | undefined {\n debug(content`Getting theme store...`)\n return this.get('themeStore')\n }\n\n setTheme(store: string): void {\n debug(content`Setting theme store...`)\n this.set('themeStore', store)\n }\n\n getSession(): string | undefined {\n debug(content`Getting session store...`)\n return this.get('sessionStore')\n }\n\n setSession(store: string): void {\n debug(content`Setting session store...`)\n this.set('sessionStore', store)\n }\n\n removeSession(): void {\n debug(content`Removing session store...`)\n this.set('sessionStore', '')\n }\n}\n"]}