@shopify/cli-kit 3.6.2 → 3.9.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 (146) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +61 -0
  3. package/dist/analytics.d.ts +11 -1
  4. package/dist/analytics.js +33 -23
  5. package/dist/analytics.js.map +1 -1
  6. package/dist/api/admin.js.map +1 -1
  7. package/dist/api/common.d.ts +1 -1
  8. package/dist/api/common.js +1 -1
  9. package/dist/api/common.js.map +1 -1
  10. package/dist/api/graphql/extension_specifications.js.map +1 -1
  11. package/dist/api/graphql/functions/app_function_set.d.ts +9 -23
  12. package/dist/api/graphql/functions/app_function_set.js +18 -27
  13. package/dist/api/graphql/functions/app_function_set.js.map +1 -1
  14. package/dist/api/graphql/functions/upload_url_generate.d.ts +12 -0
  15. package/dist/api/graphql/functions/upload_url_generate.js +11 -0
  16. package/dist/api/graphql/functions/upload_url_generate.js.map +1 -0
  17. package/dist/api/graphql/get_urls.d.ts +10 -0
  18. package/dist/api/graphql/get_urls.js +10 -0
  19. package/dist/api/graphql/get_urls.js.map +1 -0
  20. package/dist/api/graphql/index.d.ts +19 -14
  21. package/dist/api/graphql/index.js +19 -14
  22. package/dist/api/graphql/index.js.map +1 -1
  23. package/dist/api/graphql/update_draft.js.map +1 -1
  24. package/dist/api/graphql/update_urls.d.ts +2 -2
  25. package/dist/api/graphql/update_urls.js +2 -2
  26. package/dist/api/graphql/update_urls.js.map +1 -1
  27. package/dist/array.d.ts +1 -1
  28. package/dist/constants.d.ts +3 -1
  29. package/dist/constants.js +3 -1
  30. package/dist/constants.js.map +1 -1
  31. package/dist/content-tokens.d.ts +44 -0
  32. package/dist/content-tokens.js +103 -0
  33. package/dist/content-tokens.js.map +1 -0
  34. package/dist/environment/local.d.ts +19 -2
  35. package/dist/environment/local.js +45 -5
  36. package/dist/environment/local.js.map +1 -1
  37. package/dist/environment/utilities.d.ts +4 -0
  38. package/dist/environment/utilities.js +9 -0
  39. package/dist/environment/utilities.js.map +1 -1
  40. package/dist/error.d.ts +4 -4
  41. package/dist/error.js +16 -4
  42. package/dist/error.js.map +1 -1
  43. package/dist/file.d.ts +9 -1
  44. package/dist/file.js +15 -2
  45. package/dist/file.js.map +1 -1
  46. package/dist/git.js.map +1 -1
  47. package/dist/github.js.map +1 -1
  48. package/dist/index.d.ts +1 -0
  49. package/dist/index.js +1 -0
  50. package/dist/index.js.map +1 -1
  51. package/dist/metadata.d.ts +180 -12
  52. package/dist/metadata.js +39 -6
  53. package/dist/metadata.js.map +1 -1
  54. package/dist/monorail.d.ts +48 -1
  55. package/dist/monorail.js +2 -1
  56. package/dist/monorail.js.map +1 -1
  57. package/dist/node/archiver.js +1 -0
  58. package/dist/node/archiver.js.map +1 -1
  59. package/dist/node/base-command.d.ts +11 -1
  60. package/dist/node/base-command.js +19 -4
  61. package/dist/node/base-command.js.map +1 -1
  62. package/dist/node/checksum.js.map +1 -1
  63. package/dist/node/cli.js +2 -2
  64. package/dist/node/cli.js.map +1 -1
  65. package/dist/node/dot-env.d.ts +9 -0
  66. package/dist/node/dot-env.js +31 -0
  67. package/dist/node/dot-env.js.map +1 -1
  68. package/dist/node/error-handler.d.ts +14 -2
  69. package/dist/node/error-handler.js +58 -13
  70. package/dist/node/error-handler.js.map +1 -1
  71. package/dist/node/hooks/prerun.js +1 -1
  72. package/dist/node/hooks/prerun.js.map +1 -1
  73. package/dist/node/node-package-manager.d.ts +12 -18
  74. package/dist/node/node-package-manager.js +23 -14
  75. package/dist/node/node-package-manager.js.map +1 -1
  76. package/dist/node/ruby.js +2 -1
  77. package/dist/node/ruby.js.map +1 -1
  78. package/dist/output.d.ts +22 -43
  79. package/dist/output.js +31 -91
  80. package/dist/output.js.map +1 -1
  81. package/dist/path.d.ts +1 -0
  82. package/dist/plugins/tunnel.d.ts +40 -0
  83. package/dist/plugins/tunnel.js +11 -0
  84. package/dist/plugins/tunnel.js.map +1 -0
  85. package/dist/plugins.d.ts +11 -13
  86. package/dist/plugins.js +0 -1
  87. package/dist/plugins.js.map +1 -1
  88. package/dist/session/authorize.js +1 -1
  89. package/dist/session/authorize.js.map +1 -1
  90. package/dist/session/exchange.js +1 -2
  91. package/dist/session/exchange.js.map +1 -1
  92. package/dist/session/post-auth.js +7 -1
  93. package/dist/session/post-auth.js.map +1 -1
  94. package/dist/session/redirect-listener.js +6 -5
  95. package/dist/session/redirect-listener.js.map +1 -1
  96. package/dist/session/validate.js.map +1 -1
  97. package/dist/session.js +1 -1
  98. package/dist/session.js.map +1 -1
  99. package/dist/store.d.ts +4 -2
  100. package/dist/store.js +3 -4
  101. package/dist/store.js.map +1 -1
  102. package/dist/string.d.ts +1 -0
  103. package/dist/string.js +3 -0
  104. package/dist/string.js.map +1 -1
  105. package/dist/system.d.ts +2 -2
  106. package/dist/testing/output.js +6 -6
  107. package/dist/testing/output.js.map +1 -1
  108. package/dist/tsconfig.tsbuildinfo +1 -1
  109. package/dist/typing/deep-required.d.ts +12 -0
  110. package/dist/typing/deep-required.js +2 -0
  111. package/dist/typing/deep-required.js.map +1 -0
  112. package/dist/typing/pick-by-prefix.d.ts +12 -0
  113. package/dist/typing/pick-by-prefix.js +2 -0
  114. package/dist/typing/pick-by-prefix.js.map +1 -0
  115. package/dist/ui/executor.d.ts +14 -0
  116. package/dist/ui/executor.js +88 -0
  117. package/dist/ui/executor.js.map +1 -0
  118. package/dist/ui/inquirer/autocomplete.d.ts +11 -0
  119. package/dist/ui/inquirer/autocomplete.js +105 -0
  120. package/dist/ui/inquirer/autocomplete.js.map +1 -0
  121. package/dist/ui/inquirer/input.d.ts +16 -0
  122. package/dist/ui/inquirer/input.js +46 -0
  123. package/dist/ui/inquirer/input.js.map +1 -0
  124. package/dist/ui/inquirer/password.d.ts +7 -0
  125. package/dist/ui/inquirer/password.js +8 -0
  126. package/dist/ui/inquirer/password.js.map +1 -0
  127. package/dist/ui/inquirer/select.d.ts +14 -0
  128. package/dist/ui/inquirer/select.js +27 -0
  129. package/dist/ui/inquirer/select.js.map +1 -0
  130. package/dist/ui.d.ts +12 -23
  131. package/dist/ui.js +14 -61
  132. package/dist/ui.js.map +1 -1
  133. package/dist/version.d.ts +1 -0
  134. package/package.json +23 -13
  135. package/dist/api/graphql/functions/module_upload_url_generate.d.ts +0 -18
  136. package/dist/api/graphql/functions/module_upload_url_generate.js +0 -17
  137. package/dist/api/graphql/functions/module_upload_url_generate.js.map +0 -1
  138. package/dist/ui/autocomplete.d.ts +0 -7
  139. package/dist/ui/autocomplete.js +0 -43
  140. package/dist/ui/autocomplete.js.map +0 -1
  141. package/dist/ui/input.d.ts +0 -7
  142. package/dist/ui/input.js +0 -48
  143. package/dist/ui/input.js.map +0 -1
  144. package/dist/ui/select.d.ts +0 -6
  145. package/dist/ui/select.js +0 -30
  146. package/dist/ui/select.js.map +0 -1
