@shopify/cli-kit 3.91.1 → 3.92.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 (261) hide show
  1. package/dist/private/node/analytics/bounded-collections.d.ts +1 -3
  2. package/dist/private/node/analytics/bounded-collections.js.map +1 -1
  3. package/dist/private/node/analytics/error-categorizer.js.map +1 -1
  4. package/dist/private/node/analytics.js.map +1 -1
  5. package/dist/private/node/api/graphql.d.ts +1 -3
  6. package/dist/private/node/api/graphql.js.map +1 -1
  7. package/dist/private/node/api/headers.d.ts +2 -6
  8. package/dist/private/node/api/headers.js +0 -1
  9. package/dist/private/node/api/headers.js.map +1 -1
  10. package/dist/private/node/api/rest.d.ts +2 -6
  11. package/dist/private/node/api/rest.js.map +1 -1
  12. package/dist/private/node/api.js.map +1 -1
  13. package/dist/private/node/conf-store.d.ts +6 -6
  14. package/dist/private/node/conf-store.js +13 -6
  15. package/dist/private/node/conf-store.js.map +1 -1
  16. package/dist/private/node/session/device-authorization.js.map +1 -1
  17. package/dist/private/node/session/exchange.d.ts +1 -19
  18. package/dist/private/node/session/exchange.js +13 -30
  19. package/dist/private/node/session/exchange.js.map +1 -1
  20. package/dist/private/node/session/schema.d.ts +62 -62
  21. package/dist/private/node/session/store.js +1 -1
  22. package/dist/private/node/session/store.js.map +1 -1
  23. package/dist/private/node/session/validate.d.ts +4 -5
  24. package/dist/private/node/session/validate.js +7 -35
  25. package/dist/private/node/session/validate.js.map +1 -1
  26. package/dist/private/node/session.js +18 -65
  27. package/dist/private/node/session.js.map +1 -1
  28. package/dist/private/node/testing/ui.d.ts +2 -1
  29. package/dist/private/node/testing/ui.js +22 -24
  30. package/dist/private/node/testing/ui.js.map +1 -1
  31. package/dist/private/node/themes/generate-theme-name.js +0 -1
  32. package/dist/private/node/themes/generate-theme-name.js.map +1 -1
  33. package/dist/private/node/ui/alert.js.map +1 -1
  34. package/dist/private/node/ui/components/Alert.test.js +2 -4
  35. package/dist/private/node/ui/components/Alert.test.js.map +1 -1
  36. package/dist/private/node/ui/components/AutocompletePrompt.js +6 -1
  37. package/dist/private/node/ui/components/AutocompletePrompt.js.map +1 -1
  38. package/dist/private/node/ui/components/AutocompletePrompt.test.js +2 -3
  39. package/dist/private/node/ui/components/AutocompletePrompt.test.js.map +1 -1
  40. package/dist/private/node/ui/components/Banner.js +0 -1
  41. package/dist/private/node/ui/components/Banner.js.map +1 -1
  42. package/dist/private/node/ui/components/Banner.test.js +2 -2
  43. package/dist/private/node/ui/components/Banner.test.js.map +1 -1
  44. package/dist/private/node/ui/components/ConcurrentOutput.js +4 -2
  45. package/dist/private/node/ui/components/ConcurrentOutput.js.map +1 -1
  46. package/dist/private/node/ui/components/ConcurrentOutput.test.js +9 -3
  47. package/dist/private/node/ui/components/ConcurrentOutput.test.js.map +1 -1
  48. package/dist/private/node/ui/components/DangerousConfirmationPrompt.js.map +1 -1
  49. package/dist/private/node/ui/components/DangerousConfirmationPrompt.test.js.map +1 -1
  50. package/dist/private/node/ui/components/FatalError.js +0 -1
  51. package/dist/private/node/ui/components/FatalError.js.map +1 -1
  52. package/dist/private/node/ui/components/FatalError.test.js.map +1 -1
  53. package/dist/private/node/ui/components/List.test.js.map +1 -1
  54. package/dist/private/node/ui/components/LoadingBar.js.map +1 -1
  55. package/dist/private/node/ui/components/LoadingBar.test.js.map +1 -1
  56. package/dist/private/node/ui/components/Prompts/InfoTable.d.ts +1 -3
  57. package/dist/private/node/ui/components/Prompts/InfoTable.js +0 -1
  58. package/dist/private/node/ui/components/Prompts/InfoTable.js.map +1 -1
  59. package/dist/private/node/ui/components/Prompts/InfoTable.test.js.map +1 -1
  60. package/dist/private/node/ui/components/Prompts/PromptLayout.d.ts +1 -1
  61. package/dist/private/node/ui/components/Prompts/PromptLayout.js +1 -1
  62. package/dist/private/node/ui/components/Prompts/PromptLayout.js.map +1 -1
  63. package/dist/private/node/ui/components/Prompts/PromptLayout.test.js +1 -1
  64. package/dist/private/node/ui/components/Prompts/PromptLayout.test.js.map +1 -1
  65. package/dist/private/node/ui/components/SelectInput.d.ts +4 -5
  66. package/dist/private/node/ui/components/SelectInput.js +5 -7
  67. package/dist/private/node/ui/components/SelectInput.js.map +1 -1
  68. package/dist/private/node/ui/components/SelectInput.test.js.map +1 -1
  69. package/dist/private/node/ui/components/SelectPrompt.js +0 -1
  70. package/dist/private/node/ui/components/SelectPrompt.js.map +1 -1
  71. package/dist/private/node/ui/components/SelectPrompt.test.js +0 -1
  72. package/dist/private/node/ui/components/SelectPrompt.test.js.map +1 -1
  73. package/dist/private/node/ui/components/SingleTask.js.map +1 -1
  74. package/dist/private/node/ui/components/SingleTask.test.js.map +1 -1
  75. package/dist/private/node/ui/components/Table/ScalarDict.d.ts +2 -4
  76. package/dist/private/node/ui/components/Table/ScalarDict.js.map +1 -1
  77. package/dist/private/node/ui/components/Table/Table.js +0 -1
  78. package/dist/private/node/ui/components/Table/Table.js.map +1 -1
  79. package/dist/private/node/ui/components/Table/Table.test.js.map +1 -1
  80. package/dist/private/node/ui/components/Tasks.js +0 -2
  81. package/dist/private/node/ui/components/Tasks.js.map +1 -1
  82. package/dist/private/node/ui/components/Tasks.test.js +2 -6
  83. package/dist/private/node/ui/components/Tasks.test.js.map +1 -1
  84. package/dist/private/node/ui/components/TextAnimation.test.js +1 -1
  85. package/dist/private/node/ui/components/TextAnimation.test.js.map +1 -1
  86. package/dist/private/node/ui/components/TextInput.js +19 -19
  87. package/dist/private/node/ui/components/TextInput.js.map +1 -1
  88. package/dist/private/node/ui/components/TextPrompt.js +1 -1
  89. package/dist/private/node/ui/components/TextPrompt.js.map +1 -1
  90. package/dist/private/node/ui/components/TextPrompt.test.js +0 -1
  91. package/dist/private/node/ui/components/TextPrompt.test.js.map +1 -1
  92. package/dist/private/node/ui/components/TokenizedText.js +1 -2
  93. package/dist/private/node/ui/components/TokenizedText.js.map +1 -1
  94. package/dist/private/node/ui/components/TokenizedText.test.js.map +1 -1
  95. package/dist/private/node/ui/contexts/LinksContext.d.ts +1 -3
  96. package/dist/private/node/ui/contexts/LinksContext.js.map +1 -1
  97. package/dist/private/node/ui/hooks/use-abort-signal.js +9 -1
  98. package/dist/private/node/ui/hooks/use-abort-signal.js.map +1 -1
  99. package/dist/private/node/ui.js +8 -1
  100. package/dist/private/node/ui.js.map +1 -1
  101. package/dist/public/common/array.js +0 -1
  102. package/dist/public/common/array.js.map +1 -1
  103. package/dist/public/common/collection.d.ts +1 -3
  104. package/dist/public/common/collection.js.map +1 -1
  105. package/dist/public/common/string.js +1 -4
  106. package/dist/public/common/string.js.map +1 -1
  107. package/dist/public/common/ts/json-narrowing.d.ts +1 -3
  108. package/dist/public/common/ts/json-narrowing.js.map +1 -1
  109. package/dist/public/common/version.d.ts +1 -1
  110. package/dist/public/common/version.js +1 -1
  111. package/dist/public/common/version.js.map +1 -1
  112. package/dist/public/node/analytics.js +1 -1
  113. package/dist/public/node/analytics.js.map +1 -1
  114. package/dist/public/node/api/admin.d.ts +2 -6
  115. package/dist/public/node/api/admin.js +1 -2
  116. package/dist/public/node/api/admin.js.map +1 -1
  117. package/dist/public/node/api/app-dev.d.ts +1 -1
  118. package/dist/public/node/api/app-dev.js +1 -1
  119. package/dist/public/node/api/app-dev.js.map +1 -1
  120. package/dist/public/node/api/app-management.d.ts +1 -3
  121. package/dist/public/node/api/app-management.js +1 -1
  122. package/dist/public/node/api/app-management.js.map +1 -1
  123. package/dist/public/node/api/business-platform.js.map +1 -1
  124. package/dist/public/node/api/functions.js +1 -1
  125. package/dist/public/node/api/functions.js.map +1 -1
  126. package/dist/public/node/api/graphql.d.ts +4 -12
  127. package/dist/public/node/api/graphql.js.map +1 -1
  128. package/dist/public/node/api/partners.js +1 -1
  129. package/dist/public/node/api/partners.js.map +1 -1
  130. package/dist/public/node/api/rest-api-throttler.js +0 -1
  131. package/dist/public/node/api/rest-api-throttler.js.map +1 -1
  132. package/dist/public/node/archiver.js +2 -2
  133. package/dist/public/node/archiver.js.map +1 -1
  134. package/dist/public/node/base-command.js +0 -2
  135. package/dist/public/node/base-command.js.map +1 -1
  136. package/dist/public/node/cli.js.map +1 -1
  137. package/dist/public/node/context/local.js.map +1 -1
  138. package/dist/public/node/custom-oclif-loader.js +0 -1
  139. package/dist/public/node/custom-oclif-loader.js.map +1 -1
  140. package/dist/public/node/doctor/framework.d.ts +14 -9
  141. package/dist/public/node/doctor/framework.js +10 -3
  142. package/dist/public/node/doctor/framework.js.map +1 -1
  143. package/dist/public/node/doctor/reporter.d.ts +23 -0
  144. package/dist/public/node/doctor/reporter.js +33 -1
  145. package/dist/public/node/doctor/reporter.js.map +1 -1
  146. package/dist/public/node/dot-env.d.ts +2 -6
  147. package/dist/public/node/dot-env.js +1 -2
  148. package/dist/public/node/dot-env.js.map +1 -1
  149. package/dist/public/node/environments.d.ts +1 -3
  150. package/dist/public/node/environments.js.map +1 -1
  151. package/dist/public/node/error-handler.js +3 -3
  152. package/dist/public/node/error-handler.js.map +1 -1
  153. package/dist/public/node/error.d.ts +1 -1
  154. package/dist/public/node/error.js +2 -2
  155. package/dist/public/node/error.js.map +1 -1
  156. package/dist/public/node/framework.js +0 -1
  157. package/dist/public/node/framework.js.map +1 -1
  158. package/dist/public/node/fs.d.ts +1 -1
  159. package/dist/public/node/fs.js +1 -1
  160. package/dist/public/node/fs.js.map +1 -1
  161. package/dist/public/node/git.d.ts +1 -3
  162. package/dist/public/node/git.js +1 -3
  163. package/dist/public/node/git.js.map +1 -1
  164. package/dist/public/node/github.js +14 -8
  165. package/dist/public/node/github.js.map +1 -1
  166. package/dist/public/node/hooks/postrun.js +2 -2
  167. package/dist/public/node/hooks/postrun.js.map +1 -1
  168. package/dist/public/node/hooks/prerun.js +2 -2
  169. package/dist/public/node/hooks/prerun.js.map +1 -1
  170. package/dist/public/node/http.js +2 -3
  171. package/dist/public/node/http.js.map +1 -1
  172. package/dist/public/node/json-schema.d.ts +1 -3
  173. package/dist/public/node/json-schema.js +0 -1
  174. package/dist/public/node/json-schema.js.map +1 -1
  175. package/dist/public/node/liquid.js +1 -1
  176. package/dist/public/node/liquid.js.map +1 -1
  177. package/dist/public/node/local-storage.d.ts +1 -3
  178. package/dist/public/node/local-storage.js.map +1 -1
  179. package/dist/public/node/metadata.d.ts +1 -3
  180. package/dist/public/node/metadata.js +0 -1
  181. package/dist/public/node/metadata.js.map +1 -1
  182. package/dist/public/node/mimes.d.ts +1 -3
  183. package/dist/public/node/mimes.js.map +1 -1
  184. package/dist/public/node/monorail.js +1 -1
  185. package/dist/public/node/monorail.js.map +1 -1
  186. package/dist/public/node/multiple-installation-warning.d.ts +1 -3
  187. package/dist/public/node/multiple-installation-warning.js.map +1 -1
  188. package/dist/public/node/node-package-manager.d.ts +9 -27
  189. package/dist/public/node/node-package-manager.js +1 -1
  190. package/dist/public/node/node-package-manager.js.map +1 -1
  191. package/dist/public/node/os.js +1 -1
  192. package/dist/public/node/os.js.map +1 -1
  193. package/dist/public/node/output.d.ts +1 -3
  194. package/dist/public/node/output.js +1 -2
  195. package/dist/public/node/output.js.map +1 -1
  196. package/dist/public/node/path.d.ts +13 -0
  197. package/dist/public/node/path.js +10 -1
  198. package/dist/public/node/path.js.map +1 -1
  199. package/dist/public/node/plugins/tunnel.d.ts +5 -11
  200. package/dist/public/node/plugins/tunnel.js.map +1 -1
  201. package/dist/public/node/plugins.d.ts +4 -12
  202. package/dist/public/node/plugins.js.map +1 -1
  203. package/dist/public/node/result.js +1 -1
  204. package/dist/public/node/result.js.map +1 -1
  205. package/dist/public/node/session.js +15 -7
  206. package/dist/public/node/session.js.map +1 -1
  207. package/dist/public/node/system.d.ts +1 -3
  208. package/dist/public/node/system.js +1 -1
  209. package/dist/public/node/system.js.map +1 -1
  210. package/dist/public/node/tcp.js +1 -1
  211. package/dist/public/node/tcp.js.map +1 -1
  212. package/dist/public/node/testing/output.js +1 -1
  213. package/dist/public/node/testing/output.js.map +1 -1
  214. package/dist/public/node/themes/api.js +2 -2
  215. package/dist/public/node/themes/api.js.map +1 -1
  216. package/dist/public/node/themes/conf.d.ts +1 -3
  217. package/dist/public/node/themes/conf.js.map +1 -1
  218. package/dist/public/node/tree-kill.js +0 -1
  219. package/dist/public/node/tree-kill.js.map +1 -1
  220. package/dist/public/node/ui.js +0 -12
  221. package/dist/public/node/ui.js.map +1 -1
  222. package/dist/public/node/vendor/dev_server/dev-server-2016.d.ts +8 -0
  223. package/dist/public/node/vendor/dev_server/dev-server-2016.js +10 -2
  224. package/dist/public/node/vendor/dev_server/dev-server-2016.js.map +1 -1
  225. package/dist/public/node/vendor/dev_server/dev-server-2024.d.ts +8 -0
  226. package/dist/public/node/vendor/dev_server/dev-server-2024.js +10 -2
  227. package/dist/public/node/vendor/dev_server/dev-server-2024.js.map +1 -1
  228. package/dist/public/node/vendor/dev_server/dev-server.js +1 -1
  229. package/dist/public/node/vendor/dev_server/dev-server.js.map +1 -1
  230. package/dist/public/node/vendor/dev_server/env.d.ts +3 -0
  231. package/dist/public/node/vendor/dev_server/env.js +3 -0
  232. package/dist/public/node/vendor/dev_server/env.js.map +1 -1
  233. package/dist/public/node/vendor/dev_server/network/host.d.ts +7 -0
  234. package/dist/public/node/vendor/dev_server/network/host.js +7 -1
  235. package/dist/public/node/vendor/dev_server/network/host.js.map +1 -1
  236. package/dist/public/node/vendor/dev_server/network/index.d.ts +7 -0
  237. package/dist/public/node/vendor/dev_server/network/index.js +7 -2
  238. package/dist/public/node/vendor/dev_server/network/index.js.map +1 -1
  239. package/dist/public/node/vendor/otel-js/export/InstantaneousMetricReader.d.ts +1 -1
  240. package/dist/public/node/vendor/otel-js/export/InstantaneousMetricReader.js +2 -4
  241. package/dist/public/node/vendor/otel-js/export/InstantaneousMetricReader.js.map +1 -1
  242. package/dist/public/node/vendor/otel-js/service/BaseOtelService/BaseOtelService.d.ts +7 -0
  243. package/dist/public/node/vendor/otel-js/service/BaseOtelService/BaseOtelService.js +9 -1
  244. package/dist/public/node/vendor/otel-js/service/BaseOtelService/BaseOtelService.js.map +1 -1
  245. package/dist/public/node/vendor/otel-js/service/DefaultOtelService/DefaultOtelService.d.ts +12 -1
  246. package/dist/public/node/vendor/otel-js/service/DefaultOtelService/DefaultOtelService.js +11 -0
  247. package/dist/public/node/vendor/otel-js/service/DefaultOtelService/DefaultOtelService.js.map +1 -1
  248. package/dist/public/node/vendor/otel-js/service/types.d.ts +6 -10
  249. package/dist/public/node/vendor/otel-js/service/types.js.map +1 -1
  250. package/dist/public/node/vendor/otel-js/utils/throttle.d.ts +10 -2
  251. package/dist/public/node/vendor/otel-js/utils/throttle.js +9 -0
  252. package/dist/public/node/vendor/otel-js/utils/throttle.js.map +1 -1
  253. package/dist/public/node/vendor/otel-js/utils/validators.d.ts +4 -0
  254. package/dist/public/node/vendor/otel-js/utils/validators.js +4 -0
  255. package/dist/public/node/vendor/otel-js/utils/validators.js.map +1 -1
  256. package/dist/public/node/version.js +1 -1
  257. package/dist/public/node/version.js.map +1 -1
  258. package/dist/public/node/vscode.js +1 -1
  259. package/dist/public/node/vscode.js.map +1 -1
  260. package/dist/tsconfig.tsbuildinfo +1 -1
  261. package/package.json +5 -5
