@shopify/cli-kit 3.12.0 → 3.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/analytics.js +1 -1
  3. package/dist/analytics.js.map +1 -1
  4. package/dist/api/graphql/create_app.d.ts +1 -0
  5. package/dist/api/graphql/create_app.js +1 -0
  6. package/dist/api/graphql/create_app.js.map +1 -1
  7. package/dist/api/graphql/find_app.d.ts +1 -0
  8. package/dist/api/graphql/find_app.js +1 -0
  9. package/dist/api/graphql/find_app.js.map +1 -1
  10. package/dist/api/graphql/find_org.d.ts +1 -0
  11. package/dist/api/graphql/find_org.js +1 -0
  12. package/dist/api/graphql/find_org.js.map +1 -1
  13. package/dist/api.d.ts +2 -1
  14. package/dist/api.js +2 -1
  15. package/dist/api.js.map +1 -1
  16. package/dist/constants.js +1 -1
  17. package/dist/constants.js.map +1 -1
  18. package/dist/file.d.ts +3 -0
  19. package/dist/file.js +3 -0
  20. package/dist/file.js.map +1 -1
  21. package/dist/git.d.ts +20 -0
  22. package/dist/git.js +53 -0
  23. package/dist/git.js.map +1 -1
  24. package/dist/haiku.js +2 -2
  25. package/dist/haiku.js.map +1 -1
  26. package/dist/http.d.ts +1 -0
  27. package/dist/http.js +1 -0
  28. package/dist/http.js.map +1 -1
  29. package/dist/index.d.ts +0 -1
  30. package/dist/index.js +0 -1
  31. package/dist/index.js.map +1 -1
  32. package/dist/node/cli.d.ts +6 -0
  33. package/dist/node/cli.js +38 -12
  34. package/dist/node/cli.js.map +1 -1
  35. package/dist/node/ruby.d.ts +2 -1
  36. package/dist/node/ruby.js +3 -2
  37. package/dist/node/ruby.js.map +1 -1
  38. package/dist/path.d.ts +2 -2
  39. package/dist/path.js +2 -2
  40. package/dist/path.js.map +1 -1
  41. package/dist/plugins.js +4 -4
  42. package/dist/plugins.js.map +1 -1
  43. package/dist/public/common/array.d.ts +17 -0
  44. package/dist/public/common/array.js +24 -0
  45. package/dist/public/common/array.js.map +1 -0
  46. package/dist/session/store.js +2 -1
  47. package/dist/session/store.js.map +1 -1
  48. package/dist/session/validate.js +2 -2
  49. package/dist/session/validate.js.map +1 -1
  50. package/dist/store.d.ts +5 -0
  51. package/dist/store.js +10 -1
  52. package/dist/store.js.map +1 -1
  53. package/dist/tsconfig.tsbuildinfo +1 -1
  54. package/dist/ui/inquirer/autocomplete.js +0 -3
  55. package/dist/ui/inquirer/autocomplete.js.map +1 -1
  56. package/dist/ui.d.ts +2 -2
  57. package/dist/ui.js.map +1 -1
  58. package/package.json +6 -2
  59. package/dist/array.d.ts +0 -3
  60. package/dist/array.js +0 -10
  61. package/dist/array.js.map +0 -1
package/dist/node/cli.js CHANGED
@@ -1,18 +1,36 @@
1
- // CLI
2
- import { findUpAndReadPackageJson } from './node-package-manager.js';
3
- import { errorHandler } from './error-handler.js';
4
- import { isDevelopment } from '../environment/local.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';
9
- import { run, settings, flush } from '@oclif/core';
1
+ /**
2
+ * IMPORTANT NOTE: Imports in this module are dynamic to ensure that "setupEnvironmentVariables" can dynamically
3
+ * set the DEBUG environment variable before the 'debug' package sets up its configuration when modules
4
+ * are loaded statically.
5
+ */
6
+ function setupEnvironmentVariables(options) {
7
+ /**
8
+ * By setting DEBUG=* when --verbose is passed we are increasing the
9
+ * verbosity of oclif. Oclif uses debug (https://www.npmjs.com/package/debug)
10
+ * for logging, and it's configured through the DEBUG= environment variable.
11
+ */
12
+ if (process.argv.includes('--verbose')) {
13
+ process.env.DEBUG = process.env.DEBUG ?? '*';
14
+ }
15
+ if (options.development) {
16
+ process.env.SHOPIFY_CLI_ENV = process.env.SHOPIFY_CLI_ENV ?? 'development';
17
+ }
18
+ }
10
19
  /**
11
20
  * A function that abstracts away setting up the environment and running
12
21
  * a CLI
13
22
  * @param options {RunCLIOptions} Options.
14
23
  */
