@shopify/cli-kit 3.10.1 → 3.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +1 -1
  3. package/dist/analytics.d.ts +2 -1
  4. package/dist/analytics.js +5 -1
  5. package/dist/analytics.js.map +1 -1
  6. package/dist/api/admin.js +2 -6
  7. package/dist/api/admin.js.map +1 -1
  8. package/dist/api/identity.js +2 -2
  9. package/dist/api/identity.js.map +1 -1
  10. package/dist/api/partners.js +2 -10
  11. package/dist/api/partners.js.map +1 -1
  12. package/dist/common/result.d.ts +17 -0
  13. package/dist/common/result.js +31 -0
  14. package/dist/common/result.js.map +1 -0
  15. package/dist/constants.d.ts +8 -4
  16. package/dist/constants.js +9 -4
  17. package/dist/constants.js.map +1 -1
  18. package/dist/environment/fqdn.js +4 -4
  19. package/dist/environment/fqdn.js.map +1 -1
  20. package/dist/environment/local.d.ts +5 -1
  21. package/dist/environment/local.js +24 -3
  22. package/dist/environment/local.js.map +1 -1
  23. package/dist/environment/service.d.ts +2 -17
  24. package/dist/environment/service.js +5 -46
  25. package/dist/environment/service.js.map +1 -1
  26. package/dist/environment/spin-cache.d.ts +2 -0
  27. package/dist/environment/spin-cache.js +8 -0
  28. package/dist/environment/spin-cache.js.map +1 -0
  29. package/dist/environment/spin.d.ts +3 -0
  30. package/dist/environment/spin.js +19 -3
  31. package/dist/environment/spin.js.map +1 -1
  32. package/dist/error.d.ts +0 -1
  33. package/dist/error.js +0 -1
  34. package/dist/error.js.map +1 -1
  35. package/dist/http/fetch.d.ts +1 -2
  36. package/dist/http/fetch.js +2 -2
  37. package/dist/http/fetch.js.map +1 -1
  38. package/dist/http/graphql.d.ts +0 -2
  39. package/dist/http/graphql.js +1 -1
  40. package/dist/http/graphql.js.map +1 -1
  41. package/dist/http.d.ts +2 -3
  42. package/dist/http.js +5 -5
  43. package/dist/http.js.map +1 -1
  44. package/dist/index.d.ts +1 -0
  45. package/dist/index.js +1 -0
  46. package/dist/index.js.map +1 -1
  47. package/dist/log.d.ts +21 -0
  48. package/dist/log.js +155 -0
  49. package/dist/log.js.map +1 -0
  50. package/dist/node/base-command.d.ts +3 -1
  51. package/dist/node/base-command.js +5 -2
  52. package/dist/node/base-command.js.map +1 -1
  53. package/dist/node/cli.d.ts +2 -1
  54. package/dist/node/cli.js +51 -2
  55. package/dist/node/cli.js.map +1 -1
  56. package/dist/node/hooks/init.js +2 -2
  57. package/dist/node/hooks/init.js.map +1 -1
  58. package/dist/node/hooks/prerun.js.map +1 -1
  59. package/dist/node/node-package-manager.d.ts +2 -2
  60. package/dist/node/node-package-manager.js +9 -16
  61. package/dist/node/node-package-manager.js.map +1 -1
  62. package/dist/output.d.ts +1 -8
  63. package/dist/output.js +2 -99
  64. package/dist/output.js.map +1 -1
  65. package/dist/port.js +1 -1
  66. package/dist/port.js.map +1 -1
  67. package/dist/session/device-authorization.d.ts +32 -0
  68. package/dist/session/device-authorization.js +92 -0
  69. package/dist/session/device-authorization.js.map +1 -0
  70. package/dist/session/exchange.d.ts +9 -0
  71. package/dist/session/exchange.js +49 -23
  72. package/dist/session/exchange.js.map +1 -1
  73. package/dist/session/identity.js +5 -5
  74. package/dist/session/identity.js.map +1 -1
  75. package/dist/session.js +19 -7
  76. package/dist/session.js.map +1 -1
  77. package/dist/tsconfig.tsbuildinfo +1 -1
  78. package/dist/ui.js +2 -1
  79. package/dist/ui.js.map +1 -1
  80. package/package.json +1 -1
@@ -1,57 +1,16 @@
1
- import { partners as partnersEnvironment, shopify as shopifyEnvironment, identity as identityEnvironment, } from './service.js';
2
- import { Environment } from '../network/service.js';
1
+ import { isSpin } from './spin.js';
3
2
  import constants from '../constants.js';