@@ -1 +1 @@
1
- {"version":3,"file":"prerun.js","sourceRoot":"","sources":["../../../../src/public/node/hooks/prerun.ts"],"names":[],"mappings":"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","sourcesContent":["import {CLI_KIT_VERSION} from '../../common/version.js'\nimport {checkForNewVersion, checkForCachedNewVersion} from '../node-package-manager.js'\nimport {startAnalytics} from '../../../private/node/analytics.js'\nimport {outputDebug, outputWarn} from '../../../public/node/output.js'\nimport {getOutputUpdateCLIReminder} from '../../../public/node/upgrade.js'\nimport Command from '../../../public/node/base-command.js'\nimport {runAtMinimumInterval} from '../../../private/node/conf-store.js'\nimport {fetchNotificationsInBackground} from '../notifications-system.js'\nimport {isPreReleaseVersion} from '../version.js'\nimport {Hook} from '@oclif/core'\n\nexport declare interface CommandContent {\n command: string\n topic?: string\n alias?: string\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 commandContent = parseCommandContent({\n id: options.Command.id,\n aliases: options.Command.aliases,\n pluginAlias: options.Command.plugin?.alias,\n })\n const args = options.argv\n await warnOnAvailableUpgrade()\n outputDebug(`Running command ${commandContent.command}`)\n await startAnalytics({commandContent, args, commandClass: options.Command as unknown as typeof Command})\n fetchNotificationsInBackground(options.Command.id)\n}\n\nexport function parseCommandContent(cmdInfo: {id: string; aliases: string[]; pluginAlias?: string}): CommandContent {\n let commandContent = parseCreateCommand(cmdInfo.pluginAlias)\n if (!commandContent) {\n commandContent = parseNormalCommand(cmdInfo.id, cmdInfo.aliases)\n }\n return commandContent\n}\n\nfunction parseNormalCommand(id: string, aliases: string[]): CommandContent {\n return {\n command: id.replace(/:/g, ' '),\n topic: parseTopic(id),\n alias: findAlias(aliases),\n }\n}\n\n/**\n * Create commands implement Init by default, so the name of the command must be extracted from\n * the plugin/module name. Neither alias or topic are supported\n *\n * @param commandClass - Oclif command configuration\n * @returns Command content with the name of the command or undefined otherwise\n */\nfunction parseCreateCommand(pluginAlias?: string): CommandContent | undefined {\n if (!pluginAlias?.startsWith('@shopify/create-')) {\n return undefined\n }\n\n return {command: pluginAlias.substring(pluginAlias.indexOf('/') + 1)}\n}\n\n/**\n * Commands use this pattern topic:subtopic1:...:subtopicN:command. This method extract the topic and subtopic\n * information replacing the ':' separator with one space\n *\n * @param cmd - Complete command string to extract the topic information\n * @returns The topic name or undefined otherwise\n */\nfunction parseTopic(cmd: string) {\n if (cmd.lastIndexOf(':') === -1) {\n return\n }\n return cmd.slice(0, cmd.lastIndexOf(':')).replace(/:/g, ' ')\n}\n\n/**\n * Identifies if the command was launched using an alias instead of the oficial command name\n *\n * @param aliases - List of possible alias a command has\n * @returns The alias used or undefined otherwise\n */\nfunction findAlias(aliases: string[]) {\n const existingAlias = aliases.find((alias) =>\n alias.split(':').every((aliasToken) => process.argv.includes(aliasToken)),\n )\n if (existingAlias) {\n return existingAlias.replace(/:/g, ' ')\n }\n}\n\n/**\n * Warns the user if there is a new version of the CLI available\n */\nexport async function warnOnAvailableUpgrade(): Promise<void> {\n const cliDependency = '@shopify/cli'\n const currentVersion = CLI_KIT_VERSION\n if (isPreReleaseVersion(currentVersion)) {\n // This is a nightly/snapshot/experimental version, so we don't want to check for updates\n return\n }\n\n // Check in the background, once daily\n // eslint-disable-next-line no-void\n void checkForNewVersion(cliDependency, currentVersion, {cacheExpiryInHours: 24})\n\n // Warn if we previously found a new version\n await runAtMinimumInterval('warn-on-available-upgrade', {days: 1}, async () => {\n const newerVersion = checkForCachedNewVersion(cliDependency, currentVersion)\n if (newerVersion) {\n outputWarn(getOutputUpdateCLIReminder(newerVersion))\n }\n })\n}\n"]}
1
+ {"version":3,"file":"prerun.js","sourceRoot":"","sources":["../../../../src/public/node/hooks/prerun.ts"],"names":[],"mappings":"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","sourcesContent":["import {CLI_KIT_VERSION} from '../../common/version.js'\nimport {checkForNewVersion, checkForCachedNewVersion} from '../node-package-manager.js'\nimport {startAnalytics} from '../../../private/node/analytics.js'\nimport {outputDebug, outputWarn} from '../output.js'\nimport {getOutputUpdateCLIReminder} from '../upgrade.js'\nimport Command from '../base-command.js'\nimport {runAtMinimumInterval} from '../../../private/node/conf-store.js'\nimport {fetchNotificationsInBackground} from '../notifications-system.js'\nimport {isPreReleaseVersion} from '../version.js'\nimport {Hook} from '@oclif/core'\n\nexport declare interface CommandContent {\n command: string\n topic?: string\n alias?: string\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 commandContent = parseCommandContent({\n id: options.Command.id,\n aliases: options.Command.aliases,\n pluginAlias: options.Command.plugin?.alias,\n })\n const args = options.argv\n await warnOnAvailableUpgrade()\n outputDebug(`Running command ${commandContent.command}`)\n await startAnalytics({commandContent, args, commandClass: options.Command as unknown as typeof Command})\n fetchNotificationsInBackground(options.Command.id)\n}\n\nexport function parseCommandContent(cmdInfo: {id: string; aliases: string[]; pluginAlias?: string}): CommandContent {\n let commandContent = parseCreateCommand(cmdInfo.pluginAlias)\n if (!commandContent) {\n commandContent = parseNormalCommand(cmdInfo.id, cmdInfo.aliases)\n }\n return commandContent\n}\n\nfunction parseNormalCommand(id: string, aliases: string[]): CommandContent {\n return {\n command: id.replace(/:/g, ' '),\n topic: parseTopic(id),\n alias: findAlias(aliases),\n }\n}\n\n/**\n * Create commands implement Init by default, so the name of the command must be extracted from\n * the plugin/module name. Neither alias or topic are supported\n *\n * @param commandClass - Oclif command configuration\n * @returns Command content with the name of the command or undefined otherwise\n */\nfunction parseCreateCommand(pluginAlias?: string): CommandContent | undefined {\n if (!pluginAlias?.startsWith('@shopify/create-')) {\n return undefined\n }\n\n return {command: pluginAlias.substring(pluginAlias.indexOf('/') + 1)}\n}\n\n/**\n * Commands use this pattern topic:subtopic1:...:subtopicN:command. This method extract the topic and subtopic\n * information replacing the ':' separator with one space\n *\n * @param cmd - Complete command string to extract the topic information\n * @returns The topic name or undefined otherwise\n */\nfunction parseTopic(cmd: string) {\n if (cmd.lastIndexOf(':') === -1) {\n return\n }\n return cmd.slice(0, cmd.lastIndexOf(':')).replace(/:/g, ' ')\n}\n\n/**\n * Identifies if the command was launched using an alias instead of the oficial command name\n *\n * @param aliases - List of possible alias a command has\n * @returns The alias used or undefined otherwise\n */\nfunction findAlias(aliases: string[]) {\n const existingAlias = aliases.find((alias) =>\n alias.split(':').every((aliasToken) => process.argv.includes(aliasToken)),\n )\n if (existingAlias) {\n return existingAlias.replace(/:/g, ' ')\n }\n}\n\n/**\n * Warns the user if there is a new version of the CLI available\n */\nexport async function warnOnAvailableUpgrade(): Promise<void> {\n const cliDependency = '@shopify/cli'\n const currentVersion = CLI_KIT_VERSION\n if (isPreReleaseVersion(currentVersion)) {\n // This is a nightly/snapshot/experimental version, so we don't want to check for updates\n return\n }\n\n // Check in the background, once daily\n // eslint-disable-next-line no-void\n void checkForNewVersion(cliDependency, currentVersion, {cacheExpiryInHours: 24})\n\n // Warn if we previously found a new version\n await runAtMinimumInterval('warn-on-available-upgrade', {days: 1}, async () => {\n const newerVersion = checkForCachedNewVersion(cliDependency, currentVersion)\n if (newerVersion) {\n outputWarn(getOutputUpdateCLIReminder(newerVersion))\n }\n })\n}\n"]}
@@ -1,11 +1,10 @@
1
- /* eslint-disable @typescript-eslint/no-base-to-string */
2
1
  import { dirname } from './path.js';
3
2
  import { createFileWriteStream, fileExistsSync, mkdirSync, unlinkFileSync } from './fs.js';
4
3
  import { runWithTimer } from './metadata.js';
5
4
  import { maxRequestTimeForNetworkCallsMs, skipNetworkLevelRetry } from './environment.js';
6
- import { httpsAgent, sanitizedHeadersOutput } from '../../private/node/api/headers.js';
5
+ import { outputContent, outputDebug, outputToken } from './output.js';
7
6
  import { sanitizeURL } from '../../private/node/api/urls.js';
8
- import { outputContent, outputDebug, outputToken } from '../../public/node/output.js';
7
+ import { httpsAgent, sanitizedHeadersOutput } from '../../private/node/api/headers.js';
9
8
  import { simpleRequestWithDebugLog } from '../../private/node/api.js';
10
9
  import { DEFAULT_MAX_TIME_MS } from '../../private/node/sleep-with-backoff.js';