15
24
  export async function runCLI(options) {
25
+ setupEnvironmentVariables(options);
26
+ /**
27
+ * These imports need to be dynamic because if they are static
28
+ * they are loaded before se set the DEBUG=* environment variable
29
+ * and therefore it has no effect.
30
+ */
31
+ const { errorHandler } = await import('./error-handler.js');
32
+ const { isDevelopment } = await import('../environment/local.js');
33
+ const { run, settings, flush } = await import('@oclif/core');
16
34
  if (isDevelopment()) {
17
35
  settings.debug = true;
18
36
  }
@@ -23,6 +41,9 @@ export async function runCLI(options) {
23
41
  * @param options
24
42
  */
25
43
  export async function runCreateCLI(options) {
44
+ setupEnvironmentVariables(options);
45
+ const { findUpAndReadPackageJson } = await import('./node-package-manager.js');
46
+ const { moduleDirectory } = await import('../path.js');
26
47
  const packageJson = await findUpAndReadPackageJson(moduleDirectory(options.moduleURL));
27
48
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
28
49
  const packageName = packageJson.content.name;
@@ -35,11 +56,15 @@ export async function runCreateCLI(options) {
35
56
  await runCLI(options);
36
57
  }
37
58
  export async function useLocalCLIIfDetected(filepath) {
59
+ const { isTruthy } = await import('../environment/utilities.js');
60
+ const constants = await import('../constants.js');
61
+ const { join } = await import('../path.js');
62
+ const { exec } = await import('../system.js');
38
63
  // Temporary flag while we test out this feature and ensure it won't break anything!
39
- if (!isTruthy(process.env[constants.environmentVariables.enableCliRedirect]))
64
+ if (!isTruthy(process.env[constants.default.environmentVariables.enableCliRedirect]))
40
65
  return false;
41
66
  // Setting an env variable in the child process prevents accidental recursion.
42
- if (isTruthy(process.env[constants.environmentVariables.skipCliRedirect]))
67
+ if (isTruthy(process.env[constants.default.environmentVariables.skipCliRedirect]))
43
68
  return false;
44
69
  // If already running via package manager, we can assume it's running correctly already.
45
70
  if (process.env.npm_config_user_agent)
@@ -53,7 +78,7 @@ export async function useLocalCLIIfDetected(filepath) {
53
78
  try {
54
79
  await exec(correctExecutablePath, process.argv.slice(2, process.argv.length), {
55
80
  stdio: 'inherit',
56
- env: { [constants.environmentVariables.skipCliRedirect]: '1' },
81
+ env: { [constants.default.environmentVariables.skipCliRedirect]: '1' },
57
82
  });
58
83
  // eslint-disable-next-line no-catch-all/no-catch-all, @typescript-eslint/no-explicit-any
59
84
  }
@@ -63,6 +88,7 @@ export async function useLocalCLIIfDetected(filepath) {
63
88
  return true;
64
89
  }
65
90
  async function localCliPackage() {
91
+ const { captureOutput } = await import('../system.js');
66
92
  let npmListOutput = '';
67
93
  let localShopifyCLI = {};
68
94
  try {
@@ -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,QAAQ,EAAC,MAAM,6BAA6B,CAAA;AACpD,OAAO,SAAS,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAC,IAAI,EAAE,eAAe,EAAC,MAAM,YAAY,CAAA;AAChD,OAAO,EAAC,aAAa,EAAE,IAAI,EAAC,MAAM,cAAc,CAAA;AAChD,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,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,QAAgB;IAC1D,oFAAoF;IACpF,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;QAAE,OAAO,KAAK,CAAA;IAE1F,8EAA8E;IAC9E,IAAI,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,eAAe,CAAC,CAAC;QAAE,OAAO,KAAK,CAAA;IAEvF,wFAAwF;IACxF,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB;QAAE,OAAO,KAAK,CAAA;IAEnD,MAAM,UAAU,GAAG,MAAM,eAAe,EAAE,CAAA;IAC1C,IAAI,CAAC,UAAU;QAAE,OAAO,KAAK,CAAA;IAE7B,MAAM,qBAAqB,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IAC3E,IAAI,qBAAqB,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IACpD,IAAI;QACF,MAAM,IAAI,CAAC,qBAAqB,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;YAC5E,KAAK,EAAE,SAAS;YAChB,GAAG,EAAE,EAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,eAAe,CAAC,EAAE,GAAG,EAAC;SAC7D,CAAC,CAAA;QACF,yFAAyF;KAC1F;IAAC,OAAO,YAAiB,EAAE;QAC1B,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAA;KACpC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAaD,KAAK,UAAU,eAAe;IAC5B,IAAI,aAAa,GAAG,EAAE,CAAA;IACtB,IAAI,eAAe,GAAgB,EAAE,CAAA;IACrC,IAAI;QACF,aAAa,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAA;QACpF,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;QAC3C,qDAAqD;KACtD;IAAC,OAAO,GAAG,EAAE;QACZ,OAAM;KACP;IACD,MAAM,gBAAgB,GAAG;QACvB,GAAG,eAAe,CAAC,gBAAgB;QACnC,GAAG,eAAe,CAAC,eAAe;QAClC,GAAG,eAAe,CAAC,YAAY;KAChC,CAAA;IACD,OAAO,gBAAgB,CAAC,cAAc,CAAC,CAAA;AACzC,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 {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
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/node/cli.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * IMPORTANT NOTE: Imports in this module are dynamic to ensure that \"setupEnvironmentVariables\" can dynamically\n * set the DEBUG environment variable before the 'debug' package sets up its configuration when modules\n * are loaded statically.\n */\n\ninterface RunCLIOptions {\n /** The value of import.meta.url of the CLI executable module */\n moduleURL: string\n development: boolean\n}\n\nfunction setupEnvironmentVariables(options: Pick<RunCLIOptions, 'development'>) {\n /**\n * By setting DEBUG=* when --verbose is passed we are increasing the\n * verbosity of oclif. Oclif uses debug (https://www.npmjs.com/package/debug)\n * for logging, and it's configured through the DEBUG= environment variable.\n */\n if (process.argv.includes('--verbose')) {\n process.env.DEBUG = process.env.DEBUG ?? '*'\n }\n if (options.development) {\n process.env.SHOPIFY_CLI_ENV = process.env.SHOPIFY_CLI_ENV ?? 'development'\n }\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 setupEnvironmentVariables(options)\n /**\n * These imports need to be dynamic because if they are static\n * they are loaded before se set the DEBUG=* environment variable\n * and therefore it has no effect.\n */\n const {errorHandler} = await import('./error-handler.js')\n const {isDevelopment} = await import('../environment/local.js')\n const {run, settings, flush} = await import('@oclif/core')\n\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 setupEnvironmentVariables(options)\n\n const {findUpAndReadPackageJson} = await import('./node-package-manager.js')\n const {moduleDirectory} = await import('../path.js')\n\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 const {isTruthy} = await import('../environment/utilities.js')\n const constants = await import('../constants.js')\n const {join} = await import('../path.js')\n const {exec} = await import('../system.js')\n\n // Temporary flag while we test out this feature and ensure it won't break anything!\n if (!isTruthy(process.env[constants.default.environmentVariables.enableCliRedirect])) return false\n\n // Setting an env variable in the child process prevents accidental recursion.\n if (isTruthy(process.env[constants.default.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.default.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 const {captureOutput} = await import('../system.js')\n\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"]}
@@ -4,6 +4,7 @@ import { Writable } from 'node:stream';
4
4
  interface ExecCLI2Options {
5
5
  adminSession?: AdminSession;
6
6
  storefrontToken?: string;
7
+ token?: string;
7
8
  directory?: string;
8
9
  }
9
10
  /**
@@ -14,7 +15,7 @@ interface ExecCLI2Options {
14
15
  * @param args {string[]} List of argumets to execute. (ex: ['theme', 'pull'])
15
16
  * @param options {ExecCLI2Options}
16
17
  */
17
- export declare function execCLI2(args: string[], { adminSession, storefrontToken, directory }?: ExecCLI2Options): Promise<void>;
18
+ export declare function execCLI2(args: string[], { adminSession, storefrontToken, token, directory }?: ExecCLI2Options): Promise<void>;
18
19
  interface ExecThemeCheckCLIOptions {
19
20
  /** A list of directories in which theme-check should run */
20
21
  directories: string[];
package/dist/node/ruby.js CHANGED
@@ -7,7 +7,7 @@ import constants from '../constants.js';
7
7
  import { coerce } from '../semver.js';
8
8
  import { content, token } from '../output.js';
9
9
  import { Writable } from 'node:stream';
10
- const RubyCLIVersion = '2.23.0';
10
+ const RubyCLIVersion = '2.25.0';
11
11
  const ThemeCheckVersion = '1.10.3';
12
12
  const MinBundlerVersion = '2.3.8';
13
13
  const MinRubyVersion = '2.7.5';
@@ -19,13 +19,14 @@ const MinRubyVersion = '2.7.5';
19
19
  * @param args {string[]} List of argumets to execute. (ex: ['theme', 'pull'])
20
20
  * @param options {ExecCLI2Options}
21
21
  */
22
- export async function execCLI2(args, { adminSession, storefrontToken, directory } = {}) {
22
+ export async function execCLI2(args, { adminSession, storefrontToken, token, directory } = {}) {
23
23
  await installCLIDependencies();
24
24
  const env = {
25
25
  ...process.env,
26
26
  SHOPIFY_CLI_STOREFRONT_RENDERER_AUTH_TOKEN: storefrontToken,
27
27
  SHOPIFY_CLI_ADMIN_AUTH_TOKEN: adminSession?.token,
28
28
  SHOPIFY_CLI_STORE: adminSession?.storeFqdn,
29
+ SHOPIFY_CLI_AUTH_TOKEN: token,
29
30
  SHOPIFY_CLI_RUN_AS_SUBPROCESS: 'true',
30
31
  // Bundler uses this Gemfile to understand which gems are available in the
31
32
  // environment. We use this to specify our own Gemfile for CLI2, which exists
@@ -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'\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"]}
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.25.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 // Contains token for partners access to pass to CLI 2.0 as environment variable\n token?: 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(\n args: string[],\n {adminSession, storefrontToken, token, directory}: ExecCLI2Options = {},\n) {\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_AUTH_TOKEN: token,\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/path.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  /// <reference types="node" />
2
2
  import { OverloadParameters } from './typing/overloaded-parameters.js';
3
- import { relative, dirname, join, normalize, resolve, basename, extname, isAbsolute } from 'pathe';
3
+ import { relative, dirname, join, normalize, resolve, basename, extname, isAbsolute, parse } from 'pathe';
4
4
  import { findUp as internalFindUp } from 'find-up';
5
- export { join, relative, dirname, normalize, resolve, basename, extname, isAbsolute };
5
+ export { join, relative, dirname, normalize, resolve, basename, extname, isAbsolute, parse };
6
6
  export { default as glob } from 'fast-glob';
7
7
  export { pathToFileURL } from 'node:url';
8
8
  export declare function findUp(matcher: OverloadParameters<typeof internalFindUp>[0], options: OverloadParameters<typeof internalFindUp>[1]): ReturnType<typeof internalFindUp>;
package/dist/path.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import commondir from 'commondir';
2
- import { relative, dirname, join, normalize, resolve, basename, extname, isAbsolute } from 'pathe';
2
+ import { relative, dirname, join, normalize, resolve, basename, extname, isAbsolute, parse } from 'pathe';
3
3
  import { findUp as internalFindUp } from 'find-up';
4
4
  import { fileURLToPath } from 'url';
5
- export { join, relative, dirname, normalize, resolve, basename, extname, isAbsolute };
5
+ export { join, relative, dirname, normalize, resolve, basename, extname, isAbsolute, parse };
6
6
  export { default as glob } from 'fast-glob';
7
7
  export { pathToFileURL } from 'node:url';
8
8
  export async function findUp(matcher, options) {
package/dist/path.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"path.js","sourceRoot":"","sources":["../src/path.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,WAAW,CAAA;AACjC,OAAO,EAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAC,MAAM,OAAO,CAAA;AAChG,OAAO,EAAC,MAAM,IAAI,cAAc,EAAuB,MAAM,SAAS,CAAA;AACtE,OAAO,EAAC,aAAa,EAAC,MAAM,KAAK,CAAA;AAEjC,OAAO,EAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAC,CAAA;AAEnF,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,WAAW,CAAA;AACzC,OAAO,EAAC,aAAa,EAAC,MAAM,UAAU,CAAA;AAItC,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,OAAqD,EACrD,OAAqD;IAErD,wBAAwB;IACxB,8DAA8D;IAC9D,MAAM,GAAG,GAAG,MAAM,cAAc,CAAC,OAAc,EAAE,OAAO,CAAC,CAAA;IACzD,OAAO,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AACzC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;IAC/C,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAA;IAClD,MAAM,kBAAkB,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,MAAM,CAAA;IACnG,IAAI,MAAM,KAAK,GAAG,IAAI,YAAY,KAAK,EAAE,IAAI,kBAAkB,GAAG,CAAC,EAAE;QACnE,OAAO,IAAI,CAAA;KACZ;SAAM;QACL,OAAO,YAAY,CAAA;KACpB;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,SAAuB;IACrD,OAAO,OAAO,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAA;AAC1C,CAAC","sourcesContent":["import {OverloadParameters} from './typing/overloaded-parameters.js'\nimport commondir from 'commondir'\nimport {relative, dirname, join, normalize, resolve, basename, extname, isAbsolute} from 'pathe'\nimport {findUp as internalFindUp, Match as FindUpMatch} from 'find-up'\nimport {fileURLToPath} from 'url'\n\nexport {join, relative, dirname, normalize, resolve, basename, extname, isAbsolute}\n\nexport {default as glob} from 'fast-glob'\nexport {pathToFileURL} from 'node:url'\n\ntype FindUpMatcher = (directory: string) => FindUpMatch | Promise<FindUpMatch>\n\nexport async function findUp(\n matcher: OverloadParameters<typeof internalFindUp>[0],\n options: OverloadParameters<typeof internalFindUp>[1],\n): ReturnType<typeof internalFindUp> {\n // findUp has odd typing\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const got = await internalFindUp(matcher as any, options)\n return got ? normalize(got) : undefined\n}\n\n/**\n * Given an absolute filesystem path, it makes it relative to\n * the current working directory. This is useful when logging paths\n * to allow the users to click on the file and let the OS open it\n * in the editor of choice.\n * @param path {string} Path to relativize\n * @returns {string} Relativized path.\n */\nexport function relativize(path: string): string {\n const result = commondir([path, process.cwd()])\n const relativePath = relative(process.cwd(), path)\n const relativeComponents = relativePath.split('/').filter((component) => component === '..').length\n if (result === '/' || relativePath === '' || relativeComponents > 2) {\n return path\n } else {\n return relativePath\n }\n}\n\n/**\n * Given a module's import.meta.url it returns the directory containing the module.\n * @param moduleURL {string} The value of import.meta.url in the context of the caller module.\n * @returns {string} The path to the directory containing the caller module.\n */\nexport function moduleDirectory(moduleURL: string | URL): string {\n return dirname(fileURLToPath(moduleURL))\n}\n"]}
1
+ {"version":3,"file":"path.js","sourceRoot":"","sources":["../src/path.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,WAAW,CAAA;AACjC,OAAO,EAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAC,MAAM,OAAO,CAAA;AACvG,OAAO,EAAC,MAAM,IAAI,cAAc,EAAuB,MAAM,SAAS,CAAA;AACtE,OAAO,EAAC,aAAa,EAAC,MAAM,KAAK,CAAA;AAEjC,OAAO,EAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAC,CAAA;AAE1F,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,WAAW,CAAA;AACzC,OAAO,EAAC,aAAa,EAAC,MAAM,UAAU,CAAA;AAItC,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,OAAqD,EACrD,OAAqD;IAErD,wBAAwB;IACxB,8DAA8D;IAC9D,MAAM,GAAG,GAAG,MAAM,cAAc,CAAC,OAAc,EAAE,OAAO,CAAC,CAAA;IACzD,OAAO,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AACzC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;IAC/C,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAA;IAClD,MAAM,kBAAkB,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,MAAM,CAAA;IACnG,IAAI,MAAM,KAAK,GAAG,IAAI,YAAY,KAAK,EAAE,IAAI,kBAAkB,GAAG,CAAC,EAAE;QACnE,OAAO,IAAI,CAAA;KACZ;SAAM;QACL,OAAO,YAAY,CAAA;KACpB;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,SAAuB;IACrD,OAAO,OAAO,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAA;AAC1C,CAAC","sourcesContent":["import {OverloadParameters} from './typing/overloaded-parameters.js'\nimport commondir from 'commondir'\nimport {relative, dirname, join, normalize, resolve, basename, extname, isAbsolute, parse} from 'pathe'\nimport {findUp as internalFindUp, Match as FindUpMatch} from 'find-up'\nimport {fileURLToPath} from 'url'\n\nexport {join, relative, dirname, normalize, resolve, basename, extname, isAbsolute, parse}\n\nexport {default as glob} from 'fast-glob'\nexport {pathToFileURL} from 'node:url'\n\ntype FindUpMatcher = (directory: string) => FindUpMatch | Promise<FindUpMatch>\n\nexport async function findUp(\n matcher: OverloadParameters<typeof internalFindUp>[0],\n options: OverloadParameters<typeof internalFindUp>[1],\n): ReturnType<typeof internalFindUp> {\n // findUp has odd typing\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const got = await internalFindUp(matcher as any, options)\n return got ? normalize(got) : undefined\n}\n\n/**\n * Given an absolute filesystem path, it makes it relative to\n * the current working directory. This is useful when logging paths\n * to allow the users to click on the file and let the OS open it\n * in the editor of choice.\n * @param path {string} Path to relativize\n * @returns {string} Relativized path.\n */\nexport function relativize(path: string): string {\n const result = commondir([path, process.cwd()])\n const relativePath = relative(process.cwd(), path)\n const relativeComponents = relativePath.split('/').filter((component) => component === '..').length\n if (result === '/' || relativePath === '' || relativeComponents > 2) {\n return path\n } else {\n return relativePath\n }\n}\n\n/**\n * Given a module's import.meta.url it returns the directory containing the module.\n * @param moduleURL {string} The value of import.meta.url in the context of the caller module.\n * @returns {string} The path to the directory containing the caller module.\n */\nexport function moduleDirectory(moduleURL: string | URL): string {\n return dirname(fileURLToPath(moduleURL))\n}\n"]}
package/dist/plugins.js CHANGED
@@ -1,4 +1,4 @@
1
- import { containsDuplicates, filterUndefined } from './array.js';
1
+ import { getArrayContainsDuplicates, getArrayRejectingUndefined } from './public/common/array.js';
2
2
  /**
3
3
  * Convenience function to trigger a hook, and gather any successful responses. Failures are ignored.
4
4
  *
@@ -18,8 +18,8 @@ export async function fanoutHooks(config, event, options, timeout) {
18
18
  */
19
19
  export async function getListOfTunnelPlugins(config) {
20
20
  const hooks = await fanoutHooks(config, 'tunnel_provider', {});
21
- const names = filterUndefined(Object.values(hooks).map((key) => key?.name));
22
- if (containsDuplicates(names))
21
+ const names = getArrayRejectingUndefined(Object.values(hooks).map((key) => key?.name));
22
+ if (getArrayContainsDuplicates(names))
23
23
  return { plugins: names, error: 'multiple-plugins-for-provider' };
24
24
  return { plugins: names };
25
25
  }
@@ -34,7 +34,7 @@ export async function getListOfTunnelPlugins(config) {
34
34
  */
35
35
  export async function runTunnelPlugin(config, port, provider) {
36
36
  const hooks = await fanoutHooks(config, 'tunnel_start', { port, provider });
37
- const urls = filterUndefined(Object.values(hooks).map((key) => key?.url));
37
+ const urls = getArrayRejectingUndefined(Object.values(hooks).map((key) => key?.url));
38
38
  if (urls.length > 1)
39
39
  return { error: 'multiple-urls' };
40
40
  if (urls.length === 0)
@@ -1 +1 @@
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"]}
1
+ {"version":3,"file":"plugins.js","sourceRoot":"","sources":["../src/plugins.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,0BAA0B,EAAE,0BAA0B,EAAC,MAAM,0BAA0B,CAAA;AAG/F;;;;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,0BAA0B,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAA;IACtF,IAAI,0BAA0B,CAAC,KAAK,CAAC;QAAE,OAAO,EAAC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,+BAA+B,EAAC,CAAA;IACtG,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,0BAA0B,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;IACpF,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 {getArrayContainsDuplicates, getArrayRejectingUndefined} from './public/common/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 = getArrayRejectingUndefined(Object.values(hooks).map((key) => key?.name))\n if (getArrayContainsDuplicates(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 = getArrayRejectingUndefined(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"]}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Takes a random value from an array.
3
+ * @param array {T[]} Array from which we'll select a random item.
4
+ * @returns A random element from the array.
5
+ */
6
+ export declare function takeRandomFromArray<T>(array: T[]): T | undefined;
7
+ /**
8
+ * Returns a copy of the array deleting the elemements that are undefined.
9
+ * @param array {T[]} The array whose undefined will be deleted.
10
+ * @returns {T[]} A copy of the array with the undefined elements deleted.
11
+ */
12
+ export declare function getArrayRejectingUndefined<T>(array: T[]): Exclude<T, null | undefined>[];
13
+ /**
14
+ * Returns true if an array contains duplicates.
15
+ * @returns {boolean} True if the array contains duplicates.
16
+ */
17
+ export declare function getArrayContainsDuplicates<T>(array: T[]): boolean;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Takes a random value from an array.
3
+ * @param array {T[]} Array from which we'll select a random item.
4
+ * @returns A random element from the array.
5
+ */
6
+ export function takeRandomFromArray(array) {
7
+ return array[Math.floor(Math.random() * array.length)];
8
+ }
9
+ /**
10
+ * Returns a copy of the array deleting the elemements that are undefined.
11
+ * @param array {T[]} The array whose undefined will be deleted.
12
+ * @returns {T[]} A copy of the array with the undefined elements deleted.
13
+ */
14
+ export function getArrayRejectingUndefined(array) {
15
+ return array.filter((item) => item !== undefined);
16
+ }
17
+ /**
18
+ * Returns true if an array contains duplicates.
19
+ * @returns {boolean} True if the array contains duplicates.
20
+ */
21
+ export function getArrayContainsDuplicates(array) {
22
+ return array.length !== new Set(array).size;
23
+ }
24
+ //# sourceMappingURL=array.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"array.js","sourceRoot":"","sources":["../../../src/public/common/array.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAI,KAAU;IAC/C,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAA;AACxD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CAAI,KAAU;IACtD,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,CAAmC,CAAA;AACrF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,0BAA0B,CAAI,KAAU;IACtD,OAAO,KAAK,CAAC,MAAM,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAA;AAC7C,CAAC","sourcesContent":["/**\n * Takes a random value from an array.\n * @param array {T[]} Array from which we'll select a random item.\n * @returns A random element from the array.\n */\nexport function takeRandomFromArray<T>(array: T[]) {\n return array[Math.floor(Math.random() * array.length)]\n}\n\n/**\n * Returns a copy of the array deleting the elemements that are undefined.\n * @param array {T[]} The array whose undefined will be deleted.\n * @returns {T[]} A copy of the array with the undefined elements deleted.\n */\nexport function getArrayRejectingUndefined<T>(array: T[]) {\n return array.filter((item) => item !== undefined) as Exclude<T, null | undefined>[]\n}\n\n/**\n * Returns true if an array contains duplicates.\n * @returns {boolean} True if the array contains duplicates.\n */\nexport function getArrayContainsDuplicates<T>(array: T[]) {\n return array.length !== new Set(array).size\n}\n"]}
@@ -3,7 +3,7 @@ import constants from '../constants.js';
3
3
  import { platformAndArch } from '../os.js';
4
4
  import { store as secureStore, fetch as secureFetch, remove as secureRemove } from '../secure-store.js';
5
5
  import { content, debug } from '../output.js';
6
- import { getSession, removeSession, setSession } from '../store.js';
6
+ import { getSession, removeSession, setSession, clearAllAppInfo } from '../store.js';
7
7
  /**
8
8
  * The identifier of the session in the secure store.
9
9
  */
@@ -61,6 +61,7 @@ export async function remove() {
61
61
  else {
62
62
  await removeSession();
63
63
  }
64
+ await clearAllAppInfo();
64
65
  }
65
66
  /**
66
67
  * Returns true if the secure store is available on the system.
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/session/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,aAAa,CAAA;AACzC,OAAO,SAAS,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAC,eAAe,EAAC,MAAM,UAAU,CAAA;AACxC,OAAO,EAAC,KAAK,IAAI,WAAW,EAAE,KAAK,IAAI,WAAW,EAAE,MAAM,IAAI,YAAY,EAAC,MAAM,oBAAoB,CAAA;AACrG,OAAO,EAAC,OAAO,EAAE,KAAK,EAAC,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAC,UAAU,EAAE,aAAa,EAAE,UAAU,EAAC,MAAM,aAAa,CAAA;AAGjE;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,CAAA;AAEnC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,OAAgB;IAC1C,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;IAC3C,IAAI,MAAM,oBAAoB,EAAE,EAAE;QAChC,MAAM,WAAW,CAAC,UAAU,EAAE,WAAW,CAAC,CAAA;KAC3C;SAAM;QACL,MAAM,UAAU,CAAC,WAAW,CAAC,CAAA;KAC9B;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK;IACzB,IAAI,OAAO,CAAA;IACX,IAAI,MAAM,oBAAoB,EAAE,EAAE;QAChC,OAAO,GAAG,MAAM,WAAW,CAAC,UAAU,CAAC,CAAA;KACxC;SAAM;QACL,OAAO,GAAG,MAAM,UAAU,EAAE,CAAA;KAC7B;IAED,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,SAAS,CAAA;KACjB;IACD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IACvC,MAAM,aAAa,GAAG,MAAM,aAAa,CAAC,cAAc,CAAC,WAAW,CAAC,CAAA;IACrE,IAAI,aAAa,CAAC,OAAO,EAAE;QACzB,OAAO,aAAa,CAAC,IAAI,CAAA;KAC1B;SAAM;QACL,MAAM,MAAM,EAAE,CAAA;QACd,OAAO,SAAS,CAAA;KACjB;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM;IAC1B,IAAI,MAAM,oBAAoB,EAAE,EAAE;QAChC,MAAM,YAAY,CAAC,UAAU,CAAC,CAAA;KAC/B;SAAM;QACL,MAAM,aAAa,EAAE,CAAA;KACtB;AACH,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,oBAAoB;IACjC,IAAI;QACF,IAAI,eAAe,EAAE,CAAC,QAAQ,KAAK,SAAS,EAAE;YAC5C,KAAK,CAAC,OAAO,CAAA,uCAAuC,CAAC,CAAA;YACrD,OAAO,KAAK,CAAA;SACb;QACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAA;QACrC,MAAM,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QAChE,KAAK,CAAC,OAAO,CAAA,2BAA2B,CAAC,CAAA;QACzC,OAAO,IAAI,CAAA;QACX,qDAAqD;KACtD;IAAC,OAAO,MAAM,EAAE;QACf,KAAK,CAAC,OAAO,CAAA,6BAA6B,CAAC,CAAA;QAC3C,OAAO,KAAK,CAAA;KACb;AACH,CAAC","sourcesContent":["import {SessionSchema} from './schema.js'\nimport constants from '../constants.js'\nimport {platformAndArch} from '../os.js'\nimport {store as secureStore, fetch as secureFetch, remove as secureRemove} from '../secure-store.js'\nimport {content, debug} from '../output.js'\nimport {getSession, removeSession, setSession} from '../store.js'\nimport type {Session} from './schema.js'\n\n/**\n * The identifier of the session in the secure store.\n */\nexport const identifier = 'session'\n\n/**\n * Serializes the session as a JSON and stores it securely in the system.\n * If the secure store is not available, the session is stored in the local config.\n * @param session {Session} the session to store.\n */\nexport async function store(session: Session) {\n const jsonSession = JSON.stringify(session)\n if (await secureStoreAvailable()) {\n await secureStore(identifier, jsonSession)\n } else {\n await setSession(jsonSession)\n }\n}\n\n/**\n * Fetches the session from the secure store and returns it.\n * If the secure store is not available, the session is fetched from the local config.\n * If the format of the session is invalid, the method will discard it.\n * In the future might add some logic for supporting migrating the schema\n * of already-persisted sessions.\n * @returns {Promise<Session\\undefined>} Returns a promise that resolves with the session if it exists and is valid.\n */\nexport async function fetch(): Promise<Session | undefined> {\n let content\n if (await secureStoreAvailable()) {\n content = await secureFetch(identifier)\n } else {\n content = await getSession()\n }\n\n if (!content) {\n return undefined\n }\n const contentJson = JSON.parse(content)\n const parsedSession = await SessionSchema.safeParseAsync(contentJson)\n if (parsedSession.success) {\n return parsedSession.data\n } else {\n await remove()\n return undefined\n }\n}\n\n/**\n * Removes a session from the system.\n */\nexport async function remove() {\n if (await secureStoreAvailable()) {\n await secureRemove(identifier)\n } else {\n await removeSession()\n }\n}\n\n/**\n * Returns true if the secure store is available on the system.\n * Keytar it's not supported on some Linux environments or Windows.\n * More details: https://github.com/Shopify/shopify-cli-planning/issues/261\n * @returns a boolean indicating if the secure store is available.\n */\nasync function secureStoreAvailable(): Promise<boolean> {\n try {\n if (platformAndArch().platform === 'windows') {\n debug(content`Secure store not supported on Windows`)\n return false\n }\n const keytar = await import('keytar')\n await keytar.default.findCredentials(constants.keychain.service)\n debug(content`Secure store is available`)\n return true\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (_error) {\n debug(content`Failed to load secure store`)\n return false\n }\n}\n"]}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/session/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,aAAa,CAAA;AACzC,OAAO,SAAS,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAC,eAAe,EAAC,MAAM,UAAU,CAAA;AACxC,OAAO,EAAC,KAAK,IAAI,WAAW,EAAE,KAAK,IAAI,WAAW,EAAE,MAAM,IAAI,YAAY,EAAC,MAAM,oBAAoB,CAAA;AACrG,OAAO,EAAC,OAAO,EAAE,KAAK,EAAC,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAC,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAC,MAAM,aAAa,CAAA;AAGlF;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,CAAA;AAEnC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,OAAgB;IAC1C,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;IAC3C,IAAI,MAAM,oBAAoB,EAAE,EAAE;QAChC,MAAM,WAAW,CAAC,UAAU,EAAE,WAAW,CAAC,CAAA;KAC3C;SAAM;QACL,MAAM,UAAU,CAAC,WAAW,CAAC,CAAA;KAC9B;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK;IACzB,IAAI,OAAO,CAAA;IACX,IAAI,MAAM,oBAAoB,EAAE,EAAE;QAChC,OAAO,GAAG,MAAM,WAAW,CAAC,UAAU,CAAC,CAAA;KACxC;SAAM;QACL,OAAO,GAAG,MAAM,UAAU,EAAE,CAAA;KAC7B;IAED,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,SAAS,CAAA;KACjB;IACD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IACvC,MAAM,aAAa,GAAG,MAAM,aAAa,CAAC,cAAc,CAAC,WAAW,CAAC,CAAA;IACrE,IAAI,aAAa,CAAC,OAAO,EAAE;QACzB,OAAO,aAAa,CAAC,IAAI,CAAA;KAC1B;SAAM;QACL,MAAM,MAAM,EAAE,CAAA;QACd,OAAO,SAAS,CAAA;KACjB;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM;IAC1B,IAAI,MAAM,oBAAoB,EAAE,EAAE;QAChC,MAAM,YAAY,CAAC,UAAU,CAAC,CAAA;KAC/B;SAAM;QACL,MAAM,aAAa,EAAE,CAAA;KACtB;IAED,MAAM,eAAe,EAAE,CAAA;AACzB,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,oBAAoB;IACjC,IAAI;QACF,IAAI,eAAe,EAAE,CAAC,QAAQ,KAAK,SAAS,EAAE;YAC5C,KAAK,CAAC,OAAO,CAAA,uCAAuC,CAAC,CAAA;YACrD,OAAO,KAAK,CAAA;SACb;QACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAA;QACrC,MAAM,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QAChE,KAAK,CAAC,OAAO,CAAA,2BAA2B,CAAC,CAAA;QACzC,OAAO,IAAI,CAAA;QACX,qDAAqD;KACtD;IAAC,OAAO,MAAM,EAAE;QACf,KAAK,CAAC,OAAO,CAAA,6BAA6B,CAAC,CAAA;QAC3C,OAAO,KAAK,CAAA;KACb;AACH,CAAC","sourcesContent":["import {SessionSchema} from './schema.js'\nimport constants from '../constants.js'\nimport {platformAndArch} from '../os.js'\nimport {store as secureStore, fetch as secureFetch, remove as secureRemove} from '../secure-store.js'\nimport {content, debug} from '../output.js'\nimport {getSession, removeSession, setSession, clearAllAppInfo} from '../store.js'\nimport type {Session} from './schema.js'\n\n/**\n * The identifier of the session in the secure store.\n */\nexport const identifier = 'session'\n\n/**\n * Serializes the session as a JSON and stores it securely in the system.\n * If the secure store is not available, the session is stored in the local config.\n * @param session {Session} the session to store.\n */\nexport async function store(session: Session) {\n const jsonSession = JSON.stringify(session)\n if (await secureStoreAvailable()) {\n await secureStore(identifier, jsonSession)\n } else {\n await setSession(jsonSession)\n }\n}\n\n/**\n * Fetches the session from the secure store and returns it.\n * If the secure store is not available, the session is fetched from the local config.\n * If the format of the session is invalid, the method will discard it.\n * In the future might add some logic for supporting migrating the schema\n * of already-persisted sessions.\n * @returns {Promise<Session\\undefined>} Returns a promise that resolves with the session if it exists and is valid.\n */\nexport async function fetch(): Promise<Session | undefined> {\n let content\n if (await secureStoreAvailable()) {\n content = await secureFetch(identifier)\n } else {\n content = await getSession()\n }\n\n if (!content) {\n return undefined\n }\n const contentJson = JSON.parse(content)\n const parsedSession = await SessionSchema.safeParseAsync(contentJson)\n if (parsedSession.success) {\n return parsedSession.data\n } else {\n await remove()\n return undefined\n }\n}\n\n/**\n * Removes a session from the system.\n */\nexport async function remove() {\n if (await secureStoreAvailable()) {\n await secureRemove(identifier)\n } else {\n await removeSession()\n }\n\n await clearAllAppInfo()\n}\n\n/**\n * Returns true if the secure store is available on the system.\n * Keytar it's not supported on some Linux environments or Windows.\n * More details: https://github.com/Shopify/shopify-cli-planning/issues/261\n * @returns a boolean indicating if the secure store is available.\n */\nasync function secureStoreAvailable(): Promise<boolean> {\n try {\n if (platformAndArch().platform === 'windows') {\n debug(content`Secure store not supported on Windows`)\n return false\n }\n const keytar = await import('keytar')\n await keytar.default.findCredentials(constants.keychain.service)\n debug(content`Secure store is available`)\n return true\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (_error) {\n debug(content`Failed to load secure store`)\n return false\n }\n}\n"]}
@@ -54,12 +54,12 @@ The validation of the token for application/identity completed with the followin
54
54
  - It's been revoked: ${tokensAreRevoked}
55
55
  - It's invalid in identity: ${!identityIsValid}
56
56
  `);
57
- if (tokensAreExpired)
58
- return 'needs_refresh';
59
57
  if (tokensAreRevoked)
60
58
  return 'needs_full_auth';
61
59
  if (!identityIsValid)
62
60
  return 'needs_full_auth';
61
+ if (tokensAreExpired)
62
+ return 'needs_refresh';
63
63
  return 'ok';
64
64
  }
65
65
  function isTokenExpired(token) {
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/session/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,eAAe,CAAA;AAE3C,OAAO,SAAS,MAAM,iBAAiB,CAAA;AAEvC,OAAO,EAAC,QAAQ,EAAE,QAAQ,EAAC,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAA;AAClC,OAAO,EAAC,aAAa,EAAC,MAAM,yBAAyB,CAAA;AAIrD;;;;;GAKG;AACH,SAAS,cAAc,CAAC,eAAyB,EAAE,QAAuB;IACxE,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAA;IACrC,IAAI,aAAa,EAAE,KAAK,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAA;IACxE,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAA;AACxE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAgB,EAChB,YAA+B,EAC/B,OAGC;IAED,IAAI,CAAC,OAAO;QAAE,OAAO,iBAAiB,CAAA;IACtC,MAAM,cAAc,GAAG,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC/D,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,qBAAqB,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;IAC1F,IAAI,CAAC,cAAc;QAAE,OAAO,iBAAiB,CAAA;IAC7C,IAAI,gBAAgB,GAAG,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IACvD,IAAI,gBAAgB,GAAG,KAAK,CAAA;IAE5B,IAAI,YAAY,CAAC,WAAW,EAAE;QAC5B,MAAM,KAAK,GAAG,aAAa,CAAC,UAAU,CAAC,CAAA;QACvC,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAE,CAAA;QAC1C,gBAAgB,GAAG,gBAAgB,IAAI,CAAC,MAAM,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAAA;QAC5E,gBAAgB,GAAG,gBAAgB,IAAI,cAAc,CAAC,KAAK,CAAC,CAAA;KAC7D;IAED,IAAI,YAAY,CAAC,qBAAqB,EAAE;QACtC,MAAM,KAAK,GAAG,aAAa,CAAC,qBAAqB,CAAC,CAAA;QAClD,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAE,CAAA;QAC1C,gBAAgB,GAAG,gBAAgB,IAAI,cAAc,CAAC,KAAK,CAAC,CAAA;KAC7D;IAED,IAAI,YAAY,CAAC,QAAQ,EAAE;QACzB,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;QACpC,MAAM,SAAS,GAAG,GAAG,YAAY,CAAC,QAAQ,CAAC,SAAS,IAAI,KAAK,EAAE,CAAA;QAC/D,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,SAAS,CAAE,CAAA;QAC9C,gBAAgB,GAAG,gBAAgB,IAAI,cAAc,CAAC,KAAK,CAAC,CAAA;KAC7D;IAED,KAAK,CAAC;;kBAEU,gBAAgB;uBACX,gBAAgB;8BACT,CAAC,eAAe;GAC3C,CAAC,CAAA;IAEF,IAAI,gBAAgB;QAAE,OAAO,eAAe,CAAA;IAC5C,IAAI,gBAAgB;QAAE,OAAO,iBAAiB,CAAA;IAC9C,IAAI,CAAC,eAAe;QAAE,OAAO,iBAAiB,CAAA;IAC9C,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,cAAc,CAAC,KAAuB;IAC7C,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IACvB,OAAO,KAAK,CAAC,SAAS,GAAG,eAAe,EAAE,CAAA;AAC5C,CAAC;AAED,KAAK,UAAU,sBAAsB,CAAC,KAAuB;IAC3D,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAA;IACxB,OAAO,QAAQ,CAAC,qBAAqB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;AAC1D,CAAC;AAED,SAAS,eAAe;IACtB,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,6BAA6B,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;AAC3F,CAAC","sourcesContent":["import {applicationId} from './identity.js'\nimport {ApplicationToken, IdentityToken} from './schema.js'\nimport constants from '../constants.js'\nimport {OAuthApplications} from '../session.js'\nimport {identity, partners} from '../api.js'\nimport {debug} from '../output.js'\nimport {firstPartyDev} from '../environment/local.js'\n\ntype ValidationResult = 'needs_refresh' | 'needs_full_auth' | 'ok'\n\n/**\n * Validate if an identity token is valid for the requested scopes\n * @param requestedScopes scopes\n * @param identity\n * @returns\n */\nfunction validateScopes(requestedScopes: string[], identity: IdentityToken) {\n const currentScopes = identity.scopes\n if (firstPartyDev() !== currentScopes.includes('employee')) return false\n return requestedScopes.every((scope) => currentScopes.includes(scope))\n}\n\n/**\n * Validate if the current session is valid or we need to refresh/re-authenticate\n * @param scopes {string[]} requested scopes to validate\n * @param applications {OAuthApplications} requested applications\n * @param session current session with identity and application tokens\n * @returns {ValidationResult} 'ok' if the session is valid, 'needs_full_auth' if we need to re-authenticate, 'needs_refresh' if we need to refresh the session\n */\nexport async function validateSession(\n scopes: string[],\n applications: OAuthApplications,\n session: {\n identity: IdentityToken\n applications: {[x: string]: ApplicationToken}\n },\n): Promise<ValidationResult> {\n if (!session) return 'needs_full_auth'\n const scopesAreValid = validateScopes(scopes, session.identity)\n const identityIsValid = await identity.validateIdentityToken(session.identity.accessToken)\n if (!scopesAreValid) return 'needs_full_auth'\n let tokensAreExpired = isTokenExpired(session.identity)\n let tokensAreRevoked = false\n\n if (applications.partnersApi) {\n const appId = applicationId('partners')\n const token = session.applications[appId]!\n tokensAreRevoked = tokensAreRevoked || (await isPartnersTokenRevoked(token))\n tokensAreExpired = tokensAreExpired || isTokenExpired(token)\n }\n\n if (applications.storefrontRendererApi) {\n const appId = applicationId('storefront-renderer')\n const token = session.applications[appId]!\n tokensAreExpired = tokensAreExpired || isTokenExpired(token)\n }\n\n if (applications.adminApi) {\n const appId = applicationId('admin')\n const realAppId = `${applications.adminApi.storeFqdn}-${appId}`\n const token = session.applications[realAppId]!\n tokensAreExpired = tokensAreExpired || isTokenExpired(token)\n }\n\n debug(`\nThe validation of the token for application/identity completed with the following results:\n- It's expired: ${tokensAreExpired}\n- It's been revoked: ${tokensAreRevoked}\n- It's invalid in identity: ${!identityIsValid}\n `)\n\n if (tokensAreExpired) return 'needs_refresh'\n if (tokensAreRevoked) return 'needs_full_auth'\n if (!identityIsValid) return 'needs_full_auth'\n return 'ok'\n}\n\nfunction isTokenExpired(token: ApplicationToken): boolean {\n if (!token) return true\n return token.expiresAt < expireThreshold()\n}\n\nasync function isPartnersTokenRevoked(token: ApplicationToken) {\n if (!token) return false\n return partners.checkIfTokenIsRevoked(token.accessToken)\n}\n\nfunction expireThreshold(): Date {\n return new Date(Date.now() + constants.session.expirationTimeMarginInMinutes * 60 * 1000)\n}\n"]}
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/session/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,eAAe,CAAA;AAE3C,OAAO,SAAS,MAAM,iBAAiB,CAAA;AAEvC,OAAO,EAAC,QAAQ,EAAE,QAAQ,EAAC,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAA;AAClC,OAAO,EAAC,aAAa,EAAC,MAAM,yBAAyB,CAAA;AAIrD;;;;;GAKG;AACH,SAAS,cAAc,CAAC,eAAyB,EAAE,QAAuB;IACxE,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAA;IACrC,IAAI,aAAa,EAAE,KAAK,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAA;IACxE,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAA;AACxE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAgB,EAChB,YAA+B,EAC/B,OAGC;IAED,IAAI,CAAC,OAAO;QAAE,OAAO,iBAAiB,CAAA;IACtC,MAAM,cAAc,GAAG,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC/D,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,qBAAqB,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;IAC1F,IAAI,CAAC,cAAc;QAAE,OAAO,iBAAiB,CAAA;IAC7C,IAAI,gBAAgB,GAAG,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IACvD,IAAI,gBAAgB,GAAG,KAAK,CAAA;IAE5B,IAAI,YAAY,CAAC,WAAW,EAAE;QAC5B,MAAM,KAAK,GAAG,aAAa,CAAC,UAAU,CAAC,CAAA;QACvC,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAE,CAAA;QAC1C,gBAAgB,GAAG,gBAAgB,IAAI,CAAC,MAAM,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAAA;QAC5E,gBAAgB,GAAG,gBAAgB,IAAI,cAAc,CAAC,KAAK,CAAC,CAAA;KAC7D;IAED,IAAI,YAAY,CAAC,qBAAqB,EAAE;QACtC,MAAM,KAAK,GAAG,aAAa,CAAC,qBAAqB,CAAC,CAAA;QAClD,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAE,CAAA;QAC1C,gBAAgB,GAAG,gBAAgB,IAAI,cAAc,CAAC,KAAK,CAAC,CAAA;KAC7D;IAED,IAAI,YAAY,CAAC,QAAQ,EAAE;QACzB,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;QACpC,MAAM,SAAS,GAAG,GAAG,YAAY,CAAC,QAAQ,CAAC,SAAS,IAAI,KAAK,EAAE,CAAA;QAC/D,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,SAAS,CAAE,CAAA;QAC9C,gBAAgB,GAAG,gBAAgB,IAAI,cAAc,CAAC,KAAK,CAAC,CAAA;KAC7D;IAED,KAAK,CAAC;;kBAEU,gBAAgB;uBACX,gBAAgB;8BACT,CAAC,eAAe;GAC3C,CAAC,CAAA;IAEF,IAAI,gBAAgB;QAAE,OAAO,iBAAiB,CAAA;IAC9C,IAAI,CAAC,eAAe;QAAE,OAAO,iBAAiB,CAAA;IAC9C,IAAI,gBAAgB;QAAE,OAAO,eAAe,CAAA;IAC5C,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,cAAc,CAAC,KAAuB;IAC7C,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IACvB,OAAO,KAAK,CAAC,SAAS,GAAG,eAAe,EAAE,CAAA;AAC5C,CAAC;AAED,KAAK,UAAU,sBAAsB,CAAC,KAAuB;IAC3D,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAA;IACxB,OAAO,QAAQ,CAAC,qBAAqB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;AAC1D,CAAC;AAED,SAAS,eAAe;IACtB,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,6BAA6B,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;AAC3F,CAAC","sourcesContent":["import {applicationId} from './identity.js'\nimport {ApplicationToken, IdentityToken} from './schema.js'\nimport constants from '../constants.js'\nimport {OAuthApplications} from '../session.js'\nimport {identity, partners} from '../api.js'\nimport {debug} from '../output.js'\nimport {firstPartyDev} from '../environment/local.js'\n\ntype ValidationResult = 'needs_refresh' | 'needs_full_auth' | 'ok'\n\n/**\n * Validate if an identity token is valid for the requested scopes\n * @param requestedScopes scopes\n * @param identity\n * @returns\n */\nfunction validateScopes(requestedScopes: string[], identity: IdentityToken) {\n const currentScopes = identity.scopes\n if (firstPartyDev() !== currentScopes.includes('employee')) return false\n return requestedScopes.every((scope) => currentScopes.includes(scope))\n}\n\n/**\n * Validate if the current session is valid or we need to refresh/re-authenticate\n * @param scopes {string[]} requested scopes to validate\n * @param applications {OAuthApplications} requested applications\n * @param session current session with identity and application tokens\n * @returns {ValidationResult} 'ok' if the session is valid, 'needs_full_auth' if we need to re-authenticate, 'needs_refresh' if we need to refresh the session\n */\nexport async function validateSession(\n scopes: string[],\n applications: OAuthApplications,\n session: {\n identity: IdentityToken\n applications: {[x: string]: ApplicationToken}\n },\n): Promise<ValidationResult> {\n if (!session) return 'needs_full_auth'\n const scopesAreValid = validateScopes(scopes, session.identity)\n const identityIsValid = await identity.validateIdentityToken(session.identity.accessToken)\n if (!scopesAreValid) return 'needs_full_auth'\n let tokensAreExpired = isTokenExpired(session.identity)\n let tokensAreRevoked = false\n\n if (applications.partnersApi) {\n const appId = applicationId('partners')\n const token = session.applications[appId]!\n tokensAreRevoked = tokensAreRevoked || (await isPartnersTokenRevoked(token))\n tokensAreExpired = tokensAreExpired || isTokenExpired(token)\n }\n\n if (applications.storefrontRendererApi) {\n const appId = applicationId('storefront-renderer')\n const token = session.applications[appId]!\n tokensAreExpired = tokensAreExpired || isTokenExpired(token)\n }\n\n if (applications.adminApi) {\n const appId = applicationId('admin')\n const realAppId = `${applications.adminApi.storeFqdn}-${appId}`\n const token = session.applications[realAppId]!\n tokensAreExpired = tokensAreExpired || isTokenExpired(token)\n }\n\n debug(`\nThe validation of the token for application/identity completed with the following results:\n- It's expired: ${tokensAreExpired}\n- It's been revoked: ${tokensAreRevoked}\n- It's invalid in identity: ${!identityIsValid}\n `)\n\n if (tokensAreRevoked) return 'needs_full_auth'\n if (!identityIsValid) return 'needs_full_auth'\n if (tokensAreExpired) return 'needs_refresh'\n return 'ok'\n}\n\nfunction isTokenExpired(token: ApplicationToken): boolean {\n if (!token) return true\n return token.expiresAt < expireThreshold()\n}\n\nasync function isPartnersTokenRevoked(token: ApplicationToken) {\n if (!token) return false\n return partners.checkIfTokenIsRevoked(token.accessToken)\n}\n\nfunction expireThreshold(): Date {\n return new Date(Date.now() + constants.session.expirationTimeMarginInMinutes * 60 * 1000)\n}\n"]}
package/dist/store.d.ts CHANGED
@@ -6,6 +6,7 @@ export interface CachedAppInfo {
6
6
  orgId?: string;
7
7
  storeFqdn?: string;
8
8
  updateURLs?: boolean;
9
+ tunnelPlugin?: string;
9
10
  }
10
11
  interface ConfSchema {
11
12
  appInfo: CachedAppInfo[];
@@ -21,6 +22,7 @@ export declare function setAppInfo(options: {
21
22
  storeFqdn?: string;
22
23
  orgId?: string;
23
24
  updateURLs?: boolean;
25
+ tunnelPlugin?: string;
24
26
  }): Promise<void>;
25
27
  export declare function clearAppInfo(directory: string): Promise<void>;
26
28
  export declare function getThemeStore(): Promise<string | undefined>;
@@ -28,6 +30,7 @@ export declare function setThemeStore(themeStore: string): Promise<void>;
28
30
  export declare function getSession(): Promise<string | undefined>;
29
31
  export declare function setSession(session: string): Promise<void>;
30
32
  export declare function removeSession(): Promise<void>;
33
+ export declare function clearAllAppInfo(): Promise<void>;
31
34
  export declare class CLIKitStore extends Conf<ConfSchema> {
32
35
  getAppInfo(directory: string): CachedAppInfo | undefined;
33
36
  setAppInfo(options: {
@@ -37,8 +40,10 @@ export declare class CLIKitStore extends Conf<ConfSchema> {
37
40
  storeFqdn?: string;
38
41
  orgId?: string;
39
42
  updateURLs?: boolean;
43
+ tunnelPlugin?: string;
40
44
  }): void;
41
45
  clearAppInfo(directory: string): void;
46
+ clearAllAppInfo(): void;
42
47
  getThemeStore(): string | undefined;
43
48
  setThemeStore(themeStore: string): void;
44
49
  getSession(): string | undefined;
package/dist/store.js CHANGED
@@ -66,6 +66,10 @@ export async function removeSession() {
66
66
  const store = await cliKitStore();
67
67
  store.removeSession();
68
68
  }
69
+ export async function clearAllAppInfo() {
70
+ const store = await cliKitStore();
71
+ store.clearAllAppInfo();
72
+ }
69
73
  export class CLIKitStore extends Conf {
70
74
  getAppInfo(directory) {
71
75
  debug(content `Reading cached app information for directory ${token.path(directory)}...`);
@@ -88,12 +92,13 @@ export class CLIKitStore extends Conf {
88
92
  storeFqdn: options.storeFqdn ?? app.storeFqdn,
89
93
  orgId: options.orgId ?? app.orgId,
90
94
  updateURLs: options.updateURLs ?? app.updateURLs,
95
+ tunnelPlugin: options.tunnelPlugin ?? app.tunnelPlugin,
91
96
  };
92
97
  }
93
98
  this.set('appInfo', apps);
94
99
  }
95
100
  clearAppInfo(directory) {
96
- debug(content `Clearning app information for directory ${token.path(directory)}...`);
101
+ debug(content `Clearing app information for directory ${token.path(directory)}...`);
97
102
  const apps = this.get('appInfo') ?? [];
98
103
  const index = apps.findIndex((saved) => saved.directory === directory);
99
104
  if (index !== -1) {
@@ -101,6 +106,10 @@ export class CLIKitStore extends Conf {
101
106
  }
102
107
  this.set('appInfo', apps);
103
108
  }
109
+ clearAllAppInfo() {
110
+ debug(content `Clearing all app information...`);
111
+ this.set('appInfo', []);
112
+ }
104
113
  getThemeStore() {
105
114
  debug(content `Getting theme store...`);
106
115
  return this.get('themeStore');