4
- export async function environmentForService(service) {
5
- let environment;
6
- switch (service) {
7
- case 'identity':
8
- environment = await identityEnvironment();
9
- break;
10
- case 'partners':
11
- environment = await partnersEnvironment();
12
- break;
13
- case 'shopify':
14
- environment = await shopifyEnvironment();
15
- break;
16
- }
17
- return environment;
18
- }
19
- /**
20
- * Given an environment variable that represents the environment to use for a given serve,
21
- * it returns the environment as a enum;
22
- * @param value The environment variable value.
23
- * @returns {Environment} representing the environment to use.
24
- */
25
- function service(value) {
3
+ import { Environment } from '../network/service.js';
4
+ export function serviceEnvironment(env = process.env) {
5
+ const value = env[constants.environmentVariables.serviceEnv];
26
6
  if (value === 'local') {
27
7
  return Environment.Local;
28
8
  }
29
- else if (value === 'spin') {
9
+ else if (value === 'spin' || isSpin(env)) {
30
10
  return Environment.Spin;
31
11
  }
32
12
  else {
33
13
  return Environment.Production;
34
14
  }
35
15
  }
36
- /**
37
- * Returns the environment to be used for the interactions with the partners' CLI API.
38
- * @param env The environment variables from the environment of the current process.
39
- */
40
- export function partners(env = process.env) {
41
- return service(env[constants.environmentVariables.partnersEnv]);
42
- }
43
- /**
44
- * Returns the environment to be used for the interactions with the admin API.
45
- * @param env The environment variables from the environment of the current process.
46
- */
47
- export function shopify(env = process.env) {
48
- return service(env[constants.environmentVariables.shopifyEnv]);
49
- }
50
- /**
51
- * Returns the environment to be used for the interactions with identity.
52
- * @param env The environment variables from the environment of the current process.
53
- */
54
- export function identity(env = process.env) {
55
- return service(env[constants.environmentVariables.identityEnv]);
56
- }
57
16
  //# sourceMappingURL=service.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/environment/service.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,IAAI,mBAAmB,EAC/B,OAAO,IAAI,kBAAkB,EAC7B,QAAQ,IAAI,mBAAmB,GAChC,MAAM,cAAc,CAAA;AACrB,OAAO,EAAC,WAAW,EAAU,MAAM,uBAAuB,CAAA;AAC1D,OAAO,SAAS,MAAM,iBAAiB,CAAA;AAEvC,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,OAAgB;IAC1D,IAAI,WAAwB,CAAA;IAC5B,QAAQ,OAAO,EAAE;QACf,KAAK,UAAU;YACb,WAAW,GAAG,MAAM,mBAAmB,EAAE,CAAA;YACzC,MAAK;QACP,KAAK,UAAU;YACb,WAAW,GAAG,MAAM,mBAAmB,EAAE,CAAA;YACzC,MAAK;QACP,KAAK,SAAS;YACZ,WAAW,GAAG,MAAM,kBAAkB,EAAE,CAAA;YACxC,MAAK;KACR;IACD,OAAO,WAAW,CAAA;AACpB,CAAC;AAED;;;;;GAKG;AACH,SAAS,OAAO,CAAC,KAAyB;IACxC,IAAI,KAAK,KAAK,OAAO,EAAE;QACrB,OAAO,WAAW,CAAC,KAAK,CAAA;KACzB;SAAM,IAAI,KAAK,KAAK,MAAM,EAAE;QAC3B,OAAO,WAAW,CAAC,IAAI,CAAA;KACxB;SAAM;QACL,OAAO,WAAW,CAAC,UAAU,CAAA;KAC9B;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IACxC,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAA;AACjE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IACvC,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC,CAAA;AAChE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IACxC,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAA;AACjE,CAAC","sourcesContent":["import {\n partners as partnersEnvironment,\n shopify as shopifyEnvironment,\n identity as identityEnvironment,\n} from './service.js'\nimport {Environment, Service} from '../network/service.js'\nimport constants from '../constants.js'\n\nexport async function environmentForService(service: Service): Promise<Environment> {\n let environment: Environment\n switch (service) {\n case 'identity':\n environment = await identityEnvironment()\n break\n case 'partners':\n environment = await partnersEnvironment()\n break\n case 'shopify':\n environment = await shopifyEnvironment()\n break\n }\n return environment\n}\n\n/**\n * Given an environment variable that represents the environment to use for a given serve,\n * it returns the environment as a enum;\n * @param value The environment variable value.\n * @returns {Environment} representing the environment to use.\n */\nfunction service(value: undefined | string): Environment {\n if (value === 'local') {\n return Environment.Local\n } else if (value === 'spin') {\n return Environment.Spin\n } else {\n return Environment.Production\n }\n}\n\n/**\n * Returns the environment to be used for the interactions with the partners' CLI API.\n * @param env The environment variables from the environment of the current process.\n */\nexport function partners(env = process.env): Environment {\n return service(env[constants.environmentVariables.partnersEnv])\n}\n\n/**\n * Returns the environment to be used for the interactions with the admin API.\n * @param env The environment variables from the environment of the current process.\n */\nexport function shopify(env = process.env): Environment {\n return service(env[constants.environmentVariables.shopifyEnv])\n}\n\n/**\n * Returns the environment to be used for the interactions with identity.\n * @param env The environment variables from the environment of the current process.\n */\nexport function identity(env = process.env): Environment {\n return service(env[constants.environmentVariables.identityEnv])\n}\n"]}
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/environment/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,WAAW,CAAA;AAChC,OAAO,SAAS,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAC,WAAW,EAAC,MAAM,uBAAuB,CAAA;AAEjD,MAAM,UAAU,kBAAkB,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IAClD,MAAM,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAA;IAC5D,IAAI,KAAK,KAAK,OAAO,EAAE;QACrB,OAAO,WAAW,CAAC,KAAK,CAAA;KACzB;SAAM,IAAI,KAAK,KAAK,MAAM,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE;QAC1C,OAAO,WAAW,CAAC,IAAI,CAAA;KACxB;SAAM;QACL,OAAO,WAAW,CAAC,UAAU,CAAA;KAC9B;AACH,CAAC","sourcesContent":["import {isSpin} from './spin.js'\nimport constants from '../constants.js'\nimport {Environment} from '../network/service.js'\n\nexport function serviceEnvironment(env = process.env): Environment {\n const value = env[constants.environmentVariables.serviceEnv]\n if (value === 'local') {\n return Environment.Local\n } else if (value === 'spin' || isSpin(env)) {\n return Environment.Spin\n } else {\n return Environment.Production\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare function getCachedSpinFqdn(): string | undefined;
2
+ export declare function setCachedSpinFqdn(fqdn: string): void;
@@ -0,0 +1,8 @@
1
+ let cachedSpinFQDN;
2
+ export function getCachedSpinFqdn() {
3
+ return cachedSpinFQDN;
4
+ }
5
+ export function setCachedSpinFqdn(fqdn) {
6
+ cachedSpinFQDN = fqdn;
7
+ }
8
+ //# sourceMappingURL=spin-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spin-cache.js","sourceRoot":"","sources":["../../src/environment/spin-cache.ts"],"names":[],"mappings":"AAAA,IAAI,cAAsB,CAAA;AAE1B,MAAM,UAAU,iBAAiB;IAC/B,OAAO,cAAc,CAAA;AACvB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,cAAc,GAAG,IAAI,CAAA;AACvB,CAAC","sourcesContent":["let cachedSpinFQDN: string\n\nexport function getCachedSpinFqdn(): string | undefined {\n return cachedSpinFQDN\n}\n\nexport function setCachedSpinFqdn(fqdn: string) {\n cachedSpinFQDN = fqdn\n}\n"]}
@@ -3,6 +3,9 @@ import { Abort } from '../error.js';
3
3
  export declare const SpinInstanceNotFound: (spinInstance: string | undefined, error: string) => Abort;
4
4
  /**
5
5
  * When ran in a Spin environment, it returns the fqdn of the instance.
6
+ *
7
+ * Will cache the value of the Spin FQDN during the execution of the CLI.
8
+ * To avoid multiple calls to `readSync` or `show`
6
9
  * @returns {string} fqdn of the Spin environment.
7
10
  */
8
11
  export declare function fqdn(env?: NodeJS.ProcessEnv): Promise<string>;
@@ -1,8 +1,10 @@
1
1
  import { isTruthy } from './utilities.js';
2
+ import { getCachedSpinFqdn, setCachedSpinFqdn } from './spin-cache.js';
2
3
  import constants from '../constants.js';
3
4
  import { captureOutput } from '../system.js';
4
5
  import { Abort } from '../error.js';
5
6
  import { content, token } from '../output.js';
7
+ import { exists, readSync } from '../file.js';
6
8
  export const SpinInstanceNotFound = (spinInstance, error) => {
7
9
  const errorMessage = content `${token.genericShellCommand(`spin`)} yielded the following error trying to obtain the fully qualified domain name of the Spin instance:
8
10
  ${error}
@@ -13,14 +15,28 @@ ${error}
13
15
  }
14
16
  return new Abort(errorMessage, nextSteps);
15
17
  };
18
+ const spinFqdnFilePath = '/etc/spin/machine/fqdn';
16
19
  /**
17
20
  * When ran in a Spin environment, it returns the fqdn of the instance.
21
+ *
22
+ * Will cache the value of the Spin FQDN during the execution of the CLI.
23
+ * To avoid multiple calls to `readSync` or `show`
18
24
  * @returns {string} fqdn of the Spin environment.
19
25
  */
20
26
  export async function fqdn(env = process.env) {
21
- const spinInstance = await instance(env);
22
- const showResponse = await show(spinInstance, env);
23
- return showResponse.fqdn;
27
+ let spinFqdn = getCachedSpinFqdn();
28
+ if (spinFqdn)
29
+ return spinFqdn;
30
+ if (await exists(spinFqdnFilePath)) {
31
+ spinFqdn = await readSync(spinFqdnFilePath).toString();
32
+ }
33
+ else {
34
+ const spinInstance = await instance(env);
35
+ const showResponse = await show(spinInstance, env);
36
+ spinFqdn = showResponse.fqdn;
37
+ }
38
+ setCachedSpinFqdn(spinFqdn);
39
+ return spinFqdn;
24
40
  }
25
41
  /**
26
42
  * Runs "spin show" and returns the JSON-parsed output.
@@ -1 +1 @@
1
- {"version":3,"file":"spin.js","sourceRoot":"","sources":["../../src/environment/spin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,gBAAgB,CAAA;AACvC,OAAO,SAAS,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAC,aAAa,EAAC,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAC,KAAK,EAAC,MAAM,aAAa,CAAA;AACjC,OAAO,EAAC,OAAO,EAAE,KAAK,EAAC,MAAM,cAAc,CAAA;AAE3C,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,YAAgC,EAAE,KAAa,EAAE,EAAE;IACtF,MAAM,YAAY,GAAG,OAAO,CAAA,GAAG,KAAK,CAAC,mBAAmB,CACtD,MAAM,CACP;EACD,KAAK;GACJ,CAAA;IACD,IAAI,SAA6B,CAAA;IACjC,IAAI,YAAY,EAAE;QAChB,SAAS,GAAG,aAAa,YAAY,6DAA6D,CAAA;KACnG;IACD,OAAO,IAAI,KAAK,CAAC,YAAY,EAAE,SAAS,CAAC,CAAA;AAC3C,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IAC1C,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAA;IACxC,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,GAAG,CAAC,CAAA;IAClD,OAAO,YAAY,CAAC,IAAI,CAAA;AAC1B,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,YAAgC,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG;IAC5E,MAAM,MAAM,GAAG,YAAY,KAAK,SAAS,CAAA;IACzC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IACzE,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,IAAI,EAAE,EAAC,GAAG,EAAC,CAAC,CAAA;IACvD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAC/B,IAAI,IAAI,CAAC,KAAK,EAAE;QACd,MAAM,oBAAoB,CAAC,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;KACrD;SAAM;QACL,OAAO,IAAI,CAAA;KACZ;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,MAAM,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IACtC,OAAO,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAA;AAC3D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IACxC,OAAO,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,YAAY,CAAC,CAAA;AACzD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IACzC,OAAO,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAA;AAC1D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IACzC,OAAO,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAA;AAC1D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IACpC,OAAO,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAA;AACrD,CAAC","sourcesContent":["import {isTruthy} from './utilities.js'\nimport constants from '../constants.js'\nimport {captureOutput} from '../system.js'\nimport {Abort} from '../error.js'\nimport {content, token} from '../output.js'\n\nexport const SpinInstanceNotFound = (spinInstance: string | undefined, error: string) => {\n const errorMessage = content`${token.genericShellCommand(\n `spin`,\n )} yielded the following error trying to obtain the fully qualified domain name of the Spin instance:\n${error}\n `\n let nextSteps: string | undefined\n if (spinInstance) {\n nextSteps = `Make sure ${spinInstance} is the instance name and not a fully qualified domain name`\n }\n return new Abort(errorMessage, nextSteps)\n}\n\n/**\n * When ran in a Spin environment, it returns the fqdn of the instance.\n * @returns {string} fqdn of the Spin environment.\n */\nexport async function fqdn(env = process.env): Promise<string> {\n const spinInstance = await instance(env)\n const showResponse = await show(spinInstance, env)\n return showResponse.fqdn\n}\n\n/**\n * Runs \"spin show\" and returns the JSON-parsed output.\n * @param {latest} Whether to pass --latest when running the command.\n * @returns The JSON-parsed output of the Spin CLI.\n * @throws Any error raised from the underlying Spin CLI.\n */\nexport async function show(spinInstance: string | undefined, env = process.env): Promise<{fqdn: string}> {\n const latest = spinInstance === undefined\n const args = latest ? ['show', '--latest', '--json'] : ['show', '--json']\n const output = await captureOutput('spin', args, {env})\n const json = JSON.parse(output)\n if (json.error) {\n throw SpinInstanceNotFound(spinInstance, json.error)\n } else {\n return json\n }\n}\n\n/**\n * Returns true if the CLI is running in a Spin environment.\n * @param env {[key: string]: string} Environment variables\n * @returns {boolean} True if the CLI is running in a Spin environment.\n */\nexport function isSpin(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.spin])\n}\n\n/**\n * Returns the value of the SPIN_INSTANCE environment variable.\n * @param env {[key: string]: string} Environment variables\n * @returns {string | undefined} The value of the SPIN_INSTANCE environment variable.\n */\nexport function instance(env = process.env): string | undefined {\n return env[constants.environmentVariables.spinInstance]\n}\n\n/**\n * Returns the value of the SPIN_WORKSPACE environment variable.\n * @param env {[key: string]: string} Environment variables\n * @returns {string | undefined} The value of the SPIN_WORKSPACE environment variable.\n */\nexport function workspace(env = process.env): string | undefined {\n return env[constants.environmentVariables.spinWorkspace]\n}\n\n/**\n * Returns the value of the SPIN_NAMESPACE environment variable.\n * @param env {[key: string]: string} Environment variables\n * @returns {string | undefined} The value of the SPIN_NAMESPACE environment variable.\n */\nexport function namespace(env = process.env): string | undefined {\n return env[constants.environmentVariables.spinNamespace]\n}\n\n/**\n * Returns the value of the SPIN_HOST environment variable.\n * @param env {[key: string]: string} Environment variables\n * @returns {string | undefined} The value of the SPIN_HOST environment variable.\n */\nexport function host(env = process.env): string | undefined {\n return env[constants.environmentVariables.spinHost]\n}\n"]}
1
+ {"version":3,"file":"spin.js","sourceRoot":"","sources":["../../src/environment/spin.ts"],"names":[],"mappings":"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","sourcesContent":["import {isTruthy} from './utilities.js'\nimport {getCachedSpinFqdn, setCachedSpinFqdn} from './spin-cache.js'\nimport constants from '../constants.js'\nimport {captureOutput} from '../system.js'\nimport {Abort} from '../error.js'\nimport {content, token} from '../output.js'\nimport {exists, readSync} from '../file.js'\n\nexport const SpinInstanceNotFound = (spinInstance: string | undefined, error: string) => {\n const errorMessage = content`${token.genericShellCommand(\n `spin`,\n )} yielded the following error trying to obtain the fully qualified domain name of the Spin instance:\n${error}\n `\n let nextSteps: string | undefined\n if (spinInstance) {\n nextSteps = `Make sure ${spinInstance} is the instance name and not a fully qualified domain name`\n }\n return new Abort(errorMessage, nextSteps)\n}\n\nconst spinFqdnFilePath = '/etc/spin/machine/fqdn'\n\n/**\n * When ran in a Spin environment, it returns the fqdn of the instance.\n *\n * Will cache the value of the Spin FQDN during the execution of the CLI.\n * To avoid multiple calls to `readSync` or `show`\n * @returns {string} fqdn of the Spin environment.\n */\nexport async function fqdn(env = process.env): Promise<string> {\n let spinFqdn = getCachedSpinFqdn()\n if (spinFqdn) return spinFqdn\n\n if (await exists(spinFqdnFilePath)) {\n spinFqdn = await readSync(spinFqdnFilePath).toString()\n } else {\n const spinInstance = await instance(env)\n const showResponse = await show(spinInstance, env)\n\n spinFqdn = showResponse.fqdn\n }\n setCachedSpinFqdn(spinFqdn)\n return spinFqdn\n}\n\n/**\n * Runs \"spin show\" and returns the JSON-parsed output.\n * @param {latest} Whether to pass --latest when running the command.\n * @returns The JSON-parsed output of the Spin CLI.\n * @throws Any error raised from the underlying Spin CLI.\n */\nexport async function show(spinInstance: string | undefined, env = process.env): Promise<{fqdn: string}> {\n const latest = spinInstance === undefined\n const args = latest ? ['show', '--latest', '--json'] : ['show', '--json']\n const output = await captureOutput('spin', args, {env})\n const json = JSON.parse(output)\n if (json.error) {\n throw SpinInstanceNotFound(spinInstance, json.error)\n } else {\n return json\n }\n}\n\n/**\n * Returns true if the CLI is running in a Spin environment.\n * @param env {[key: string]: string} Environment variables\n * @returns {boolean} True if the CLI is running in a Spin environment.\n */\nexport function isSpin(env = process.env): boolean {\n return isTruthy(env[constants.environmentVariables.spin])\n}\n\n/**\n * Returns the value of the SPIN_INSTANCE environment variable.\n * @param env {[key: string]: string} Environment variables\n * @returns {string | undefined} The value of the SPIN_INSTANCE environment variable.\n */\nexport function instance(env = process.env): string | undefined {\n return env[constants.environmentVariables.spinInstance]\n}\n\n/**\n * Returns the value of the SPIN_WORKSPACE environment variable.\n * @param env {[key: string]: string} Environment variables\n * @returns {string | undefined} The value of the SPIN_WORKSPACE environment variable.\n */\nexport function workspace(env = process.env): string | undefined {\n return env[constants.environmentVariables.spinWorkspace]\n}\n\n/**\n * Returns the value of the SPIN_NAMESPACE environment variable.\n * @param env {[key: string]: string} Environment variables\n * @returns {string | undefined} The value of the SPIN_NAMESPACE environment variable.\n */\nexport function namespace(env = process.env): string | undefined {\n return env[constants.environmentVariables.spinNamespace]\n}\n\n/**\n * Returns the value of the SPIN_HOST environment variable.\n * @param env {[key: string]: string} Environment variables\n * @returns {string | undefined} The value of the SPIN_HOST environment variable.\n */\nexport function host(env = process.env): string | undefined {\n return env[constants.environmentVariables.spinHost]\n}\n"]}
package/dist/error.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { Message } from './output.js';
2
2
  export { ExtendableError } from 'ts-error';
3
- export { AbortSignal } from 'abort-controller';
4
3
  declare enum FatalErrorType {
5
4
  Abort = 0,
6
5
  AbortSilent = 1,
package/dist/error.js CHANGED
@@ -2,7 +2,6 @@ import { stringifyMessage, error as outputError } from './output.js';
2
2
  import { normalize } from './path.js';
3
3
  import { Errors } from '@oclif/core';
4
4
  export { ExtendableError } from 'ts-error';
5
- export { AbortSignal } from 'abort-controller';
6
5
  var FatalErrorType;
7
6
  (function (FatalErrorType) {
8
7
  FatalErrorType[FatalErrorType["Abort"] = 0] = "Abort";
package/dist/error.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"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","sourcesContent":["import {Message, stringifyMessage, error as outputError} from './output.js'\nimport {normalize} from './path.js'\nimport {Errors} from '@oclif/core'\n\nexport {ExtendableError} from 'ts-error'\nexport {AbortSignal} from 'abort-controller'\n\nenum FatalErrorType {\n Abort,\n AbortSilent,\n Bug,\n}\n\nexport class CancelExecution extends Error {}\n\n/**\n * A fatal error represents an error shouldn't be rescued and that causes the execution to terminate.\n * There shouldn't be code that catches fatal errors.\n */\nexport abstract class Fatal extends Error {\n tryMessage: string | null\n type: FatalErrorType\n constructor(message: Message, type: FatalErrorType, tryMessage: Message | null = null) {\n super(stringifyMessage(message))\n this.tryMessage = tryMessage ? stringifyMessage(tryMessage) : null\n this.type = type\n }\n}\n\n/**\n * An abort error is a fatal error that shouldn't be reported as a bug.\n * Those usually represent unexpected scenarios that we can't handle and that usually require some action from the developer\n */\nexport class Abort extends Fatal {\n constructor(message: Message, tryMessage: Message | null = null) {\n super(message, FatalErrorType.Abort, tryMessage)\n }\n}\n\nexport class AbortSilent extends Fatal {\n constructor() {\n super('', FatalErrorType.AbortSilent)\n }\n}\n\n/**\n * A bug error is an error that represents a bug and therefore should be reported.\n */\nexport class Bug extends Fatal {\n constructor(message: Message, tryMessage: string | null = null) {\n super(message, FatalErrorType.Bug, tryMessage)\n }\n}\n\n/**\n * A function that handles errors that blow up in the CLI.\n * @param error Error to be handled.\n * @returns A promise that resolves with the error passed.\n */\nexport async function handler(error: unknown): Promise<unknown> {\n let fatal: Fatal\n if (isFatal(error)) {\n fatal = error\n } else if (typeof error === 'string') {\n fatal = new Bug(error)\n } else if (error instanceof Error) {\n fatal = new Bug(error.message)\n fatal.stack = error.stack\n } else {\n // errors can come in all shapes and sizes...\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const maybeError = error as any\n fatal = new Bug(maybeError?.message ?? 'Unknown error')\n if (maybeError?.stack) {\n fatal.stack = maybeError?.stack\n }\n }\n\n await outputError(fatal)\n return Promise.resolve(error)\n}\n\nexport function mapper(error: unknown): Promise<unknown> {\n if (error instanceof Errors.CLIError) {\n const mappedError = new Abort(error.message)\n mappedError.stack = error.stack\n return Promise.resolve(mappedError)\n } else {\n return Promise.resolve(error)\n }\n}\n\nexport function isFatal(error: unknown): error is Fatal {\n try {\n return Object.prototype.hasOwnProperty.call(error, 'type')\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return false\n }\n}\n\nexport function shouldReport(error: unknown): boolean {\n if (!isFatal(error)) {\n return true\n }\n if (error.type === FatalErrorType.Bug) {\n return true\n }\n return false\n}\n\n/**\n * Stack traces usually have file:// - we strip that and also remove the Windows drive designation\n *\n */\nexport function cleanSingleStackTracePath(filePath: string): string {\n return normalize(filePath)\n .replace('file:/', '/')\n .replace(/^\\/?[A-Z]:/, '')\n}\n"]}
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"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","sourcesContent":["import {Message, stringifyMessage, error as outputError} from './output.js'\nimport {normalize} from './path.js'\nimport {Errors} from '@oclif/core'\n\nexport {ExtendableError} from 'ts-error'\n\nenum FatalErrorType {\n Abort,\n AbortSilent,\n Bug,\n}\n\nexport class CancelExecution extends Error {}\n\n/**\n * A fatal error represents an error shouldn't be rescued and that causes the execution to terminate.\n * There shouldn't be code that catches fatal errors.\n */\nexport abstract class Fatal extends Error {\n tryMessage: string | null\n type: FatalErrorType\n constructor(message: Message, type: FatalErrorType, tryMessage: Message | null = null) {\n super(stringifyMessage(message))\n this.tryMessage = tryMessage ? stringifyMessage(tryMessage) : null\n this.type = type\n }\n}\n\n/**\n * An abort error is a fatal error that shouldn't be reported as a bug.\n * Those usually represent unexpected scenarios that we can't handle and that usually require some action from the developer\n */\nexport class Abort extends Fatal {\n constructor(message: Message, tryMessage: Message | null = null) {\n super(message, FatalErrorType.Abort, tryMessage)\n }\n}\n\nexport class AbortSilent extends Fatal {\n constructor() {\n super('', FatalErrorType.AbortSilent)\n }\n}\n\n/**\n * A bug error is an error that represents a bug and therefore should be reported.\n */\nexport class Bug extends Fatal {\n constructor(message: Message, tryMessage: string | null = null) {\n super(message, FatalErrorType.Bug, tryMessage)\n }\n}\n\n/**\n * A function that handles errors that blow up in the CLI.\n * @param error Error to be handled.\n * @returns A promise that resolves with the error passed.\n */\nexport async function handler(error: unknown): Promise<unknown> {\n let fatal: Fatal\n if (isFatal(error)) {\n fatal = error\n } else if (typeof error === 'string') {\n fatal = new Bug(error)\n } else if (error instanceof Error) {\n fatal = new Bug(error.message)\n fatal.stack = error.stack\n } else {\n // errors can come in all shapes and sizes...\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const maybeError = error as any\n fatal = new Bug(maybeError?.message ?? 'Unknown error')\n if (maybeError?.stack) {\n fatal.stack = maybeError?.stack\n }\n }\n\n await outputError(fatal)\n return Promise.resolve(error)\n}\n\nexport function mapper(error: unknown): Promise<unknown> {\n if (error instanceof Errors.CLIError) {\n const mappedError = new Abort(error.message)\n mappedError.stack = error.stack\n return Promise.resolve(mappedError)\n } else {\n return Promise.resolve(error)\n }\n}\n\nexport function isFatal(error: unknown): error is Fatal {\n try {\n return Object.prototype.hasOwnProperty.call(error, 'type')\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return false\n }\n}\n\nexport function shouldReport(error: unknown): boolean {\n if (!isFatal(error)) {\n return true\n }\n if (error.type === FatalErrorType.Bug) {\n return true\n }\n return false\n}\n\n/**\n * Stack traces usually have file:// - we strip that and also remove the Windows drive designation\n *\n */\nexport function cleanSingleStackTracePath(filePath: string): string {\n return normalize(filePath)\n .replace('file:/', '/')\n .replace(/^\\/?[A-Z]:/, '')\n}\n"]}
@@ -1,4 +1,3 @@
1
- import { Service } from '../network/service.js';
2
1
  import nodeFetch from 'node-fetch';
3
2
  import type { RequestInfo, RequestInit } from 'node-fetch';
4
3
  declare type Response = ReturnType<typeof nodeFetch>;
@@ -19,5 +18,5 @@ export default function fetch(url: RequestInfo, init?: RequestInit): Response;
19
18
  * TLS configuragion is used based on the environment in which the service is running
20
19
  * (e.g. spin)
21
20
  */
22
- export declare function shopifyFetch(service: Service, url: RequestInfo, init?: RequestInit): Response;
21
+ export declare function shopifyFetch(url: RequestInfo, init?: RequestInit): Response;
23
22
  export {};
@@ -20,8 +20,8 @@ export default async function fetch(url, init) {
20
20
  * TLS configuragion is used based on the environment in which the service is running
21
21
  * (e.g. spin)
22
22
  */
23
- export async function shopifyFetch(service, url, init) {
24
- const response = await nodeFetch(url, { ...init, agent: await httpsAgent(service) });
23
+ export async function shopifyFetch(url, init) {
24
+ const response = await nodeFetch(url, { ...init, agent: await httpsAgent() });
25
25
  return response;
26
26
  }
27
27
  //# sourceMappingURL=fetch.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/http/fetch.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,UAAU,EAAC,MAAM,YAAY,CAAA;AACrC,OAAO,SAAS,MAAM,YAAY,CAAA;AAIlC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,KAAK,CAAC,GAAgB,EAAE,IAAkB;IACtE,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAC3C,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAgB,EAAE,GAAgB,EAAE,IAAkB;IACvF,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,EAAC,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC,OAAO,CAAC,EAAC,CAAC,CAAA;IAClF,OAAO,QAAQ,CAAA;AACjB,CAAC","sourcesContent":["import {Service} from '../network/service.js'\n\nimport {httpsAgent} from '../http.js'\nimport nodeFetch from 'node-fetch'\nimport type {RequestInfo, RequestInit} from 'node-fetch'\n\ntype Response = ReturnType<typeof nodeFetch>\n/**\n * An interface that abstracts way node-fetch. When Node has built-in\n * support for \"fetch\" in the standard library, we can drop the node-fetch\n * dependency from here.\n * Note that we are exposing types from \"node-fetch\". The reason being is that\n * they are consistent with the Web API so if we drop node-fetch in the future\n * it won't require changes from the callers.\n * @param url {RequestInfo} This defines the resource that you wish to fetch.\n * @param init {RequestInit} An object containing any custom settings that you want to apply to the request\n * @returns A promise that resolves with the response.\n */\nexport default async function fetch(url: RequestInfo, init?: RequestInit): Response {\n const response = await nodeFetch(url, init)\n return response\n}\n\n/**\n * A fetch function to use with Shopify services. The function ensures the right\n * TLS configuragion is used based on the environment in which the service is running\n * (e.g. spin)\n */\nexport async function shopifyFetch(service: Service, url: RequestInfo, init?: RequestInit): Response {\n const response = await nodeFetch(url, {...init, agent: await httpsAgent(service)})\n return response\n}\n"]}
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/http/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,YAAY,CAAA;AACrC,OAAO,SAAS,MAAM,YAAY,CAAA;AAIlC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,KAAK,CAAC,GAAgB,EAAE,IAAkB;IACtE,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAC3C,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAgB,EAAE,IAAkB;IACrE,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,EAAC,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,UAAU,EAAE,EAAC,CAAC,CAAA;IAC3E,OAAO,QAAQ,CAAA;AACjB,CAAC","sourcesContent":["import {httpsAgent} from '../http.js'\nimport nodeFetch from 'node-fetch'\nimport type {RequestInfo, RequestInit} from 'node-fetch'\n\ntype Response = ReturnType<typeof nodeFetch>\n/**\n * An interface that abstracts way node-fetch. When Node has built-in\n * support for \"fetch\" in the standard library, we can drop the node-fetch\n * dependency from here.\n * Note that we are exposing types from \"node-fetch\". The reason being is that\n * they are consistent with the Web API so if we drop node-fetch in the future\n * it won't require changes from the callers.\n * @param url {RequestInfo} This defines the resource that you wish to fetch.\n * @param init {RequestInit} An object containing any custom settings that you want to apply to the request\n * @returns A promise that resolves with the response.\n */\nexport default async function fetch(url: RequestInfo, init?: RequestInit): Response {\n const response = await nodeFetch(url, init)\n return response\n}\n\n/**\n * A fetch function to use with Shopify services. The function ensures the right\n * TLS configuragion is used based on the environment in which the service is running\n * (e.g. spin)\n */\nexport async function shopifyFetch(url: RequestInfo, init?: RequestInit): Response {\n const response = await nodeFetch(url, {...init, agent: await httpsAgent()})\n return response\n}\n"]}
@@ -1,8 +1,6 @@
1
- import { Service } from '../network/service.js';
2
1
  import { GraphQLClient } from 'graphql-request';
3
2
  interface GraphqlClientOptions {
4
3
  url: string;
5
- service: Service;
6
4
  headers: {
7
5
  [key: string]: string;
8
6
  };
@@ -5,7 +5,7 @@ import { GraphQLClient } from 'graphql-request';
5
5
  * the client will interact with.
6
6
  */
7
7
  export async function graphqlClient(options) {
8
- const clientOptions = { agent: await httpsAgent(options.service), headers: options.headers };
8
+ const clientOptions = { agent: await httpsAgent(), headers: options.headers };
9
9
  const client = new GraphQLClient(options.url, clientOptions);
10
10
  return client;
11
11
  }
@@ -1 +1 @@
1
- {"version":3,"file":"graphql.js","sourceRoot":"","sources":["../../src/http/graphql.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,UAAU,EAAC,MAAM,YAAY,CAAA;AACrC,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAA;AAQ7C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAA6B;IAC/D,MAAM,aAAa,GAAG,EAAC,KAAK,EAAE,MAAM,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAC,CAAA;IAC1F,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,aAAa,CAAC,CAAA;IAC5D,OAAO,MAAM,CAAA;AACf,CAAC","sourcesContent":["import {Service} from '../network/service.js'\nimport {httpsAgent} from '../http.js'\nimport {GraphQLClient} from 'graphql-request'\n\ninterface GraphqlClientOptions {\n url: string\n service: Service\n headers: {[key: string]: string}\n}\n\n/**\n * Creates a GraphQLClient instance with the right HTTPs agent baed on the service\n * the client will interact with.\n */\nexport async function graphqlClient(options: GraphqlClientOptions) {\n const clientOptions = {agent: await httpsAgent(options.service), headers: options.headers}\n const client = new GraphQLClient(options.url, clientOptions)\n return client\n}\n"]}
1
+ {"version":3,"file":"graphql.js","sourceRoot":"","sources":["../../src/http/graphql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,YAAY,CAAA;AACrC,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAA;AAO7C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAA6B;IAC/D,MAAM,aAAa,GAAG,EAAC,KAAK,EAAE,MAAM,UAAU,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAC,CAAA;IAC3E,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,aAAa,CAAC,CAAA;IAC5D,OAAO,MAAM,CAAA;AACf,CAAC","sourcesContent":["import {httpsAgent} from '../http.js'\nimport {GraphQLClient} from 'graphql-request'\n\ninterface GraphqlClientOptions {\n url: string\n headers: {[key: string]: string}\n}\n\n/**\n * Creates a GraphQLClient instance with the right HTTPs agent baed on the service\n * the client will interact with.\n */\nexport async function graphqlClient(options: GraphqlClientOptions) {\n const clientOptions = {agent: await httpsAgent(), headers: options.headers}\n const client = new GraphQLClient(options.url, clientOptions)\n return client\n}\n"]}
package/dist/http.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  /// <reference types="node" />
2
- import { Service } from './network/service.js';
3
2
  import https from 'https';
4
3
  export { default as fetch } from './http/fetch.js';
5
4
  export { shopifyFetch } from './http/fetch.js';
@@ -10,7 +9,7 @@ export { default as formData } from './http/formdata.js';
10
9
  * if the service is running in a Spin environment, the attribute "rejectUnauthorized" is
11
10
  * set to false
12
11
  */
13
- export declare function httpsAgent(service: Service): Promise<https.Agent>;
12
+ export declare function httpsAgent(): Promise<https.Agent>;
14
13
  /**
15
14
  * Spin stores the CA certificate in the keychain and it should be used when sending HTTP
16
15
  * requests to Spin instances. However, Node doesn't read certificates from the Keychain
@@ -23,4 +22,4 @@ export declare function httpsAgent(service: Service): Promise<https.Agent>;
23
22
  * @returns {Promise<boolean>} A promise that resolves with a boolean indicating whether
24
23
  * unauthorized requests should be rejected or not.
25
24
  */
26
- export declare function shouldRejectUnauthorizedRequests(service: Service): Promise<boolean>;
25
+ export declare function shouldRejectUnauthorizedRequests(): Promise<boolean>;
package/dist/http.js CHANGED
@@ -1,4 +1,4 @@
1
- import { environmentForService } from './environment/service.js';
1
+ import { serviceEnvironment } from './environment/service.js';
2
2
  import https from 'https';
3
3
  export { default as fetch } from './http/fetch.js';
4
4
  export { shopifyFetch } from './http/fetch.js';
@@ -9,8 +9,8 @@ export { default as formData } from './http/formdata.js';
9
9
  * if the service is running in a Spin environment, the attribute "rejectUnauthorized" is
10
10
  * set to false
11
11
  */
12
- export async function httpsAgent(service) {
13
- return new https.Agent({ rejectUnauthorized: await shouldRejectUnauthorizedRequests(service) });
12
+ export async function httpsAgent() {
13
+ return new https.Agent({ rejectUnauthorized: await shouldRejectUnauthorizedRequests() });
14
14
  }
15
15
  /**
16
16
  * Spin stores the CA certificate in the keychain and it should be used when sending HTTP
@@ -24,7 +24,7 @@ export async function httpsAgent(service) {
24
24
  * @returns {Promise<boolean>} A promise that resolves with a boolean indicating whether
25
25
  * unauthorized requests should be rejected or not.
26
26
  */
27
- export async function shouldRejectUnauthorizedRequests(service) {
28
- return (await environmentForService(service)) !== 'spin';
27
+ export async function shouldRejectUnauthorizedRequests() {
28
+ return (await serviceEnvironment()) !== 'spin';
29
29
  }
30
30
  //# sourceMappingURL=http.js.map
package/dist/http.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,qBAAqB,EAAC,MAAM,0BAA0B,CAAA;AAC9D,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAC,YAAY,EAAC,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,oBAAoB,CAAA;AAEtD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAgB;IAC/C,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC,EAAC,kBAAkB,EAAE,MAAM,gCAAgC,CAAC,OAAO,CAAC,EAAC,CAAC,CAAA;AAC/F,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,gCAAgC,CAAC,OAAgB;IACrE,OAAO,CAAC,MAAM,qBAAqB,CAAC,OAAO,CAAC,CAAC,KAAK,MAAM,CAAA;AAC1D,CAAC","sourcesContent":["import {Service} from './network/service.js'\nimport {environmentForService} from './environment/service.js'\nimport https from 'https'\n\nexport {default as fetch} from './http/fetch.js'\nexport {shopifyFetch} from './http/fetch.js'\nexport {default as formData} from './http/formdata.js'\n\n/**\n * This utility function returns the https.Agent to use for a given service. The agent\n * includes the right configuration based on the service's environment. For example,\n * if the service is running in a Spin environment, the attribute \"rejectUnauthorized\" is\n * set to false\n */\nexport async function httpsAgent(service: Service) {\n return new https.Agent({rejectUnauthorized: await shouldRejectUnauthorizedRequests(service)})\n}\n\n/**\n * Spin stores the CA certificate in the keychain and it should be used when sending HTTP\n * requests to Spin instances. However, Node doesn't read certificates from the Keychain\n * by default, which leads to Shopifolks running into issues that they workaround by setting the\n * NODE_TLS_REJECT_UNAUTHORIZED=0 environment variable, which applies to all the HTTP\n * requests sent from the CLI (context: https://github.com/nodejs/node/issues/39657)\n * This utility function allows controlling the behavior in a per-service level by returning\n * the value of for the \"rejectUnauthorized\" attribute that's used in the https agent.\n *\n * @returns {Promise<boolean>} A promise that resolves with a boolean indicating whether\n * unauthorized requests should be rejected or not.\n */\nexport async function shouldRejectUnauthorizedRequests(service: Service): Promise<boolean> {\n return (await environmentForService(service)) !== 'spin'\n}\n"]}
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kBAAkB,EAAC,MAAM,0BAA0B,CAAA;AAC3D,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAC,YAAY,EAAC,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,oBAAoB,CAAA;AAEtD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC,EAAC,kBAAkB,EAAE,MAAM,gCAAgC,EAAE,EAAC,CAAC,CAAA;AACxF,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,gCAAgC;IACpD,OAAO,CAAC,MAAM,kBAAkB,EAAE,CAAC,KAAK,MAAM,CAAA;AAChD,CAAC","sourcesContent":["import {serviceEnvironment} from './environment/service.js'\nimport https from 'https'\n\nexport {default as fetch} from './http/fetch.js'\nexport {shopifyFetch} from './http/fetch.js'\nexport {default as formData} from './http/formdata.js'\n\n/**\n * This utility function returns the https.Agent to use for a given service. The agent\n * includes the right configuration based on the service's environment. For example,\n * if the service is running in a Spin environment, the attribute \"rejectUnauthorized\" is\n * set to false\n */\nexport async function httpsAgent() {\n return new https.Agent({rejectUnauthorized: await shouldRejectUnauthorizedRequests()})\n}\n\n/**\n * Spin stores the CA certificate in the keychain and it should be used when sending HTTP\n * requests to Spin instances. However, Node doesn't read certificates from the Keychain\n * by default, which leads to Shopifolks running into issues that they workaround by setting the\n * NODE_TLS_REJECT_UNAUTHORIZED=0 environment variable, which applies to all the HTTP\n * requests sent from the CLI (context: https://github.com/nodejs/node/issues/39657)\n * This utility function allows controlling the behavior in a per-service level by returning\n * the value of for the \"rejectUnauthorized\" attribute that's used in the https agent.\n *\n * @returns {Promise<boolean>} A promise that resolves with a boolean indicating whether\n * unauthorized requests should be rejected or not.\n */\nexport async function shouldRejectUnauthorizedRequests(): Promise<boolean> {\n return (await serviceEnvironment()) !== 'spin'\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -13,6 +13,7 @@ export * as github from './github.js';
13
13
  export * as haiku from './haiku.js';
14
14
  export * as http from './http.js';
15
15
  export * as id from './id.js';
16
+ export * as log from './log.js';
16
17
  export * as npm from './npm.js';
17
18
  export * as os from './os.js';
18
19
  export * as output from './output.js';
package/dist/index.js CHANGED
@@ -13,6 +13,7 @@ export * as github from './github.js';
13
13
  export * as haiku from './haiku.js';
14
14
  export * as http from './http.js';
15
15
  export * as id from './id.js';
16
+ export * as log from './log.js';
16
17
  export * as npm from './npm.js';
17
18
  export * as os from './os.js';
18
19
  export * as output from './output.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,gBAAgB,CAAA;AACnD,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAC/C,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,OAAO,MAAM,SAAS,CAAA;AAClC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,YAAY,MAAM,qBAAqB,CAAA;AACnD,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA","sourcesContent":["export {default as constants} from './constants.js'\nexport * as abort from './abort.js'\nexport * as analytics from './analytics.js'\nexport * as api from './api.js'\nexport * as array from './array.js'\nexport * as cli from './cli.js'\nexport * as environment from './environment.js'\nexport * as error from './error.js'\nexport * as fastify from 'fastify'\nexport * as file from './file.js'\nexport * as git from './git.js'\nexport * as github from './github.js'\nexport * as haiku from './haiku.js'\nexport * as http from './http.js'\nexport * as id from './id.js'\nexport * as npm from './npm.js'\nexport * as os from './os.js'\nexport * as output from './output.js'\nexport * as path from './path.js'\nexport * as plugins from './plugins.js'\nexport * as port from './port.js'\nexport * as schema from './schema.js'\nexport * as semver from './semver.js'\nexport * as session from './session.js'\nexport * as store from './store.js'\nexport * as string from './string.js'\nexport * as system from './system.js'\nexport * as template from './template.js'\nexport * as toml from './toml.js'\nexport * as ui from './ui.js'\nexport * as version from './version.js'\nexport * as vscode from './vscode.js'\nexport * as yaml from './yaml.js'\nexport * as outputMocker from './testing/output.js'\nexport * as metadata from './metadata.js'\nexport * as monorail from './monorail.js'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,gBAAgB,CAAA;AACnD,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAC/C,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,OAAO,MAAM,SAAS,CAAA;AAClC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,YAAY,MAAM,qBAAqB,CAAA;AACnD,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA","sourcesContent":["export {default as constants} from './constants.js'\nexport * as abort from './abort.js'\nexport * as analytics from './analytics.js'\nexport * as api from './api.js'\nexport * as array from './array.js'\nexport * as cli from './cli.js'\nexport * as environment from './environment.js'\nexport * as error from './error.js'\nexport * as fastify from 'fastify'\nexport * as file from './file.js'\nexport * as git from './git.js'\nexport * as github from './github.js'\nexport * as haiku from './haiku.js'\nexport * as http from './http.js'\nexport * as id from './id.js'\nexport * as log from './log.js'\nexport * as npm from './npm.js'\nexport * as os from './os.js'\nexport * as output from './output.js'\nexport * as path from './path.js'\nexport * as plugins from './plugins.js'\nexport * as port from './port.js'\nexport * as schema from './schema.js'\nexport * as semver from './semver.js'\nexport * as session from './session.js'\nexport * as store from './store.js'\nexport * as string from './string.js'\nexport * as system from './system.js'\nexport * as template from './template.js'\nexport * as toml from './toml.js'\nexport * as ui from './ui.js'\nexport * as version from './version.js'\nexport * as vscode from './vscode.js'\nexport * as yaml from './yaml.js'\nexport * as outputMocker from './testing/output.js'\nexport * as metadata from './metadata.js'\nexport * as monorail from './monorail.js'\n"]}
package/dist/log.d.ts ADDED
@@ -0,0 +1,21 @@
1
+ /// <reference types="node" />
2
+ import { Transform, TransformCallback, TransformOptions } from 'node:stream';
3
+ export declare class LinesTruncatorTransformer extends Transform {
4
+ readonly maxFileSize: number;
5
+ linesToRetain: string[];
6
+ lastLineCompleted: boolean;
7
+ constructor(maxFileSize: number, opts?: TransformOptions);
8
+ _transform(chunk: unknown, encoding: BufferEncoding, callback: TransformCallback): void;
9
+ _flush(callback: TransformCallback): void;
10
+ calculateNumLinesToRetain(): number;
11
+ completeLastLine(tokens: string[]): void;
12
+ }
13
+ export declare function initiateLogging(options?: {
14
+ logDir?: string;
15
+ override?: boolean;
16
+ }): Promise<void>;
17
+ export declare function closeLogging(): void;
18
+ export declare function logToFile(message: string, logLevel: string): void;
19
+ export declare function pageLogs({ lastCommand }: {
20
+ lastCommand: boolean;
21
+ }): Promise<void>;
package/dist/log.js ADDED
@@ -0,0 +1,155 @@
1
+ import { isUnitTest } from './environment/local.js';
2
+ import constants from './constants.js';
3
+ import { generateRandomUUID } from './id.js';
4
+ import { mkdirSync as fileMkdirSync, sizeSync as fileSizeSync, touchSync as fileTouchSync, readSync as fileReadSync, } from './file.js';
5
+ import { join as pathJoin } from './path.js';
6
+ import { consoleLog } from './output.js';
7
+ import { page } from './system.js';
8
+ import { promisify } from 'node:util';
9
+ import { Stream, Transform } from 'node:stream';
10
+ import { createWriteStream, createReadStream, unlinkSync } from 'node:fs';
11
+ import { EOL } from 'node:os';
12
+ const logFileName = 'shopify.cli.log';
13
+ const maxLogFileSize = 5 * 1024 * 1024;
14
+ let logFileStream;
15
+ let commandUuid;
16
+ let logFilePath;
17
+ export class LinesTruncatorTransformer extends Transform {
18
+ constructor(maxFileSize, opts) {
19
+ super(opts);
20
+ this.maxFileSize = maxFileSize;
21
+ this.linesToRetain = [];
22
+ this.lastLineCompleted = true;
23
+ }
24
+ _transform(chunk, encoding, callback) {
25
+ const tokens = chunk.toString().split(EOL);
26
+ this.completeLastLine(tokens);
27
+ // last splitted token will be an empty string when last character is a breakline
28
+ this.lastLineCompleted = tokens[tokens.length - 1] === '';
29
+ if (this.lastLineCompleted) {
30
+ tokens.pop();
31
+ }
32
+ this.linesToRetain = this.linesToRetain.concat(tokens);
33
+ const numLinesToRetain = this.calculateNumLinesToRetain();
34
+ if (this.linesToRetain.length > numLinesToRetain) {
35
+ this.linesToRetain = this.linesToRetain.splice(this.linesToRetain.length - numLinesToRetain);
36
+ }
37
+ callback();
38
+ }
39
+ _flush(callback) {
40
+ this.push(this.linesToRetain.join(EOL));
41
+ callback();
42
+ }
43
+ // Lines retained length average is used so the number of lines depends on the length of them
44
+ calculateNumLinesToRetain() {
45
+ return Math.floor(this.maxFileSize /
46
+ (this.linesToRetain.map((line) => line.length).reduce((l1, l2) => l1 + l2, 0) / this.linesToRetain.length));
47
+ }
48
+ completeLastLine(tokens) {
49
+ if (this.lastLineCompleted) {
50
+ return;
51
+ }
52
+ const remainingToken = tokens.shift() ?? '';
53
+ const incompleteToken = this.linesToRetain[this.linesToRetain.length - 1] ?? '';
54
+ this.linesToRetain[this.linesToRetain.length - 1] = incompleteToken.concat(remainingToken);
55
+ }
56
+ }
57
+ export async function initiateLogging(options = {}) {
58
+ if (isUnitTest())
59
+ return;
60
+ commandUuid = generateRandomUUID();
61
+ logFilePath = getLogFilePath(options);
62
+ await truncateLogs(logFilePath);
63
+ logFileStream = createWriteStream(logFilePath, { flags: 'a' });
64
+ }
65
+ export function closeLogging() {
66
+ if (logFileExists()) {
67
+ logFileStream.end();
68
+ }
69
+ }
70
+ // DO NOT USE THIS FUNCTION DIRECTLY under normal circumstances.
71
+ // It is exported purely for use in cases where output is already being logged
72
+ // to the terminal but is not reflected in the logfile, e.g. Listr output.
73
+ export function logToFile(message, logLevel) {
74
+ // If file logging hasn't been initiated, skip it
75
+ if (!logFileExists())
76
+ return;
77
+ const timestamp = new Date().toISOString();
78
+ const logContents = `[${timestamp} ${commandUuid} ${logLevel}]: ${message}\n`;
79
+ logFileStream.write(logContents);
80
+ }
81
+ export async function pageLogs({ lastCommand }) {
82
+ const logDir = constants.paths.directories.cache.path();
83
+ const logFile = pathJoin(logDir, logFileName);
84
+ // Ensure file exists in case they deleted it or something
85
+ fileTouchSync(logFile);
86
+ if (lastCommand) {
87
+ printLastCommand(logFile);
88
+ }
89
+ else {
90
+ await page(logFile);
91
+ }
92
+ }
93
+ function getLogFilePath(options = {}) {
94
+ if (!logFilePath || options.override) {
95
+ const logDir = options.logDir || constants.paths.directories.cache.path();
96
+ fileMkdirSync(logDir);
97
+ logFilePath = pathJoin(logDir, logFileName);
98
+ fileTouchSync(logFilePath);
99
+ }
100
+ return logFilePath;
101
+ }
102
+ // Shaves off older log lines if logs are over maxLogFileSize long.
103
+ async function truncateLogs(logFile) {
104
+ if (fileSizeSync(logFile) < maxLogFileSize) {
105
+ return;
106
+ }
107
+ const tmpLogFile = logFile.concat('.tmp');
108
+ const truncateLines = new LinesTruncatorTransformer(maxLogFileSize);
109
+ const pipeline = promisify(Stream.pipeline);
110
+ await pipeline(createReadStream(logFile), truncateLines, createWriteStream(tmpLogFile));
111
+ await pipeline(createReadStream(tmpLogFile), createWriteStream(logFile));
112
+ unlinkSync(tmpLogFile);
113
+ }
114
+ function logFileExists() {
115
+ return Boolean(logFileStream);
116
+ }
117
+ function printLastCommand(logFile) {
118
+ const contents = fileReadSync(logFile).split('\n');
119
+ const uuids = contents
120
+ .map(logfileLineUUID)
121
+ .filter((uuid) => uuid)
122
+ .reverse();
123
+ // 2nd unique UUID, because the currently running command will be the 1st
124
+ const relevantUuid = Array.from(new Set(uuids))[1];
125
+ if (relevantUuid) {
126
+ consoleLog(relevantLines(contents, relevantUuid).join('\n'));
127
+ }
128
+ }
129
+ function relevantLines(contents, relevantUuid) {
130
+ // We run through the file line by line, keeping track of the most recently
131
+ // encountered UUID.
132
+ //
133
+ // If the current line has a UUID, it's a new logged unit and should be
134
+ // considered. Otherwise, the line is related to the most recent UUID.
135
+ let mostRecentUuid = '';
136
+ return contents.filter((line) => {
137
+ const currentUuid = logfileLineUUID(line) || mostRecentUuid;
138
+ mostRecentUuid = currentUuid;
139
+ return currentUuid === relevantUuid;
140
+ });
141
+ }
142
+ function logfileLineUUID(line) {
143
+ // Log lines look like:
144
+ //
145
+ // timestamp UUID contents
146
+ // ===========================================================================================
147
+ // [2022-07-20T08:51:40.296Z 5288e1da-a06a-4f96-b1a6-e34fcdd7b416 DEBUG]: Running command logs
148
+ // ===========================================================================================
149
+ //
150
+ // There may be subsequent lines if the contents section is multi-line.
151
+ //
152
+ const match = line.match(/^\[\S+ ([0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}) [A-Z]+\]/);
153
+ return match && match[1];
154
+ }
155
+ //# sourceMappingURL=log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.js","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"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","sourcesContent":["import {isUnitTest} from './environment/local.js'\nimport constants from './constants.js'\nimport {generateRandomUUID} from './id.js'\nimport {\n mkdirSync as fileMkdirSync,\n sizeSync as fileSizeSync,\n touchSync as fileTouchSync,\n readSync as fileReadSync,\n} from './file.js'\nimport {join as pathJoin} from './path.js'\nimport {consoleLog} from './output.js'\nimport {page} from './system.js'\nimport {promisify} from 'node:util'\nimport {Stream, Transform, TransformCallback, TransformOptions} from 'node:stream'\nimport {WriteStream, createWriteStream, createReadStream, unlinkSync} from 'node:fs'\nimport {EOL} from 'node:os'\n\nconst logFileName = 'shopify.cli.log'\nconst maxLogFileSize = 5 * 1024 * 1024\nlet logFileStream: WriteStream\nlet commandUuid: string\nlet logFilePath: string\nexport class LinesTruncatorTransformer extends Transform {\n linesToRetain: string[] = []\n lastLineCompleted = true\n\n constructor(readonly maxFileSize: number, opts?: TransformOptions) {\n super(opts)\n }\n\n _transform(chunk: unknown, encoding: BufferEncoding, callback: TransformCallback): void {\n const tokens = (chunk as string).toString().split(EOL)\n\n this.completeLastLine(tokens)\n // last splitted token will be an empty string when last character is a breakline\n this.lastLineCompleted = tokens[tokens.length - 1] === ''\n if (this.lastLineCompleted) {\n tokens.pop()\n }\n this.linesToRetain = this.linesToRetain.concat(tokens)\n\n const numLinesToRetain = this.calculateNumLinesToRetain()\n if (this.linesToRetain.length > numLinesToRetain) {\n this.linesToRetain = this.linesToRetain.splice(this.linesToRetain.length - numLinesToRetain)\n }\n callback()\n }\n\n _flush(callback: TransformCallback): void {\n this.push(this.linesToRetain.join(EOL))\n callback()\n }\n\n // Lines retained length average is used so the number of lines depends on the length of them\n calculateNumLinesToRetain() {\n return Math.floor(\n this.maxFileSize /\n (this.linesToRetain.map((line) => line.length).reduce((l1, l2) => l1 + l2, 0) / this.linesToRetain.length),\n )\n }\n\n completeLastLine(tokens: string[]) {\n if (this.lastLineCompleted) {\n return\n }\n\n const remainingToken = tokens.shift() ?? ''\n const incompleteToken = this.linesToRetain[this.linesToRetain.length - 1] ?? ''\n this.linesToRetain[this.linesToRetain.length - 1] = incompleteToken.concat(remainingToken)\n }\n}\n\nexport async function initiateLogging(options: {logDir?: string; override?: boolean} = {}) {\n if (isUnitTest()) return\n commandUuid = generateRandomUUID()\n logFilePath = getLogFilePath(options)\n await truncateLogs(logFilePath)\n logFileStream = createWriteStream(logFilePath, {flags: 'a'})\n}\n\nexport function closeLogging() {\n if (logFileExists()) {\n logFileStream.end()\n }\n}\n\n// DO NOT USE THIS FUNCTION DIRECTLY under normal circumstances.\n// It is exported purely for use in cases where output is already being logged\n// to the terminal but is not reflected in the logfile, e.g. Listr output.\nexport function logToFile(message: string, logLevel: string): void {\n // If file logging hasn't been initiated, skip it\n if (!logFileExists()) return\n const timestamp = new Date().toISOString()\n const logContents = `[${timestamp} ${commandUuid} ${logLevel}]: ${message}\\n`\n logFileStream.write(logContents)\n}\n\nexport async function pageLogs({lastCommand}: {lastCommand: boolean}) {\n const logDir = constants.paths.directories.cache.path()\n const logFile = pathJoin(logDir, logFileName)\n // Ensure file exists in case they deleted it or something\n fileTouchSync(logFile)\n if (lastCommand) {\n printLastCommand(logFile)\n } else {\n await page(logFile)\n }\n}\n\nfunction getLogFilePath(options: {logDir?: string; override?: boolean} = {}) {\n if (!logFilePath || options.override) {\n const logDir = options.logDir || constants.paths.directories.cache.path()\n fileMkdirSync(logDir)\n logFilePath = pathJoin(logDir, logFileName)\n fileTouchSync(logFilePath)\n }\n\n return logFilePath\n}\n\n// Shaves off older log lines if logs are over maxLogFileSize long.\nasync function truncateLogs(logFile: string) {\n if (fileSizeSync(logFile) < maxLogFileSize) {\n return\n }\n const tmpLogFile = logFile.concat('.tmp')\n const truncateLines = new LinesTruncatorTransformer(maxLogFileSize)\n const pipeline = promisify(Stream.pipeline)\n await pipeline(createReadStream(logFile), truncateLines, createWriteStream(tmpLogFile))\n await pipeline(createReadStream(tmpLogFile), createWriteStream(logFile))\n unlinkSync(tmpLogFile)\n}\n\nfunction logFileExists(): boolean {\n return Boolean(logFileStream)\n}\n\nfunction printLastCommand(logFile: string): void {\n const contents = fileReadSync(logFile).split('\\n')\n const uuids = contents\n .map(logfileLineUUID)\n .filter((uuid) => uuid)\n .reverse()\n // 2nd unique UUID, because the currently running command will be the 1st\n const relevantUuid = Array.from(new Set(uuids))[1]\n if (relevantUuid) {\n consoleLog(relevantLines(contents, relevantUuid).join('\\n'))\n }\n}\n\nfunction relevantLines(contents: string[], relevantUuid: string): string[] {\n // We run through the file line by line, keeping track of the most recently\n // encountered UUID.\n //\n // If the current line has a UUID, it's a new logged unit and should be\n // considered. Otherwise, the line is related to the most recent UUID.\n let mostRecentUuid = ''\n return contents.filter((line: string) => {\n const currentUuid = logfileLineUUID(line) || mostRecentUuid\n mostRecentUuid = currentUuid\n return currentUuid === relevantUuid\n })\n}\n\nfunction logfileLineUUID(line: string): string | null {\n // Log lines look like:\n //\n // timestamp UUID contents\n // ===========================================================================================\n // [2022-07-20T08:51:40.296Z 5288e1da-a06a-4f96-b1a6-e34fcdd7b416 DEBUG]: Running command logs\n // ===========================================================================================\n //\n // There may be subsequent lines if the contents section is multi-line.\n //\n const match = line.match(/^\\[\\S+ ([0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}) [A-Z]+\\]/)\n return match && match[1]!\n}\n"]}
@@ -1,5 +1,6 @@
1
1
  import { Command, Interfaces } from '@oclif/core';
2
- export default abstract class extends Command {
2
+ declare abstract class BaseCommand extends Command {
3
+ static analyticsNameOverride(): string | undefined;
3
4
  catch(error: Error & {
4
5
  exitCode?: number | undefined;
5
6
  }): Promise<void>;
@@ -11,6 +12,7 @@ export default abstract class extends Command {
11
12
  [name: string]: any;
12
13
  }>(options?: Interfaces.Input<TFlags> | undefined, argv?: string[] | undefined): Promise<Interfaces.ParserOutput<TFlags, TArgs>>;
13
14
  }
15
+ export default BaseCommand;
14
16
  export declare function addFromParsedFlags(flags: {
15
17
  path?: string;
16
18
  verbose?: boolean;