@@ -1,18 +1,33 @@
1
1
  import { errorHandler, registerCleanBugsnagErrorsFromWithinPlugins } from './error-handler.js';
2
- import { isDebug } from '../environment/local.js';
2
+ import { isDevelopment } from '../environment/local.js';
3
+ import { addPublic } from '../metadata.js';
4
+ import { hashString } from '../string.js';
3
5
  import { Command } from '@oclif/core';
4
6
  // eslint-disable-next-line import/no-anonymous-default-export
5
7
  export default class extends Command {
6
8
  async catch(error) {
7
- errorHandler(error, this.config);
9
+ await errorHandler(error, this.config);
8
10
  }
9
11
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
12
  async init() {
11
- if (!isDebug()) {
13
+ if (!isDevelopment()) {
12
14
  // This function runs just prior to `run`
13
- registerCleanBugsnagErrorsFromWithinPlugins(this.config.plugins);
15
+ await registerCleanBugsnagErrorsFromWithinPlugins(this.config);
14
16
  }
15
17
  return super.init();
16
18
  }
19
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
+ async parse(options, argv) {
21
+ const result = await super.parse(options, argv);
22
+ await addFromParsedFlags(result.flags);
23
+ return result;
24
+ }
25
+ }
26
+ export async function addFromParsedFlags(flags) {
27
+ await addPublic(() => ({
28
+ cmd_all_verbose: flags.verbose,
29
+ cmd_all_path_override: flags.path !== undefined,
30
+ cmd_all_path_override_hash: flags.path === undefined ? undefined : hashString(flags.path),
31
+ }));
17
32
  }
18
33
  //# sourceMappingURL=base-command.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"base-command.js","sourceRoot":"","sources":["../../src/node/base-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,2CAA2C,EAAC,MAAM,oBAAoB,CAAA;AAC5F,OAAO,EAAC,OAAO,EAAC,MAAM,yBAAyB,CAAA;AAC/C,OAAO,EAAC,OAAO,EAAC,MAAM,aAAa,CAAA;AAEnC,8DAA8D;AAC9D,MAAM,CAAC,OAAO,MAAgB,SAAQ,OAAO;IAC3C,KAAK,CAAC,KAAK,CAAC,KAA8C;QACxD,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IAClC,CAAC;IAED,8DAA8D;IACpD,KAAK,CAAC,IAAI;QAClB,IAAI,CAAC,OAAO,EAAE,EAAE;YACd,yCAAyC;YACzC,2CAA2C,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;SACjE;QACD,OAAO,KAAK,CAAC,IAAI,EAAE,CAAA;IACrB,CAAC;CACF","sourcesContent":["import {errorHandler, registerCleanBugsnagErrorsFromWithinPlugins} from './error-handler.js'\nimport {isDebug} from '../environment/local.js'\nimport {Command} from '@oclif/core'\n\n// eslint-disable-next-line import/no-anonymous-default-export\nexport default abstract class extends Command {\n async catch(error: Error & {exitCode?: number | undefined}) {\n errorHandler(error, this.config)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected async init(): Promise<any> {\n if (!isDebug()) {\n // This function runs just prior to `run`\n registerCleanBugsnagErrorsFromWithinPlugins(this.config.plugins)\n }\n return super.init()\n }\n}\n"]}
1
+ {"version":3,"file":"base-command.js","sourceRoot":"","sources":["../../src/node/base-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,2CAA2C,EAAC,MAAM,oBAAoB,CAAA;AAC5F,OAAO,EAAC,aAAa,EAAC,MAAM,yBAAyB,CAAA;AACrD,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAA;AACxC,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAA;AACvC,OAAO,EAAC,OAAO,EAAa,MAAM,aAAa,CAAA;AAE/C,8DAA8D;AAC9D,MAAM,CAAC,OAAO,MAAgB,SAAQ,OAAO;IAC3C,KAAK,CAAC,KAAK,CAAC,KAA8C;QACxD,MAAM,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IACxC,CAAC;IAED,8DAA8D;IACpD,KAAK,CAAC,IAAI;QAClB,IAAI,CAAC,aAAa,EAAE,EAAE;YACpB,yCAAyC;YACzC,MAAM,2CAA2C,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;SAC/D;QACD,OAAO,KAAK,CAAC,IAAI,EAAE,CAAA;IACrB,CAAC;IAED,8DAA8D;IACpD,KAAK,CAAC,KAAK,CACnB,OAA8C,EAC9C,IAA2B;QAE3B,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,KAAK,CAAgB,OAAO,EAAE,IAAI,CAAC,CAAA;QAC9D,MAAM,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACtC,OAAO,MAAM,CAAA;IACf,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,KAAyC;IAChF,MAAM,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC;QACrB,eAAe,EAAE,KAAK,CAAC,OAAO;QAC9B,qBAAqB,EAAE,KAAK,CAAC,IAAI,KAAK,SAAS;QAC/C,0BAA0B,EAAE,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC;KAC1F,CAAC,CAAC,CAAA;AACL,CAAC","sourcesContent":["import {errorHandler, registerCleanBugsnagErrorsFromWithinPlugins} from './error-handler.js'\nimport {isDevelopment} from '../environment/local.js'\nimport {addPublic} from '../metadata.js'\nimport {hashString} from '../string.js'\nimport {Command, Interfaces} from '@oclif/core'\n\n// eslint-disable-next-line import/no-anonymous-default-export\nexport default abstract class extends Command {\n async catch(error: Error & {exitCode?: number | undefined}) {\n await errorHandler(error, this.config)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected async init(): Promise<any> {\n if (!isDevelopment()) {\n // This function runs just prior to `run`\n await registerCleanBugsnagErrorsFromWithinPlugins(this.config)\n }\n return super.init()\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected async parse<TFlags extends {path?: string; verbose?: boolean}, TArgs extends {[name: string]: any}>(\n options?: Interfaces.Input<TFlags> | undefined,\n argv?: string[] | undefined,\n ): Promise<Interfaces.ParserOutput<TFlags, TArgs>> {\n const result = await super.parse<TFlags, TArgs>(options, argv)\n await addFromParsedFlags(result.flags)\n return result\n }\n}\n\nexport async function addFromParsedFlags(flags: {path?: string; verbose?: boolean}) {\n await addPublic(() => ({\n cmd_all_verbose: flags.verbose,\n cmd_all_path_override: flags.path !== undefined,\n cmd_all_path_override_hash: flags.path === undefined ? undefined : hashString(flags.path),\n }))\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"checksum.js","sourceRoot":"","sources":["../../src/node/checksum.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,YAAY,CAAA;AAChC,OAAO,EAAC,KAAK,EAAC,MAAM,aAAa,CAAA;AACjC,OAAO,EAAC,KAAK,EAAE,KAAK,EAAC,MAAM,cAAc,CAAA;AACzC,OAAO,OAAO,MAAM,UAAU,CAAA;AAE9B;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,EAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAgD,EAAE,EAAE;IAC3G,OAAO,IAAI,KAAK,CAAC,qBAAqB,IAAI,qCAAqC,QAAQ,aAAa,GAAG,GAAG,CAAC,CAAA;AAC7G,CAAC,CAAA;AACD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,EAAC,IAAI,EAAE,UAAU,EAAqC;IACtF,KAAK,CAAC,wBAAwB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,uBAAuB,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE,CAAC,CAAA;IACrG,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,CAAA;IAC3C,MAAM,WAAW,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,CAAA;IAC5C,MAAM,YAAY,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;IAC9C,IAAI,CAAC,CAAC,YAAY,KAAK,SAAS,CAAC,EAAE;QACjC,MAAM,oBAAoB,CAAC;YACzB,IAAI;YACJ,GAAG,EAAE,SAAS;YACd,QAAQ,EAAE,YAAY;SACvB,CAAC,CAAA;KACH;AACH,CAAC","sourcesContent":["import {fetch} from '../http.js'\nimport {Abort} from '../error.js'\nimport {debug, token} from '../output.js'\nimport md5File from 'md5-file'\n\n/**\n * An error that's thrown when a file's MD5 doesn't match the expected value.\n * @param options An options object that includes the file path, and the expected and actual MD5.\n * @returns An instance of Abort.\n */\nexport const InvalidChecksumError = ({file, expected, got}: {file: string; expected: string; got: string}) => {\n return new Abort(`The validation of ${file} failed. We expected the checksum ${expected}, but got ${got})`)\n}\n/**\n * Given a local file and a URL pointing to a remote file representing the MD5 of a local file,\n * it validates the authenticity of the binary using an MD5 checksum.\n * @param options: The file to validate and the URL that points to the file containing the MD5.\n */\nexport async function validateMD5({file, md5FileURL}: {file: string; md5FileURL: string}) {\n debug(`Checking MD5 of file ${token.path(file)} against the MD5 in ${token.link('URL', md5FileURL)}`)\n const md5Digest = await md5File(file)\n const md5Response = await fetch(md5FileURL)\n const md5Contents = await md5Response.text()\n const canonicalMD5 = md5Contents.split(' ')[0]\n if (!(canonicalMD5 === md5Digest)) {\n throw InvalidChecksumError({\n file,\n got: md5Digest,\n expected: canonicalMD5,\n })\n }\n}\n"]}
1
+ {"version":3,"file":"checksum.js","sourceRoot":"","sources":["../../src/node/checksum.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,YAAY,CAAA;AAChC,OAAO,EAAC,KAAK,EAAC,MAAM,aAAa,CAAA;AACjC,OAAO,EAAC,KAAK,EAAE,KAAK,EAAC,MAAM,cAAc,CAAA;AACzC,OAAO,OAAO,MAAM,UAAU,CAAA;AAE9B;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,EAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAgD,EAAE,EAAE;IAC3G,OAAO,IAAI,KAAK,CAAC,qBAAqB,IAAI,qCAAqC,QAAQ,aAAa,GAAG,GAAG,CAAC,CAAA;AAC7G,CAAC,CAAA;AACD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,EAAC,IAAI,EAAE,UAAU,EAAqC;IACtF,KAAK,CAAC,wBAAwB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,uBAAuB,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE,CAAC,CAAA;IACrG,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,CAAA;IAC3C,MAAM,WAAW,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,CAAA;IAC5C,MAAM,YAAY,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAA;IAC/C,IAAI,CAAC,CAAC,YAAY,KAAK,SAAS,CAAC,EAAE;QACjC,MAAM,oBAAoB,CAAC;YACzB,IAAI;YACJ,GAAG,EAAE,SAAS;YACd,QAAQ,EAAE,YAAY;SACvB,CAAC,CAAA;KACH;AACH,CAAC","sourcesContent":["import {fetch} from '../http.js'\nimport {Abort} from '../error.js'\nimport {debug, token} from '../output.js'\nimport md5File from 'md5-file'\n\n/**\n * An error that's thrown when a file's MD5 doesn't match the expected value.\n * @param options An options object that includes the file path, and the expected and actual MD5.\n * @returns An instance of Abort.\n */\nexport const InvalidChecksumError = ({file, expected, got}: {file: string; expected: string; got: string}) => {\n return new Abort(`The validation of ${file} failed. We expected the checksum ${expected}, but got ${got})`)\n}\n/**\n * Given a local file and a URL pointing to a remote file representing the MD5 of a local file,\n * it validates the authenticity of the binary using an MD5 checksum.\n * @param options: The file to validate and the URL that points to the file containing the MD5.\n */\nexport async function validateMD5({file, md5FileURL}: {file: string; md5FileURL: string}) {\n debug(`Checking MD5 of file ${token.path(file)} against the MD5 in ${token.link('URL', md5FileURL)}`)\n const md5Digest = await md5File(file)\n const md5Response = await fetch(md5FileURL)\n const md5Contents = await md5Response.text()\n const canonicalMD5 = md5Contents.split(' ')[0]!\n if (!(canonicalMD5 === md5Digest)) {\n throw InvalidChecksumError({\n file,\n got: md5Digest,\n expected: canonicalMD5,\n })\n }\n}\n"]}
package/dist/node/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // CLI
2
2
  import { findUpAndReadPackageJson } from './node-package-manager.js';
3
3
  import { errorHandler } from './error-handler.js';
4
- import { isDebug } from '../environment/local.js';
4
+ import { isDevelopment } from '../environment/local.js';
5
5
  import constants, { bugsnagApiKey } from '../constants.js';
6
6
  import { moduleDirectory } from '../path.js';
7
7
  import { run, settings, flush } from '@oclif/core';
@@ -12,7 +12,7 @@ import Bugsnag from '@bugsnag/js';
12
12
  * @param module {RunCLIOptions} Options.
13
13
  */
14
14
  export async function runCLI(options) {
15
- if (isDebug()) {
15
+ if (isDevelopment()) {
16
16
  settings.debug = true;
17
17
  }
18
18
  else {
@@ -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,OAAO,EAAC,MAAM,yBAAyB,CAAA;AAC/C,OAAO,SAAS,EAAE,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAA;AACxD,OAAO,EAAC,eAAe,EAAC,MAAM,YAAY,CAAA;AAC1C,OAAO,EAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAC,MAAM,aAAa,CAAA;AAChD,OAAO,OAAO,MAAM,aAAa,CAAA;AAOjC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,OAAsB;IACjD,IAAI,OAAO,EAAE,EAAE;QACb,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAA;KACtB;SAAM;QACL,OAAO,CAAC,KAAK,CAAC;YACZ,OAAO,EAAE,MAAM;YACf,MAAM,EAAE,aAAa;YACrB,MAAM,EAAE,IAAI;YACZ,UAAU,EAAE,MAAM,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE;YAC7C,iBAAiB,EAAE,KAAK;YACxB,gBAAgB,EAAE,KAAK;SACxB,CAAC,CAAA;KACH;IAED,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;AACnE,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAsB;IACvD,MAAM,WAAW,GAAG,MAAM,wBAAwB,CAAC,eAAe,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAA;IACtF,8DAA8D;IAC9D,MAAM,WAAW,GAAI,WAAW,CAAC,OAAe,CAAC,IAAc,CAAA;IAC/D,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAA;IACxD,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAA;IACvE,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE;QACpB,MAAM,SAAS,GACb,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,yBAAyB,IAAI,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QACtG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,EAAE,MAAM,CAAC,CAAA;KAC1C;IACD,MAAM,MAAM,CAAC,OAAO,CAAC,CAAA;AACvB,CAAC;AAED,eAAe,MAAM,CAAA","sourcesContent":["// CLI\nimport {findUpAndReadPackageJson} from './node-package-manager.js'\nimport {errorHandler} from './error-handler.js'\nimport {isDebug} from '../environment/local.js'\nimport constants, {bugsnagApiKey} from '../constants.js'\nimport {moduleDirectory} from '../path.js'\nimport {run, settings, flush} from '@oclif/core'\nimport Bugsnag from '@bugsnag/js'\n\ninterface RunCLIOptions {\n /** The value of import.meta.url of the CLI executable module */\n moduleURL: string\n}\n\n/**\n * A function that abstracts away setting up the environment and running\n * a CLI\n * @param module {RunCLIOptions} Options.\n */\nexport async function runCLI(options: RunCLIOptions) {\n if (isDebug()) {\n settings.debug = true\n } else {\n Bugsnag.start({\n appType: 'node',\n apiKey: bugsnagApiKey,\n logger: null,\n appVersion: await constants.versions.cliKit(),\n autoTrackSessions: false,\n autoDetectErrors: false,\n })\n }\n\n run(undefined, options.moduleURL).then(flush).catch(errorHandler)\n}\n\n/**\n * A function for create-x CLIs that automatically runs the \"init\" command.\n * @param options\n */\nexport async function runCreateCLI(options: RunCLIOptions) {\n const packageJson = await findUpAndReadPackageJson(moduleDirectory(options.moduleURL))\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const packageName = (packageJson.content as any).name as string\n const name = packageName.replace('@shopify/create-', '')\n const initIndex = process.argv.findIndex((arg) => arg.includes('init'))\n if (initIndex === -1) {\n const initIndex =\n process.argv.findIndex((arg) => arg.match(new RegExp(`bin(\\\\/|\\\\\\\\)+(create-${name}|dev|run)`))) + 1\n process.argv.splice(initIndex, 0, 'init')\n }\n await runCLI(options)\n}\n\nexport default runCLI\n"]}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/node/cli.ts"],"names":[],"mappings":"AAAA,MAAM;AACN,OAAO,EAAC,wBAAwB,EAAC,MAAM,2BAA2B,CAAA;AAClE,OAAO,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAC,aAAa,EAAC,MAAM,yBAAyB,CAAA;AACrD,OAAO,SAAS,EAAE,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAA;AACxD,OAAO,EAAC,eAAe,EAAC,MAAM,YAAY,CAAA;AAC1C,OAAO,EAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAC,MAAM,aAAa,CAAA;AAChD,OAAO,OAAO,MAAM,aAAa,CAAA;AAOjC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,OAAsB;IACjD,IAAI,aAAa,EAAE,EAAE;QACnB,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAA;KACtB;SAAM;QACL,OAAO,CAAC,KAAK,CAAC;YACZ,OAAO,EAAE,MAAM;YACf,MAAM,EAAE,aAAa;YACrB,MAAM,EAAE,IAAI;YACZ,UAAU,EAAE,MAAM,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE;YAC7C,iBAAiB,EAAE,KAAK;YACxB,gBAAgB,EAAE,KAAK;SACxB,CAAC,CAAA;KACH;IAED,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;AACnE,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAsB;IACvD,MAAM,WAAW,GAAG,MAAM,wBAAwB,CAAC,eAAe,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAA;IACtF,8DAA8D;IAC9D,MAAM,WAAW,GAAI,WAAW,CAAC,OAAe,CAAC,IAAc,CAAA;IAC/D,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAA;IACxD,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAA;IACvE,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE;QACpB,MAAM,SAAS,GACb,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,yBAAyB,IAAI,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QACtG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,EAAE,MAAM,CAAC,CAAA;KAC1C;IACD,MAAM,MAAM,CAAC,OAAO,CAAC,CAAA;AACvB,CAAC;AAED,eAAe,MAAM,CAAA","sourcesContent":["// CLI\nimport {findUpAndReadPackageJson} from './node-package-manager.js'\nimport {errorHandler} from './error-handler.js'\nimport {isDevelopment} from '../environment/local.js'\nimport constants, {bugsnagApiKey} from '../constants.js'\nimport {moduleDirectory} from '../path.js'\nimport {run, settings, flush} from '@oclif/core'\nimport Bugsnag from '@bugsnag/js'\n\ninterface RunCLIOptions {\n /** The value of import.meta.url of the CLI executable module */\n moduleURL: string\n}\n\n/**\n * A function that abstracts away setting up the environment and running\n * a CLI\n * @param module {RunCLIOptions} Options.\n */\nexport async function runCLI(options: RunCLIOptions) {\n if (isDevelopment()) {\n settings.debug = true\n } else {\n Bugsnag.start({\n appType: 'node',\n apiKey: bugsnagApiKey,\n logger: null,\n appVersion: await constants.versions.cliKit(),\n autoTrackSessions: false,\n autoDetectErrors: false,\n })\n }\n\n run(undefined, options.moduleURL).then(flush).catch(errorHandler)\n}\n\n/**\n * A function for create-x CLIs that automatically runs the \"init\" command.\n * @param options\n */\nexport async function runCreateCLI(options: RunCLIOptions) {\n const packageJson = await findUpAndReadPackageJson(moduleDirectory(options.moduleURL))\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const packageName = (packageJson.content as any).name as string\n const name = packageName.replace('@shopify/create-', '')\n const initIndex = process.argv.findIndex((arg) => arg.includes('init'))\n if (initIndex === -1) {\n const initIndex =\n process.argv.findIndex((arg) => arg.match(new RegExp(`bin(\\\\/|\\\\\\\\)+(create-${name}|dev|run)`))) + 1\n process.argv.splice(initIndex, 0, 'init')\n }\n await runCLI(options)\n}\n\nexport default runCLI\n"]}
@@ -31,3 +31,12 @@ export declare function readAndParseDotEnv(path: string): Promise<DotEnvFile>;
31
31
  * @param file {DotEnvFile} .env file to be written.
32
32
  */
33
33
  export declare function writeDotEnv(file: DotEnvFile): Promise<void>;
34
+ /**
35
+ * Given an .env file content, generates a new one with new values
36
+ * without removing already existing lines.
37
+ * @param envFileContent {string | null} .env file contents.
38
+ * @param updatedValues {[key: string]: string}} object containing new env variables values.
39
+ */
40
+ export declare function patchEnvFile(envFileContent: string | null, updatedValues: {
41
+ [key: string]: string | undefined;
42
+ }): string;
@@ -33,4 +33,35 @@ export async function readAndParseDotEnv(path) {
33
33
  export async function writeDotEnv(file) {
34
34
  await writeFile(file.path, stringify(file.variables));
35
35
  }
36
+ /**
37
+ * Given an .env file content, generates a new one with new values
38
+ * without removing already existing lines.
39
+ * @param envFileContent {string | null} .env file contents.
40
+ * @param updatedValues {[key: string]: string}} object containing new env variables values.
41
+ */
42
+ export function patchEnvFile(envFileContent, updatedValues) {
43
+ const outputLines = [];
44
+ const lines = envFileContent === null ? [] : envFileContent.split('\n');
45
+ const alreadyPresentKeys = [];
46
+ const toLine = (key, value) => `${key}=${value}`;
47
+ for (const line of lines) {
48
+ const match = line.match(/^([^=:#]+?)[=:](.*)/);
49
+ let lineToWrite = line;
50
+ if (match) {
51
+ const key = match[1].trim();
52
+ const newValue = updatedValues[key];
53
+ if (newValue) {
54
+ alreadyPresentKeys.push(key);
55
+ lineToWrite = toLine(key, newValue);
56
+ }
57
+ }
58
+ outputLines.push(lineToWrite);
59
+ }
60
+ for (const [patchKey, updatedValue] of Object.entries(updatedValues)) {
61
+ if (!alreadyPresentKeys.includes(patchKey)) {
62
+ outputLines.push(toLine(patchKey, updatedValue));
63
+ }
64
+ }
65
+ return outputLines.join('\n');
66
+ }
36
67
  //# sourceMappingURL=dot-env.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dot-env.js","sourceRoot":"","sources":["../../src/node/dot-env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,aAAa,CAAA;AACjC,OAAO,EAAC,MAAM,EAAE,IAAI,IAAI,QAAQ,EAAE,KAAK,IAAI,SAAS,EAAC,MAAM,YAAY,CAAA;AACvE,OAAO,EAAC,KAAK,EAAE,OAAO,IAAI,aAAa,EAAE,KAAK,EAAC,MAAM,cAAc,CAAA;AACnE,OAAO,EAAC,KAAK,EAAE,SAAS,EAAC,MAAM,SAAS,CAAA;AAExC;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,IAAY,EAAE,EAAE;IAClD,OAAO,IAAI,KAAK,CAAC,2BAA2B,IAAI,kBAAkB,CAAC,CAAA;AACrE,CAAC,CAAA;AAgBD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAAY;IACnD,KAAK,CAAC,aAAa,CAAA,4BAA4B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAClE,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE;QACzB,MAAM,mBAAmB,CAAC,IAAI,CAAC,CAAA;KAChC;IACD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAA;IACpC,OAAO;QACL,IAAI;QACJ,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC;KAC1B,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAgB;IAChD,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAA;AACvD,CAAC","sourcesContent":["import {Abort} from '../error.js'\nimport {exists, read as readFile, write as writeFile} from '../file.js'\nimport {debug, content as outputContent, token} from '../output.js'\nimport {parse, stringify} from 'envfile'\n\n/**\n * Error that's thrown when the .env is not found.\n * @param path {string} Path to the .env file.\n * @returns {Abort} An abort error.\n */\nexport const DotEnvNotFoundError = (path: string) => {\n return new Abort(`The environment file at ${path} does not exist.`)\n}\n\n/**\n * This interface represents a .env file.\n */\nexport interface DotEnvFile {\n /**\n * Path to the .env file.\n */\n path: string\n /**\n * Variables of the .env file.\n */\n variables: {[name: string]: string}\n}\n\n/**\n * Reads and parses a .env file.\n * @param path {string} Path to the .env file\n * @returns {Promise<DotEnvFile>} An in-memory representation of the .env file.\n */\nexport async function readAndParseDotEnv(path: string): Promise<DotEnvFile> {\n debug(outputContent`Reading the .env file at ${token.path(path)}`)\n if (!(await exists(path))) {\n throw DotEnvNotFoundError(path)\n }\n const content = await readFile(path)\n return {\n path,\n variables: parse(content),\n }\n}\n\n/**\n * Writes a .env file to disk.\n * @param file {DotEnvFile} .env file to be written.\n */\nexport async function writeDotEnv(file: DotEnvFile) {\n await writeFile(file.path, stringify(file.variables))\n}\n"]}
1
+ {"version":3,"file":"dot-env.js","sourceRoot":"","sources":["../../src/node/dot-env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,aAAa,CAAA;AACjC,OAAO,EAAC,MAAM,EAAE,IAAI,IAAI,QAAQ,EAAE,KAAK,IAAI,SAAS,EAAC,MAAM,YAAY,CAAA;AACvE,OAAO,EAAC,KAAK,EAAE,OAAO,IAAI,aAAa,EAAE,KAAK,EAAC,MAAM,cAAc,CAAA;AACnE,OAAO,EAAC,KAAK,EAAE,SAAS,EAAC,MAAM,SAAS,CAAA;AAExC;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,IAAY,EAAE,EAAE;IAClD,OAAO,IAAI,KAAK,CAAC,2BAA2B,IAAI,kBAAkB,CAAC,CAAA;AACrE,CAAC,CAAA;AAgBD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAAY;IACnD,KAAK,CAAC,aAAa,CAAA,4BAA4B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAClE,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE;QACzB,MAAM,mBAAmB,CAAC,IAAI,CAAC,CAAA;KAChC;IACD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAA;IACpC,OAAO;QACL,IAAI;QACJ,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC;KAC1B,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAgB;IAChD,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAA;AACvD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAC1B,cAA6B,EAC7B,aAAkD;IAElD,MAAM,WAAW,GAAa,EAAE,CAAA;IAChC,MAAM,KAAK,GAAG,cAAc,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAEvE,MAAM,kBAAkB,GAAa,EAAE,CAAA;IAEvC,MAAM,MAAM,GAAG,CAAC,GAAW,EAAE,KAAc,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,KAAK,EAAE,CAAA;IAEjE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;QACxB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAA;QAC/C,IAAI,WAAW,GAAG,IAAI,CAAA;QAEtB,IAAI,KAAK,EAAE;YACT,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAA;YAC5B,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;YACnC,IAAI,QAAQ,EAAE;gBACZ,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;gBAC5B,WAAW,GAAG,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;aACpC;SACF;QAED,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;KAC9B;IAED,KAAK,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE;QACpE,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;YAC1C,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAA;SACjD;KACF;IAED,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAC/B,CAAC","sourcesContent":["import {Abort} from '../error.js'\nimport {exists, read as readFile, write as writeFile} from '../file.js'\nimport {debug, content as outputContent, token} from '../output.js'\nimport {parse, stringify} from 'envfile'\n\n/**\n * Error that's thrown when the .env is not found.\n * @param path {string} Path to the .env file.\n * @returns {Abort} An abort error.\n */\nexport const DotEnvNotFoundError = (path: string) => {\n return new Abort(`The environment file at ${path} does not exist.`)\n}\n\n/**\n * This interface represents a .env file.\n */\nexport interface DotEnvFile {\n /**\n * Path to the .env file.\n */\n path: string\n /**\n * Variables of the .env file.\n */\n variables: {[name: string]: string}\n}\n\n/**\n * Reads and parses a .env file.\n * @param path {string} Path to the .env file\n * @returns {Promise<DotEnvFile>} An in-memory representation of the .env file.\n */\nexport async function readAndParseDotEnv(path: string): Promise<DotEnvFile> {\n debug(outputContent`Reading the .env file at ${token.path(path)}`)\n if (!(await exists(path))) {\n throw DotEnvNotFoundError(path)\n }\n const content = await readFile(path)\n return {\n path,\n variables: parse(content),\n }\n}\n\n/**\n * Writes a .env file to disk.\n * @param file {DotEnvFile} .env file to be written.\n */\nexport async function writeDotEnv(file: DotEnvFile) {\n await writeFile(file.path, stringify(file.variables))\n}\n\n/**\n * Given an .env file content, generates a new one with new values\n * without removing already existing lines.\n * @param envFileContent {string | null} .env file contents.\n * @param updatedValues {[key: string]: string}} object containing new env variables values.\n */\nexport function patchEnvFile(\n envFileContent: string | null,\n updatedValues: {[key: string]: string | undefined},\n): string {\n const outputLines: string[] = []\n const lines = envFileContent === null ? [] : envFileContent.split('\\n')\n\n const alreadyPresentKeys: string[] = []\n\n const toLine = (key: string, value?: string) => `${key}=${value}`\n\n for (const line of lines) {\n const match = line.match(/^([^=:#]+?)[=:](.*)/)\n let lineToWrite = line\n\n if (match) {\n const key = match[1]!.trim()\n const newValue = updatedValues[key]\n if (newValue) {\n alreadyPresentKeys.push(key)\n lineToWrite = toLine(key, newValue)\n }\n }\n\n outputLines.push(lineToWrite)\n }\n\n for (const [patchKey, updatedValue] of Object.entries(updatedValues)) {\n if (!alreadyPresentKeys.includes(patchKey)) {\n outputLines.push(toLine(patchKey, updatedValue))\n }\n }\n\n return outputLines.join('\\n')\n}\n"]}
@@ -3,6 +3,18 @@ import { Event } from '@bugsnag/js';
3
3
  export declare function errorHandler(error: Error & {
4
4
  exitCode?: number | undefined;
5
5
  }, config?: Interfaces.Config): Promise<never> | undefined;
6
+ /**
7
+ * Sends an error to Bugsnag. This is configured automatically for uncaught errors from CLI commands, but can also be used to manually record an error.
8
+ *
9
+ * @returns the reported error (this may have been tweaked for better reporting), and a bool to indicate if the error was actually submitted or not
10
+ */
11
+ export declare function sendErrorToBugsnag(error: unknown): Promise<{
12
+ reported: false;
13
+ error: unknown;
14
+ } | {
15
+ error: Error;
16
+ reported: true;
17
+ }>;
6
18
  /**
7
19
  * If the given file path comes from within a plugin, return the relative path, plus the plugin name.
8
20
  *
@@ -21,5 +33,5 @@ export declare function cleanStackFrameFilePath({ currentFilePath, projectRoot,
21
33
  * Register a Bugsnag error listener to clean up stack traces for errors within plugin code.
22
34
  *
23
35
  */
24
- export declare function registerCleanBugsnagErrorsFromWithinPlugins(plugins: Interfaces.Plugin[]): Promise<void>;
25
- export declare function addBugsnagMetadata(event: Event): void;
36
+ export declare function registerCleanBugsnagErrorsFromWithinPlugins(config: Interfaces.Config): Promise<void>;
37
+ export declare function addBugsnagMetadata(event: Event, config: Interfaces.Config): Promise<void>;
@@ -1,8 +1,9 @@
1
1
  import { AbortSilent, CancelExecution, mapper as errorMapper, shouldReport as shouldReportError, handler, cleanSingleStackTracePath, } from '../error.js';
2
2
  import { debug, info } from '../output.js';
3
- import { reportEvent } from '../analytics.js';
3
+ import { getEnvironmentData, reportEvent } from '../analytics.js';
4
4
  import * as path from '../path.js';
5
5
  import * as metadata from '../metadata.js';
6
+ import { fanoutHooks } from '../plugins.js';
6
7
  import { settings } from '@oclif/core';
7
8
  import StackTracey from 'stacktracey';
8
9
  import Bugsnag from '@bugsnag/js';
@@ -29,15 +30,23 @@ export function errorHandler(error, config) {
29
30
  }
30
31
  const reportError = async (error, config) => {
31
32
  if (config !== undefined) {
32
- await reportEvent({ config, errorMessage: error.message });
33
+ // Log an analytics event when there's an error
34
+ await reportEvent({ config, errorMessage: error instanceof Error ? error.message : undefined });
33
35
  }
36
+ await sendErrorToBugsnag(error);
37
+ };
38
+ /**
39
+ * Sends an error to Bugsnag. This is configured automatically for uncaught errors from CLI commands, but can also be used to manually record an error.
40
+ *
41
+ * @returns the reported error (this may have been tweaked for better reporting), and a bool to indicate if the error was actually submitted or not
42
+ */
43
+ export async function sendErrorToBugsnag(error) {
34
44
  if (settings.debug || !shouldReportError(error))
35
- return error;
45
+ return { reported: false, error };
36
46
  let reportableError;
37
47
  let stacktrace;
38
48
  let report = false;
39
- // eslint-disable-next-line no-prototype-builtins
40
- if (Error.prototype.isPrototypeOf(error)) {
49
+ if (error instanceof Error) {
41
50
  report = true;
42
51
  reportableError = new Error(error.message);
43
52
  stacktrace = error.stack;
@@ -78,8 +87,8 @@ const reportError = async (error, config) => {
78
87
  });
79
88
  });
80
89
  }
81
- return reportableError;
82
- };
90
+ return { error: reportableError, reported: report };
91
+ }
83
92
  /**
84
93
  * If the given file path comes from within a plugin, return the relative path, plus the plugin name.
85
94
  *
@@ -99,23 +108,23 @@ export function cleanStackFrameFilePath({ currentFilePath, projectRoot, pluginLo
99
108
  * Register a Bugsnag error listener to clean up stack traces for errors within plugin code.
100
109
  *
101
110
  */
102
- export async function registerCleanBugsnagErrorsFromWithinPlugins(plugins) {
111
+ export async function registerCleanBugsnagErrorsFromWithinPlugins(config) {
103
112
  // Bugsnag have their own plug-ins that use this private field
104
113
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
105
114
  const bugsnagConfigProjectRoot = Bugsnag?._client?._config?.projectRoot ?? process.cwd();
106
115
  const projectRoot = path.normalize(bugsnagConfigProjectRoot);
107
- const pluginLocations = await Promise.all(plugins.map(async (plugin) => {
116
+ const pluginLocations = await Promise.all(config.plugins.map(async (plugin) => {
108
117
  const followSymlinks = await realpath(plugin.root);
109
118
  return { name: plugin.name, pluginPath: path.normalize(followSymlinks) };
110
119
  }));
111
- Bugsnag.addOnError((event) => {
120
+ Bugsnag.addOnError(async (event) => {
112
121
  event.errors.forEach((error) => {
113
122
  error.stacktrace.forEach((stackFrame) => {
114
123
  stackFrame.file = cleanStackFrameFilePath({ currentFilePath: stackFrame.file, projectRoot, pluginLocations });
115
124
  });
116
125
  });
117
126
  try {
118
- addBugsnagMetadata(event);
127
+ await addBugsnagMetadata(event, config);
119
128
  // eslint-disable-next-line no-catch-all/no-catch-all
120
129
  }
121
130
  catch (metadataError) {
@@ -123,10 +132,46 @@ export async function registerCleanBugsnagErrorsFromWithinPlugins(plugins) {
123
132
  }
124
133
  });
125
134
  }
126
- export function addBugsnagMetadata(event) {
135
+ export async function addBugsnagMetadata(event, config) {
127
136
  const publicData = metadata.getAllPublic();
137
+ const { commandStartOptions } = metadata.getAllSensitive();
138
+ const { startCommand } = commandStartOptions ?? {};
139
+ const { '@shopify/app': appPublic, ...otherPluginsPublic } = await fanoutHooks(config, 'public_command_metadata', {});
140
+ const environment = getEnvironmentData(config);
141
+ const allMetadata = {
142
+ command: startCommand,
143
+ ...appPublic,
144
+ ...publicData,
145
+ ...environment,
146
+ pluginData: otherPluginsPublic,
147
+ };
148
+ const appData = {};
149
+ const commandData = {};
150
+ const environmentData = {};
151
+ const miscData = {};
152
+ const appKeys = ['api_key', 'partner_id', 'project_type'];
153
+ const commandKeys = ['command'];
154
+ const environmentKeys = ['cli_version', 'node_version', 'ruby_version', 'uname'];
155
+ Object.entries(allMetadata).forEach(([key, value]) => {
156
+ if (key.startsWith('app_') || appKeys.includes(key)) {
157
+ appData[key] = value;
158
+ }
159
+ else if (key.startsWith('cmd_') || commandKeys.includes(key)) {
160
+ commandData[key] = value;
161
+ }
162
+ else if (key.startsWith('env_') || environmentKeys) {
163
+ environmentData[key] = value;
164
+ }
165
+ else {
166
+ miscData[key] = value;
167
+ }
168
+ });
169
+ // app, command, environment, misc
128
170
  const bugsnagMetadata = {
129
- misc: publicData,
171
+ 'Shopify App': appData,
172
+ Command: commandData,
173
+ Environment: environmentData,
174
+ Misc: miscData,
130
175
  };
131
176
  Object.entries(bugsnagMetadata).forEach(([section, values]) => {
132
177
  event.addMetadata(section, values);
@@ -1 +1 @@
1
- {"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/node/error-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n AbortSilent,\n CancelExecution,\n mapper as errorMapper,\n shouldReport as shouldReportError,\n handler,\n cleanSingleStackTracePath,\n} from '../error.js'\nimport {debug, info} from '../output.js'\nimport {reportEvent} from '../analytics.js'\nimport * as path from '../path.js'\nimport * as metadata from '../metadata.js'\nimport {settings, Interfaces} from '@oclif/core'\nimport StackTracey from 'stacktracey'\nimport Bugsnag, {Event} from '@bugsnag/js'\nimport {realpath} from 'fs/promises'\n\nexport function errorHandler(error: Error & {exitCode?: number | undefined}, config?: Interfaces.Config) {\n if (error instanceof CancelExecution) {\n if (error.message && error.message !== '') {\n info(`✨ ${error.message}`)\n }\n } else if (error instanceof AbortSilent) {\n process.exit(1)\n } else {\n return errorMapper(error)\n .then((error: Error) => {\n return handler(error)\n })\n .then((mappedError) => reportError(mappedError, config))\n .then(() => {\n process.exit(1)\n })\n }\n}\n\nconst reportError = async (error: Error, config?: Interfaces.Config): Promise<Error> => {\n if (config !== undefined) {\n await reportEvent({config, errorMessage: error.message})\n }\n if (settings.debug || !shouldReportError(error)) return error\n\n let reportableError: Error\n let stacktrace: string | undefined\n let report = false\n\n // eslint-disable-next-line no-prototype-builtins\n if (Error.prototype.isPrototypeOf(error)) {\n report = true\n reportableError = new Error(error.message)\n stacktrace = error.stack\n\n /**\n * Some errors that reach this point have an empty string. For example:\n * https://app.bugsnag.com/shopify/cli/errors/62cd5d31fd5040000814086c?filters[event.since]=30d&filters[error.status]=new&filters[release.seen_in]=3.1.0\n *\n * Because at this point we have neither the error message nor a stack trace reporting them\n * to Bugsnag is pointless and adds noise.\n */\n } else if (typeof error === 'string' && (error as string).trim().length !== 0) {\n report = true\n reportableError = new Error(error)\n stacktrace = reportableError.stack\n } else {\n report = false\n reportableError = new Error('Unknown error')\n }\n\n const formattedStacktrace = new StackTracey(stacktrace ?? '')\n .clean()\n .items.map((item) => {\n const filePath = cleanSingleStackTracePath(item.file)\n return ` at ${item.callee} (${filePath}:${item.line}:${item.column})`\n })\n .join('\\n')\n reportableError.stack = `Error: ${reportableError.message}\\n${formattedStacktrace}`\n\n if (report) {\n await new Promise((resolve, reject) => {\n Bugsnag.notify(reportableError, undefined, (error, event) => {\n if (error) {\n reject(error)\n } else {\n resolve(reportableError)\n }\n })\n })\n }\n return reportableError\n}\n\n/**\n * If the given file path comes from within a plugin, return the relative path, plus the plugin name.\n *\n * This gives us very consistent paths for errors thrown from plugin code.\n *\n */\nexport function cleanStackFrameFilePath({\n currentFilePath,\n projectRoot,\n pluginLocations,\n}: {\n currentFilePath: string\n projectRoot: string\n pluginLocations: {name: string; pluginPath: string}[]\n}): string {\n const fullLocation = path.isAbsolute(currentFilePath) ? currentFilePath : path.join(projectRoot, currentFilePath)\n\n const matchingPluginPath = pluginLocations.filter(({pluginPath}) => fullLocation.indexOf(pluginPath) === 0)[0]\n\n if (matchingPluginPath !== undefined) {\n // the plugin name (e.g. @shopify/cli-kit), plus the relative path of the error line from within the plugin's code (e.g. dist/something.js )\n return path.join(matchingPluginPath.name, path.relative(matchingPluginPath.pluginPath, fullLocation))\n }\n return currentFilePath\n}\n\n/**\n * Register a Bugsnag error listener to clean up stack traces for errors within plugin code.\n *\n */\nexport async function registerCleanBugsnagErrorsFromWithinPlugins(plugins: Interfaces.Plugin[]) {\n // Bugsnag have their own plug-ins that use this private field\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const bugsnagConfigProjectRoot: string = (Bugsnag as any)?._client?._config?.projectRoot ?? process.cwd()\n const projectRoot = path.normalize(bugsnagConfigProjectRoot)\n const pluginLocations = await Promise.all(\n plugins.map(async (plugin) => {\n const followSymlinks = await realpath(plugin.root)\n return {name: plugin.name, pluginPath: path.normalize(followSymlinks)}\n }),\n )\n Bugsnag.addOnError((event) => {\n event.errors.forEach((error) => {\n error.stacktrace.forEach((stackFrame) => {\n stackFrame.file = cleanStackFrameFilePath({currentFilePath: stackFrame.file, projectRoot, pluginLocations})\n })\n })\n try {\n addBugsnagMetadata(event)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (metadataError) {\n debug(`There was an error adding metadata to the Bugsnag report; Ignoring and carrying on ${metadataError}`)\n }\n })\n}\n\nexport function addBugsnagMetadata(event: Event) {\n const publicData = metadata.getAllPublic()\n const bugsnagMetadata = {\n misc: publicData,\n }\n Object.entries(bugsnagMetadata).forEach(([section, values]) => {\n event.addMetadata(section, values)\n })\n}\n"]}
1
+ {"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/node/error-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n AbortSilent,\n CancelExecution,\n mapper as errorMapper,\n shouldReport as shouldReportError,\n handler,\n cleanSingleStackTracePath,\n} from '../error.js'\nimport {debug, info} from '../output.js'\nimport {getEnvironmentData, reportEvent} from '../analytics.js'\nimport * as path from '../path.js'\nimport * as metadata from '../metadata.js'\nimport {fanoutHooks} from '../plugins.js'\nimport {settings, Interfaces} from '@oclif/core'\nimport StackTracey from 'stacktracey'\nimport Bugsnag, {Event} from '@bugsnag/js'\nimport {realpath} from 'fs/promises'\n\nexport function errorHandler(error: Error & {exitCode?: number | undefined}, config?: Interfaces.Config) {\n if (error instanceof CancelExecution) {\n if (error.message && error.message !== '') {\n info(`✨ ${error.message}`)\n }\n } else if (error instanceof AbortSilent) {\n process.exit(1)\n } else {\n return errorMapper(error)\n .then((error) => {\n return handler(error)\n })\n .then((mappedError) => reportError(mappedError, config))\n .then(() => {\n process.exit(1)\n })\n }\n}\n\nconst reportError = async (error: unknown, config?: Interfaces.Config): Promise<void> => {\n if (config !== undefined) {\n // Log an analytics event when there's an error\n await reportEvent({config, errorMessage: error instanceof Error ? error.message : undefined})\n }\n await sendErrorToBugsnag(error)\n}\n\n/**\n * Sends an error to Bugsnag. This is configured automatically for uncaught errors from CLI commands, but can also be used to manually record an error.\n *\n * @returns the reported error (this may have been tweaked for better reporting), and a bool to indicate if the error was actually submitted or not\n */\nexport async function sendErrorToBugsnag(\n error: unknown,\n): Promise<{reported: false; error: unknown} | {error: Error; reported: true}> {\n if (settings.debug || !shouldReportError(error)) return {reported: false, error}\n\n let reportableError: Error\n let stacktrace: string | undefined\n let report = false\n\n if (error instanceof Error) {\n report = true\n reportableError = new Error(error.message)\n stacktrace = error.stack\n\n /**\n * Some errors that reach this point have an empty string. For example:\n * https://app.bugsnag.com/shopify/cli/errors/62cd5d31fd5040000814086c?filters[event.since]=30d&filters[error.status]=new&filters[release.seen_in]=3.1.0\n *\n * Because at this point we have neither the error message nor a stack trace reporting them\n * to Bugsnag is pointless and adds noise.\n */\n } else if (typeof error === 'string' && error.trim().length !== 0) {\n report = true\n reportableError = new Error(error)\n stacktrace = reportableError.stack\n } else {\n report = false\n reportableError = new Error('Unknown error')\n }\n\n const formattedStacktrace = new StackTracey(stacktrace ?? '')\n .clean()\n .items.map((item) => {\n const filePath = cleanSingleStackTracePath(item.file)\n return ` at ${item.callee} (${filePath}:${item.line}:${item.column})`\n })\n .join('\\n')\n reportableError.stack = `Error: ${reportableError.message}\\n${formattedStacktrace}`\n\n if (report) {\n await new Promise((resolve, reject) => {\n Bugsnag.notify(reportableError, undefined, (error, event) => {\n if (error) {\n reject(error)\n } else {\n resolve(reportableError)\n }\n })\n })\n }\n return {error: reportableError, reported: report}\n}\n\n/**\n * If the given file path comes from within a plugin, return the relative path, plus the plugin name.\n *\n * This gives us very consistent paths for errors thrown from plugin code.\n *\n */\nexport function cleanStackFrameFilePath({\n currentFilePath,\n projectRoot,\n pluginLocations,\n}: {\n currentFilePath: string\n projectRoot: string\n pluginLocations: {name: string; pluginPath: string}[]\n}): string {\n const fullLocation = path.isAbsolute(currentFilePath) ? currentFilePath : path.join(projectRoot, currentFilePath)\n\n const matchingPluginPath = pluginLocations.filter(({pluginPath}) => fullLocation.indexOf(pluginPath) === 0)[0]\n\n if (matchingPluginPath !== undefined) {\n // the plugin name (e.g. @shopify/cli-kit), plus the relative path of the error line from within the plugin's code (e.g. dist/something.js )\n return path.join(matchingPluginPath.name, path.relative(matchingPluginPath.pluginPath, fullLocation))\n }\n return currentFilePath\n}\n\n/**\n * Register a Bugsnag error listener to clean up stack traces for errors within plugin code.\n *\n */\nexport async function registerCleanBugsnagErrorsFromWithinPlugins(config: Interfaces.Config) {\n // Bugsnag have their own plug-ins that use this private field\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const bugsnagConfigProjectRoot: string = (Bugsnag as any)?._client?._config?.projectRoot ?? process.cwd()\n const projectRoot = path.normalize(bugsnagConfigProjectRoot)\n const pluginLocations = await Promise.all(\n config.plugins.map(async (plugin) => {\n const followSymlinks = await realpath(plugin.root)\n return {name: plugin.name, pluginPath: path.normalize(followSymlinks)}\n }),\n )\n Bugsnag.addOnError(async (event) => {\n event.errors.forEach((error) => {\n error.stacktrace.forEach((stackFrame) => {\n stackFrame.file = cleanStackFrameFilePath({currentFilePath: stackFrame.file, projectRoot, pluginLocations})\n })\n })\n try {\n await addBugsnagMetadata(event, config)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (metadataError) {\n debug(`There was an error adding metadata to the Bugsnag report; Ignoring and carrying on ${metadataError}`)\n }\n })\n}\n\nexport async function addBugsnagMetadata(event: Event, config: Interfaces.Config) {\n const publicData = metadata.getAllPublic()\n const {commandStartOptions} = metadata.getAllSensitive()\n const {startCommand} = commandStartOptions ?? {}\n\n const {'@shopify/app': appPublic, ...otherPluginsPublic} = await fanoutHooks(config, 'public_command_metadata', {})\n\n const environment = getEnvironmentData(config)\n\n const allMetadata = {\n command: startCommand,\n ...appPublic,\n ...publicData,\n ...environment,\n pluginData: otherPluginsPublic,\n }\n\n const appData = {} as {[key: string]: unknown}\n const commandData = {} as {[key: string]: unknown}\n const environmentData = {} as {[key: string]: unknown}\n const miscData = {} as {[key: string]: unknown}\n const appKeys = ['api_key', 'partner_id', 'project_type']\n const commandKeys = ['command']\n const environmentKeys = ['cli_version', 'node_version', 'ruby_version', 'uname']\n\n Object.entries(allMetadata).forEach(([key, value]) => {\n if (key.startsWith('app_') || appKeys.includes(key)) {\n appData[key] = value\n } else if (key.startsWith('cmd_') || commandKeys.includes(key)) {\n commandData[key] = value\n } else if (key.startsWith('env_') || environmentKeys) {\n environmentData[key] = value\n } else {\n miscData[key] = value\n }\n })\n\n // app, command, environment, misc\n const bugsnagMetadata = {\n 'Shopify App': appData,\n Command: commandData,\n Environment: environmentData,\n Misc: miscData,\n }\n Object.entries(bugsnagMetadata).forEach(([section, values]) => {\n event.addMetadata(section, values)\n })\n}\n"]}
@@ -6,6 +6,6 @@ export const hook = async (options) => {
6
6
  const command = cmd.replace(/:/g, ' ');
7
7
  const args = options.argv;
8
8
  debug(`Running command ${command}`);
9
- start({ command, args });
9
+ await start({ command, args, commandClass: options.Command });
10
10
  };
11
11
  //# sourceMappingURL=prerun.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prerun.js","sourceRoot":"","sources":["../../../src/node/hooks/prerun.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,oBAAoB,CAAA;AACxC,OAAO,EAAC,KAAK,EAAC,MAAM,iBAAiB,CAAA;AAGrC,sFAAsF;AACtF,MAAM,CAAC,MAAM,IAAI,GAAgB,KAAK,EAAE,OAAO,EAAE,EAAE;IACjD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IAClG,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IACtC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;IACzB,KAAK,CAAC,mBAAmB,OAAO,EAAE,CAAC,CAAA;IACnC,KAAK,CAAC,EAAC,OAAO,EAAE,IAAI,EAAC,CAAC,CAAA;AACxB,CAAC,CAAA","sourcesContent":["import {start} from '../../analytics.js'\nimport {debug} from '../../output.js'\nimport {Hook} from '@oclif/core'\n\n// This hook is called before each command run. More info: https://oclif.io/docs/hooks\nexport const hook: Hook.Prerun = async (options) => {\n const cmd = options.Command.aliases.length === 0 ? options.Command.id : options.Command.aliases[0]\n const command = cmd.replace(/:/g, ' ')\n const args = options.argv\n debug(`Running command ${command}`)\n start({command, args})\n}\n"]}
1
+ {"version":3,"file":"prerun.js","sourceRoot":"","sources":["../../../src/node/hooks/prerun.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,oBAAoB,CAAA;AACxC,OAAO,EAAC,KAAK,EAAC,MAAM,iBAAiB,CAAA;AAGrC,sFAAsF;AACtF,MAAM,CAAC,MAAM,IAAI,GAAgB,KAAK,EAAE,OAAO,EAAE,EAAE;IACjD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAE,CAAA;IACnG,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IACtC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;IACzB,KAAK,CAAC,mBAAmB,OAAO,EAAE,CAAC,CAAA;IACnC,MAAM,KAAK,CAAC,EAAC,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,CAAC,OAAO,EAAC,CAAC,CAAA;AAC7D,CAAC,CAAA","sourcesContent":["import {start} from '../../analytics.js'\nimport {debug} from '../../output.js'\nimport {Hook} from '@oclif/core'\n\n// This hook is called before each command run. More info: https://oclif.io/docs/hooks\nexport const hook: Hook.Prerun = async (options) => {\n const cmd = options.Command.aliases.length === 0 ? options.Command.id : options.Command.aliases[0]!\n const command = cmd.replace(/:/g, ' ')\n const args = options.argv\n debug(`Running command ${command}`)\n await start({command, args, commandClass: options.Command})\n}\n"]}
@@ -1,5 +1,4 @@
1
1
  /// <reference types="node" />
2
- /// <reference types="node" />
3
2
  import { Abort, Bug } from '../error.js';
4
3
  import { AbortSignal } from 'abort-controller';
5
4
  import type { Writable } from 'node:stream';
@@ -40,7 +39,7 @@ export declare const FindUpAndReadPackageJsonNotFoundError: (directory: string)
40
39
  * @param env {Object} The environment variables of the process in which the CLI runs.
41
40
  * @returns The dependency manager
42
41
  */
43
- export declare function packageManagerUsedForCreating(env?: NodeJS.ProcessEnv): PackageManager;
42
+ export declare function packageManagerUsedForCreating(env?: NodeJS.ProcessEnv): PackageManager | 'unknown';
44
43
  /**
45
44
  * Returns the dependency manager used by an existing project.
46
45
  * @param directory {string} The root directory of the project.
@@ -68,22 +67,21 @@ interface InstallNPMDependenciesRecursivelyOptions {
68
67
  * @param options {InstallNPMDependenciesRecursivelyOptions} Options to install dependencies recursively.
69
68
  */
70
69
  export declare function installNPMDependenciesRecursively(options: InstallNPMDependenciesRecursivelyOptions): Promise<void>;
71
- /**
72
- * Installs the dependencies in the given directory.
73
- * @param directory {string} The directory that contains the package.json
74
- * @param packageManager {PackageManager} The package manager to use to install the dependencies.
75
- * @param stdout {Writable} Standard output stream.
76
- * @param stderr {Writable} Standard error stream.
77
- * @param signal {AbortSignal} Abort signal.
78
- * @returns stderr {Writable} Standard error stream.
79
- */
80
- export declare function installNodeModules(directory: string, packageManager: PackageManager, stdout?: Writable, stderr?: Writable, signal?: AbortSignal): Promise<void>;
70
+ interface InstallNodeModulesOptions {
71
+ directory: string;
72
+ args: string[];
73
+ packageManager: PackageManager;
74
+ stdout?: Writable;
75
+ stderr?: Writable;
76
+ signal?: AbortSignal;
77
+ }
78
+ export declare function installNodeModules(options: InstallNodeModulesOptions): Promise<void>;
81
79
  /**
82
80
  * Returns the name of the package configured in its package.json
83
81
  * @param packageJsonPath {string} Path to the package.json file
84
82
  * @returns A promise that resolves with the name.
85
83
  */
86
- export declare function getPackageName(packageJsonPath: string): Promise<string>;
84
+ export declare function getPackageName(packageJsonPath: string): Promise<string | undefined>;
87
85
  /**
88
86
  * Returns the list of production and dev dependencies of a package.json
89
87
  * @param packageJsonPath {string} Path to the package.json file
@@ -103,14 +101,10 @@ export declare function checkForNewVersion(dependency: string, currentVersion: s
103
101
  * An interface that represents a package.json
104
102
  */
105
103
  interface PackageJson {
106
- /**
107
- * The absolute path to the package.json
108
- */
109
- path: string;
110
104
  /**
111
105
  * The name attribute of the package.json
112
106
  */
113
- name: string;
107
+ name?: string;
114
108
  /**
115
109
  * The version attribute of the package.json
116
110
  */
@@ -46,9 +46,10 @@ export function packageManagerUsedForCreating(env = process.env) {
46
46
  else if (env.npm_config_user_agent?.includes('pnpm')) {
47
47
  return 'pnpm';
48
48
  }
49
- else {
49
+ else if (env.npm_config_user_agent?.includes('npm')) {
50
50
  return 'npm';
51
51
  }
52
+ return 'unknown';
52
53
  }
53
54
  /**
54
55
  * Returns the dependency manager used by an existing project.
@@ -86,7 +87,14 @@ export async function installNPMDependenciesRecursively(options) {
86
87
  try {
87
88
  await Promise.all(packageJsons.map(async (packageJsonPath) => {
88
89
  const directory = dirname(packageJsonPath);
89
- await installNodeModules(directory, options.packageManager, undefined, undefined, abortController.signal);
90
+ await installNodeModules({
91
+ directory,
92
+ packageManager: options.packageManager,
93
+ stdout: undefined,
94
+ stderr: undefined,
95
+ signal: abortController.signal,
96
+ args: [],
97
+ });
90
98
  }));
91
99
  }
92
100
  catch (error) {
@@ -94,18 +102,19 @@ export async function installNPMDependenciesRecursively(options) {
94
102
  throw error;
95
103
  }
96
104
  }
97
- /**
98
- * Installs the dependencies in the given directory.
99
- * @param directory {string} The directory that contains the package.json
100
- * @param packageManager {PackageManager} The package manager to use to install the dependencies.
101
- * @param stdout {Writable} Standard output stream.
102
- * @param stderr {Writable} Standard error stream.
103
- * @param signal {AbortSignal} Abort signal.
104
- * @returns stderr {Writable} Standard error stream.
105
- */
106
- export async function installNodeModules(directory, packageManager, stdout, stderr, signal) {
107
- const options = { cwd: directory, stdin: undefined, stdout, stderr, signal };
108
- await exec(packageManager, ['install'], options);
105
+ export async function installNodeModules(options) {
106
+ const execOptions = {
107
+ cwd: options.directory,
108
+ stdin: undefined,
109
+ stdout: options.stdout,
110
+ stderr: options.stderr,
111
+ signal: options.signal,
112
+ };
113
+ let args = ['install'];
114
+ if (options.args) {
115
+ args = args.concat(options.args);
116
+ }
117
+ await exec(options.packageManager, args, execOptions);
109
118
  }
110
119
  /**
111
120
  * Returns the name of the package configured in its package.json