11
10
  import FormData from 'form-data';
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/public/node/http.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-base-to-string */\nimport {dirname} from './path.js'\nimport {createFileWriteStream, fileExistsSync, mkdirSync, unlinkFileSync} from './fs.js'\nimport {runWithTimer} from './metadata.js'\nimport {maxRequestTimeForNetworkCallsMs, skipNetworkLevelRetry} from './environment.js'\nimport {httpsAgent, sanitizedHeadersOutput} from '../../private/node/api/headers.js'\nimport {sanitizeURL} from '../../private/node/api/urls.js'\nimport {outputContent, outputDebug, outputToken} from '../../public/node/output.js'\nimport {NetworkRetryBehaviour, simpleRequestWithDebugLog} from '../../private/node/api.js'\nimport {DEFAULT_MAX_TIME_MS} from '../../private/node/sleep-with-backoff.js'\nimport FormData from 'form-data'\nimport nodeFetch, {RequestInfo, RequestInit, Response} from 'node-fetch'\n\nexport {FetchError, Request, Response} from 'node-fetch'\n\n/**\n * Create a new FormData object.\n *\n * @returns A FormData object.\n */\nexport function formData(): FormData {\n return new FormData()\n}\n\ntype AbortSignal = RequestInit['signal']\n\ntype PresetFetchBehaviour = 'default' | 'non-blocking' | 'slow-request'\n\ntype AutomaticCancellationBehaviour =\n | {\n useAbortSignal: true\n timeoutMs: number\n }\n | {\n useAbortSignal: false\n }\n | {\n useAbortSignal: AbortSignal | (() => AbortSignal)\n }\n\nexport type RequestBehaviour = NetworkRetryBehaviour & AutomaticCancellationBehaviour\n\nexport type RequestModeInput = PresetFetchBehaviour | RequestBehaviour\n\n/**\n * Specify the behaviour of a network request.\n *\n * - default: Requests are automatically retried, and are subject to automatic cancellation if they're taking too long.\n * This is generally desirable.\n * - non-blocking: Requests are not retried if they fail with a network error, and are automatically cancelled if\n * they're taking too long. This is good for throwaway requests, like polling or tracking.\n * - slow-request: Requests are not retried if they fail with a network error, and are not automatically cancelled.\n * This is good for slow requests that should be give the chance to complete, and are unlikely to be safe to retry.\n *\n * Some request behaviours may be de-activated by the environment, and this function takes care of that concern. You\n * can also provide a customised request behaviour.\n *\n * @param preset - The preset to use.\n * @param env - Process environment variables.\n * @returns A request behaviour object.\n */\nexport function requestMode(\n preset: RequestModeInput = 'default',\n env: NodeJS.ProcessEnv = process.env,\n): RequestBehaviour {\n const networkLevelRetryIsSupported = !skipNetworkLevelRetry(env)\n switch (preset) {\n case 'default':\n return {\n useNetworkLevelRetry: networkLevelRetryIsSupported,\n maxRetryTimeMs: DEFAULT_MAX_TIME_MS,\n useAbortSignal: true,\n timeoutMs: maxRequestTimeForNetworkCallsMs(env),\n }\n case 'non-blocking':\n return {\n useNetworkLevelRetry: false,\n useAbortSignal: true,\n timeoutMs: maxRequestTimeForNetworkCallsMs(env),\n }\n case 'slow-request':\n return {\n useNetworkLevelRetry: false,\n useAbortSignal: false,\n }\n }\n return {\n ...preset,\n useNetworkLevelRetry: networkLevelRetryIsSupported && preset.useNetworkLevelRetry,\n } as RequestBehaviour\n}\n\ninterface FetchOptions {\n url: RequestInfo\n behaviour: RequestBehaviour\n init?: RequestInit\n logRequest: boolean\n useHttpsAgent: boolean\n}\n\n/**\n * Create an AbortSignal for automatic request cancellation, from a request behaviour.\n *\n * @param behaviour - The request behaviour.\n * @returns An AbortSignal.\n */\nexport function abortSignalFromRequestBehaviour(behaviour: RequestBehaviour): AbortSignal {\n let signal: AbortSignal\n if (behaviour.useAbortSignal === true) {\n signal = AbortSignal.timeout(behaviour.timeoutMs)\n } else if (behaviour.useAbortSignal && typeof behaviour.useAbortSignal === 'function') {\n signal = behaviour.useAbortSignal()\n } else if (behaviour.useAbortSignal) {\n signal = behaviour.useAbortSignal\n }\n return signal\n}\n\nasync function innerFetch({url, behaviour, init, logRequest, useHttpsAgent}: FetchOptions): Promise<Response> {\n if (logRequest) {\n outputDebug(outputContent`Sending ${init?.method ?? 'GET'} request to URL ${sanitizeURL(url.toString())}\nWith request headers:\n${sanitizedHeadersOutput((init?.headers ?? {}) as {[header: string]: string})}\n`)\n }\n\n let agent: RequestInit['agent']\n if (useHttpsAgent) {\n agent = await httpsAgent()\n }\n\n const request = async () => {\n // each time we make the request, we need to potentially reset the abort signal, as the request logic may make\n // the same request multiple times.\n let signal = abortSignalFromRequestBehaviour(behaviour)\n\n // it's possible to provide a signal through the request's init structure.\n if (init?.signal) {\n signal = init.signal\n }\n\n return nodeFetch(url, {...init, agent, signal})\n }\n\n return runWithTimer('cmd_all_timing_network_ms')(async () => {\n return simpleRequestWithDebugLog({\n url: url.toString(),\n request,\n ...behaviour,\n })\n })\n}\n\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 *\n * The CLI's fetch function supports special behaviours, like automatic retries. These are disabled by default through\n * this function.\n *\n * @param url - This defines the resource that you wish to fetch.\n * @param init - An object containing any custom settings that you want to apply to the request.\n * @param preferredBehaviour - A request behaviour object that overrides the default behaviour.\n * @returns A promise that resolves with the response.\n */\nexport async function fetch(\n url: RequestInfo,\n init?: RequestInit,\n preferredBehaviour?: RequestModeInput,\n): Promise<Response> {\n const options = {\n url,\n init,\n logRequest: false,\n useHttpsAgent: false,\n // all special behaviours are disabled by default\n behaviour: preferredBehaviour ? requestMode(preferredBehaviour) : requestMode('non-blocking'),\n } as const\n\n return innerFetch(options)\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. Local). NB: headers/auth are the responsibility of the caller.\n *\n * By default, the CLI's fetch function's special behaviours, like automatic retries, are enabled.\n *\n * @param url - This defines the resource that you wish to fetch.\n * @param init - An object containing any custom settings that you want to apply to the request.\n * @param preferredBehaviour - A request behaviour object that overrides the default behaviour.\n * @returns A promise that resolves with the response.\n */\nexport async function shopifyFetch(\n url: RequestInfo,\n init?: RequestInit,\n preferredBehaviour?: RequestModeInput,\n): Promise<Response> {\n const options = {\n url,\n init,\n logRequest: true,\n useHttpsAgent: true,\n // special behaviours enabled by default\n behaviour: preferredBehaviour ? requestMode(preferredBehaviour) : requestMode(),\n }\n\n return innerFetch(options)\n}\n\n/**\n * Download a file from a URL to a local path.\n *\n * @param url - The URL to download from.\n * @param to - The local path to download to.\n * @returns - A promise that resolves with the local path.\n */\nexport function downloadFile(url: string, to: string): Promise<string> {\n const sanitizedUrl = sanitizeURL(url)\n outputDebug(`Downloading ${sanitizedUrl} to ${to}`)\n\n return runWithTimer('cmd_all_timing_network_ms')(() => {\n return new Promise<string>((resolve, reject) => {\n if (!fileExistsSync(dirname(to))) {\n mkdirSync(dirname(to))\n }\n\n const file = createFileWriteStream(to)\n\n // if we can't remove the file for some reason (seen on windows), that's ok -- it's in a temporary directory\n const tryToRemoveFile = () => {\n try {\n unlinkFileSync(to)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (err: unknown) {\n outputDebug(outputContent`Failed to remove file ${outputToken.path(to)}: ${outputToken.raw(String(err))}`)\n }\n }\n\n file.on('finish', () => {\n file.close()\n resolve(to)\n })\n\n file.on('error', (err) => {\n tryToRemoveFile()\n reject(err)\n })\n\n nodeFetch(url, {redirect: 'follow'})\n .then((res) => {\n res.body?.pipe(file)\n })\n .catch((err) => {\n tryToRemoveFile()\n reject(err)\n })\n })\n })\n}\n"]}
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/public/node/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AACjC,OAAO,EAAC,qBAAqB,EAAE,cAAc,EAAE,SAAS,EAAE,cAAc,EAAC,MAAM,SAAS,CAAA;AACxF,OAAO,EAAC,YAAY,EAAC,MAAM,eAAe,CAAA;AAC1C,OAAO,EAAC,+BAA+B,EAAE,qBAAqB,EAAC,MAAM,kBAAkB,CAAA;AACvF,OAAO,EAAC,aAAa,EAAE,WAAW,EAAE,WAAW,EAAC,MAAM,aAAa,CAAA;AACnE,OAAO,EAAC,WAAW,EAAC,MAAM,gCAAgC,CAAA;AAC1D,OAAO,EAAC,UAAU,EAAE,sBAAsB,EAAC,MAAM,mCAAmC,CAAA;AACpF,OAAO,EAAwB,yBAAyB,EAAC,MAAM,2BAA2B,CAAA;AAC1F,OAAO,EAAC,mBAAmB,EAAC,MAAM,0CAA0C,CAAA;AAE5E,OAAO,QAAQ,MAAM,WAAW,CAAA;AAChC,OAAO,SAA+C,MAAM,YAAY,CAAA;AAExE,OAAO,EAAC,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAC,MAAM,YAAY,CAAA;AAExD;;;;GAIG;AACH,MAAM,UAAU,QAAQ;IACtB,OAAO,IAAI,QAAQ,EAAE,CAAA;AACvB,CAAC;AAsBD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,WAAW,CACzB,SAA2B,SAAS,EACpC,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,4BAA4B,GAAG,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAA;IAChE,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,SAAS;YACZ,OAAO;gBACL,oBAAoB,EAAE,4BAA4B;gBAClD,cAAc,EAAE,mBAAmB;gBACnC,cAAc,EAAE,IAAI;gBACpB,SAAS,EAAE,+BAA+B,CAAC,GAAG,CAAC;aAChD,CAAA;QACH,KAAK,cAAc;YACjB,OAAO;gBACL,oBAAoB,EAAE,KAAK;gBAC3B,cAAc,EAAE,IAAI;gBACpB,SAAS,EAAE,+BAA+B,CAAC,GAAG,CAAC;aAChD,CAAA;QACH,KAAK,cAAc;YACjB,OAAO;gBACL,oBAAoB,EAAE,KAAK;gBAC3B,cAAc,EAAE,KAAK;aACtB,CAAA;IACL,CAAC;IACD,OAAO;QACL,GAAG,MAAM;QACT,oBAAoB,EAAE,4BAA4B,IAAI,MAAM,CAAC,oBAAoB;KAC9D,CAAA;AACvB,CAAC;AAUD;;;;;GAKG;AACH,MAAM,UAAU,+BAA+B,CAAC,SAA2B;IACzE,IAAI,MAAmB,CAAA;IACvB,IAAI,SAAS,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;QACtC,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,CAAA;IACnD,CAAC;SAAM,IAAI,SAAS,CAAC,cAAc,IAAI,OAAO,SAAS,CAAC,cAAc,KAAK,UAAU,EAAE,CAAC;QACtF,MAAM,GAAG,SAAS,CAAC,cAAc,EAAE,CAAA;IACrC,CAAC;SAAM,IAAI,SAAS,CAAC,cAAc,EAAE,CAAC;QACpC,MAAM,GAAG,SAAS,CAAC,cAAc,CAAA;IACnC,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,EAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,aAAa,EAAe;IACvF,IAAI,UAAU,EAAE,CAAC;QACf,WAAW,CAAC,aAAa,CAAA,WAAW,IAAI,EAAE,MAAM,IAAI,KAAK,mBAAmB,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;;EAEzG,sBAAsB,CAAC,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,CAA2B,CAAC;CACxE,CAAC,CAAA;IACA,CAAC;IAED,IAAI,KAA2B,CAAA;IAC/B,IAAI,aAAa,EAAE,CAAC;QAClB,KAAK,GAAG,MAAM,UAAU,EAAE,CAAA;IAC5B,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;QACzB,8GAA8G;QAC9G,mCAAmC;QACnC,IAAI,MAAM,GAAG,+BAA+B,CAAC,SAAS,CAAC,CAAA;QAEvD,0EAA0E;QAC1E,IAAI,IAAI,EAAE,MAAM,EAAE,CAAC;YACjB,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QACtB,CAAC;QAED,OAAO,SAAS,CAAC,GAAG,EAAE,EAAC,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,EAAC,CAAC,CAAA;IACjD,CAAC,CAAA;IAED,OAAO,YAAY,CAAC,2BAA2B,CAAC,CAAC,KAAK,IAAI,EAAE;QAC1D,OAAO,yBAAyB,CAAC;YAC/B,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE;YACnB,OAAO;YACP,GAAG,SAAS;SACb,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CACzB,GAAgB,EAChB,IAAkB,EAClB,kBAAqC;IAErC,MAAM,OAAO,GAAG;QACd,GAAG;QACH,IAAI;QACJ,UAAU,EAAE,KAAK;QACjB,aAAa,EAAE,KAAK;QACpB,iDAAiD;QACjD,SAAS,EAAE,kBAAkB,CAAC,CAAC,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,cAAc,CAAC;KACrF,CAAA;IAEV,OAAO,UAAU,CAAC,OAAO,CAAC,CAAA;AAC5B,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,GAAgB,EAChB,IAAkB,EAClB,kBAAqC;IAErC,MAAM,OAAO,GAAG;QACd,GAAG;QACH,IAAI;QACJ,UAAU,EAAE,IAAI;QAChB,aAAa,EAAE,IAAI;QACnB,wCAAwC;QACxC,SAAS,EAAE,kBAAkB,CAAC,CAAC,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;KAChF,CAAA;IAED,OAAO,UAAU,CAAC,OAAO,CAAC,CAAA;AAC5B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,EAAU;IAClD,MAAM,YAAY,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;IACrC,WAAW,CAAC,eAAe,YAAY,OAAO,EAAE,EAAE,CAAC,CAAA;IAEnD,OAAO,YAAY,CAAC,2BAA2B,CAAC,CAAC,GAAG,EAAE;QACpD,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC7C,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;gBACjC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAA;YACxB,CAAC;YAED,MAAM,IAAI,GAAG,qBAAqB,CAAC,EAAE,CAAC,CAAA;YAEtC,4GAA4G;YAC5G,MAAM,eAAe,GAAG,GAAG,EAAE;gBAC3B,IAAI,CAAC;oBACH,cAAc,CAAC,EAAE,CAAC,CAAA;oBAClB,qDAAqD;gBACvD,CAAC;gBAAC,OAAO,GAAY,EAAE,CAAC;oBACtB,WAAW,CAAC,aAAa,CAAA,yBAAyB,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAA;gBAC5G,CAAC;YACH,CAAC,CAAA;YAED,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;gBACrB,IAAI,CAAC,KAAK,EAAE,CAAA;gBACZ,OAAO,CAAC,EAAE,CAAC,CAAA;YACb,CAAC,CAAC,CAAA;YAEF,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACvB,eAAe,EAAE,CAAA;gBACjB,MAAM,CAAC,GAAG,CAAC,CAAA;YACb,CAAC,CAAC,CAAA;YAEF,SAAS,CAAC,GAAG,EAAE,EAAC,QAAQ,EAAE,QAAQ,EAAC,CAAC;iBACjC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;gBACZ,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;YACtB,CAAC,CAAC;iBACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBACb,eAAe,EAAE,CAAA;gBACjB,MAAM,CAAC,GAAG,CAAC,CAAA;YACb,CAAC,CAAC,CAAA;QACN,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import {dirname} from './path.js'\nimport {createFileWriteStream, fileExistsSync, mkdirSync, unlinkFileSync} from './fs.js'\nimport {runWithTimer} from './metadata.js'\nimport {maxRequestTimeForNetworkCallsMs, skipNetworkLevelRetry} from './environment.js'\nimport {outputContent, outputDebug, outputToken} from './output.js'\nimport {sanitizeURL} from '../../private/node/api/urls.js'\nimport {httpsAgent, sanitizedHeadersOutput} from '../../private/node/api/headers.js'\nimport {NetworkRetryBehaviour, simpleRequestWithDebugLog} from '../../private/node/api.js'\nimport {DEFAULT_MAX_TIME_MS} from '../../private/node/sleep-with-backoff.js'\n\nimport FormData from 'form-data'\nimport nodeFetch, {RequestInfo, RequestInit, Response} from 'node-fetch'\n\nexport {FetchError, Request, Response} from 'node-fetch'\n\n/**\n * Create a new FormData object.\n *\n * @returns A FormData object.\n */\nexport function formData(): FormData {\n return new FormData()\n}\n\ntype AbortSignal = RequestInit['signal']\n\ntype PresetFetchBehaviour = 'default' | 'non-blocking' | 'slow-request'\n\ntype AutomaticCancellationBehaviour =\n | {\n useAbortSignal: true\n timeoutMs: number\n }\n | {\n useAbortSignal: false\n }\n | {\n useAbortSignal: AbortSignal | (() => AbortSignal)\n }\n\nexport type RequestBehaviour = NetworkRetryBehaviour & AutomaticCancellationBehaviour\n\nexport type RequestModeInput = PresetFetchBehaviour | RequestBehaviour\n\n/**\n * Specify the behaviour of a network request.\n *\n * - default: Requests are automatically retried, and are subject to automatic cancellation if they're taking too long.\n * This is generally desirable.\n * - non-blocking: Requests are not retried if they fail with a network error, and are automatically cancelled if\n * they're taking too long. This is good for throwaway requests, like polling or tracking.\n * - slow-request: Requests are not retried if they fail with a network error, and are not automatically cancelled.\n * This is good for slow requests that should be give the chance to complete, and are unlikely to be safe to retry.\n *\n * Some request behaviours may be de-activated by the environment, and this function takes care of that concern. You\n * can also provide a customised request behaviour.\n *\n * @param preset - The preset to use.\n * @param env - Process environment variables.\n * @returns A request behaviour object.\n */\nexport function requestMode(\n preset: RequestModeInput = 'default',\n env: NodeJS.ProcessEnv = process.env,\n): RequestBehaviour {\n const networkLevelRetryIsSupported = !skipNetworkLevelRetry(env)\n switch (preset) {\n case 'default':\n return {\n useNetworkLevelRetry: networkLevelRetryIsSupported,\n maxRetryTimeMs: DEFAULT_MAX_TIME_MS,\n useAbortSignal: true,\n timeoutMs: maxRequestTimeForNetworkCallsMs(env),\n }\n case 'non-blocking':\n return {\n useNetworkLevelRetry: false,\n useAbortSignal: true,\n timeoutMs: maxRequestTimeForNetworkCallsMs(env),\n }\n case 'slow-request':\n return {\n useNetworkLevelRetry: false,\n useAbortSignal: false,\n }\n }\n return {\n ...preset,\n useNetworkLevelRetry: networkLevelRetryIsSupported && preset.useNetworkLevelRetry,\n } as RequestBehaviour\n}\n\ninterface FetchOptions {\n url: RequestInfo\n behaviour: RequestBehaviour\n init?: RequestInit\n logRequest: boolean\n useHttpsAgent: boolean\n}\n\n/**\n * Create an AbortSignal for automatic request cancellation, from a request behaviour.\n *\n * @param behaviour - The request behaviour.\n * @returns An AbortSignal.\n */\nexport function abortSignalFromRequestBehaviour(behaviour: RequestBehaviour): AbortSignal {\n let signal: AbortSignal\n if (behaviour.useAbortSignal === true) {\n signal = AbortSignal.timeout(behaviour.timeoutMs)\n } else if (behaviour.useAbortSignal && typeof behaviour.useAbortSignal === 'function') {\n signal = behaviour.useAbortSignal()\n } else if (behaviour.useAbortSignal) {\n signal = behaviour.useAbortSignal\n }\n return signal\n}\n\nasync function innerFetch({url, behaviour, init, logRequest, useHttpsAgent}: FetchOptions): Promise<Response> {\n if (logRequest) {\n outputDebug(outputContent`Sending ${init?.method ?? 'GET'} request to URL ${sanitizeURL(url.toString())}\nWith request headers:\n${sanitizedHeadersOutput((init?.headers ?? {}) as Record<string, string>)}\n`)\n }\n\n let agent: RequestInit['agent']\n if (useHttpsAgent) {\n agent = await httpsAgent()\n }\n\n const request = async () => {\n // each time we make the request, we need to potentially reset the abort signal, as the request logic may make\n // the same request multiple times.\n let signal = abortSignalFromRequestBehaviour(behaviour)\n\n // it's possible to provide a signal through the request's init structure.\n if (init?.signal) {\n signal = init.signal\n }\n\n return nodeFetch(url, {...init, agent, signal})\n }\n\n return runWithTimer('cmd_all_timing_network_ms')(async () => {\n return simpleRequestWithDebugLog({\n url: url.toString(),\n request,\n ...behaviour,\n })\n })\n}\n\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 *\n * The CLI's fetch function supports special behaviours, like automatic retries. These are disabled by default through\n * this function.\n *\n * @param url - This defines the resource that you wish to fetch.\n * @param init - An object containing any custom settings that you want to apply to the request.\n * @param preferredBehaviour - A request behaviour object that overrides the default behaviour.\n * @returns A promise that resolves with the response.\n */\nexport async function fetch(\n url: RequestInfo,\n init?: RequestInit,\n preferredBehaviour?: RequestModeInput,\n): Promise<Response> {\n const options = {\n url,\n init,\n logRequest: false,\n useHttpsAgent: false,\n // all special behaviours are disabled by default\n behaviour: preferredBehaviour ? requestMode(preferredBehaviour) : requestMode('non-blocking'),\n } as const\n\n return innerFetch(options)\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. Local). NB: headers/auth are the responsibility of the caller.\n *\n * By default, the CLI's fetch function's special behaviours, like automatic retries, are enabled.\n *\n * @param url - This defines the resource that you wish to fetch.\n * @param init - An object containing any custom settings that you want to apply to the request.\n * @param preferredBehaviour - A request behaviour object that overrides the default behaviour.\n * @returns A promise that resolves with the response.\n */\nexport async function shopifyFetch(\n url: RequestInfo,\n init?: RequestInit,\n preferredBehaviour?: RequestModeInput,\n): Promise<Response> {\n const options = {\n url,\n init,\n logRequest: true,\n useHttpsAgent: true,\n // special behaviours enabled by default\n behaviour: preferredBehaviour ? requestMode(preferredBehaviour) : requestMode(),\n }\n\n return innerFetch(options)\n}\n\n/**\n * Download a file from a URL to a local path.\n *\n * @param url - The URL to download from.\n * @param to - The local path to download to.\n * @returns - A promise that resolves with the local path.\n */\nexport function downloadFile(url: string, to: string): Promise<string> {\n const sanitizedUrl = sanitizeURL(url)\n outputDebug(`Downloading ${sanitizedUrl} to ${to}`)\n\n return runWithTimer('cmd_all_timing_network_ms')(() => {\n return new Promise<string>((resolve, reject) => {\n if (!fileExistsSync(dirname(to))) {\n mkdirSync(dirname(to))\n }\n\n const file = createFileWriteStream(to)\n\n // if we can't remove the file for some reason (seen on windows), that's ok -- it's in a temporary directory\n const tryToRemoveFile = () => {\n try {\n unlinkFileSync(to)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (err: unknown) {\n outputDebug(outputContent`Failed to remove file ${outputToken.path(to)}: ${outputToken.raw(String(err))}`)\n }\n }\n\n file.on('finish', () => {\n file.close()\n resolve(to)\n })\n\n file.on('error', (err) => {\n tryToRemoveFile()\n reject(err)\n })\n\n nodeFetch(url, {redirect: 'follow'})\n .then((res) => {\n res.body?.pipe(file)\n })\n .catch((err) => {\n tryToRemoveFile()\n reject(err)\n })\n })\n })\n}\n"]}
@@ -1,9 +1,7 @@
1
1
  import { ParseConfigurationResult } from './schema.js';
2
2
  import { ErrorObject, SchemaObject } from 'ajv';
3
3
  export type HandleInvalidAdditionalProperties = 'strip' | 'fail';
4
- type AjvError = ErrorObject<string, {
5
- [key: string]: unknown;
6
- }>;
4
+ type AjvError = ErrorObject<string, Record<string, unknown>>;
7
5
  /**
8
6
  * Normalises a JSON Schema by standardising it's internal implementation.
9
7
  *
@@ -64,7 +64,6 @@ export function jsonSchemaValidate(subject, schema, handleInvalidAdditionalPrope
64
64
  Object.keys(subjectToModify).forEach((key) => {
65
65
  if (!topLevelSchemaProperties.includes(key)) {
66
66
  // this isn't actually dynamic, because key came from Object.keys
67
- // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
68
67
  delete subjectToModify[key];
69
68
  }
70
69
  });
@@ -1 +1 @@
1
- {"version":3,"file":"json-schema.js","sourceRoot":"","sources":["../../../src/public/node/json-schema.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-non-null-assertion */\nimport {ParseConfigurationResult} from './schema.js'\nimport {randomUUID} from './crypto.js'\nimport {getPathValue} from '../common/object.js'\nimport {capitalize} from '../common/string.js'\nimport {Ajv, ErrorObject, SchemaObject, ValidateFunction} from 'ajv'\nimport $RefParser from '@apidevtools/json-schema-ref-parser'\nimport cloneDeep from 'lodash/cloneDeep.js'\n\nexport type HandleInvalidAdditionalProperties = 'strip' | 'fail'\n\ntype AjvError = ErrorObject<string, {[key: string]: unknown}>\n\n/**\n * Normalises a JSON Schema by standardising it's internal implementation.\n *\n * We prefer to not use $ref elements in our schemas, so we inline them; it's easier then to process errors.\n *\n * @param schema - The JSON schema (as a string) to normalise.\n * @returns The normalised JSON schema.\n */\nexport async function normaliseJsonSchema(schema: string): Promise<SchemaObject> {\n // we want to modify the schema, removing any $ref elements and inlining with their source\n const parsedSchema = JSON.parse(schema)\n await $RefParser.dereference(parsedSchema, {resolve: {external: false}})\n return parsedSchema\n}\n\nfunction createAjvValidator(\n handleInvalidAdditionalProperties: HandleInvalidAdditionalProperties,\n schema: SchemaObject,\n) {\n // allowUnionTypes: Allows types like `type: [\"string\", \"number\"]`\n if (handleInvalidAdditionalProperties === 'strip') {\n // we need to let additional properties through, so that we can strip them later\n schema.additionalProperties = true\n }\n\n const ajv = new Ajv({allowUnionTypes: true, allErrors: true, verbose: true})\n ajv.addKeyword('x-taplo')\n\n const validator = ajv.compile(schema)\n\n return validator\n}\n\nconst validatorsCache = new Map<string, ValidateFunction>()\n\n/**\n * Given a subject object and a JSON schema contract, validate the subject against the contract.\n *\n * Errors are returned in a zod-like format, and processed to better handle unions.\n *\n * @param subject - The object to validate.\n * @param schema - The JSON schema to validate against.\n * @param handleInvalidAdditionalProperties - Whether to strip or fail on invalid additional properties.\n * @param identifier - The identifier of the schema being validated, used to cache the validator.\n * @returns The result of the validation. If the state is 'error', the errors will be in a zod-like format.\n */\nexport function jsonSchemaValidate(\n subject: object,\n schema: SchemaObject,\n handleInvalidAdditionalProperties: HandleInvalidAdditionalProperties,\n identifier?: string,\n): ParseConfigurationResult<unknown> & {rawErrors?: AjvError[]} {\n const subjectToModify = cloneDeep(subject)\n\n const cacheKey = identifier ?? randomUUID()\n\n const validator = validatorsCache.get(cacheKey) ?? createAjvValidator(handleInvalidAdditionalProperties, schema)\n validatorsCache.set(cacheKey, validator)\n\n validator(subjectToModify)\n\n // Errors from the contract are post-processed to be more zod-like and to deal with unions better\n let jsonSchemaErrors\n if (validator.errors && validator.errors.length > 0) {\n jsonSchemaErrors = convertJsonSchemaErrors(validator.errors, subjectToModify, schema)\n return {\n state: 'error',\n data: undefined,\n errors: jsonSchemaErrors,\n rawErrors: validator.errors,\n }\n }\n\n if (handleInvalidAdditionalProperties === 'strip') {\n const topLevelSchemaProperties = Object.keys(schema.properties ?? {})\n // strip any properties that are not in the top level schema from subjectToModify\n Object.keys(subjectToModify).forEach((key) => {\n if (!topLevelSchemaProperties.includes(key)) {\n // this isn't actually dynamic, because key came from Object.keys\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete subjectToModify[key as keyof typeof subjectToModify]\n }\n })\n }\n\n return {\n state: 'ok',\n data: subjectToModify,\n errors: undefined,\n rawErrors: undefined,\n }\n}\n\n/**\n * Converts errors from Ajv into a zod-like format.\n *\n * @param rawErrors - JSON Schema errors taken directly from Ajv.\n * @param subject - The object being validated.\n * @param schema - The JSON schema to validated against.\n * @returns The errors in a zod-like format.\n */\nfunction convertJsonSchemaErrors(rawErrors: AjvError[], subject: object, schema: SchemaObject) {\n // This reduces the number of errors by simplifying errors coming from different branches of a union\n const errors = simplifyUnionErrors(rawErrors, subject, schema)\n\n // Now we can remap errors to be more zod-like\n return errors.map((error) => {\n const path: string[] = error.instancePath.split('/').slice(1)\n if (error.params.missingProperty) {\n const missingProperty = error.params.missingProperty as string\n return {path: [...path, missingProperty], message: 'Required'}\n }\n\n if (error.params.type) {\n const expectedType = Array.isArray(error.params.type)\n ? error.params.type.join(', ')\n : (error.params.type as string)\n const actualType = getPathValue(subject, path.join('.'))\n return {path, message: `Expected ${expectedType}, received ${typeof actualType}`}\n }\n\n if (error.keyword === 'anyOf' || error.keyword === 'oneOf') {\n return {path, message: 'Invalid input'}\n }\n\n if (error.params.allowedValues) {\n const allowedValues = error.params.allowedValues as string[]\n const actualValue = getPathValue(subject, path.join('.'))\n return {\n path,\n message: `Invalid enum value. Expected ${allowedValues\n .map((value) => JSON.stringify(value))\n .join(' | ')}, received ${JSON.stringify(actualValue)}`.replace(/\"/g, \"'\"),\n }\n }\n\n if (error.params.comparison) {\n const comparison = error.params.comparison as string\n const limit = error.params.limit\n const actualValue = getPathValue(subject, path.join('.'))\n\n let comparisonText = comparison\n switch (comparison) {\n case '<=':\n comparisonText = 'less than or equal to'\n break\n case '<':\n comparisonText = 'less than'\n break\n case '>=':\n comparisonText = 'greater than or equal to'\n break\n case '>':\n comparisonText = 'greater than'\n break\n }\n\n return {\n path,\n message: capitalize(`${typeof actualValue} must be ${comparisonText} ${limit}`),\n }\n }\n\n if (error.params.additionalProperty) {\n const supportedProperties = Object.keys(error.parentSchema?.properties ?? {})\n\n // if a property was already set, remove it from here\n const alreadySetProperties = Object.keys(error.data ?? {})\n const remainingProperties = supportedProperties.filter((property) => !alreadySetProperties.includes(property))\n\n if (remainingProperties.length > 0) {\n return {\n path: [...path, error.params.additionalProperty as string],\n message: `No additional properties allowed. You can set ${remainingProperties.sort().join(', ')}.`,\n }\n }\n }\n\n return {\n path,\n message: error.message,\n }\n })\n}\n\n/**\n * If a JSON schema specifies a union (anyOf, oneOf), and the subject doesn't meet any of the 'candidates' for the\n * union, then the error list received ends up being quite long: you get an error for the union property itself, and\n * then additional errors for each of the candidate branches.\n *\n * This function simplifies the error collection. By default it strips anything other than the union error itself.\n *\n * In some cases, it can be possible to identify what the intended branch of the union was -- for instance, maybe there\n * is a discriminating field like `type` that is unique between the branches. We inspect each candidate branch and if\n * one branch is less wrong than the others -- e.g. It had a valid `type`, but problems elsewhere -- then we keep the\n * errors for that branch.\n *\n * This is complex but in practise gives much more actionable errors.\n *\n * @param rawErrors - JSON Schema errors taken directly from Ajv.\n * @param subject - The object being validated.\n * @param schema - The JSON schema to validated against.\n * @returns A simplified list of errors.\n */\nfunction simplifyUnionErrors(rawErrors: AjvError[], subject: object, schema: SchemaObject): AjvError[] {\n let errors = rawErrors\n\n const resolvedUnionErrors = new Set()\n while (true) {\n const unionError = errors.filter(\n (error) =>\n (error.keyword === 'oneOf' || error.keyword === 'anyOf') && !resolvedUnionErrors.has(error.instancePath),\n )[0]\n if (unionError === undefined) {\n break\n }\n // split errors into those sharing an instance path and those not\n const unrelatedErrors = errors.filter((error) => !error.instancePath.startsWith(unionError.instancePath))\n\n // we start by assuming only the union error itself is useful, and not the errors from the candidate schemas\n let simplifiedUnionRelatedErrors: AjvError[] = [unionError]\n\n // get the schema list from where the union issue occured\n const dottedSchemaPath = unionError.schemaPath.replace('#/', '').replace(/\\//g, '.')\n const unionSchemas = getPathValue<SchemaObject[]>(schema, dottedSchemaPath)\n // and the slice of the subject that caused the issue\n const subjectValue = getPathValue(subject, unionError.instancePath.split('/').slice(1).join('.'))\n\n if (unionSchemas !== undefined && subjectValue !== undefined) {\n // we know that none of the union schemas are correct, but for each of them we can measure how wrong they are\n const correctValuesAndErrors = unionSchemas\n .map((candidateSchemaFromUnion: SchemaObject) => {\n const candidateSchemaValidator = createAjvValidator('fail', candidateSchemaFromUnion)\n candidateSchemaValidator(subjectValue)\n\n let score = 0\n if (candidateSchemaFromUnion.type === 'object') {\n // provided the schema is an object, we can measure how many properties are good\n const candidatesObjectProperties = Object.keys(candidateSchemaFromUnion.properties)\n score = candidatesObjectProperties.reduce((acc, propertyName) => {\n const subSchema = candidateSchemaFromUnion.properties[propertyName] as SchemaObject\n const subjectValueSlice = getPathValue(subjectValue, propertyName)\n\n const subValidator = createAjvValidator('fail', subSchema)\n if (subValidator(subjectValueSlice)) {\n return acc + 1\n }\n return acc\n }, score)\n }\n\n return [score, candidateSchemaValidator.errors!] as const\n })\n .sort(([scoreA], [scoreB]) => scoreA - scoreB)\n\n if (correctValuesAndErrors.length >= 2) {\n const [bestScore, bestErrors] = correctValuesAndErrors[correctValuesAndErrors.length - 1]!\n const [penultimateScore] = correctValuesAndErrors[correctValuesAndErrors.length - 2]!\n\n if (bestScore !== penultimateScore) {\n // If there's a winner, show the errors for the best schema as they'll likely be actionable.\n // We got these through a nested schema, so we need to adjust the instance path\n simplifiedUnionRelatedErrors = [\n unionError,\n ...bestErrors.map((bestError) => ({\n ...bestError,\n instancePath: unionError.instancePath + bestError.instancePath,\n })),\n ]\n }\n }\n }\n errors = [...unrelatedErrors, ...simplifiedUnionRelatedErrors]\n\n resolvedUnionErrors.add(unionError.instancePath)\n }\n return errors\n}\n"]}
1
+ {"version":3,"file":"json-schema.js","sourceRoot":"","sources":["../../../src/public/node/json-schema.ts"],"names":[],"mappings":"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","sourcesContent":["import {randomUUID} from './crypto.js'\nimport {ParseConfigurationResult} from './schema.js'\nimport {getPathValue} from '../common/object.js'\n\nimport {capitalize} from '../common/string.js'\nimport {Ajv, ErrorObject, SchemaObject, ValidateFunction} from 'ajv'\nimport $RefParser from '@apidevtools/json-schema-ref-parser'\nimport cloneDeep from 'lodash/cloneDeep.js'\n\nexport type HandleInvalidAdditionalProperties = 'strip' | 'fail'\n\ntype AjvError = ErrorObject<string, Record<string, unknown>>\n\n/**\n * Normalises a JSON Schema by standardising it's internal implementation.\n *\n * We prefer to not use $ref elements in our schemas, so we inline them; it's easier then to process errors.\n *\n * @param schema - The JSON schema (as a string) to normalise.\n * @returns The normalised JSON schema.\n */\nexport async function normaliseJsonSchema(schema: string): Promise<SchemaObject> {\n // we want to modify the schema, removing any $ref elements and inlining with their source\n const parsedSchema = JSON.parse(schema)\n await $RefParser.dereference(parsedSchema, {resolve: {external: false}})\n return parsedSchema\n}\n\nfunction createAjvValidator(\n handleInvalidAdditionalProperties: HandleInvalidAdditionalProperties,\n schema: SchemaObject,\n) {\n // allowUnionTypes: Allows types like `type: [\"string\", \"number\"]`\n if (handleInvalidAdditionalProperties === 'strip') {\n // we need to let additional properties through, so that we can strip them later\n schema.additionalProperties = true\n }\n\n const ajv = new Ajv({allowUnionTypes: true, allErrors: true, verbose: true})\n ajv.addKeyword('x-taplo')\n\n const validator = ajv.compile(schema)\n\n return validator\n}\n\nconst validatorsCache = new Map<string, ValidateFunction>()\n\n/**\n * Given a subject object and a JSON schema contract, validate the subject against the contract.\n *\n * Errors are returned in a zod-like format, and processed to better handle unions.\n *\n * @param subject - The object to validate.\n * @param schema - The JSON schema to validate against.\n * @param handleInvalidAdditionalProperties - Whether to strip or fail on invalid additional properties.\n * @param identifier - The identifier of the schema being validated, used to cache the validator.\n * @returns The result of the validation. If the state is 'error', the errors will be in a zod-like format.\n */\nexport function jsonSchemaValidate(\n subject: object,\n schema: SchemaObject,\n handleInvalidAdditionalProperties: HandleInvalidAdditionalProperties,\n identifier?: string,\n): ParseConfigurationResult<unknown> & {rawErrors?: AjvError[]} {\n const subjectToModify = cloneDeep(subject)\n\n const cacheKey = identifier ?? randomUUID()\n\n const validator = validatorsCache.get(cacheKey) ?? createAjvValidator(handleInvalidAdditionalProperties, schema)\n validatorsCache.set(cacheKey, validator)\n\n validator(subjectToModify)\n\n // Errors from the contract are post-processed to be more zod-like and to deal with unions better\n let jsonSchemaErrors\n if (validator.errors && validator.errors.length > 0) {\n jsonSchemaErrors = convertJsonSchemaErrors(validator.errors, subjectToModify, schema)\n return {\n state: 'error',\n data: undefined,\n errors: jsonSchemaErrors,\n rawErrors: validator.errors,\n }\n }\n\n if (handleInvalidAdditionalProperties === 'strip') {\n const topLevelSchemaProperties = Object.keys(schema.properties ?? {})\n // strip any properties that are not in the top level schema from subjectToModify\n Object.keys(subjectToModify).forEach((key) => {\n if (!topLevelSchemaProperties.includes(key)) {\n // this isn't actually dynamic, because key came from Object.keys\n\n delete subjectToModify[key as keyof typeof subjectToModify]\n }\n })\n }\n\n return {\n state: 'ok',\n data: subjectToModify,\n errors: undefined,\n rawErrors: undefined,\n }\n}\n\n/**\n * Converts errors from Ajv into a zod-like format.\n *\n * @param rawErrors - JSON Schema errors taken directly from Ajv.\n * @param subject - The object being validated.\n * @param schema - The JSON schema to validated against.\n * @returns The errors in a zod-like format.\n */\nfunction convertJsonSchemaErrors(rawErrors: AjvError[], subject: object, schema: SchemaObject) {\n // This reduces the number of errors by simplifying errors coming from different branches of a union\n const errors = simplifyUnionErrors(rawErrors, subject, schema)\n\n // Now we can remap errors to be more zod-like\n return errors.map((error) => {\n const path: string[] = error.instancePath.split('/').slice(1)\n if (error.params.missingProperty) {\n const missingProperty = error.params.missingProperty as string\n return {path: [...path, missingProperty], message: 'Required'}\n }\n\n if (error.params.type) {\n const expectedType = Array.isArray(error.params.type)\n ? error.params.type.join(', ')\n : (error.params.type as string)\n const actualType = getPathValue(subject, path.join('.'))\n return {path, message: `Expected ${expectedType}, received ${typeof actualType}`}\n }\n\n if (error.keyword === 'anyOf' || error.keyword === 'oneOf') {\n return {path, message: 'Invalid input'}\n }\n\n if (error.params.allowedValues) {\n const allowedValues = error.params.allowedValues as string[]\n const actualValue = getPathValue(subject, path.join('.'))\n return {\n path,\n message: `Invalid enum value. Expected ${allowedValues\n .map((value) => JSON.stringify(value))\n .join(' | ')}, received ${JSON.stringify(actualValue)}`.replace(/\"/g, \"'\"),\n }\n }\n\n if (error.params.comparison) {\n const comparison = error.params.comparison as string\n const limit = error.params.limit\n const actualValue = getPathValue(subject, path.join('.'))\n\n let comparisonText = comparison\n switch (comparison) {\n case '<=':\n comparisonText = 'less than or equal to'\n break\n case '<':\n comparisonText = 'less than'\n break\n case '>=':\n comparisonText = 'greater than or equal to'\n break\n case '>':\n comparisonText = 'greater than'\n break\n }\n\n return {\n path,\n message: capitalize(`${typeof actualValue} must be ${comparisonText} ${limit}`),\n }\n }\n\n if (error.params.additionalProperty) {\n const supportedProperties = Object.keys(error.parentSchema?.properties ?? {})\n\n // if a property was already set, remove it from here\n const alreadySetProperties = Object.keys(error.data ?? {})\n const remainingProperties = supportedProperties.filter((property) => !alreadySetProperties.includes(property))\n\n if (remainingProperties.length > 0) {\n return {\n path: [...path, error.params.additionalProperty as string],\n message: `No additional properties allowed. You can set ${remainingProperties.sort().join(', ')}.`,\n }\n }\n }\n\n return {\n path,\n message: error.message,\n }\n })\n}\n\n/**\n * If a JSON schema specifies a union (anyOf, oneOf), and the subject doesn't meet any of the 'candidates' for the\n * union, then the error list received ends up being quite long: you get an error for the union property itself, and\n * then additional errors for each of the candidate branches.\n *\n * This function simplifies the error collection. By default it strips anything other than the union error itself.\n *\n * In some cases, it can be possible to identify what the intended branch of the union was -- for instance, maybe there\n * is a discriminating field like `type` that is unique between the branches. We inspect each candidate branch and if\n * one branch is less wrong than the others -- e.g. It had a valid `type`, but problems elsewhere -- then we keep the\n * errors for that branch.\n *\n * This is complex but in practise gives much more actionable errors.\n *\n * @param rawErrors - JSON Schema errors taken directly from Ajv.\n * @param subject - The object being validated.\n * @param schema - The JSON schema to validated against.\n * @returns A simplified list of errors.\n */\nfunction simplifyUnionErrors(rawErrors: AjvError[], subject: object, schema: SchemaObject): AjvError[] {\n let errors = rawErrors\n\n const resolvedUnionErrors = new Set()\n while (true) {\n const unionError = errors.filter(\n (error) =>\n (error.keyword === 'oneOf' || error.keyword === 'anyOf') && !resolvedUnionErrors.has(error.instancePath),\n )[0]\n if (unionError === undefined) {\n break\n }\n // split errors into those sharing an instance path and those not\n const unrelatedErrors = errors.filter((error) => !error.instancePath.startsWith(unionError.instancePath))\n\n // we start by assuming only the union error itself is useful, and not the errors from the candidate schemas\n let simplifiedUnionRelatedErrors: AjvError[] = [unionError]\n\n // get the schema list from where the union issue occured\n const dottedSchemaPath = unionError.schemaPath.replace('#/', '').replace(/\\//g, '.')\n const unionSchemas = getPathValue<SchemaObject[]>(schema, dottedSchemaPath)\n // and the slice of the subject that caused the issue\n const subjectValue = getPathValue(subject, unionError.instancePath.split('/').slice(1).join('.'))\n\n if (unionSchemas !== undefined && subjectValue !== undefined) {\n // we know that none of the union schemas are correct, but for each of them we can measure how wrong they are\n const correctValuesAndErrors = unionSchemas\n .map((candidateSchemaFromUnion: SchemaObject) => {\n const candidateSchemaValidator = createAjvValidator('fail', candidateSchemaFromUnion)\n candidateSchemaValidator(subjectValue)\n\n let score = 0\n if (candidateSchemaFromUnion.type === 'object') {\n // provided the schema is an object, we can measure how many properties are good\n const candidatesObjectProperties = Object.keys(candidateSchemaFromUnion.properties)\n score = candidatesObjectProperties.reduce((acc, propertyName) => {\n const subSchema = candidateSchemaFromUnion.properties[propertyName] as SchemaObject\n const subjectValueSlice = getPathValue(subjectValue, propertyName)\n\n const subValidator = createAjvValidator('fail', subSchema)\n if (subValidator(subjectValueSlice)) {\n return acc + 1\n }\n return acc\n }, score)\n }\n\n return [score, candidateSchemaValidator.errors!] as const\n })\n .sort(([scoreA], [scoreB]) => scoreA - scoreB)\n\n if (correctValuesAndErrors.length >= 2) {\n const [bestScore, bestErrors] = correctValuesAndErrors[correctValuesAndErrors.length - 1]!\n const [penultimateScore] = correctValuesAndErrors[correctValuesAndErrors.length - 2]!\n\n if (bestScore !== penultimateScore) {\n // If there's a winner, show the errors for the best schema as they'll likely be actionable.\n // We got these through a nested schema, so we need to adjust the instance path\n simplifiedUnionRelatedErrors = [\n unionError,\n ...bestErrors.map((bestError) => ({\n ...bestError,\n instancePath: unionError.instancePath + bestError.instancePath,\n })),\n ]\n }\n }\n }\n errors = [...unrelatedErrors, ...simplifiedUnionRelatedErrors]\n\n resolvedUnionErrors.add(unionError.instancePath)\n }\n return errors\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { mkdir, readFile, copyFile, chmod, isDirectory, writeFile, fileHasExecutablePermissions, glob, fileExists, matchGlob, } from './fs.js';
2
2
  import { joinPath, dirname, relativePath } from './path.js';
3
- import { outputContent, outputToken, outputDebug } from '../../public/node/output.js';
3
+ import { outputContent, outputToken, outputDebug } from './output.js';
4
4
  import { Liquid } from 'liquidjs';
5
5
  /**
6
6
  * Renders a template using the Liquid template engine.
@@ -1 +1 @@
1
- {"version":3,"file":"liquid.js","sourceRoot":"","sources":["../../../src/public/node/liquid.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n mkdir,\n readFile,\n copyFile,\n chmod,\n isDirectory,\n writeFile,\n fileHasExecutablePermissions,\n glob,\n fileExists,\n matchGlob,\n} from './fs.js'\nimport {joinPath, dirname, relativePath} from './path.js'\nimport {outputContent, outputToken, outputDebug} from '../../public/node/output.js'\nimport {Liquid} from 'liquidjs'\n\n/**\n * Renders a template using the Liquid template engine.\n *\n * @param templateContent - Template content.\n * @param data - Data to feed the template engine.\n * @returns Rendered template.\n */\nexport function renderLiquidTemplate(templateContent: string, data: object): Promise<string> {\n const engine = new Liquid()\n return engine.render(engine.parse(templateContent), data)\n}\n\n/**\n * Given a directory, it traverses the files and directories recursively\n * and replaces variables in directory and file names, and files' content\n * using the Liquid template engine.\n * Files indicate that they are liquid template by using the .liquid extension.\n *\n * @param from - Directory that contains the template.\n * @param to - Output directory.\n * @param data - Data to feed the template engine.\n */\nexport async function recursiveLiquidTemplateCopy(from: string, to: string, data: object): Promise<void> {\n outputDebug(outputContent`Copying template from directory ${outputToken.path(from)} to ${outputToken.path(to)}`)\n const templateFiles: string[] = await glob(joinPath(from, '**/*'), {dot: true})\n\n const bypassPaths = joinPath(from, '.cli-liquid-bypass')\n let bypassPatterns: string[] = []\n if (await fileExists(bypassPaths)) {\n bypassPatterns = (await readFile(bypassPaths)).split('\\n').filter((line) => line.trim().length > 0)\n }\n\n const sortedTemplateFiles = templateFiles\n .map((path) => path.split('/'))\n .sort((lhs, rhs) => (lhs.length < rhs.length ? 1 : -1))\n .map((components) => components.join('/'))\n await Promise.all(\n sortedTemplateFiles.map(async (templateItemPath) => {\n const outputPath = await renderLiquidTemplate(joinPath(to, relativePath(from, templateItemPath)), data)\n const bypass = bypassPatterns.some((pattern) => {\n const path = relativePath(from, templateItemPath)\n const cleanPattern = pattern.replace(/^\\.\\//, '')\n\n return matchGlob(path, cleanPattern) || path.startsWith(cleanPattern)\n })\n\n if (await isDirectory(templateItemPath)) {\n await mkdir(outputPath)\n } else if (templateItemPath.endsWith('.liquid') && !bypass) {\n await mkdir(dirname(outputPath))\n const content = await readFile(templateItemPath)\n const contentOutput = await renderLiquidTemplate(content, data)\n const isExecutable = await fileHasExecutablePermissions(templateItemPath)\n const outputPathWithoutLiquid = outputPath.replace('.liquid', '')\n await copyFile(templateItemPath, outputPathWithoutLiquid)\n await writeFile(outputPathWithoutLiquid, contentOutput)\n if (isExecutable) {\n await chmod(outputPathWithoutLiquid, 0o755)\n }\n } else if (templateItemPath.endsWith('.raw')) {\n const outputPathWithoutRaw = outputPath.replace('.raw', '')\n await copyFile(templateItemPath, outputPathWithoutRaw)\n } else {\n await copyFile(templateItemPath, outputPath)\n }\n }),\n )\n}\n"]}
1
+ {"version":3,"file":"liquid.js","sourceRoot":"","sources":["../../../src/public/node/liquid.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n mkdir,\n readFile,\n copyFile,\n chmod,\n isDirectory,\n writeFile,\n fileHasExecutablePermissions,\n glob,\n fileExists,\n matchGlob,\n} from './fs.js'\nimport {joinPath, dirname, relativePath} from './path.js'\nimport {outputContent, outputToken, outputDebug} from './output.js'\nimport {Liquid} from 'liquidjs'\n\n/**\n * Renders a template using the Liquid template engine.\n *\n * @param templateContent - Template content.\n * @param data - Data to feed the template engine.\n * @returns Rendered template.\n */\nexport function renderLiquidTemplate(templateContent: string, data: object): Promise<string> {\n const engine = new Liquid()\n return engine.render(engine.parse(templateContent), data)\n}\n\n/**\n * Given a directory, it traverses the files and directories recursively\n * and replaces variables in directory and file names, and files' content\n * using the Liquid template engine.\n * Files indicate that they are liquid template by using the .liquid extension.\n *\n * @param from - Directory that contains the template.\n * @param to - Output directory.\n * @param data - Data to feed the template engine.\n */\nexport async function recursiveLiquidTemplateCopy(from: string, to: string, data: object): Promise<void> {\n outputDebug(outputContent`Copying template from directory ${outputToken.path(from)} to ${outputToken.path(to)}`)\n const templateFiles: string[] = await glob(joinPath(from, '**/*'), {dot: true})\n\n const bypassPaths = joinPath(from, '.cli-liquid-bypass')\n let bypassPatterns: string[] = []\n if (await fileExists(bypassPaths)) {\n bypassPatterns = (await readFile(bypassPaths)).split('\\n').filter((line) => line.trim().length > 0)\n }\n\n const sortedTemplateFiles = templateFiles\n .map((path) => path.split('/'))\n .sort((lhs, rhs) => (lhs.length < rhs.length ? 1 : -1))\n .map((components) => components.join('/'))\n await Promise.all(\n sortedTemplateFiles.map(async (templateItemPath) => {\n const outputPath = await renderLiquidTemplate(joinPath(to, relativePath(from, templateItemPath)), data)\n const bypass = bypassPatterns.some((pattern) => {\n const path = relativePath(from, templateItemPath)\n const cleanPattern = pattern.replace(/^\\.\\//, '')\n\n return matchGlob(path, cleanPattern) || path.startsWith(cleanPattern)\n })\n\n if (await isDirectory(templateItemPath)) {\n await mkdir(outputPath)\n } else if (templateItemPath.endsWith('.liquid') && !bypass) {\n await mkdir(dirname(outputPath))\n const content = await readFile(templateItemPath)\n const contentOutput = await renderLiquidTemplate(content, data)\n const isExecutable = await fileHasExecutablePermissions(templateItemPath)\n const outputPathWithoutLiquid = outputPath.replace('.liquid', '')\n await copyFile(templateItemPath, outputPathWithoutLiquid)\n await writeFile(outputPathWithoutLiquid, contentOutput)\n if (isExecutable) {\n await chmod(outputPathWithoutLiquid, 0o755)\n }\n } else if (templateItemPath.endsWith('.raw')) {\n const outputPathWithoutRaw = outputPath.replace('.raw', '')\n await copyFile(templateItemPath, outputPathWithoutRaw)\n } else {\n await copyFile(templateItemPath, outputPath)\n }\n }),\n )\n}\n"]}
@@ -2,9 +2,7 @@
2
2
  * A wrapper around the `conf` package that provides a strongly-typed interface
3
3
  * for accessing the local storage.
4
4
  */
5
- export declare class LocalStorage<T extends {
6
- [key: string]: any;
7
- }> {
5
+ export declare class LocalStorage<T extends Record<string, any>> {
8
6
  private readonly config;
9
7
  constructor(options: {
10
8
  projectName?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"local-storage.js","sourceRoot":"","sources":["../../../src/public/node/local-storage.ts"],"names":[],"mappings":"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","sourcesContent":["import {AbortError, BugError} from './error.js'\nimport {fileHasWritePermissions, unixFileIsOwnedByCurrentUser} from './fs.js'\nimport {dirname} from './path.js'\nimport {TokenItem} from './ui.js'\nimport Config from 'conf'\n\n/**\n * A wrapper around the `conf` package that provides a strongly-typed interface\n * for accessing the local storage.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class LocalStorage<T extends {[key: string]: any}> {\n private readonly config: Config<T>\n\n constructor(options: {projectName?: string; cwd?: string}) {\n this.config = new Config<T>(options)\n }\n\n /**\n * Get a value from the local storage.\n *\n * @param key - The key to get.\n * @returns The value.\n * @throws AbortError if a permission error occurs.\n * @throws BugError if an unexpected error occurs.\n */\n get<TKey extends keyof T>(key: TKey): T[TKey] | undefined {\n try {\n return this.config.get(key)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n this.handleError(error, 'get')\n }\n }\n\n /**\n * Set a value in the local storage.\n *\n * @param key - The key to set.\n * @param value - The value to set.\n * @throws AbortError if a permission error occurs.\n * @throws BugError if an unexpected error occurs.\n */\n set<TKey extends keyof T>(key: TKey, value?: T[TKey]): void {\n try {\n this.config.set(key, value)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n this.handleError(error, 'set')\n }\n }\n\n /**\n * Delete a value from the local storage.\n *\n * @param key - The key to delete.\n * @throws AbortError if a permission error occurs.\n * @throws BugError if an unexpected error occurs.\n */\n delete<TKey extends keyof T>(key: TKey): void {\n try {\n this.config.delete(key)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n this.handleError(error, 'delete')\n }\n }\n\n /**\n * Clear the local storage (delete all values).\n *\n * @throws AbortError if a permission error occurs.\n * @throws BugError if an unexpected error occurs.\n */\n clear(): void {\n try {\n this.config.clear()\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n this.handleError(error, 'clear')\n }\n }\n\n /**\n * Handle errors from config operations.\n * If the error is permission-related, throw an AbortError with helpful hints.\n * Otherwise, throw a BugError.\n *\n * @param error - The error that occurred.\n * @param operation - The operation that failed.\n * @throws AbortError if the error is permission-related.\n * @throws BugError if the error is not permission-related.\n */\n private handleError(error: unknown, operation: string): never {\n if (this.isPermissionError()) {\n throw new AbortError(`Failed to access local storage (${operation}): ${error}`, this.tryMessage())\n } else {\n throw new BugError(\n `Unexpected error while accessing local storage at ${this.config.path} (${operation}): ${error}`,\n )\n }\n }\n\n private isPermissionError(): boolean {\n const canAccessFile = fileHasWritePermissions(this.config.path)\n const canAccessFolder = fileHasWritePermissions(dirname(this.config.path))\n const ownsFile = unixFileIsOwnedByCurrentUser(this.config.path)\n\n return !canAccessFile || !canAccessFolder || ownsFile === false\n }\n\n private tryMessage() {\n const ownsFile = unixFileIsOwnedByCurrentUser(this.config.path)\n const ownsFolder = unixFileIsOwnedByCurrentUser(dirname(this.config.path))\n\n const message: TokenItem = [`Check that you have write permissions for`, {filePath: this.config.path}]\n if (ownsFile === false || ownsFolder === false) {\n message.push(\n '- The file is owned by a different user. This typically happens when Shopify CLI was previously run with elevated permissions (e.g., sudo).',\n )\n }\n\n message.push('\\n\\nTo resolve this, remove the Shopify CLI preferences folder:')\n message.push({command: `rm -rf ${dirname(this.config.path)}`})\n\n return message\n }\n}\n"]}
1
+ {"version":3,"file":"local-storage.js","sourceRoot":"","sources":["../../../src/public/node/local-storage.ts"],"names":[],"mappings":"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","sourcesContent":["import {AbortError, BugError} from './error.js'\nimport {fileHasWritePermissions, unixFileIsOwnedByCurrentUser} from './fs.js'\nimport {dirname} from './path.js'\nimport {TokenItem} from './ui.js'\nimport Config from 'conf'\n\n/**\n * A wrapper around the `conf` package that provides a strongly-typed interface\n * for accessing the local storage.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class LocalStorage<T extends Record<string, any>> {\n private readonly config: Config<T>\n\n constructor(options: {projectName?: string; cwd?: string}) {\n this.config = new Config<T>(options)\n }\n\n /**\n * Get a value from the local storage.\n *\n * @param key - The key to get.\n * @returns The value.\n * @throws AbortError if a permission error occurs.\n * @throws BugError if an unexpected error occurs.\n */\n get<TKey extends keyof T>(key: TKey): T[TKey] | undefined {\n try {\n return this.config.get(key)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n this.handleError(error, 'get')\n }\n }\n\n /**\n * Set a value in the local storage.\n *\n * @param key - The key to set.\n * @param value - The value to set.\n * @throws AbortError if a permission error occurs.\n * @throws BugError if an unexpected error occurs.\n */\n set<TKey extends keyof T>(key: TKey, value?: T[TKey]): void {\n try {\n this.config.set(key, value)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n this.handleError(error, 'set')\n }\n }\n\n /**\n * Delete a value from the local storage.\n *\n * @param key - The key to delete.\n * @throws AbortError if a permission error occurs.\n * @throws BugError if an unexpected error occurs.\n */\n delete<TKey extends keyof T>(key: TKey): void {\n try {\n this.config.delete(key)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n this.handleError(error, 'delete')\n }\n }\n\n /**\n * Clear the local storage (delete all values).\n *\n * @throws AbortError if a permission error occurs.\n * @throws BugError if an unexpected error occurs.\n */\n clear(): void {\n try {\n this.config.clear()\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n this.handleError(error, 'clear')\n }\n }\n\n /**\n * Handle errors from config operations.\n * If the error is permission-related, throw an AbortError with helpful hints.\n * Otherwise, throw a BugError.\n *\n * @param error - The error that occurred.\n * @param operation - The operation that failed.\n * @throws AbortError if the error is permission-related.\n * @throws BugError if the error is not permission-related.\n */\n private handleError(error: unknown, operation: string): never {\n if (this.isPermissionError()) {\n throw new AbortError(`Failed to access local storage (${operation}): ${error}`, this.tryMessage())\n } else {\n throw new BugError(\n `Unexpected error while accessing local storage at ${this.config.path} (${operation}): ${error}`,\n )\n }\n }\n\n private isPermissionError(): boolean {\n const canAccessFile = fileHasWritePermissions(this.config.path)\n const canAccessFolder = fileHasWritePermissions(dirname(this.config.path))\n const ownsFile = unixFileIsOwnedByCurrentUser(this.config.path)\n\n return !canAccessFile || !canAccessFolder || ownsFile === false\n }\n\n private tryMessage() {\n const ownsFile = unixFileIsOwnedByCurrentUser(this.config.path)\n const ownsFolder = unixFileIsOwnedByCurrentUser(dirname(this.config.path))\n\n const message: TokenItem = [`Check that you have write permissions for`, {filePath: this.config.path}]\n if (ownsFile === false || ownsFolder === false) {\n message.push(\n '- The file is owned by a different user. This typically happens when Shopify CLI was previously run with elevated permissions (e.g., sudo).',\n )\n }\n\n message.push('\\n\\nTo resolve this, remove the Shopify CLI preferences folder:')\n message.push({command: `rm -rf ${dirname(this.config.path)}`})\n\n return message\n }\n}\n"]}
@@ -33,9 +33,7 @@ export type SensitiveSchema<T> = T extends RuntimeMetadataManager<infer _TPublic
33
33
  * @param defaultPublicMetadata - Optional, default data for the container.
34
34
  * @returns A container for the metadata.
35
35
  */
36
- export declare function createRuntimeMetadataContainer<TPublic extends AnyJson, TSensitive extends AnyJson = {
37
- [key: string]: never;
38
- }>(defaultPublicMetadata?: Partial<TPublic>): RuntimeMetadataManager<TPublic, TSensitive>;
36
+ export declare function createRuntimeMetadataContainer<TPublic extends AnyJson, TSensitive extends AnyJson = Record<string, never>>(defaultPublicMetadata?: Partial<TPublic>): RuntimeMetadataManager<TPublic, TSensitive>;
39
37
  type CmdFieldsFromMonorail = PickByPrefix<MonorailEventPublic, 'cmd_all_'> & PickByPrefix<MonorailEventPublic, 'cmd_app_'> & PickByPrefix<MonorailEventPublic, 'cmd_create_app_'> & PickByPrefix<MonorailEventPublic, 'cmd_theme_'> & PickByPrefix<MonorailEventPublic, 'store_'>;
40
38
  declare const coreData: RuntimeMetadataManager<CmdFieldsFromMonorail, {
41
39
  commandStartOptions: {
@@ -90,7 +90,6 @@ export function createRuntimeMetadataContainer(defaultPublicMetadata = {}) {
90
90
  end = Math.max(start, end);
91
91
  // The top of the stack is the total time for all nested timers
92
92
  const wallClockDuration = Math.max(end - start, 0);
93
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
94
93
  const childDurations = durationStack.pop();
95
94
  const duration = Math.max(wallClockDuration - childDurations, 0);
96
95
  // If this is the topmost timer, the stack will be empty.
@@ -1 +1 @@
1
- {"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../../src/public/node/metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAC,WAAW,EAAC,MAAM,iBAAiB,CAAA;AAe3C;;;;GAIG;AACH,SAAS,gCAAgC;IACvC,IAAI,UAAU,EAAE,EAAE,CAAC;QACjB,OAAO,QAAQ,CAAA;IACjB,CAAC;IACD,OAAO,iBAAiB,CAAA;AAC1B,CAAC;AA4BD;;;;;;GAMG;AACH,MAAM,UAAU,8BAA8B,CAG5C,wBAA0C,EAAE;IAC5C,MAAM,GAAG,GAA+D;QACtE,SAAS,EAAE,EAAE;QACb,MAAM,EAAE;YACN,GAAG,qBAAqB;SACzB;KACF,CAAA;IACD,MAAM,SAAS,GAAG,CAAC,IAAsB,EAAE,EAAE;QAC3C,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IACjC,CAAC,CAAA;IACD,MAAM,YAAY,GAAG,CAAC,IAAyB,EAAE,EAAE;QACjD,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;IACpC,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,KAAK,EACvB,KAAiC,EACjC,KAAyB,EACzB,OAA8B,EAC9B,EAAE;QACF,MAAM,aAAa,GAAG,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,gCAAgC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAA;QACvF,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE;YAC3B,MAAM,IAAI,GAAG,MAAM,KAAK,EAAE,CAAA;YAC1B,KAAK,CAAC,IAAI,CAAC,CAAA;QACb,CAAC,CAAA;QAED,IAAI,aAAa,KAAK,QAAQ,EAAE,CAAC;YAC/B,MAAM,SAAS,EAAE,CAAA;QACnB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC;gBACH,MAAM,SAAS,EAAE,CAAA;gBACjB,yFAAyF;YAC3F,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,oFAAoF;gBACpF,MAAM,EAAC,kBAAkB,EAAC,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAA;gBAC/D,MAAM,kBAAkB,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAAA;YACrD,CAAC;QACH,CAAC;IACH,CAAC,CAAA;IAED,4BAA4B;IAC5B,MAAM,aAAa,GAAa,EAAE,CAAA;IAElC,OAAO;QACL,oBAAoB,EAAE,GAAG,EAAE;YACzB,OAAO,EAAC,GAAG,GAAG,CAAC,MAAM,EAAC,CAAA;QACxB,CAAC;QACD,uBAAuB,EAAE,GAAG,EAAE;YAC5B,OAAO,EAAC,GAAG,GAAG,CAAC,SAAS,EAAC,CAAA;QAC3B,CAAC;QACD,iBAAiB,EAAE,KAAK,EAAE,OAAiC,EAAE,UAAiC,MAAM,EAAE,EAAE;YACtG,OAAO,WAAW,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;QACjD,CAAC;QACD,oBAAoB,EAAE,KAAK,EAAE,OAAoC,EAAE,UAAiC,MAAM,EAAE,EAAE;YAC5G,OAAO,WAAW,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;QACpD,CAAC;QACD,YAAY,EAAE,CAAC,KAA4B,EAA6C,EAAE;YACxF,OAAO,KAAK,EAAE,EAAE,EAAE,EAAE;gBAClB;;;;;;mBAMG;gBAEH,8DAA8D;gBAC9D,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;gBAErB,2BAA2B;gBAC3B,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;gBAC/B,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,EAAE,EAAE,CAAA;oBACzB,OAAO,MAAM,CAAA;gBACf,CAAC;wBAAS,CAAC;oBACT,IAAI,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;oBAC3B,wGAAwG;oBACxG,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;oBAE1B,+DAA+D;oBAC/D,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,CAAA;oBAClD,oEAAoE;oBACpE,MAAM,cAAc,GAAG,aAAa,CAAC,GAAG,EAAG,CAAA;oBAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,GAAG,cAAc,EAAE,CAAC,CAAC,CAAA;oBAEhE,yDAAyD;oBACzD,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAC7B,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,iBAAiB,CAAA;oBAC9G,CAAC;oBAED,+KAA+K;oBAC/K,WAAW,CAAC,OAAO,CAAC,GAAG,KAAK,aAAa,EAAE;wBACzC,KAAK;wBACL,QAAQ;wBACR,8DAA8D;qBACxD,CAAC,CAAA;oBACT,WAAW,CAAC,OAAO,CAAC,GAAG,KAAK,OAAO,EAAE;wBACnC,KAAK;wBACL,GAAG;wBACH,8DAA8D;qBACxD,CAAC,CAAA;oBAET,sCAAsC;oBACtC,IAAI,YAAY,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAW,CAAA;oBACrD,YAAY,IAAI,QAAQ,CAAA;oBAExB,wFAAwF;oBACxF,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,YAA8C,CAAA;gBACpE,CAAC;YACH,CAAC,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC;AAUD,MAAM,QAAQ,GAAG,8BAA8B,CAU7C,EAAC,yBAAyB,EAAE,CAAC,EAAE,yBAAyB,EAAE,CAAC,EAAC,CAAC,CAAA;AAE/D,MAAM,CAAC,MAAM,EAAC,oBAAoB,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,YAAY,EAAC,GACjH,QAAQ,CAAA","sourcesContent":["import {isUnitTest} from './context/local.js'\nimport {performance} from 'node:perf_hooks'\nimport type {PickByPrefix} from '../common/ts/pick-by-prefix.js'\nimport type {AnyJson} from '../../private/common/json.js'\nimport type {MonorailEventPublic, MonorailEventSensitive} from './monorail.js'\n\ntype ProvideMetadata<T> = () => Partial<T> | Promise<Partial<T>>\n\ntype MetadataErrorHandling =\n // Mute & report errors in production, throw them whilst testing\n | 'auto'\n // Errors are not reported to the user and do not stop execution, but they are reported to Bugsnag\n | 'mute-and-report'\n // Errors are not caught and will bubble out as normal\n | 'bubble'\n\n/**\n * Get the error handling strategy for metadata.\n *\n * @returns 'mute-and-report' in production, 'bubble' in tests.\n */\nfunction getMetadataErrorHandlingStrategy(): 'mute-and-report' | 'bubble' {\n if (isUnitTest()) {\n return 'bubble'\n }\n return 'mute-and-report'\n}\n\n/**\n * Any key in T that has a numeric value.\n */\ntype NumericKeyOf<T> = {\n [K in keyof T]: T[K] extends number ? (K extends string ? K : never) : never\n}[keyof T]\n\nexport interface RuntimeMetadataManager<TPublic extends AnyJson, TSensitive extends AnyJson> {\n /** Add some public metadata -- this should not contain any PII. */\n addPublicMetadata: (getData: ProvideMetadata<TPublic>, onError?: MetadataErrorHandling) => Promise<void>\n /**\n * Add some potentially sensitive metadata -- this may include PII, but unnecessary data should never be tracked\n * (this is a good fit for command args for instance).\n */\n addSensitiveMetadata: (getData: ProvideMetadata<TSensitive>, onError?: MetadataErrorHandling) => Promise<void>\n /** Get a snapshot of the tracked public data. */\n getAllPublicMetadata: () => Partial<TPublic>\n /** Get a snapshot of the tracked sensitive data. */\n getAllSensitiveMetadata: () => Partial<TSensitive>\n /** Run a function, monitoring how long it takes, and adding the elapsed time to a running total. */\n runWithTimer: (field: NumericKeyOf<TPublic>) => <T>(fn: () => Promise<T>) => Promise<T>\n}\n\nexport type PublicSchema<T> = T extends RuntimeMetadataManager<infer TPublic, infer _TSensitive> ? TPublic : never\nexport type SensitiveSchema<T> = T extends RuntimeMetadataManager<infer _TPublic, infer TSensitive> ? TSensitive : never\n\n/**\n * Creates a container for metadata collected at runtime.\n * The container provides async-safe functions for extracting the gathered metadata, and for setting it.\n *\n * @param defaultPublicMetadata - Optional, default data for the container.\n * @returns A container for the metadata.\n */\nexport function createRuntimeMetadataContainer<\n TPublic extends AnyJson,\n TSensitive extends AnyJson = {[key: string]: never},\n>(defaultPublicMetadata: Partial<TPublic> = {}): RuntimeMetadataManager<TPublic, TSensitive> {\n const raw: {sensitive: Partial<TSensitive>; public: Partial<TPublic>} = {\n sensitive: {},\n public: {\n ...defaultPublicMetadata,\n },\n }\n const addPublic = (data: Partial<TPublic>) => {\n Object.assign(raw.public, data)\n }\n const addSensitive = (data: Partial<TSensitive>) => {\n Object.assign(raw.sensitive, data)\n }\n\n const addMetadata = async <T>(\n addFn: (data: Partial<T>) => void,\n getFn: ProvideMetadata<T>,\n onError: MetadataErrorHandling,\n ) => {\n const errorHandling = onError === 'auto' ? getMetadataErrorHandlingStrategy() : onError\n const getAndSet = async () => {\n const data = await getFn()\n addFn(data)\n }\n\n if (errorHandling === 'bubble') {\n await getAndSet()\n } else {\n try {\n await getAndSet()\n // eslint-disable-next-line no-catch-all/no-catch-all, @typescript-eslint/no-explicit-any\n } catch (error: any) {\n // This is very prone to becoming a circular dependency, so we import it dynamically\n const {sendErrorToBugsnag} = await import('./error-handler.js')\n await sendErrorToBugsnag(error, 'unexpected_error')\n }\n }\n }\n\n // See `runWithTimer` below.\n const durationStack: number[] = []\n\n return {\n getAllPublicMetadata: () => {\n return {...raw.public}\n },\n getAllSensitiveMetadata: () => {\n return {...raw.sensitive}\n },\n addPublicMetadata: async (getData: ProvideMetadata<TPublic>, onError: MetadataErrorHandling = 'auto') => {\n return addMetadata(addPublic, getData, onError)\n },\n addSensitiveMetadata: async (getData: ProvideMetadata<TSensitive>, onError: MetadataErrorHandling = 'auto') => {\n return addMetadata(addSensitive, getData, onError)\n },\n runWithTimer: (field: NumericKeyOf<TPublic>): (<T>(fn: () => Promise<T>) => Promise<T>) => {\n return async (fn) => {\n /**\n * For nested timers, we subtract the inner timer's duration from the outer timer's. We use a stack to track the\n * cumulative durations of nested timers. On starting a timer, we push a zero onto the stack to initialize the total\n * duration for subsequent nested timers. Before logging, we pop the stack to get the total nested timers' duration.\n * We subtract this from the current timer's actual duration to get its measurable duration. We then add the current\n * timer's actual duration to the stack's top, allowing any parent timer to deduct it from its own duration.\n */\n\n // Initialise the running total duration for all nested timers\n durationStack.push(0)\n\n // Do the work, and time it\n const start = performance.now()\n try {\n const result = await fn()\n return result\n } finally {\n let end = performance.now()\n // For very short durations, the end time can be before the start time(!) - we flatten this out to zero.\n end = Math.max(start, end)\n\n // The top of the stack is the total time for all nested timers\n const wallClockDuration = Math.max(end - start, 0)\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const childDurations = durationStack.pop()!\n const duration = Math.max(wallClockDuration - childDurations, 0)\n\n // If this is the topmost timer, the stack will be empty.\n if (durationStack.length > 0) {\n durationStack[durationStack.length - 1] = (durationStack[durationStack.length - 1] ?? 0) + wallClockDuration\n }\n\n // Log it -- we include it in the metadata, but also log via the standard performance API. The TS types for this library are not quite right, so we have to cast to `any` here.\n performance.measure(`${field}#measurable`, {\n start,\n duration,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as any)\n performance.measure(`${field}#wall`, {\n start,\n end,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as any)\n\n // There might not be a value set, yet\n let currentValue = (raw.public[field] || 0) as number\n currentValue += duration\n\n // TS is not quite smart enough to realise that raw.public[field] must be a numeric type\n raw.public[field] = currentValue as TPublic[NumericKeyOf<TPublic>]\n }\n }\n },\n }\n}\n\n// We want to track anything that ends up getting sent to monorail as `cmd_all_*`,\n// `cmd_app_*`, `cmd_theme_*`, and `store_*`\ntype CmdFieldsFromMonorail = PickByPrefix<MonorailEventPublic, 'cmd_all_'> &\n PickByPrefix<MonorailEventPublic, 'cmd_app_'> &\n PickByPrefix<MonorailEventPublic, 'cmd_create_app_'> &\n PickByPrefix<MonorailEventPublic, 'cmd_theme_'> &\n PickByPrefix<MonorailEventPublic, 'store_'>\n\nconst coreData = createRuntimeMetadataContainer<\n CmdFieldsFromMonorail,\n {\n commandStartOptions: {\n startTime: number\n startCommand: string\n startTopic?: string\n startArgs: string[]\n }\n } & {environmentFlags: string} & PickByPrefix<MonorailEventSensitive, 'store_'>\n>({cmd_all_timing_network_ms: 0, cmd_all_timing_prompts_ms: 0})\n\nexport const {getAllPublicMetadata, getAllSensitiveMetadata, addPublicMetadata, addSensitiveMetadata, runWithTimer} =\n coreData\n\nexport type Public = PublicSchema<typeof coreData>\nexport type Sensitive = SensitiveSchema<typeof coreData>\n"]}
1
+ {"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../../src/public/node/metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAC,WAAW,EAAC,MAAM,iBAAiB,CAAA;AAe3C;;;;GAIG;AACH,SAAS,gCAAgC;IACvC,IAAI,UAAU,EAAE,EAAE,CAAC;QACjB,OAAO,QAAQ,CAAA;IACjB,CAAC;IACD,OAAO,iBAAiB,CAAA;AAC1B,CAAC;AA4BD;;;;;;GAMG;AACH,MAAM,UAAU,8BAA8B,CAG5C,wBAA0C,EAAE;IAC5C,MAAM,GAAG,GAA+D;QACtE,SAAS,EAAE,EAAE;QACb,MAAM,EAAE;YACN,GAAG,qBAAqB;SACzB;KACF,CAAA;IACD,MAAM,SAAS,GAAG,CAAC,IAAsB,EAAE,EAAE;QAC3C,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IACjC,CAAC,CAAA;IACD,MAAM,YAAY,GAAG,CAAC,IAAyB,EAAE,EAAE;QACjD,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;IACpC,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,KAAK,EACvB,KAAiC,EACjC,KAAyB,EACzB,OAA8B,EAC9B,EAAE;QACF,MAAM,aAAa,GAAG,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,gCAAgC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAA;QACvF,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE;YAC3B,MAAM,IAAI,GAAG,MAAM,KAAK,EAAE,CAAA;YAC1B,KAAK,CAAC,IAAI,CAAC,CAAA;QACb,CAAC,CAAA;QAED,IAAI,aAAa,KAAK,QAAQ,EAAE,CAAC;YAC/B,MAAM,SAAS,EAAE,CAAA;QACnB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC;gBACH,MAAM,SAAS,EAAE,CAAA;gBACjB,yFAAyF;YAC3F,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,oFAAoF;gBACpF,MAAM,EAAC,kBAAkB,EAAC,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAA;gBAC/D,MAAM,kBAAkB,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAAA;YACrD,CAAC;QACH,CAAC;IACH,CAAC,CAAA;IAED,4BAA4B;IAC5B,MAAM,aAAa,GAAa,EAAE,CAAA;IAElC,OAAO;QACL,oBAAoB,EAAE,GAAG,EAAE;YACzB,OAAO,EAAC,GAAG,GAAG,CAAC,MAAM,EAAC,CAAA;QACxB,CAAC;QACD,uBAAuB,EAAE,GAAG,EAAE;YAC5B,OAAO,EAAC,GAAG,GAAG,CAAC,SAAS,EAAC,CAAA;QAC3B,CAAC;QACD,iBAAiB,EAAE,KAAK,EAAE,OAAiC,EAAE,UAAiC,MAAM,EAAE,EAAE;YACtG,OAAO,WAAW,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;QACjD,CAAC;QACD,oBAAoB,EAAE,KAAK,EAAE,OAAoC,EAAE,UAAiC,MAAM,EAAE,EAAE;YAC5G,OAAO,WAAW,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;QACpD,CAAC;QACD,YAAY,EAAE,CAAC,KAA4B,EAA6C,EAAE;YACxF,OAAO,KAAK,EAAE,EAAE,EAAE,EAAE;gBAClB;;;;;;mBAMG;gBAEH,8DAA8D;gBAC9D,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;gBAErB,2BAA2B;gBAC3B,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;gBAC/B,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,EAAE,EAAE,CAAA;oBACzB,OAAO,MAAM,CAAA;gBACf,CAAC;wBAAS,CAAC;oBACT,IAAI,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;oBAC3B,wGAAwG;oBACxG,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;oBAE1B,+DAA+D;oBAC/D,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,CAAA;oBAElD,MAAM,cAAc,GAAG,aAAa,CAAC,GAAG,EAAG,CAAA;oBAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,GAAG,cAAc,EAAE,CAAC,CAAC,CAAA;oBAEhE,yDAAyD;oBACzD,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAC7B,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,iBAAiB,CAAA;oBAC9G,CAAC;oBAED,+KAA+K;oBAC/K,WAAW,CAAC,OAAO,CAAC,GAAG,KAAK,aAAa,EAAE;wBACzC,KAAK;wBACL,QAAQ;wBACR,8DAA8D;qBACxD,CAAC,CAAA;oBACT,WAAW,CAAC,OAAO,CAAC,GAAG,KAAK,OAAO,EAAE;wBACnC,KAAK;wBACL,GAAG;wBACH,8DAA8D;qBACxD,CAAC,CAAA;oBAET,sCAAsC;oBACtC,IAAI,YAAY,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAW,CAAA;oBACrD,YAAY,IAAI,QAAQ,CAAA;oBAExB,wFAAwF;oBACxF,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,YAA8C,CAAA;gBACpE,CAAC;YACH,CAAC,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC;AAUD,MAAM,QAAQ,GAAG,8BAA8B,CAU7C,EAAC,yBAAyB,EAAE,CAAC,EAAE,yBAAyB,EAAE,CAAC,EAAC,CAAC,CAAA;AAE/D,MAAM,CAAC,MAAM,EAAC,oBAAoB,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,YAAY,EAAC,GACjH,QAAQ,CAAA","sourcesContent":["import {isUnitTest} from './context/local.js'\nimport {performance} from 'node:perf_hooks'\nimport type {PickByPrefix} from '../common/ts/pick-by-prefix.js'\nimport type {AnyJson} from '../../private/common/json.js'\nimport type {MonorailEventPublic, MonorailEventSensitive} from './monorail.js'\n\ntype ProvideMetadata<T> = () => Partial<T> | Promise<Partial<T>>\n\ntype MetadataErrorHandling =\n // Mute & report errors in production, throw them whilst testing\n | 'auto'\n // Errors are not reported to the user and do not stop execution, but they are reported to Bugsnag\n | 'mute-and-report'\n // Errors are not caught and will bubble out as normal\n | 'bubble'\n\n/**\n * Get the error handling strategy for metadata.\n *\n * @returns 'mute-and-report' in production, 'bubble' in tests.\n */\nfunction getMetadataErrorHandlingStrategy(): 'mute-and-report' | 'bubble' {\n if (isUnitTest()) {\n return 'bubble'\n }\n return 'mute-and-report'\n}\n\n/**\n * Any key in T that has a numeric value.\n */\ntype NumericKeyOf<T> = {\n [K in keyof T]: T[K] extends number ? (K extends string ? K : never) : never\n}[keyof T]\n\nexport interface RuntimeMetadataManager<TPublic extends AnyJson, TSensitive extends AnyJson> {\n /** Add some public metadata -- this should not contain any PII. */\n addPublicMetadata: (getData: ProvideMetadata<TPublic>, onError?: MetadataErrorHandling) => Promise<void>\n /**\n * Add some potentially sensitive metadata -- this may include PII, but unnecessary data should never be tracked\n * (this is a good fit for command args for instance).\n */\n addSensitiveMetadata: (getData: ProvideMetadata<TSensitive>, onError?: MetadataErrorHandling) => Promise<void>\n /** Get a snapshot of the tracked public data. */\n getAllPublicMetadata: () => Partial<TPublic>\n /** Get a snapshot of the tracked sensitive data. */\n getAllSensitiveMetadata: () => Partial<TSensitive>\n /** Run a function, monitoring how long it takes, and adding the elapsed time to a running total. */\n runWithTimer: (field: NumericKeyOf<TPublic>) => <T>(fn: () => Promise<T>) => Promise<T>\n}\n\nexport type PublicSchema<T> = T extends RuntimeMetadataManager<infer TPublic, infer _TSensitive> ? TPublic : never\nexport type SensitiveSchema<T> = T extends RuntimeMetadataManager<infer _TPublic, infer TSensitive> ? TSensitive : never\n\n/**\n * Creates a container for metadata collected at runtime.\n * The container provides async-safe functions for extracting the gathered metadata, and for setting it.\n *\n * @param defaultPublicMetadata - Optional, default data for the container.\n * @returns A container for the metadata.\n */\nexport function createRuntimeMetadataContainer<\n TPublic extends AnyJson,\n TSensitive extends AnyJson = Record<string, never>,\n>(defaultPublicMetadata: Partial<TPublic> = {}): RuntimeMetadataManager<TPublic, TSensitive> {\n const raw: {sensitive: Partial<TSensitive>; public: Partial<TPublic>} = {\n sensitive: {},\n public: {\n ...defaultPublicMetadata,\n },\n }\n const addPublic = (data: Partial<TPublic>) => {\n Object.assign(raw.public, data)\n }\n const addSensitive = (data: Partial<TSensitive>) => {\n Object.assign(raw.sensitive, data)\n }\n\n const addMetadata = async <T>(\n addFn: (data: Partial<T>) => void,\n getFn: ProvideMetadata<T>,\n onError: MetadataErrorHandling,\n ) => {\n const errorHandling = onError === 'auto' ? getMetadataErrorHandlingStrategy() : onError\n const getAndSet = async () => {\n const data = await getFn()\n addFn(data)\n }\n\n if (errorHandling === 'bubble') {\n await getAndSet()\n } else {\n try {\n await getAndSet()\n // eslint-disable-next-line no-catch-all/no-catch-all, @typescript-eslint/no-explicit-any\n } catch (error: any) {\n // This is very prone to becoming a circular dependency, so we import it dynamically\n const {sendErrorToBugsnag} = await import('./error-handler.js')\n await sendErrorToBugsnag(error, 'unexpected_error')\n }\n }\n }\n\n // See `runWithTimer` below.\n const durationStack: number[] = []\n\n return {\n getAllPublicMetadata: () => {\n return {...raw.public}\n },\n getAllSensitiveMetadata: () => {\n return {...raw.sensitive}\n },\n addPublicMetadata: async (getData: ProvideMetadata<TPublic>, onError: MetadataErrorHandling = 'auto') => {\n return addMetadata(addPublic, getData, onError)\n },\n addSensitiveMetadata: async (getData: ProvideMetadata<TSensitive>, onError: MetadataErrorHandling = 'auto') => {\n return addMetadata(addSensitive, getData, onError)\n },\n runWithTimer: (field: NumericKeyOf<TPublic>): (<T>(fn: () => Promise<T>) => Promise<T>) => {\n return async (fn) => {\n /**\n * For nested timers, we subtract the inner timer's duration from the outer timer's. We use a stack to track the\n * cumulative durations of nested timers. On starting a timer, we push a zero onto the stack to initialize the total\n * duration for subsequent nested timers. Before logging, we pop the stack to get the total nested timers' duration.\n * We subtract this from the current timer's actual duration to get its measurable duration. We then add the current\n * timer's actual duration to the stack's top, allowing any parent timer to deduct it from its own duration.\n */\n\n // Initialise the running total duration for all nested timers\n durationStack.push(0)\n\n // Do the work, and time it\n const start = performance.now()\n try {\n const result = await fn()\n return result\n } finally {\n let end = performance.now()\n // For very short durations, the end time can be before the start time(!) - we flatten this out to zero.\n end = Math.max(start, end)\n\n // The top of the stack is the total time for all nested timers\n const wallClockDuration = Math.max(end - start, 0)\n\n const childDurations = durationStack.pop()!\n const duration = Math.max(wallClockDuration - childDurations, 0)\n\n // If this is the topmost timer, the stack will be empty.\n if (durationStack.length > 0) {\n durationStack[durationStack.length - 1] = (durationStack[durationStack.length - 1] ?? 0) + wallClockDuration\n }\n\n // Log it -- we include it in the metadata, but also log via the standard performance API. The TS types for this library are not quite right, so we have to cast to `any` here.\n performance.measure(`${field}#measurable`, {\n start,\n duration,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as any)\n performance.measure(`${field}#wall`, {\n start,\n end,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as any)\n\n // There might not be a value set, yet\n let currentValue = (raw.public[field] || 0) as number\n currentValue += duration\n\n // TS is not quite smart enough to realise that raw.public[field] must be a numeric type\n raw.public[field] = currentValue as TPublic[NumericKeyOf<TPublic>]\n }\n }\n },\n }\n}\n\n// We want to track anything that ends up getting sent to monorail as `cmd_all_*`,\n// `cmd_app_*`, `cmd_theme_*`, and `store_*`\ntype CmdFieldsFromMonorail = PickByPrefix<MonorailEventPublic, 'cmd_all_'> &\n PickByPrefix<MonorailEventPublic, 'cmd_app_'> &\n PickByPrefix<MonorailEventPublic, 'cmd_create_app_'> &\n PickByPrefix<MonorailEventPublic, 'cmd_theme_'> &\n PickByPrefix<MonorailEventPublic, 'store_'>\n\nconst coreData = createRuntimeMetadataContainer<\n CmdFieldsFromMonorail,\n {\n commandStartOptions: {\n startTime: number\n startCommand: string\n startTopic?: string\n startArgs: string[]\n }\n } & {environmentFlags: string} & PickByPrefix<MonorailEventSensitive, 'store_'>\n>({cmd_all_timing_network_ms: 0, cmd_all_timing_prompts_ms: 0})\n\nexport const {getAllPublicMetadata, getAllSensitiveMetadata, addPublicMetadata, addSensitiveMetadata, runWithTimer} =\n coreData\n\nexport type Public = PublicSchema<typeof coreData>\nexport type Sensitive = SensitiveSchema<typeof coreData>\n"]}
@@ -10,6 +10,4 @@ export declare function lookupMimeType(fileName: string): string;
10
10
  *
11
11
  * @param newTypes - Object of key-values where key is extension and value is mime type.
12
12
  */
13
- export declare function setMimeTypes(newTypes: {
14
- [key: string]: string;
15
- }): void;
13
+ export declare function setMimeTypes(newTypes: Record<string, string>): void;
@@ -1 +1 @@
1
- {"version":3,"file":"mimes.js","sourceRoot":"","sources":["../../../src/public/node/mimes.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,OAAO,EAAC,MAAM,EAAE,KAAK,EAAC,MAAM,QAAQ,CAAA;AAEpC;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,0BAA0B,CAAA;AACvD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,QAAiC;IAC5D,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,EAAE;QACzD,KAAK,CAAC,SAAS,CAAC,GAAG,QAAQ,CAAA;IAC7B,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["// import * as mimeTypes from 'mrmime'\nimport {lookup, mimes} from 'mrmime'\n\n/**\n * Returns the MIME type for a filename.\n *\n * @param fileName - Filename.\n * @returns The mime type.\n */\nexport function lookupMimeType(fileName: string): string {\n return lookup(fileName) || 'application/octet-stream'\n}\n\n/**\n * Adds MIME type(s) to the dictionary.\n *\n * @param newTypes - Object of key-values where key is extension and value is mime type.\n */\nexport function setMimeTypes(newTypes: {[key: string]: string}): void {\n Object.entries(newTypes).forEach(([extension, mimeType]) => {\n mimes[extension] = mimeType\n })\n}\n"]}
1
+ {"version":3,"file":"mimes.js","sourceRoot":"","sources":["../../../src/public/node/mimes.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,OAAO,EAAC,MAAM,EAAE,KAAK,EAAC,MAAM,QAAQ,CAAA;AAEpC;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,0BAA0B,CAAA;AACvD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgC;IAC3D,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,EAAE;QACzD,KAAK,CAAC,SAAS,CAAC,GAAG,QAAQ,CAAA;IAC7B,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["// import * as mimeTypes from 'mrmime'\nimport {lookup, mimes} from 'mrmime'\n\n/**\n * Returns the MIME type for a filename.\n *\n * @param fileName - Filename.\n * @returns The mime type.\n */\nexport function lookupMimeType(fileName: string): string {\n return lookup(fileName) || 'application/octet-stream'\n}\n\n/**\n * Adds MIME type(s) to the dictionary.\n *\n * @param newTypes - Object of key-values where key is extension and value is mime type.\n */\nexport function setMimeTypes(newTypes: Record<string, string>): void {\n Object.entries(newTypes).forEach(([extension, mimeType]) => {\n mimes[extension] = mimeType\n })\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { fetch } from './http.js';
2
- import { outputDebug, outputContent, outputToken } from '../../public/node/output.js';
2
+ import { outputDebug, outputContent, outputToken } from './output.js';
3
3
  const url = 'https://monorail-edge.shopifysvc.com/v1/produce';
4
4
  // This is the topic name of the main event we log to Monorail, the command tracker
5
5
  export const MONORAIL_COMMAND_TOPIC = 'app_cli3_command/1.20';
@@ -1 +1 @@
1
- {"version":3,"file":"monorail.js","sourceRoot":"","sources":["../../../src/public/node/monorail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,WAAW,CAAA;AAE/B,OAAO,EAAC,WAAW,EAAE,aAAa,EAAE,WAAW,EAAC,MAAM,6BAA6B,CAAA;AAKnF,MAAM,GAAG,GAAG,iDAAiD,CAAA;AAI7D,mFAAmF;AACnF,MAAM,CAAC,MAAM,sBAAsB,GAAG,uBAAuB,CAAA;AAuK7D,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAAU,CAAA;AAE/C;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,QAAmB,EACnB,UAA8B,EAC9B,aAAoC;IAEpC,qHAAqH;IACrH,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,CAAA;IACtC,IAAI,WAAW,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;QACnD,IAAI,qBAAqB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YAC3C,OAAO,EAAC,IAAI,EAAE,IAAI,EAAC,CAAA;QACrB,CAAC;QACD,qBAAqB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;IACxC,CAAC;IAED,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAA;QACxC,MAAM,OAAO,GAAG,EAAC,GAAG,UAAU,EAAE,GAAG,aAAa,EAAC,CAAA;QACjD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAC,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAC,CAAC,CAAA;QAC3D,MAAM,OAAO,GAAG,YAAY,CAAC,WAAW,CAAC,CAAA;QAEzC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAC,EAAE,cAAc,CAAC,CAAA;QAElF,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,WAAW,CAAC,aAAa,CAAA,yBAAyB,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAA;YAC/F,OAAO,EAAC,IAAI,EAAE,IAAI,EAAC,CAAA;QACrB,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,qCAAqC,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAA;YACvE,OAAO,EAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,UAAU,EAAC,CAAA;QACtD,CAAC;QACD,qDAAqD;IACvD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,OAAO,GAAG,kCAAkC,CAAA;QAChD,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;QAChD,CAAC;QACD,WAAW,CAAC,OAAO,CAAC,CAAA;QACpB,OAAO,EAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAC,CAAA;IACjC,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,eAAe,CAAmB,OAAU;IACnD,MAAM,MAAM,GAAG,EAAC,GAAG,OAAO,EAAC,CAAA;IAC3B,IAAI,SAAS,IAAI,MAAM,EAAE,CAAC;QACxB,MAAM,CAAC,OAAO,GAAG,MAAM,CAAA;IACzB,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED,MAAM,YAAY,GAAG,CAAC,WAAmB,EAAE,EAAE;IAC3C,OAAO;QACL,cAAc,EAAE,iCAAiC;QACjD,qCAAqC,EAAE,WAAW,CAAC,QAAQ,EAAE;QAC7D,kCAAkC,EAAE,WAAW,CAAC,QAAQ,EAAE;KAC3D,CAAA;AACH,CAAC,CAAA","sourcesContent":["import {fetch} from './http.js'\nimport {JsonMap} from '../../private/common/json.js'\nimport {outputDebug, outputContent, outputToken} from '../../public/node/output.js'\nimport {DeepRequired} from '../common/ts/deep-required.js'\n\nexport {DeepRequired}\n\nconst url = 'https://monorail-edge.shopifysvc.com/v1/produce'\n\ntype Optional<T> = T | null\n\n// This is the topic name of the main event we log to Monorail, the command tracker\nexport const MONORAIL_COMMAND_TOPIC = 'app_cli3_command/1.20'\n\nexport interface Schemas {\n [MONORAIL_COMMAND_TOPIC]: {\n sensitive: {\n args: string\n error_message?: Optional<string>\n app_name?: Optional<string>\n metadata?: Optional<string>\n store_fqdn?: Optional<string>\n cmd_all_environment_flags?: Optional<string>\n\n // Dev related commands\n cmd_dev_tunnel_custom?: Optional<string>\n\n // Environment\n env_plugin_installed_all?: Optional<string>\n env_shopify_variables?: Optional<string>\n }\n public: {\n business_platform_id?: Optional<number>\n partner_id?: Optional<number>\n command: string\n project_type?: Optional<string>\n time_start: number\n time_end: number\n total_time: number\n success: boolean\n api_key?: Optional<string>\n cli_version: string\n uname: string\n ruby_version: string\n node_version: string\n is_employee: boolean\n store_fqdn_hash?: Optional<string>\n user_id: string\n\n // Any and all commands\n cmd_all_alias_used?: Optional<string>\n cmd_all_launcher?: Optional<string>\n cmd_all_path_override?: Optional<boolean>\n cmd_all_path_override_hash?: Optional<string>\n cmd_all_plugin?: Optional<string>\n cmd_all_topic?: Optional<string>\n cmd_all_verbose?: Optional<boolean>\n cmd_all_exit?: Optional<string>\n cmd_all_force?: Optional<boolean>\n cmd_all_last_graphql_request_id?: Optional<string>\n\n cmd_all_timing_network_ms?: Optional<number>\n cmd_all_timing_prompts_ms?: Optional<number>\n cmd_all_timing_active_ms?: Optional<number>\n\n // Any extension related command\n cmd_extensions_binary_from_source?: Optional<boolean>\n\n // Scaffolding related commands\n cmd_scaffold_required_auth?: Optional<boolean>\n cmd_scaffold_template_custom?: Optional<boolean>\n cmd_scaffold_template_flavor?: Optional<string>\n cmd_scaffold_type?: Optional<string>\n cmd_scaffold_type_category?: Optional<string>\n cmd_scaffold_type_gated?: Optional<boolean>\n cmd_scaffold_type_owner?: Optional<string>\n cmd_scaffold_used_prompts_for_type?: Optional<boolean>\n\n // Used in several but not all commands\n cmd_app_dependency_installation_skipped?: Optional<boolean>\n cmd_app_reset_used?: Optional<boolean>\n cmd_app_linked_config_used?: Optional<boolean>\n cmd_app_linked_config_name?: Optional<string>\n cmd_app_linked_config_git_tracked?: Optional<boolean>\n cmd_app_all_configs_any?: Optional<boolean>\n cmd_app_all_configs_clients?: Optional<string>\n cmd_app_linked_config_source?: Optional<string>\n cmd_app_linked_config_uses_cli_managed_urls?: Optional<boolean>\n cmd_app_warning_api_key_deprecation_displayed?: Optional<boolean>\n cmd_app_deployment_mode?: Optional<string>\n\n // Dev related commands\n cmd_dev_tunnel_type?: Optional<string>\n cmd_dev_tunnel_custom_hash?: Optional<string>\n cmd_dev_urls_updated?: Optional<boolean>\n cmd_dev_preview_url_opened?: Optional<boolean>\n cmd_dev_graphiql_opened?: Optional<boolean>\n cmd_dev_dev_preview_toggle_used?: Optional<boolean>\n\n // Create-app related commands\n cmd_create_app_template?: Optional<string>\n cmd_create_app_template_url?: Optional<string>\n\n // Deploy related commands\n cmd_deploy_flag_message_used?: Optional<boolean>\n cmd_deploy_flag_version_used?: Optional<boolean>\n cmd_deploy_flag_source_url_used?: Optional<boolean>\n cmd_deploy_confirm_new_registrations?: Optional<number>\n cmd_deploy_confirm_updated_registrations?: Optional<number>\n cmd_deploy_confirm_removed_registrations?: Optional<number>\n cmd_deploy_confirm_cancelled?: Optional<boolean>\n cmd_deploy_confirm_time_to_complete_ms?: Optional<number>\n cmd_deploy_prompt_upgrade_to_unified_displayed?: Optional<boolean>\n cmd_deploy_prompt_upgrade_to_unified_response?: Optional<string>\n cmd_deploy_confirm_include_config_used?: Optional<boolean>\n cmd_deploy_include_config_used?: Optional<boolean>\n cmd_deploy_config_modules_breakdown?: Optional<string>\n cmd_deploy_config_modules_updated?: Optional<string>\n cmd_deploy_config_modules_added?: Optional<string>\n cmd_deploy_config_modules_deleted?: Optional<string>\n\n // Release related commands\n cmd_release_confirm_cancelled?: Optional<boolean>\n\n // App setup\n app_extensions_any?: Optional<boolean>\n app_extensions_breakdown?: Optional<string>\n app_extensions_count?: Optional<number>\n app_extensions_custom_layout?: Optional<boolean>\n app_extensions_function_any?: Optional<boolean>\n app_extensions_function_count?: Optional<number>\n app_extensions_function_custom_layout?: Optional<boolean>\n app_extensions_theme_any?: Optional<boolean>\n app_extensions_theme_count?: Optional<number>\n app_extensions_theme_custom_layout?: Optional<boolean>\n app_extensions_ui_any?: Optional<boolean>\n app_extensions_ui_count?: Optional<number>\n app_extensions_ui_custom_layout?: Optional<boolean>\n app_name_hash?: Optional<string>\n app_path_hash?: Optional<string>\n app_scopes?: Optional<string>\n app_web_backend_any?: Optional<boolean>\n app_web_backend_count?: Optional<number>\n app_web_custom_layout?: Optional<boolean>\n app_web_framework?: Optional<string>\n app_web_frontend_any?: Optional<boolean>\n app_web_frontend_count?: Optional<number>\n\n // Theme related commands\n cmd_theme_timings?: Optional<string>\n cmd_theme_errors?: Optional<string>\n cmd_theme_retries?: Optional<string>\n cmd_theme_events?: Optional<string>\n\n // Environment\n env_ci?: Optional<boolean>\n env_ci_platform?: Optional<string>\n env_device_id?: Optional<string>\n env_package_manager?: Optional<string>\n env_package_manager_workspaces?: Optional<boolean>\n env_plugin_installed_any_custom?: Optional<boolean>\n env_plugin_installed_shopify?: Optional<string>\n env_shell?: Optional<string>\n env_web_ide?: Optional<string>\n env_cloud?: Optional<string>\n env_is_global?: Optional<boolean>\n env_auth_method?: Optional<string>\n }\n }\n [schemaId: string]: {sensitive: JsonMap; public: JsonMap}\n}\n\n// In reality, we're normally most interested in just this from Schemas, so export it for ease of use.\n// The monorail schema itself has lots of optional values as it must be backwards-compatible. For our schema we want mandatory values instead.\nexport type MonorailEventPublic = DeepRequired<Schemas[typeof MONORAIL_COMMAND_TOPIC]['public']>\nexport type MonorailEventSensitive = Schemas[typeof MONORAIL_COMMAND_TOPIC]['sensitive']\n\ntype MonorailResult = {type: 'ok'} | {type: 'error'; message: string}\n\nconst publishedCommandNames = new Set<string>()\n\n/**\n * Publishes an event to Monorail.\n *\n * @param schemaId - The schema ID of the event to publish.\n * @param publicData - The public data to publish.\n * @param sensitiveData - The sensitive data to publish.\n * @returns A result indicating whether the event was successfully published.\n */\nexport async function publishMonorailEvent<TSchemaId extends keyof Schemas, TPayload extends Schemas[TSchemaId]>(\n schemaId: TSchemaId,\n publicData: TPayload['public'],\n sensitiveData: TPayload['sensitive'],\n): Promise<MonorailResult> {\n // If a command has already been logged, never re-log it. This is to prevent duplication caused by unexpected errors.\n const commandName = publicData.command\n if (commandName && typeof commandName === 'string') {\n if (publishedCommandNames.has(commandName)) {\n return {type: 'ok'}\n }\n publishedCommandNames.add(commandName)\n }\n\n try {\n const currentTime = new Date().getTime()\n const payload = {...publicData, ...sensitiveData}\n const body = JSON.stringify({schema_id: schemaId, payload})\n const headers = buildHeaders(currentTime)\n\n const response = await fetch(url, {method: 'POST', body, headers}, 'non-blocking')\n\n if (response.status === 200) {\n outputDebug(outputContent`Analytics event sent: ${outputToken.json(sanitizePayload(payload))}`)\n return {type: 'ok'}\n } else {\n outputDebug(`Failed to report usage analytics: ${response.statusText}`)\n return {type: 'error', message: response.statusText}\n }\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n let message = 'Failed to report usage analytics'\n if (error instanceof Error) {\n message = message.concat(`: ${error.message}`)\n }\n outputDebug(message)\n return {type: 'error', message}\n }\n}\n\n/**\n * Sanitizies the api_key from the payload and returns a new hash.\n *\n * @param payload - The public and sensitive data.\n * @returns A copy of the payload with the api_key sanitized.\n */\nfunction sanitizePayload<T extends object>(payload: T): T {\n const result = {...payload}\n if ('api_key' in result) {\n result.api_key = '****'\n }\n\n return result\n}\n\nconst buildHeaders = (currentTime: number) => {\n return {\n 'Content-Type': 'application/json; charset=utf-8',\n 'X-Monorail-Edge-Event-Created-At-Ms': currentTime.toString(),\n 'X-Monorail-Edge-Event-Sent-At-Ms': currentTime.toString(),\n }\n}\n"]}
1
+ {"version":3,"file":"monorail.js","sourceRoot":"","sources":["../../../src/public/node/monorail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,WAAW,CAAA;AAC/B,OAAO,EAAC,WAAW,EAAE,aAAa,EAAE,WAAW,EAAC,MAAM,aAAa,CAAA;AAMnE,MAAM,GAAG,GAAG,iDAAiD,CAAA;AAI7D,mFAAmF;AACnF,MAAM,CAAC,MAAM,sBAAsB,GAAG,uBAAuB,CAAA;AAuK7D,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAAU,CAAA;AAE/C;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,QAAmB,EACnB,UAA8B,EAC9B,aAAoC;IAEpC,qHAAqH;IACrH,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,CAAA;IACtC,IAAI,WAAW,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;QACnD,IAAI,qBAAqB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YAC3C,OAAO,EAAC,IAAI,EAAE,IAAI,EAAC,CAAA;QACrB,CAAC;QACD,qBAAqB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;IACxC,CAAC;IAED,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAA;QACxC,MAAM,OAAO,GAAG,EAAC,GAAG,UAAU,EAAE,GAAG,aAAa,EAAC,CAAA;QACjD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAC,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAC,CAAC,CAAA;QAC3D,MAAM,OAAO,GAAG,YAAY,CAAC,WAAW,CAAC,CAAA;QAEzC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAC,EAAE,cAAc,CAAC,CAAA;QAElF,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,WAAW,CAAC,aAAa,CAAA,yBAAyB,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAA;YAC/F,OAAO,EAAC,IAAI,EAAE,IAAI,EAAC,CAAA;QACrB,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,qCAAqC,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAA;YACvE,OAAO,EAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,UAAU,EAAC,CAAA;QACtD,CAAC;QACD,qDAAqD;IACvD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,OAAO,GAAG,kCAAkC,CAAA;QAChD,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;QAChD,CAAC;QACD,WAAW,CAAC,OAAO,CAAC,CAAA;QACpB,OAAO,EAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAC,CAAA;IACjC,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,eAAe,CAAmB,OAAU;IACnD,MAAM,MAAM,GAAG,EAAC,GAAG,OAAO,EAAC,CAAA;IAC3B,IAAI,SAAS,IAAI,MAAM,EAAE,CAAC;QACxB,MAAM,CAAC,OAAO,GAAG,MAAM,CAAA;IACzB,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED,MAAM,YAAY,GAAG,CAAC,WAAmB,EAAE,EAAE;IAC3C,OAAO;QACL,cAAc,EAAE,iCAAiC;QACjD,qCAAqC,EAAE,WAAW,CAAC,QAAQ,EAAE;QAC7D,kCAAkC,EAAE,WAAW,CAAC,QAAQ,EAAE;KAC3D,CAAA;AACH,CAAC,CAAA","sourcesContent":["import {fetch} from './http.js'\nimport {outputDebug, outputContent, outputToken} from './output.js'\nimport {JsonMap} from '../../private/common/json.js'\nimport {DeepRequired} from '../common/ts/deep-required.js'\n\nexport {DeepRequired}\n\nconst url = 'https://monorail-edge.shopifysvc.com/v1/produce'\n\ntype Optional<T> = T | null\n\n// This is the topic name of the main event we log to Monorail, the command tracker\nexport const MONORAIL_COMMAND_TOPIC = 'app_cli3_command/1.20'\n\nexport interface Schemas {\n [MONORAIL_COMMAND_TOPIC]: {\n sensitive: {\n args: string\n error_message?: Optional<string>\n app_name?: Optional<string>\n metadata?: Optional<string>\n store_fqdn?: Optional<string>\n cmd_all_environment_flags?: Optional<string>\n\n // Dev related commands\n cmd_dev_tunnel_custom?: Optional<string>\n\n // Environment\n env_plugin_installed_all?: Optional<string>\n env_shopify_variables?: Optional<string>\n }\n public: {\n business_platform_id?: Optional<number>\n partner_id?: Optional<number>\n command: string\n project_type?: Optional<string>\n time_start: number\n time_end: number\n total_time: number\n success: boolean\n api_key?: Optional<string>\n cli_version: string\n uname: string\n ruby_version: string\n node_version: string\n is_employee: boolean\n store_fqdn_hash?: Optional<string>\n user_id: string\n\n // Any and all commands\n cmd_all_alias_used?: Optional<string>\n cmd_all_launcher?: Optional<string>\n cmd_all_path_override?: Optional<boolean>\n cmd_all_path_override_hash?: Optional<string>\n cmd_all_plugin?: Optional<string>\n cmd_all_topic?: Optional<string>\n cmd_all_verbose?: Optional<boolean>\n cmd_all_exit?: Optional<string>\n cmd_all_force?: Optional<boolean>\n cmd_all_last_graphql_request_id?: Optional<string>\n\n cmd_all_timing_network_ms?: Optional<number>\n cmd_all_timing_prompts_ms?: Optional<number>\n cmd_all_timing_active_ms?: Optional<number>\n\n // Any extension related command\n cmd_extensions_binary_from_source?: Optional<boolean>\n\n // Scaffolding related commands\n cmd_scaffold_required_auth?: Optional<boolean>\n cmd_scaffold_template_custom?: Optional<boolean>\n cmd_scaffold_template_flavor?: Optional<string>\n cmd_scaffold_type?: Optional<string>\n cmd_scaffold_type_category?: Optional<string>\n cmd_scaffold_type_gated?: Optional<boolean>\n cmd_scaffold_type_owner?: Optional<string>\n cmd_scaffold_used_prompts_for_type?: Optional<boolean>\n\n // Used in several but not all commands\n cmd_app_dependency_installation_skipped?: Optional<boolean>\n cmd_app_reset_used?: Optional<boolean>\n cmd_app_linked_config_used?: Optional<boolean>\n cmd_app_linked_config_name?: Optional<string>\n cmd_app_linked_config_git_tracked?: Optional<boolean>\n cmd_app_all_configs_any?: Optional<boolean>\n cmd_app_all_configs_clients?: Optional<string>\n cmd_app_linked_config_source?: Optional<string>\n cmd_app_linked_config_uses_cli_managed_urls?: Optional<boolean>\n cmd_app_warning_api_key_deprecation_displayed?: Optional<boolean>\n cmd_app_deployment_mode?: Optional<string>\n\n // Dev related commands\n cmd_dev_tunnel_type?: Optional<string>\n cmd_dev_tunnel_custom_hash?: Optional<string>\n cmd_dev_urls_updated?: Optional<boolean>\n cmd_dev_preview_url_opened?: Optional<boolean>\n cmd_dev_graphiql_opened?: Optional<boolean>\n cmd_dev_dev_preview_toggle_used?: Optional<boolean>\n\n // Create-app related commands\n cmd_create_app_template?: Optional<string>\n cmd_create_app_template_url?: Optional<string>\n\n // Deploy related commands\n cmd_deploy_flag_message_used?: Optional<boolean>\n cmd_deploy_flag_version_used?: Optional<boolean>\n cmd_deploy_flag_source_url_used?: Optional<boolean>\n cmd_deploy_confirm_new_registrations?: Optional<number>\n cmd_deploy_confirm_updated_registrations?: Optional<number>\n cmd_deploy_confirm_removed_registrations?: Optional<number>\n cmd_deploy_confirm_cancelled?: Optional<boolean>\n cmd_deploy_confirm_time_to_complete_ms?: Optional<number>\n cmd_deploy_prompt_upgrade_to_unified_displayed?: Optional<boolean>\n cmd_deploy_prompt_upgrade_to_unified_response?: Optional<string>\n cmd_deploy_confirm_include_config_used?: Optional<boolean>\n cmd_deploy_include_config_used?: Optional<boolean>\n cmd_deploy_config_modules_breakdown?: Optional<string>\n cmd_deploy_config_modules_updated?: Optional<string>\n cmd_deploy_config_modules_added?: Optional<string>\n cmd_deploy_config_modules_deleted?: Optional<string>\n\n // Release related commands\n cmd_release_confirm_cancelled?: Optional<boolean>\n\n // App setup\n app_extensions_any?: Optional<boolean>\n app_extensions_breakdown?: Optional<string>\n app_extensions_count?: Optional<number>\n app_extensions_custom_layout?: Optional<boolean>\n app_extensions_function_any?: Optional<boolean>\n app_extensions_function_count?: Optional<number>\n app_extensions_function_custom_layout?: Optional<boolean>\n app_extensions_theme_any?: Optional<boolean>\n app_extensions_theme_count?: Optional<number>\n app_extensions_theme_custom_layout?: Optional<boolean>\n app_extensions_ui_any?: Optional<boolean>\n app_extensions_ui_count?: Optional<number>\n app_extensions_ui_custom_layout?: Optional<boolean>\n app_name_hash?: Optional<string>\n app_path_hash?: Optional<string>\n app_scopes?: Optional<string>\n app_web_backend_any?: Optional<boolean>\n app_web_backend_count?: Optional<number>\n app_web_custom_layout?: Optional<boolean>\n app_web_framework?: Optional<string>\n app_web_frontend_any?: Optional<boolean>\n app_web_frontend_count?: Optional<number>\n\n // Theme related commands\n cmd_theme_timings?: Optional<string>\n cmd_theme_errors?: Optional<string>\n cmd_theme_retries?: Optional<string>\n cmd_theme_events?: Optional<string>\n\n // Environment\n env_ci?: Optional<boolean>\n env_ci_platform?: Optional<string>\n env_device_id?: Optional<string>\n env_package_manager?: Optional<string>\n env_package_manager_workspaces?: Optional<boolean>\n env_plugin_installed_any_custom?: Optional<boolean>\n env_plugin_installed_shopify?: Optional<string>\n env_shell?: Optional<string>\n env_web_ide?: Optional<string>\n env_cloud?: Optional<string>\n env_is_global?: Optional<boolean>\n env_auth_method?: Optional<string>\n }\n }\n [schemaId: string]: {sensitive: JsonMap; public: JsonMap}\n}\n\n// In reality, we're normally most interested in just this from Schemas, so export it for ease of use.\n// The monorail schema itself has lots of optional values as it must be backwards-compatible. For our schema we want mandatory values instead.\nexport type MonorailEventPublic = DeepRequired<Schemas[typeof MONORAIL_COMMAND_TOPIC]['public']>\nexport type MonorailEventSensitive = Schemas[typeof MONORAIL_COMMAND_TOPIC]['sensitive']\n\ntype MonorailResult = {type: 'ok'} | {type: 'error'; message: string}\n\nconst publishedCommandNames = new Set<string>()\n\n/**\n * Publishes an event to Monorail.\n *\n * @param schemaId - The schema ID of the event to publish.\n * @param publicData - The public data to publish.\n * @param sensitiveData - The sensitive data to publish.\n * @returns A result indicating whether the event was successfully published.\n */\nexport async function publishMonorailEvent<TSchemaId extends keyof Schemas, TPayload extends Schemas[TSchemaId]>(\n schemaId: TSchemaId,\n publicData: TPayload['public'],\n sensitiveData: TPayload['sensitive'],\n): Promise<MonorailResult> {\n // If a command has already been logged, never re-log it. This is to prevent duplication caused by unexpected errors.\n const commandName = publicData.command\n if (commandName && typeof commandName === 'string') {\n if (publishedCommandNames.has(commandName)) {\n return {type: 'ok'}\n }\n publishedCommandNames.add(commandName)\n }\n\n try {\n const currentTime = new Date().getTime()\n const payload = {...publicData, ...sensitiveData}\n const body = JSON.stringify({schema_id: schemaId, payload})\n const headers = buildHeaders(currentTime)\n\n const response = await fetch(url, {method: 'POST', body, headers}, 'non-blocking')\n\n if (response.status === 200) {\n outputDebug(outputContent`Analytics event sent: ${outputToken.json(sanitizePayload(payload))}`)\n return {type: 'ok'}\n } else {\n outputDebug(`Failed to report usage analytics: ${response.statusText}`)\n return {type: 'error', message: response.statusText}\n }\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n let message = 'Failed to report usage analytics'\n if (error instanceof Error) {\n message = message.concat(`: ${error.message}`)\n }\n outputDebug(message)\n return {type: 'error', message}\n }\n}\n\n/**\n * Sanitizies the api_key from the payload and returns a new hash.\n *\n * @param payload - The public and sensitive data.\n * @returns A copy of the payload with the api_key sanitized.\n */\nfunction sanitizePayload<T extends object>(payload: T): T {\n const result = {...payload}\n if ('api_key' in result) {\n result.api_key = '****'\n }\n\n return result\n}\n\nconst buildHeaders = (currentTime: number) => {\n return {\n 'Content-Type': 'application/json; charset=utf-8',\n 'X-Monorail-Edge-Event-Created-At-Ms': currentTime.toString(),\n 'X-Monorail-Edge-Event-Sent-At-Ms': currentTime.toString(),\n }\n}\n"]}
@@ -5,6 +5,4 @@
5
5
  * @param directory - The directory of the project.
6
6
  * @param dependencies - The dependencies of the project.
7
7
  */
8
- export declare function showMultipleCLIWarningIfNeeded(directory: string, dependencies: {
9
- [key: string]: string;
10
- }): Promise<void>;
8
+ export declare function showMultipleCLIWarningIfNeeded(directory: string, dependencies: Record<string, string>): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"multiple-installation-warning.js","sourceRoot":"","sources":["../../../src/public/node/multiple-installation-warning.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAC,MAAM,kBAAkB,CAAA;AAClD,OAAO,EAAC,sBAAsB,EAAC,MAAM,gBAAgB,CAAA;AACrD,OAAO,EAAC,UAAU,EAAC,MAAM,SAAS,CAAA;AAClC,OAAO,EAAC,gBAAgB,EAAE,eAAe,EAAC,MAAM,cAAc,CAAA;AAC9D,OAAO,EAAC,eAAe,EAAC,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAC,oBAAoB,EAAC,MAAM,kCAAkC,CAAA;AAErE;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAClD,SAAiB,EACjB,YAAqC;IAErC,qCAAqC;IACrC,MAAM,oBAAoB,CAAC,2BAA2B,EAAE,EAAC,IAAI,EAAE,CAAC,EAAC,EAAE,KAAK,IAAI,EAAE;QAC5E,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,IAAI,iBAAiB,EAAE;YAAE,OAAM;QAEhE,MAAM,QAAQ,GAAG,sBAAsB,EAAE,CAAA;QAEzC,2FAA2F;QAC3F,gDAAgD;QAChD,MAAM,aAAa,GAAG,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,gBAAgB,EAAE,CAAA;QAC3E,IAAI,CAAC,aAAa;YAAE,OAAM;QAE1B,gGAAgG;QAChG,+CAA+C;QAC/C,MAAM,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,eAAe,CAAA;QAClF,IAAI,CAAC,YAAY;YAAE,OAAM;QAEzB,MAAM,mBAAmB,GAAG,QAAQ,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,kBAAkB,CAAA;QAEjF,MAAM,cAAc,GAAG;YACrB,QAAQ,EAAE,+CAA+C,mBAAmB,EAAE;YAC9E,IAAI,EAAE;gBACJ,2BAA2B,aAAa,8BAA8B,YAAY;6JACmE;aACtJ;YACD,IAAI,EAAE;gBACJ,KAAK,EAAE,gCAAgC;gBACvC,GAAG,EAAE,oGAAoG;aAC1G;SACF,CAAA;QACD,UAAU,CAAC,cAAc,CAAC,CAAA;IAC5B,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import {jsonOutputEnabled} from './environment.js'\nimport {currentProcessIsGlobal} from './is-global.js'\nimport {renderInfo} from './ui.js'\nimport {globalCLIVersion, localCLIVersion} from './version.js'\nimport {CLI_KIT_VERSION} from '../common/version.js'\nimport {runAtMinimumInterval} from '../../private/node/conf-store.js'\n\n/**\n * Shows a warning if there are two Shopify CLI installations found (global and local).\n * Won't show anything if the user included the --json flag.\n *\n * @param directory - The directory of the project.\n * @param dependencies - The dependencies of the project.\n */\nexport async function showMultipleCLIWarningIfNeeded(\n directory: string,\n dependencies: {[key: string]: string},\n): Promise<void> {\n // Show the warning only once per day\n await runAtMinimumInterval('warn-on-multiple-versions', {days: 1}, async () => {\n if (!dependencies['@shopify/cli'] || jsonOutputEnabled()) return\n\n const isGlobal = currentProcessIsGlobal()\n\n // If running globally, use the current CLI version, otherwise fetch the global CLI version\n // Exit early if we can't get the global version\n const globalVersion = isGlobal ? CLI_KIT_VERSION : await globalCLIVersion()\n if (!globalVersion) return\n\n // If running globally, fetch the local version from npm list, otherwise use current CLI version\n // Exit early if we can't get the local version\n const localVersion = isGlobal ? await localCLIVersion(directory) : CLI_KIT_VERSION\n if (!localVersion) return\n\n const currentInstallation = isGlobal ? 'global installation' : 'local dependency'\n\n const warningContent = {\n headline: `Two Shopify CLI installations found – using ${currentInstallation}`,\n body: [\n `A global installation (v${globalVersion}) and a local dependency (v${localVersion}) were detected.\nWe recommend removing the @shopify/cli and @shopify/app dependencies from your package.json, unless you want to use different versions across multiple apps.`,\n ],\n link: {\n label: 'See Shopify CLI documentation.',\n url: 'https://shopify.dev/docs/apps/build/cli-for-apps#switch-to-a-global-executable-or-local-dependency',\n },\n }\n renderInfo(warningContent)\n })\n}\n"]}
1
+ {"version":3,"file":"multiple-installation-warning.js","sourceRoot":"","sources":["../../../src/public/node/multiple-installation-warning.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAC,MAAM,kBAAkB,CAAA;AAClD,OAAO,EAAC,sBAAsB,EAAC,MAAM,gBAAgB,CAAA;AACrD,OAAO,EAAC,UAAU,EAAC,MAAM,SAAS,CAAA;AAClC,OAAO,EAAC,gBAAgB,EAAE,eAAe,EAAC,MAAM,cAAc,CAAA;AAC9D,OAAO,EAAC,eAAe,EAAC,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAC,oBAAoB,EAAC,MAAM,kCAAkC,CAAA;AAErE;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAClD,SAAiB,EACjB,YAAoC;IAEpC,qCAAqC;IACrC,MAAM,oBAAoB,CAAC,2BAA2B,EAAE,EAAC,IAAI,EAAE,CAAC,EAAC,EAAE,KAAK,IAAI,EAAE;QAC5E,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,IAAI,iBAAiB,EAAE;YAAE,OAAM;QAEhE,MAAM,QAAQ,GAAG,sBAAsB,EAAE,CAAA;QAEzC,2FAA2F;QAC3F,gDAAgD;QAChD,MAAM,aAAa,GAAG,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,gBAAgB,EAAE,CAAA;QAC3E,IAAI,CAAC,aAAa;YAAE,OAAM;QAE1B,gGAAgG;QAChG,+CAA+C;QAC/C,MAAM,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,eAAe,CAAA;QAClF,IAAI,CAAC,YAAY;YAAE,OAAM;QAEzB,MAAM,mBAAmB,GAAG,QAAQ,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,kBAAkB,CAAA;QAEjF,MAAM,cAAc,GAAG;YACrB,QAAQ,EAAE,+CAA+C,mBAAmB,EAAE;YAC9E,IAAI,EAAE;gBACJ,2BAA2B,aAAa,8BAA8B,YAAY;6JACmE;aACtJ;YACD,IAAI,EAAE;gBACJ,KAAK,EAAE,gCAAgC;gBACvC,GAAG,EAAE,oGAAoG;aAC1G;SACF,CAAA;QACD,UAAU,CAAC,cAAc,CAAC,CAAA;IAC5B,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import {jsonOutputEnabled} from './environment.js'\nimport {currentProcessIsGlobal} from './is-global.js'\nimport {renderInfo} from './ui.js'\nimport {globalCLIVersion, localCLIVersion} from './version.js'\nimport {CLI_KIT_VERSION} from '../common/version.js'\nimport {runAtMinimumInterval} from '../../private/node/conf-store.js'\n\n/**\n * Shows a warning if there are two Shopify CLI installations found (global and local).\n * Won't show anything if the user included the --json flag.\n *\n * @param directory - The directory of the project.\n * @param dependencies - The dependencies of the project.\n */\nexport async function showMultipleCLIWarningIfNeeded(\n directory: string,\n dependencies: Record<string, string>,\n): Promise<void> {\n // Show the warning only once per day\n await runAtMinimumInterval('warn-on-multiple-versions', {days: 1}, async () => {\n if (!dependencies['@shopify/cli'] || jsonOutputEnabled()) return\n\n const isGlobal = currentProcessIsGlobal()\n\n // If running globally, use the current CLI version, otherwise fetch the global CLI version\n // Exit early if we can't get the global version\n const globalVersion = isGlobal ? CLI_KIT_VERSION : await globalCLIVersion()\n if (!globalVersion) return\n\n // If running globally, fetch the local version from npm list, otherwise use current CLI version\n // Exit early if we can't get the local version\n const localVersion = isGlobal ? await localCLIVersion(directory) : CLI_KIT_VERSION\n if (!localVersion) return\n\n const currentInstallation = isGlobal ? 'global installation' : 'local dependency'\n\n const warningContent = {\n headline: `Two Shopify CLI installations found – using ${currentInstallation}`,\n body: [\n `A global installation (v${globalVersion}) and a local dependency (v${localVersion}) were detected.\nWe recommend removing the @shopify/cli and @shopify/app dependencies from your package.json, unless you want to use different versions across multiple apps.`,\n ],\n link: {\n label: 'See Shopify CLI documentation.',\n url: 'https://shopify.dev/docs/apps/build/cli-for-apps#switch-to-a-global-executable-or-local-dependency',\n },\n }\n renderInfo(warningContent)\n })\n}\n"]}