@shopify/cli-kit 3.36.1 → 3.37.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 (155) hide show
  1. package/dist/index.d.ts +0 -7
  2. package/dist/index.js +0 -7
  3. package/dist/index.js.map +1 -1
  4. package/dist/private/node/analytics.js +5 -4
  5. package/dist/private/node/analytics.js.map +1 -1
  6. package/dist/private/node/api/graphql.js +2 -2
  7. package/dist/private/node/api/graphql.js.map +1 -1
  8. package/dist/private/node/api/headers.d.ts +1 -1
  9. package/dist/private/node/api/headers.js +1 -1
  10. package/dist/private/node/api/headers.js.map +1 -1
  11. package/dist/private/node/conf-store.d.ts +21 -0
  12. package/dist/private/node/conf-store.js +41 -0
  13. package/dist/private/node/conf-store.js.map +1 -0
  14. package/dist/{secure-store.d.ts → private/node/secure-store.d.ts} +3 -3
  15. package/dist/{secure-store.js → private/node/secure-store.js} +7 -7
  16. package/dist/private/node/secure-store.js.map +1 -0
  17. package/dist/private/node/session/authorize.d.ts +0 -2
  18. package/dist/private/node/session/authorize.js +2 -3
  19. package/dist/private/node/session/authorize.js.map +1 -1
  20. package/dist/private/node/session/device-authorization.js +2 -2
  21. package/dist/private/node/session/device-authorization.js.map +1 -1
  22. package/dist/private/node/session/exchange.d.ts +1 -1
  23. package/dist/private/node/session/exchange.js +1 -2
  24. package/dist/private/node/session/exchange.js.map +1 -1
  25. package/dist/private/node/session/identity.js +2 -2
  26. package/dist/private/node/session/identity.js.map +1 -1
  27. package/dist/private/node/session/post-auth.d.ts +2 -2
  28. package/dist/private/node/session/post-auth.js +2 -2
  29. package/dist/private/node/session/post-auth.js.map +1 -1
  30. package/dist/private/node/session/redirect-listener.js +5 -5
  31. package/dist/private/node/session/redirect-listener.js.map +1 -1
  32. package/dist/private/node/session/schema.d.ts +46 -46
  33. package/dist/private/node/session/schema.js +12 -12
  34. package/dist/private/node/session/schema.js.map +1 -1
  35. package/dist/private/node/session/scopes.js +2 -2
  36. package/dist/private/node/session/scopes.js.map +1 -1
  37. package/dist/private/node/session/store.js +5 -6
  38. package/dist/private/node/session/store.js.map +1 -1
  39. package/dist/private/node/session.js +3 -4
  40. package/dist/private/node/session.js.map +1 -1
  41. package/dist/{testing → private/node/testing}/ui.d.ts +0 -0
  42. package/dist/{testing → private/node/testing}/ui.js +1 -1
  43. package/dist/private/node/testing/ui.js.map +1 -0
  44. package/dist/private/node/ui/components/AutocompletePrompt.test.js +1 -1
  45. package/dist/private/node/ui/components/AutocompletePrompt.test.js.map +1 -1
  46. package/dist/private/node/ui/components/ConcurrentOutput.test.js +1 -1
  47. package/dist/private/node/ui/components/ConcurrentOutput.test.js.map +1 -1
  48. package/dist/private/node/ui/components/FatalError.d.ts +1 -1
  49. package/dist/private/node/ui/components/FatalError.js +2 -2
  50. package/dist/private/node/ui/components/FatalError.js.map +1 -1
  51. package/dist/private/node/ui/components/FatalError.test.js +4 -4
  52. package/dist/private/node/ui/components/FatalError.test.js.map +1 -1
  53. package/dist/private/node/ui/components/SelectInput.test.js +1 -1
  54. package/dist/private/node/ui/components/SelectInput.test.js.map +1 -1
  55. package/dist/private/node/ui/components/SelectPrompt.test.js +1 -1
  56. package/dist/private/node/ui/components/SelectPrompt.test.js.map +1 -1
  57. package/dist/private/node/ui/components/Tasks.test.js +1 -1
  58. package/dist/private/node/ui/components/Tasks.test.js.map +1 -1
  59. package/dist/private/node/ui/components/TextInput.test.js +1 -1
  60. package/dist/private/node/ui/components/TextInput.test.js.map +1 -1
  61. package/dist/private/node/ui/components/TextPrompt.test.js +1 -1
  62. package/dist/private/node/ui/components/TextPrompt.test.js.map +1 -1
  63. package/dist/public/common/version.d.ts +1 -1
  64. package/dist/public/common/version.js +1 -1
  65. package/dist/public/common/version.js.map +1 -1
  66. package/dist/public/node/analytics.js +6 -6
  67. package/dist/public/node/analytics.js.map +1 -1
  68. package/dist/public/node/api/admin.js +3 -3
  69. package/dist/public/node/api/admin.js.map +1 -1
  70. package/dist/public/node/base-command.js +6 -5
  71. package/dist/public/node/base-command.js.map +1 -1
  72. package/dist/public/node/conf.d.ts +2 -0
  73. package/dist/public/node/conf.js +3 -0
  74. package/dist/public/node/conf.js.map +1 -0
  75. package/dist/public/node/environment/fqdn.d.ts +5 -5
  76. package/dist/public/node/environment/fqdn.js +5 -5
  77. package/dist/public/node/environment/fqdn.js.map +1 -1
  78. package/dist/public/node/environment/spin.js +2 -2
  79. package/dist/public/node/environment/spin.js.map +1 -1
  80. package/dist/public/node/error-handler.d.ts +2 -2
  81. package/dist/public/node/error-handler.js +7 -7
  82. package/dist/public/node/error-handler.js.map +1 -1
  83. package/dist/public/node/error.d.ts +84 -4
  84. package/dist/public/node/error.js +165 -4
  85. package/dist/public/node/error.js.map +1 -1
  86. package/dist/public/node/fs.js +4 -0
  87. package/dist/public/node/fs.js.map +1 -1
  88. package/dist/public/node/git.d.ts +2 -2
  89. package/dist/public/node/git.js +11 -10
  90. package/dist/public/node/git.js.map +1 -1
  91. package/dist/{metadata.d.ts → public/node/metadata.d.ts} +13 -13
  92. package/dist/{metadata.js → public/node/metadata.js} +13 -8
  93. package/dist/public/node/metadata.js.map +1 -0
  94. package/dist/{monorail.d.ts → public/node/monorail.d.ts} +11 -3
  95. package/dist/{monorail.js → public/node/monorail.js} +11 -3
  96. package/dist/public/node/monorail.js.map +1 -0
  97. package/dist/public/node/node-package-manager.d.ts +2 -2
  98. package/dist/public/node/node-package-manager.js +7 -2
  99. package/dist/public/node/node-package-manager.js.map +1 -1
  100. package/dist/public/node/path.d.ts +12 -2
  101. package/dist/public/node/path.js +17 -4
  102. package/dist/public/node/path.js.map +1 -1
  103. package/dist/public/node/plugins/tunnel.d.ts +2 -2
  104. package/dist/public/node/plugins/tunnel.js +1 -1
  105. package/dist/public/node/plugins/tunnel.js.map +1 -1
  106. package/dist/{plugins.d.ts → public/node/plugins.d.ts} +17 -11
  107. package/dist/{plugins.js → public/node/plugins.js} +15 -9
  108. package/dist/public/node/plugins.js.map +1 -0
  109. package/dist/public/node/result.js +3 -4
  110. package/dist/public/node/result.js.map +1 -1
  111. package/dist/public/node/ruby.d.ts +1 -0
  112. package/dist/public/node/ruby.js +24 -31
  113. package/dist/public/node/ruby.js.map +1 -1
  114. package/dist/public/node/schema.d.ts +1 -0
  115. package/dist/public/node/schema.js +2 -0
  116. package/dist/public/node/schema.js.map +1 -0
  117. package/dist/public/node/session.js +4 -4
  118. package/dist/public/node/session.js.map +1 -1
  119. package/dist/public/node/system.js +4 -3
  120. package/dist/public/node/system.js.map +1 -1
  121. package/dist/public/node/tcp.js +2 -2
  122. package/dist/public/node/tcp.js.map +1 -1
  123. package/dist/public/node/testing/output.d.ts +16 -0
  124. package/dist/{testing → public/node/testing}/output.js +6 -2
  125. package/dist/public/node/testing/output.js.map +1 -0
  126. package/dist/public/node/ui.d.ts +1 -1
  127. package/dist/public/node/ui.js.map +1 -1
  128. package/dist/public/node/vscode.js +2 -2
  129. package/dist/public/node/vscode.js.map +1 -1
  130. package/dist/tsconfig.tsbuildinfo +1 -1
  131. package/dist/ui.js +5 -5
  132. package/dist/ui.js.map +1 -1
  133. package/package.json +1 -1
  134. package/dist/error.d.ts +0 -68
  135. package/dist/error.js +0 -143
  136. package/dist/error.js.map +0 -1
  137. package/dist/git.d.ts +0 -36
  138. package/dist/git.js +0 -133
  139. package/dist/git.js.map +0 -1
  140. package/dist/metadata.js.map +0 -1
  141. package/dist/monorail.js.map +0 -1
  142. package/dist/plugins.js.map +0 -1
  143. package/dist/schema.d.ts +0 -1
  144. package/dist/schema.js +0 -2
  145. package/dist/schema.js.map +0 -1
  146. package/dist/secure-store.js.map +0 -1
  147. package/dist/store.d.ts +0 -53
  148. package/dist/store.js +0 -133
  149. package/dist/store.js.map +0 -1
  150. package/dist/testing/output.d.ts +0 -10
  151. package/dist/testing/output.js.map +0 -1
  152. package/dist/testing/store.d.ts +0 -7
  153. package/dist/testing/store.js +0 -26
  154. package/dist/testing/store.js.map +0 -1
  155. package/dist/testing/ui.js.map +0 -1
@@ -1,9 +1,15 @@
1
- import { getArrayContainsDuplicates, getArrayRejectingUndefined } from './public/common/array.js';
2
- import { err } from './public/node/result.js';
1
+ import { err } from './result.js';
2
+ import { getArrayContainsDuplicates, getArrayRejectingUndefined } from '../common/array.js';
3
3
  /**
4
4
  * Convenience function to trigger a hook, and gather any successful responses. Failures are ignored.
5
5
  *
6
6
  * Responses are organised into a dictionary, keyed by plug-in name. Only plug-ins that have hooks registered for the given event, and the hooks were run successfully, are included.
7
+ *
8
+ * @param config - The oclif config object.
9
+ * @param event - The name of the hook to trigger.
10
+ * @param options - The options to pass to the hook.
11
+ * @param timeout - The timeout to use for the hook.
12
+ * @returns A dictionary of plug-in names to the response from the hook.
7
13
  */
8
14
  export async function fanoutHooks(config, event, options, timeout) {
9
15
  const res = await config.runHook(event, options, timeout);
@@ -12,10 +18,10 @@ export async function fanoutHooks(config, event, options, timeout) {
12
18
  }
13
19
  /**
14
20
  * Execute the 'tunnel_provider' hook, and return the list of available tunnel providers.
15
- * Fail if there are multiple plugins for the same provider
21
+ * Fail if there are multiple plugins for the same provider.
16
22
  *
17
- * @param config - oclif config used to execute hooks
18
- * @returns list of available tunnel plugins
23
+ * @param config - Oclif config used to execute hooks.
24
+ * @returns List of available tunnel plugins.
19
25
  */
20
26
  export async function getListOfTunnelPlugins(config) {
21
27
  const hooks = await fanoutHooks(config, 'tunnel_provider', {});
@@ -28,10 +34,10 @@ export async function getListOfTunnelPlugins(config) {
28
34
  * Execute the 'tunnel_start' hook for the given provider.
29
35
  * Fails if there aren't plugins for that provider or if there are more than one.
30
36
  *
31
- * @param config - oclif config used to execute hooks
32
- * @param port - port where the tunnel will be started
33
- * @param provider - selected provider, must be unique
34
- * @returns tunnel URL from the selected provider
37
+ * @param config - Oclif config used to execute hooks.
38
+ * @param port - Port where the tunnel will be started.
39
+ * @param provider - Selected provider, must be unique.
40
+ * @returns Tunnel URL from the selected provider.
35
41
  */
36
42
  export async function runTunnelPlugin(config, port, provider) {
37
43
  const hooks = await fanoutHooks(config, 'tunnel_start', { port, provider });
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugins.js","sourceRoot":"","sources":["../../../src/public/node/plugins.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,GAAG,EAAS,MAAM,aAAa,CAAA;AAEvC,OAAO,EAAC,0BAA0B,EAAE,0BAA0B,EAAC,MAAM,oBAAoB,CAAA;AAKzF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAyB,EACzB,KAAa,EACb,OAA4C,EAC5C,OAAgB;IAEhB,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACzD,8DAA8D;IAC9D,OAAO,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAC,MAAM,EAAE,MAAM,EAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAQ,CAAA;AAClG,CAAC;AA4CD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,MAAc;IACzD,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,iBAAiB,EAAE,EAAE,CAAC,CAAA;IAC9D,MAAM,KAAK,GAAG,0BAA0B,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAA;IACtF,IAAI,0BAA0B,CAAC,KAAK,CAAC;QAAE,OAAO,EAAC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,+BAA+B,EAAC,CAAA;IACtG,OAAO,EAAC,OAAO,EAAE,KAAK,EAAC,CAAA;AACzB,CAAC;AAQD;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAc,EACd,IAAY,EACZ,QAAgB;IAEhB,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,cAAc,EAAE,EAAC,IAAI,EAAE,QAAQ,EAAC,CAAC,CAAA;IACzE,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAC5C,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,cAAc,EAAE,KAAK,EAAE,IAAI,cAAc,CAAC,KAAK,CAAC,IAAI,KAAK,kBAAkB,CACjG,CAAA;IACD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC,EAAC,QAAQ,EAAE,IAAI,EAAE,eAAe,EAAC,CAAC,CAAA;IACxE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,GAAG,CAAC,EAAC,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAC,CAAC,CAAA;IAE1F,OAAO,UAAU,CAAC,CAAC,CAAC;SACjB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;SACvB,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAClB,KAAK,CAAC,IAAI,KAAK,SAAS;QACtB,CAAC,CAAC,EAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAC;QACrD,CAAC,CAAC,EAAC,QAAQ,EAAE,IAAI,EAAE,eAAe,EAAC,CACtC,CAAA;AACL,CAAC","sourcesContent":["import {HookReturnPerTunnelPlugin} from './plugins/tunnel.js'\nimport {err, Result} from './result.js'\nimport {MonorailEventPublic, MonorailEventSensitive} from './monorail.js'\nimport {getArrayContainsDuplicates, getArrayRejectingUndefined} from '../common/array.js'\nimport {PickByPrefix} from '../common/ts/pick-by-prefix.js'\nimport {JsonMap} from '../../private/common/json.js'\nimport {Config, Interfaces} from '@oclif/core'\n\n/**\n * Convenience function to trigger a hook, and gather any successful responses. Failures are ignored.\n *\n * Responses are organised into a dictionary, keyed by plug-in name. Only plug-ins that have hooks registered for the given event, and the hooks were run successfully, are included.\n *\n * @param config - The oclif config object.\n * @param event - The name of the hook to trigger.\n * @param options - The options to pass to the hook.\n * @param timeout - The timeout to use for the hook.\n * @returns A dictionary of plug-in names to the response from the hook.\n */\nexport async function fanoutHooks<TPluginMap extends HookReturnsPerPlugin, TEvent extends string & keyof TPluginMap>(\n config: Interfaces.Config,\n event: TEvent,\n options: TPluginMap[typeof event]['options'],\n timeout?: number,\n): Promise<Partial<TPluginMap[typeof event]['pluginReturns']>> {\n const res = await config.runHook(event, options, timeout)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return Object.fromEntries(res.successes.map(({result, plugin}) => [plugin.name, result])) as any\n}\n\ntype AppSpecificMonorailFields = PickByPrefix<MonorailEventPublic, 'app_', 'project_type' | 'api_key' | 'partner_id'> &\n PickByPrefix<MonorailEventPublic, 'cmd_extensions_'> &\n PickByPrefix<MonorailEventPublic, 'cmd_scaffold_'>\n\ntype AppSpecificSensitiveMonorailFields = PickByPrefix<MonorailEventSensitive, 'app_'>\n\nexport interface HookReturnsPerPlugin extends HookReturnPerTunnelPlugin {\n public_command_metadata: {\n options: {[key: string]: never}\n pluginReturns: {\n '@shopify/app': Partial<AppSpecificMonorailFields>\n [pluginName: string]: JsonMap\n }\n }\n sensitive_command_metadata: {\n options: {[key: string]: never}\n pluginReturns: {\n '@shopify/app': Partial<AppSpecificSensitiveMonorailFields>\n [pluginName: string]: JsonMap\n }\n }\n [hookName: string]: {\n options: {[key: string]: unknown}\n pluginReturns: {[key: string]: unknown}\n }\n}\n\nexport type PluginReturnsForHook<\n TEvent extends keyof TPluginMap,\n TPluginName extends keyof TPluginMap[TEvent]['pluginReturns'],\n TPluginMap extends HookReturnsPerPlugin = HookReturnsPerPlugin,\n> = TPluginMap[TEvent]['pluginReturns'][TPluginName]\n\nexport type FanoutHookFunction<\n TEvent extends keyof TPluginMap = string,\n TPluginName extends keyof TPluginMap[TEvent]['pluginReturns'] = string,\n TPluginMap extends HookReturnsPerPlugin = HookReturnsPerPlugin,\n> = (\n this: Interfaces.Hook.Context,\n options: TPluginMap[TEvent]['options'] & {config: Interfaces.Config},\n) => Promise<PluginReturnsForHook<TEvent, TPluginName, TPluginMap>>\n\n/**\n * Execute the 'tunnel_provider' hook, and return the list of available tunnel providers.\n * Fail if there are multiple plugins for the same provider.\n *\n * @param config - Oclif config used to execute hooks.\n * @returns List of available tunnel plugins.\n */\nexport async function getListOfTunnelPlugins(config: Config): Promise<{plugins: string[]; error?: string}> {\n const hooks = await fanoutHooks(config, 'tunnel_provider', {})\n const names = getArrayRejectingUndefined(Object.values(hooks).map((key) => key?.name))\n if (getArrayContainsDuplicates(names)) return {plugins: names, error: 'multiple-plugins-for-provider'}\n return {plugins: names}\n}\n\nexport interface TunnelPluginError {\n provider: string\n type: 'multiple-urls' | 'handled-error' | 'unknown' | 'no-provider'\n message?: string\n}\n\n/**\n * Execute the 'tunnel_start' hook for the given provider.\n * Fails if there aren't plugins for that provider or if there are more than one.\n *\n * @param config - Oclif config used to execute hooks.\n * @param port - Port where the tunnel will be started.\n * @param provider - Selected provider, must be unique.\n * @returns Tunnel URL from the selected provider.\n */\nexport async function runTunnelPlugin(\n config: Config,\n port: number,\n provider: string,\n): Promise<Result<string, TunnelPluginError>> {\n const hooks = await fanoutHooks(config, 'tunnel_start', {port, provider})\n const urlResults = Object.values(hooks).filter(\n (tunnelResponse) => !tunnelResponse?.isErr() || tunnelResponse.error.type !== 'invalid-provider',\n )\n if (urlResults.length > 1) return err({provider, type: 'multiple-urls'})\n if (urlResults.length === 0 || !urlResults[0]) return err({provider, type: 'no-provider'})\n\n return urlResults[0]\n .map((data) => data.url)\n .mapError((error) =>\n error.type === 'unknown'\n ? {provider, type: 'unknown', message: error.message}\n : {provider, type: 'handled-error'},\n )\n}\n"]}
@@ -1,5 +1,4 @@
1
- import { FatalError } from './error.js';
2
- import { Abort, ExtendableError } from '../../error.js';
1
+ import { FatalError, AbortError, ExtendableError } from './error.js';
3
2
  /**
4
3
  * Utility metho to create an `Ok` result from a `value`
5
4
  *
@@ -104,12 +103,12 @@ export class Err {
104
103
  throw this.error;
105
104
  }
106
105
  else if (this.error instanceof ExtendableError || this.error instanceof Error) {
107
- const error = new Abort(this.error.message);
106
+ const error = new AbortError(this.error.message);
108
107
  error.stack = this.error.stack;
109
108
  throw error;
110
109
  }
111
110
  else {
112
- throw new Abort(`${this.error}`);
111
+ throw new AbortError(`${this.error}`);
113
112
  }
114
113
  }
115
114
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"result.js","sourceRoot":"","sources":["../../../src/public/node/result.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,YAAY,CAAA;AACrC,OAAO,EAAC,KAAK,EAAE,eAAe,EAAC,MAAM,gBAAgB,CAAA;AAIrD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,EAAE,GAAG,CAAyB,KAAa,EAAsB,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAA;AAE9F;;;;;GAKG;AACH,MAAM,CAAC,MAAM,GAAG,GAAG,CAAmC,GAAW,EAAuB,EAAE,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;AAEvG,MAAM,OAAO,EAAE;IACb,YAAqB,KAAa;QAAb,UAAK,GAAL,KAAK,CAAQ;IAAG,CAAC;IAEtC;;;;OAIG;IACH,KAAK;QACH,OAAO,KAAK,CAAA;IACd,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,OAAgC;QACrC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACnB,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACvB,CAAC;IAED;;OAEG;IACH,UAAU;QACR,OAAO,IAAI,CAAC,KAAK,CAAA;IACnB,CAAC;IAED;;OAEG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,KAAK,CAAA;IACnB,CAAC;IAED;;;;;OAKG;IACH,GAAG,CAAe,MAAuC;QACvD,OAAO,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;IAC/B,CAAC;IAED;;;;;OAKG;IACH,QAAQ,CAAe,OAAwC;QAC7D,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACvB,CAAC;CACF;AAED,MAAM,OAAO,GAAG;IACd,oDAAoD;IACpD,YAAqB,KAAa;QAAb,UAAK,GAAL,KAAK,CAAQ;IAAG,CAAC;IAEtC;;;;OAIG;IACH,KAAK;QACH,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,QAAiC;QACtC,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACxB,CAAC;IAED;;OAEG;IACH,UAAU;QACR,MAAM,IAAI,CAAC,KAAK,CAAA;IAClB,CAAC;IAED;;OAEG;IACH,YAAY;QACV,IAAI,IAAI,CAAC,KAAK,YAAY,UAAU,EAAE;YACpC,MAAM,IAAI,CAAC,KAAK,CAAA;SACjB;aAAM,IAAI,IAAI,CAAC,KAAK,YAAY,eAAe,IAAI,IAAI,CAAC,KAAK,YAAY,KAAK,EAAE;YAC/E,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YAC3C,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAA;YAC9B,MAAM,KAAK,CAAA;SACZ;aAAM;YACL,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAA;SACjC;IACH,CAAC;IAED;;;;;OAKG;IACH,GAAG,CAAe,OAA6C;QAC7D,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACxB,CAAC;IAED;;;;;OAKG;IACH,QAAQ,CAAe,MAAuC;QAC5D,OAAO,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;IAChC,CAAC;CACF","sourcesContent":["import {FatalError} from './error.js'\nimport {Abort, ExtendableError} from '../../error.js'\n\nexport type Result<TValue, TError> = Ok<TValue, TError> | Err<TValue, TError>\n\n/**\n * Utility metho to create an `Ok` result from a `value`\n *\n * @param value - `value` used to crete the `Result`\n * @returns an instance of a `Ok` `Result` inferring its type\n */\nexport const ok = <TValue, TError = never>(value: TValue): Ok<TValue, TError> => new Ok(value)\n\n/**\n * Utility method to create an `Error` result from an `error`\n *\n * @param err - `error` used to crete the `Result`\n * @returns an instance of an `Error` `Result` inferring its type\n */\nexport const err = <TValue = never, TError = unknown>(err: TError): Err<TValue, TError> => new Err(err)\n\nexport class Ok<TValue, TError> {\n constructor(readonly value: TValue) {}\n\n /**\n * Check if a `Result` is an `Err` inferring its type. `!isErr()` should be used before accessing the `value`\n *\n * @returns `false` as the `Resul` is `OK`\n */\n isErr(): this is Err<TValue, TError> {\n return false\n }\n\n /**\n * Runs the `handler` method an return the same an unaltered copy of the `Result`. It could be used to log an\n * output when the result is `Ok` without breaking the flow\n *\n * @param handler - method to be run when the result is `Ok`\n * @returns a copy of the same `Result`\n */\n doOnOk(handler: (value: TValue) => void): Result<TValue, TError> {\n handler(this.value)\n return ok(this.value)\n }\n\n /**\n * A safe mode to throw the `error` of the `Result`\n */\n valueOrBug(): TValue {\n return this.value\n }\n\n /**\n * Throws an abort error if the result doesn't represent a value.\n */\n valueOrAbort(): TValue {\n return this.value\n }\n\n /**\n * Maps the value to another one with a different type. It leaves the `Error` type unaltered\n *\n * @param mapper - The mapper method to apply an `OK` value\n * @returns a new result with the new mapped value\n */\n map<TMappedValue>(mapper: (value: TValue) => TMappedValue): Result<TMappedValue, TError> {\n return ok(mapper(this.value))\n }\n\n /**\n * Maps the error type to another one. It leaves the `Ok` type and value unaltered\n *\n * @param _mapper - This mapper method is not used for an `Ok` value\n * @returns a new result with the new mapped error type and an value\n */\n mapError<TMappedError>(_mapper: (error: TError) => TMappedError): Result<TValue, TMappedError> {\n return ok(this.value)\n }\n}\n\nexport class Err<TValue, TError> {\n // eslint-disable-next-line node/handle-callback-err\n constructor(readonly error: TError) {}\n\n /**\n * Check if a `Result` is an `Err` inferring its type. `!isErr()` should be used before accessing the `value`\n *\n * @returns `false` as the `Resul` is `OK`\n */\n isErr(): this is Err<TValue, TError> {\n return true\n }\n\n /**\n * Return an unaltered copy of the `Error` without doing anything.\n *\n * @param _handler - This handler method is not used for an `Error`\n * @returns a copy of the same `Error`\n */\n doOnOk(_handler: (value: TValue) => void): Result<TValue, TError> {\n return err(this.error)\n }\n\n /**\n * A safe mode to throw the `error` of the `Result`\n */\n valueOrBug(): TValue {\n throw this.error\n }\n\n /**\n * Throws an abort error if the result doesn't represent a value.\n */\n valueOrAbort(): TValue {\n if (this.error instanceof FatalError) {\n throw this.error\n } else if (this.error instanceof ExtendableError || this.error instanceof Error) {\n const error = new Abort(this.error.message)\n error.stack = this.error.stack\n throw error\n } else {\n throw new Abort(`${this.error}`)\n }\n }\n\n /**\n * Maps the value type to another one. It leaves the `Error` unaltered\n *\n * @param _mapper - This mapper method is not used for an `Error` value\n * @returns a new result with the new value type and an unaltered error\n */\n map<TMappedValue>(_mapper: (valueOrBug: TValue) => TMappedValue): Result<TMappedValue, TError> {\n return err(this.error)\n }\n\n /**\n * Maps the error to another one with a different type. It leaves the value type unaltered\n *\n * @param mapper - The mapper method to apply an `Error` value\n * @returns a new result with the new mapped error\n */\n mapError<TMappedError>(mapper: (error: TError) => TMappedError): Result<TValue, TMappedError> {\n return err(mapper(this.error))\n }\n}\n"]}
1
+ {"version":3,"file":"result.js","sourceRoot":"","sources":["../../../src/public/node/result.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,UAAU,EAAE,eAAe,EAAC,MAAM,YAAY,CAAA;AAIlE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,EAAE,GAAG,CAAyB,KAAa,EAAsB,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAA;AAE9F;;;;;GAKG;AACH,MAAM,CAAC,MAAM,GAAG,GAAG,CAAmC,GAAW,EAAuB,EAAE,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;AAEvG,MAAM,OAAO,EAAE;IACb,YAAqB,KAAa;QAAb,UAAK,GAAL,KAAK,CAAQ;IAAG,CAAC;IAEtC;;;;OAIG;IACH,KAAK;QACH,OAAO,KAAK,CAAA;IACd,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,OAAgC;QACrC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACnB,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACvB,CAAC;IAED;;OAEG;IACH,UAAU;QACR,OAAO,IAAI,CAAC,KAAK,CAAA;IACnB,CAAC;IAED;;OAEG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,KAAK,CAAA;IACnB,CAAC;IAED;;;;;OAKG;IACH,GAAG,CAAe,MAAuC;QACvD,OAAO,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;IAC/B,CAAC;IAED;;;;;OAKG;IACH,QAAQ,CAAe,OAAwC;QAC7D,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACvB,CAAC;CACF;AAED,MAAM,OAAO,GAAG;IACd,oDAAoD;IACpD,YAAqB,KAAa;QAAb,UAAK,GAAL,KAAK,CAAQ;IAAG,CAAC;IAEtC;;;;OAIG;IACH,KAAK;QACH,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,QAAiC;QACtC,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACxB,CAAC;IAED;;OAEG;IACH,UAAU;QACR,MAAM,IAAI,CAAC,KAAK,CAAA;IAClB,CAAC;IAED;;OAEG;IACH,YAAY;QACV,IAAI,IAAI,CAAC,KAAK,YAAY,UAAU,EAAE;YACpC,MAAM,IAAI,CAAC,KAAK,CAAA;SACjB;aAAM,IAAI,IAAI,CAAC,KAAK,YAAY,eAAe,IAAI,IAAI,CAAC,KAAK,YAAY,KAAK,EAAE;YAC/E,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YAChD,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAA;YAC9B,MAAM,KAAK,CAAA;SACZ;aAAM;YACL,MAAM,IAAI,UAAU,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAA;SACtC;IACH,CAAC;IAED;;;;;OAKG;IACH,GAAG,CAAe,OAA6C;QAC7D,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACxB,CAAC;IAED;;;;;OAKG;IACH,QAAQ,CAAe,MAAuC;QAC5D,OAAO,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;IAChC,CAAC;CACF","sourcesContent":["import {FatalError, AbortError, ExtendableError} from './error.js'\n\nexport type Result<TValue, TError> = Ok<TValue, TError> | Err<TValue, TError>\n\n/**\n * Utility metho to create an `Ok` result from a `value`\n *\n * @param value - `value` used to crete the `Result`\n * @returns an instance of a `Ok` `Result` inferring its type\n */\nexport const ok = <TValue, TError = never>(value: TValue): Ok<TValue, TError> => new Ok(value)\n\n/**\n * Utility method to create an `Error` result from an `error`\n *\n * @param err - `error` used to crete the `Result`\n * @returns an instance of an `Error` `Result` inferring its type\n */\nexport const err = <TValue = never, TError = unknown>(err: TError): Err<TValue, TError> => new Err(err)\n\nexport class Ok<TValue, TError> {\n constructor(readonly value: TValue) {}\n\n /**\n * Check if a `Result` is an `Err` inferring its type. `!isErr()` should be used before accessing the `value`\n *\n * @returns `false` as the `Resul` is `OK`\n */\n isErr(): this is Err<TValue, TError> {\n return false\n }\n\n /**\n * Runs the `handler` method an return the same an unaltered copy of the `Result`. It could be used to log an\n * output when the result is `Ok` without breaking the flow\n *\n * @param handler - method to be run when the result is `Ok`\n * @returns a copy of the same `Result`\n */\n doOnOk(handler: (value: TValue) => void): Result<TValue, TError> {\n handler(this.value)\n return ok(this.value)\n }\n\n /**\n * A safe mode to throw the `error` of the `Result`\n */\n valueOrBug(): TValue {\n return this.value\n }\n\n /**\n * Throws an abort error if the result doesn't represent a value.\n */\n valueOrAbort(): TValue {\n return this.value\n }\n\n /**\n * Maps the value to another one with a different type. It leaves the `Error` type unaltered\n *\n * @param mapper - The mapper method to apply an `OK` value\n * @returns a new result with the new mapped value\n */\n map<TMappedValue>(mapper: (value: TValue) => TMappedValue): Result<TMappedValue, TError> {\n return ok(mapper(this.value))\n }\n\n /**\n * Maps the error type to another one. It leaves the `Ok` type and value unaltered\n *\n * @param _mapper - This mapper method is not used for an `Ok` value\n * @returns a new result with the new mapped error type and an value\n */\n mapError<TMappedError>(_mapper: (error: TError) => TMappedError): Result<TValue, TMappedError> {\n return ok(this.value)\n }\n}\n\nexport class Err<TValue, TError> {\n // eslint-disable-next-line node/handle-callback-err\n constructor(readonly error: TError) {}\n\n /**\n * Check if a `Result` is an `Err` inferring its type. `!isErr()` should be used before accessing the `value`\n *\n * @returns `false` as the `Resul` is `OK`\n */\n isErr(): this is Err<TValue, TError> {\n return true\n }\n\n /**\n * Return an unaltered copy of the `Error` without doing anything.\n *\n * @param _handler - This handler method is not used for an `Error`\n * @returns a copy of the same `Error`\n */\n doOnOk(_handler: (value: TValue) => void): Result<TValue, TError> {\n return err(this.error)\n }\n\n /**\n * A safe mode to throw the `error` of the `Result`\n */\n valueOrBug(): TValue {\n throw this.error\n }\n\n /**\n * Throws an abort error if the result doesn't represent a value.\n */\n valueOrAbort(): TValue {\n if (this.error instanceof FatalError) {\n throw this.error\n } else if (this.error instanceof ExtendableError || this.error instanceof Error) {\n const error = new AbortError(this.error.message)\n error.stack = this.error.stack\n throw error\n } else {\n throw new AbortError(`${this.error}`)\n }\n }\n\n /**\n * Maps the value type to another one. It leaves the `Error` unaltered\n *\n * @param _mapper - This mapper method is not used for an `Error` value\n * @returns a new result with the new value type and an unaltered error\n */\n map<TMappedValue>(_mapper: (valueOrBug: TValue) => TMappedValue): Result<TMappedValue, TError> {\n return err(this.error)\n }\n\n /**\n * Maps the error to another one with a different type. It leaves the value type unaltered\n *\n * @param mapper - The mapper method to apply an `Error` value\n * @returns a new result with the new mapped error\n */\n mapError<TMappedError>(mapper: (error: TError) => TMappedError): Result<TValue, TMappedError> {\n return err(mapper(this.error))\n }\n}\n"]}
@@ -8,6 +8,7 @@ interface ExecCLI2Options {
8
8
  token?: string;
9
9
  directory?: string;
10
10
  signal?: AbortSignal;
11
+ stdout?: Writable;
11
12
  }
12
13
  /**
13
14
  * Execute CLI 2.0 commands.
@@ -1,12 +1,12 @@
1
1
  import { coerceSemverVersion } from './semver.js';
2
- import { renderTasks } from './ui.js';
3
2
  import { platformAndArch } from './os.js';
4
3
  import { captureOutput, exec } from './system.js';
5
4
  import * as file from './fs.js';
6
- import { joinPath } from './path.js';
7
- import { Abort, AbortSilent } from '../../error.js';
5
+ import { joinPath, cwd } from './path.js';
6
+ import { AbortError, AbortSilentError } from './error.js';
8
7
  import { pathConstants } from '../../private/node/constants.js';
9
8
  import { content, token } from '../../output.js';
9
+ import { isTruthy } from '../../private/node/environment/utilities.js';
10
10
  import { Writable } from 'stream';
11
11
  const RubyCLIVersion = '2.34.0';
12
12
  const ThemeCheckVersion = '1.14.0';
@@ -21,7 +21,7 @@ const MinRubyVersion = '2.7.5';
21
21
  * @param options - Options to customize the execution of cli2.
22
22
  */
23
23
  export async function execCLI2(args, options = {}) {
24
- await installCLIDependencies();
24
+ await installCLIDependencies(options.stdout ?? process.stdout);
25
25
  const env = {
26
26
  ...process.env,
27
27
  SHOPIFY_CLI_STOREFRONT_RENDERER_AUTH_TOKEN: options.storefrontToken,
@@ -37,14 +37,14 @@ export async function execCLI2(args, options = {}) {
37
37
  try {
38
38
  await exec(bundleExecutable(), ['exec', 'shopify'].concat(args), {
39
39
  stdio: 'inherit',
40
- cwd: options.directory ?? process.cwd(),
40
+ cwd: options.directory ?? cwd(),
41
41
  env,
42
42
  signal: options.signal,
43
43
  });
44
44
  }
45
45
  catch (error) {
46
46
  // CLI2 will show it's own errors, we don't need to show an additional CLI3 error
47
- throw new AbortSilent();
47
+ throw new AbortSilentError();
48
48
  }
49
49
  }
50
50
  /**
@@ -107,32 +107,25 @@ async function installThemeCheckCLIDependencies(stdout) {
107
107
  * Install RubyCLI and its dependencies
108
108
  * Shows a loading spinner if it's the first time installing dependencies
109
109
  * or if we are installing a new version of RubyCLI.
110
+ *
111
+ * @param stdout - The Writable stream on which to write the standard output.
110
112
  */
111
- async function installCLIDependencies() {
113
+ async function installCLIDependencies(stdout) {
112
114
  const exists = await file.fileExists(shopifyCLIDirectory());
113
- const tasks = [
114
- {
115
- title: 'Installing theme dependencies',
116
- task: async () => {
117
- const usingLocalCLI2 = Boolean(process.env.SHOPIFY_CLI_2_0_DIRECTORY);
118
- await validateRubyEnv();
119
- if (usingLocalCLI2) {
120
- await bundleInstallLocalShopifyCLI();
121
- }
122
- else {
123
- await createShopifyCLIWorkingDirectory();
124
- await createShopifyCLIGemfile();
125
- await bundleInstallShopifyCLI();
126
- }
127
- },
128
- },
129
- ];
130
- if (exists) {
131
- await tasks[0].task();
115
+ if (!exists)
116
+ stdout.write('Installing theme dependencies...');
117
+ const usingLocalCLI2 = isTruthy(process.env.SHOPIFY_CLI_2_0_DIRECTORY);
118
+ await validateRubyEnv();
119
+ if (usingLocalCLI2) {
120
+ await bundleInstallLocalShopifyCLI();
132
121
  }
133
122
  else {
134
- await renderTasks(tasks);
123
+ await createShopifyCLIWorkingDirectory();
124
+ await createShopifyCLIGemfile();
125
+ await bundleInstallShopifyCLI();
135
126
  }
127
+ if (!exists)
128
+ stdout.write('Installed theme dependencies!');
136
129
  }
137
130
  /**
138
131
  * A function that validates if the environment in which the CLI is running is set up with Ruby and Bundler.
@@ -151,11 +144,11 @@ async function validateRuby() {
151
144
  version = coerceSemverVersion(stdout);
152
145
  }
153
146
  catch {
154
- throw new Abort('Ruby environment not found', `Make sure you have Ruby installed on your system. ${content `${token.link('Documentation.', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value}`);
147
+ throw new AbortError('Ruby environment not found', `Make sure you have Ruby installed on your system. ${content `${token.link('Documentation.', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value}`);
155
148
  }
156
149
  const isValid = version?.compare(MinRubyVersion);
157
150
  if (isValid === -1 || isValid === undefined) {
158
- throw new Abort(`Ruby version ${content `${token.yellow(version.raw)}`.value} is not supported`, `Make sure you have at least Ruby ${content `${token.yellow(MinRubyVersion)}`.value} installed on your system. ${content `${token.link('Documentation.', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value}`);
151
+ throw new AbortError(`Ruby version ${content `${token.yellow(version.raw)}`.value} is not supported`, `Make sure you have at least Ruby ${content `${token.yellow(MinRubyVersion)}`.value} installed on your system. ${content `${token.link('Documentation.', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value}`);
159
152
  }
160
153
  }
161
154
  /**
@@ -168,11 +161,11 @@ async function validateBundler() {
168
161
  version = coerceSemverVersion(stdout);
169
162
  }
170
163
  catch {
171
- throw new Abort('Bundler not found', `To install the latest version of Bundler, run ${content `${token.genericShellCommand(`${gemExecutable()} install bundler`)}`.value}`);
164
+ throw new AbortError('Bundler not found', `To install the latest version of Bundler, run ${content `${token.genericShellCommand(`${gemExecutable()} install bundler`)}`.value}`);
172
165
  }
173
166
  const isValid = version?.compare(MinBundlerVersion);
174
167
  if (isValid === -1 || isValid === undefined) {
175
- throw new Abort(`Bundler version ${content `${token.yellow(version.raw)}`.value} is not supported`, `To update to the latest version of Bundler, run ${content `${token.genericShellCommand(`${gemExecutable()} install bundler`)}`.value}`);
168
+ throw new AbortError(`Bundler version ${content `${token.yellow(version.raw)}`.value} is not supported`, `To update to the latest version of Bundler, run ${content `${token.genericShellCommand(`${gemExecutable()} install bundler`)}`.value}`);
176
169
  }
177
170
  }
178
171
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ruby.js","sourceRoot":"","sources":["../../../src/public/node/ruby.ts"],"names":[],"mappings":"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","sourcesContent":["import {coerceSemverVersion} from './semver.js'\nimport {renderTasks} from './ui.js'\nimport {AbortSignal} from './abort.js'\nimport {platformAndArch} from './os.js'\nimport {captureOutput, exec} from './system.js'\nimport * as file from './fs.js'\nimport {joinPath} from './path.js'\nimport {Abort, AbortSilent} from '../../error.js'\nimport {pathConstants} from '../../private/node/constants.js'\nimport {AdminSession} from '../../public/node/session.js'\nimport {content, token} from '../../output.js'\nimport {Writable} from 'stream'\n\nconst RubyCLIVersion = '2.34.0'\nconst ThemeCheckVersion = '1.14.0'\nconst MinBundlerVersion = '2.3.8'\nconst MinRubyVersion = '2.7.5'\n\ninterface ExecCLI2Options {\n // Contains token and store to pass to CLI 2.0, which will be set as environment variables\n adminSession?: AdminSession\n // Contains token for storefront access to pass to CLI 2.0 as environment variable\n storefrontToken?: string\n // Contains token for partners access to pass to CLI 2.0 as environment variable\n token?: string\n // Directory in which to execute the command. Otherwise the current directory will be used.\n directory?: string\n // A signal to stop the process execution.\n signal?: AbortSignal\n}\n/**\n * Execute CLI 2.0 commands.\n * Installs a version of RubyCLI as a vendor dependency in a hidden folder in the system.\n * User must have a valid ruby+bundler environment to run any command.\n *\n * @param args - List of argumets to execute. (ex: ['theme', 'pull']).\n * @param options - Options to customize the execution of cli2.\n */\nexport async function execCLI2(args: string[], options: ExecCLI2Options = {}): Promise<void> {\n await installCLIDependencies()\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n SHOPIFY_CLI_STOREFRONT_RENDERER_AUTH_TOKEN: options.storefrontToken,\n SHOPIFY_CLI_ADMIN_AUTH_TOKEN: options.adminSession?.token,\n SHOPIFY_SHOP: options.adminSession?.storeFqdn,\n SHOPIFY_CLI_AUTH_TOKEN: options.token,\n SHOPIFY_CLI_RUN_AS_SUBPROCESS: 'true',\n // Bundler uses this Gemfile to understand which gems are available in the\n // environment. We use this to specify our own Gemfile for CLI2, which exists\n // outside the user's project directory.\n BUNDLE_GEMFILE: joinPath(shopifyCLIDirectory(), 'Gemfile'),\n }\n\n try {\n await exec(bundleExecutable(), ['exec', 'shopify'].concat(args), {\n stdio: 'inherit',\n cwd: options.directory ?? process.cwd(),\n env,\n signal: options.signal,\n })\n } catch (error) {\n // CLI2 will show it's own errors, we don't need to show an additional CLI3 error\n throw new AbortSilent()\n }\n}\n\ninterface ExecThemeCheckCLIOptions {\n /** A list of directories in which theme-check should run. */\n directories: string[]\n /** Arguments to pass to the theme-check CLI. */\n args?: string[]\n /** Writable to send standard output content through. */\n stdout: Writable\n /** Writable to send standard error content through. */\n stderr: Writable\n}\n\n/**\n * A function that installs (if needed) and runs the theme-check CLI.\n *\n * @param options - Options to customize the execution of theme-check.\n * @returns A promise that resolves or rejects depending on the result of the underlying theme-check process.\n */\nexport async function execThemeCheckCLI(options: ExecThemeCheckCLIOptions): Promise<void[]> {\n await installThemeCheckCLIDependencies(options.stdout)\n\n const processes = options.directories.map(async (directory): Promise<void> => {\n // Check that there are files aside from the extension TOML config file,\n // otherwise theme-check will return a false failure.\n const files = await file.glob(joinPath(directory, '/**/*'))\n const fileCount = files.filter((file) => !file.match(/\\.toml$/)).length\n if (fileCount === 0) return\n\n const customStderr = new Writable({\n write(chunk, ...args) {\n // For some reason, theme-check reports this initial status line to stderr\n // See https://github.com/Shopify/theme-check/blob/1092737cfb58a73ca397ffb1371665dc55df2976/lib/theme_check/language_server/diagnostics_engine.rb#L31\n // which leads to https://github.com/Shopify/theme-check/blob/1092737cfb58a73ca397ffb1371665dc55df2976/lib/theme_check/language_server/io_messenger.rb#L65\n if (chunk.toString('ascii').match(/^Checking/)) {\n options.stdout.write(chunk, ...args)\n } else {\n options.stderr.write(chunk, ...args)\n }\n },\n })\n await exec(bundleExecutable(), ['exec', 'theme-check'].concat([directory, ...(options.args || [])]), {\n stdout: options.stdout,\n stderr: customStderr,\n cwd: themeCheckDirectory(),\n })\n })\n return Promise.all(processes)\n}\n\n/**\n * Validate Ruby Enviroment\n * Install Theme Check CLI and its dependencies\n * Shows a loading message if it's the first time installing dependencies\n * or if we are installing a new version of Theme Check CLI.\n *\n * @param stdout - The Writable stream on which to write the standard output.\n */\nasync function installThemeCheckCLIDependencies(stdout: Writable) {\n const exists = await file.fileExists(themeCheckDirectory())\n\n if (!exists) stdout.write('Installing theme dependencies...')\n await validateRubyEnv()\n await createThemeCheckCLIWorkingDirectory()\n await createThemeCheckGemfile()\n await bundleInstallThemeCheck()\n if (!exists) stdout.write('Installed theme dependencies!')\n}\n\n/**\n * Validate Ruby Enviroment\n * Install RubyCLI and its dependencies\n * Shows a loading spinner if it's the first time installing dependencies\n * or if we are installing a new version of RubyCLI.\n */\nasync function installCLIDependencies() {\n const exists = await file.fileExists(shopifyCLIDirectory())\n const tasks = [\n {\n title: 'Installing theme dependencies',\n task: async () => {\n const usingLocalCLI2 = Boolean(process.env.SHOPIFY_CLI_2_0_DIRECTORY)\n await validateRubyEnv()\n if (usingLocalCLI2) {\n await bundleInstallLocalShopifyCLI()\n } else {\n await createShopifyCLIWorkingDirectory()\n await createShopifyCLIGemfile()\n await bundleInstallShopifyCLI()\n }\n },\n },\n ]\n\n if (exists) {\n await tasks[0]!.task()\n } else {\n await renderTasks(tasks)\n }\n}\n\n/**\n * A function that validates if the environment in which the CLI is running is set up with Ruby and Bundler.\n */\nasync function validateRubyEnv() {\n await validateRuby()\n await validateBundler()\n}\n\n/**\n * A function that validates if the environment in which the CLI is running is set up with Ruby.\n */\nasync function validateRuby() {\n let version\n try {\n const stdout = await captureOutput(rubyExecutable(), ['-v'])\n version = coerceSemverVersion(stdout)\n } catch {\n throw new Abort(\n 'Ruby environment not found',\n `Make sure you have Ruby installed on your system. ${\n content`${token.link('Documentation.', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value\n }`,\n )\n }\n\n const isValid = version?.compare(MinRubyVersion)\n if (isValid === -1 || isValid === undefined) {\n throw new Abort(\n `Ruby version ${content`${token.yellow(version.raw)}`.value} is not supported`,\n `Make sure you have at least Ruby ${content`${token.yellow(MinRubyVersion)}`.value} installed on your system. ${\n content`${token.link('Documentation.', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value\n }`,\n )\n }\n}\n\n/**\n * A function that validates if the environment in which the CLI is running is set up with Bundler.\n */\nasync function validateBundler() {\n let version\n try {\n const stdout = await captureOutput(bundleExecutable(), ['-v'])\n version = coerceSemverVersion(stdout)\n } catch {\n throw new Abort(\n 'Bundler not found',\n `To install the latest version of Bundler, run ${\n content`${token.genericShellCommand(`${gemExecutable()} install bundler`)}`.value\n }`,\n )\n }\n\n const isValid = version?.compare(MinBundlerVersion)\n if (isValid === -1 || isValid === undefined) {\n throw new Abort(\n `Bundler version ${content`${token.yellow(version.raw)}`.value} is not supported`,\n `To update to the latest version of Bundler, run ${\n content`${token.genericShellCommand(`${gemExecutable()} install bundler`)}`.value\n }`,\n )\n }\n}\n\n/**\n * It creates the directory where the Ruby CLI will be downloaded along its dependencies.\n */\nasync function createShopifyCLIWorkingDirectory(): Promise<void> {\n return file.mkdir(shopifyCLIDirectory())\n}\n\n/**\n * It creates the directory where the theme-check CLI will be downloaded along its dependencies.\n */\nasync function createThemeCheckCLIWorkingDirectory(): Promise<void> {\n return file.mkdir(themeCheckDirectory())\n}\n\n/**\n * It creates the Gemfile to install The Ruby CLI and the dependencies.\n */\nasync function createShopifyCLIGemfile(): Promise<void> {\n const gemPath = joinPath(shopifyCLIDirectory(), 'Gemfile')\n const gemFileContent = [\"source 'https://rubygems.org'\", `gem 'shopify-cli', '${RubyCLIVersion}'`]\n const {platform} = platformAndArch()\n if (platform === 'windows') {\n // 'wdm' is required by 'listen', see https://github.com/Shopify/cli/issues/780\n gemFileContent.push(\"gem 'wdm', '>= 0.1.0'\")\n }\n await file.writeFile(gemPath, gemFileContent.join('\\n'))\n}\n\n/**\n * It creates the Gemfile to install theme-check and its dependencies.\n */\nasync function createThemeCheckGemfile(): Promise<void> {\n const gemPath = joinPath(themeCheckDirectory(), 'Gemfile')\n await file.writeFile(gemPath, `source 'https://rubygems.org'\\ngem 'theme-check', '${ThemeCheckVersion}'`)\n}\n\n/**\n * It runs bundle install for the dev-managed copy of the Ruby CLI.\n */\nasync function bundleInstallLocalShopifyCLI(): Promise<void> {\n await exec(bundleExecutable(), ['install'], {cwd: shopifyCLIDirectory()})\n}\n\n/**\n * It runs bundle install for the CLI-managed copy of the Ruby CLI.\n */\nasync function bundleInstallShopifyCLI() {\n await exec(bundleExecutable(), ['config', 'set', '--local', 'path', shopifyCLIDirectory()], {\n cwd: shopifyCLIDirectory(),\n })\n await exec(bundleExecutable(), ['install'], {cwd: shopifyCLIDirectory()})\n}\n\n/**\n * It runs bundle install for the CLI-managed copy of theme-check.\n */\nasync function bundleInstallThemeCheck() {\n await exec(bundleExecutable(), ['config', 'set', '--local', 'path', themeCheckDirectory()], {\n cwd: themeCheckDirectory(),\n })\n await exec(bundleExecutable(), ['install'], {cwd: themeCheckDirectory()})\n}\n\n/**\n * It returns the directory where the Ruby CLI is located.\n *\n * @returns The absolute path to the directory.\n */\nfunction shopifyCLIDirectory(): string {\n return (\n process.env.SHOPIFY_CLI_2_0_DIRECTORY ??\n joinPath(pathConstants.directories.cache.vendor.path(), 'ruby-cli', RubyCLIVersion)\n )\n}\n\n/**\n * It returns the path to the directory containing the theme-check CLI.\n *\n * @returns The absolute path to the theme-check directory.\n */\nfunction themeCheckDirectory(): string {\n return joinPath(pathConstants.directories.cache.vendor.path(), 'theme-check', ThemeCheckVersion)\n}\n\n/**\n * It returns the Ruby version present in the envirronment.\n */\nexport async function version(): Promise<string | undefined> {\n const parseOutput = (version: string) => version.match(/ruby (\\d+\\.\\d+\\.\\d+)/)?.[1]\n return captureOutput(rubyExecutable(), ['-v'])\n .then(parseOutput)\n .catch(() => undefined)\n}\n\n/**\n * It returns the Ruby binary path set through the environment variable SHOPIFY_RUBY_BINDIR.\n * This is useful when the CLI is managed by an installer like a Homebrew where we need to\n * point the CLI to the Ruby installation managed by Homebrew.\n *\n * @returns The value of the environment variable.\n */\nfunction getRubyBinDir(): string | undefined {\n return process.env.SHOPIFY_RUBY_BINDIR\n}\n\n/**\n * It returns the path to the \"ruby\" executable.\n *\n * @returns The path to the executable.\n */\nfunction rubyExecutable(): string {\n const rubyBinDir = getRubyBinDir()\n return rubyBinDir ? joinPath(rubyBinDir, 'ruby') : 'ruby'\n}\n\n/**\n * It returns the path to the \"bundle\" executable.\n *\n * @returns The path to the executable.\n */\nfunction bundleExecutable(): string {\n const rubyBinDir = getRubyBinDir()\n return rubyBinDir ? joinPath(rubyBinDir, 'bundle') : 'bundle'\n}\n\n/**\n * It returns the path to the \"gem\"\" executable.\n *\n * @returns The path to the executable.\n */\nfunction gemExecutable(): string {\n const rubyBinDir = getRubyBinDir()\n return rubyBinDir ? joinPath(rubyBinDir, 'gem') : 'gem'\n}\n"]}
1
+ {"version":3,"file":"ruby.js","sourceRoot":"","sources":["../../../src/public/node/ruby.ts"],"names":[],"mappings":"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","sourcesContent":["import {coerceSemverVersion} from './semver.js'\nimport {AbortSignal} from './abort.js'\nimport {platformAndArch} from './os.js'\nimport {captureOutput, exec} from './system.js'\nimport * as file from './fs.js'\nimport {joinPath, cwd} from './path.js'\nimport {AbortError, AbortSilentError} from './error.js'\nimport {pathConstants} from '../../private/node/constants.js'\nimport {AdminSession} from '../../public/node/session.js'\nimport {content, token} from '../../output.js'\nimport {isTruthy} from '../../private/node/environment/utilities.js'\nimport {Writable} from 'stream'\n\nconst RubyCLIVersion = '2.34.0'\nconst ThemeCheckVersion = '1.14.0'\nconst MinBundlerVersion = '2.3.8'\nconst MinRubyVersion = '2.7.5'\n\ninterface ExecCLI2Options {\n // Contains token and store to pass to CLI 2.0, which will be set as environment variables\n adminSession?: AdminSession\n // Contains token for storefront access to pass to CLI 2.0 as environment variable\n storefrontToken?: string\n // Contains token for partners access to pass to CLI 2.0 as environment variable\n token?: string\n // Directory in which to execute the command. Otherwise the current directory will be used.\n directory?: string\n // A signal to stop the process execution.\n signal?: AbortSignal\n // Stream to pipe the command's stdout to.\n stdout?: Writable\n}\n/**\n * Execute CLI 2.0 commands.\n * Installs a version of RubyCLI as a vendor dependency in a hidden folder in the system.\n * User must have a valid ruby+bundler environment to run any command.\n *\n * @param args - List of argumets to execute. (ex: ['theme', 'pull']).\n * @param options - Options to customize the execution of cli2.\n */\nexport async function execCLI2(args: string[], options: ExecCLI2Options = {}): Promise<void> {\n await installCLIDependencies(options.stdout ?? process.stdout)\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n SHOPIFY_CLI_STOREFRONT_RENDERER_AUTH_TOKEN: options.storefrontToken,\n SHOPIFY_CLI_ADMIN_AUTH_TOKEN: options.adminSession?.token,\n SHOPIFY_SHOP: options.adminSession?.storeFqdn,\n SHOPIFY_CLI_AUTH_TOKEN: options.token,\n SHOPIFY_CLI_RUN_AS_SUBPROCESS: 'true',\n // Bundler uses this Gemfile to understand which gems are available in the\n // environment. We use this to specify our own Gemfile for CLI2, which exists\n // outside the user's project directory.\n BUNDLE_GEMFILE: joinPath(shopifyCLIDirectory(), 'Gemfile'),\n }\n\n try {\n await exec(bundleExecutable(), ['exec', 'shopify'].concat(args), {\n stdio: 'inherit',\n cwd: options.directory ?? cwd(),\n env,\n signal: options.signal,\n })\n } catch (error) {\n // CLI2 will show it's own errors, we don't need to show an additional CLI3 error\n throw new AbortSilentError()\n }\n}\n\ninterface ExecThemeCheckCLIOptions {\n /** A list of directories in which theme-check should run. */\n directories: string[]\n /** Arguments to pass to the theme-check CLI. */\n args?: string[]\n /** Writable to send standard output content through. */\n stdout: Writable\n /** Writable to send standard error content through. */\n stderr: Writable\n}\n\n/**\n * A function that installs (if needed) and runs the theme-check CLI.\n *\n * @param options - Options to customize the execution of theme-check.\n * @returns A promise that resolves or rejects depending on the result of the underlying theme-check process.\n */\nexport async function execThemeCheckCLI(options: ExecThemeCheckCLIOptions): Promise<void[]> {\n await installThemeCheckCLIDependencies(options.stdout)\n\n const processes = options.directories.map(async (directory): Promise<void> => {\n // Check that there are files aside from the extension TOML config file,\n // otherwise theme-check will return a false failure.\n const files = await file.glob(joinPath(directory, '/**/*'))\n const fileCount = files.filter((file) => !file.match(/\\.toml$/)).length\n if (fileCount === 0) return\n\n const customStderr = new Writable({\n write(chunk, ...args) {\n // For some reason, theme-check reports this initial status line to stderr\n // See https://github.com/Shopify/theme-check/blob/1092737cfb58a73ca397ffb1371665dc55df2976/lib/theme_check/language_server/diagnostics_engine.rb#L31\n // which leads to https://github.com/Shopify/theme-check/blob/1092737cfb58a73ca397ffb1371665dc55df2976/lib/theme_check/language_server/io_messenger.rb#L65\n if (chunk.toString('ascii').match(/^Checking/)) {\n options.stdout.write(chunk, ...args)\n } else {\n options.stderr.write(chunk, ...args)\n }\n },\n })\n await exec(bundleExecutable(), ['exec', 'theme-check'].concat([directory, ...(options.args || [])]), {\n stdout: options.stdout,\n stderr: customStderr,\n cwd: themeCheckDirectory(),\n })\n })\n return Promise.all(processes)\n}\n\n/**\n * Validate Ruby Enviroment\n * Install Theme Check CLI and its dependencies\n * Shows a loading message if it's the first time installing dependencies\n * or if we are installing a new version of Theme Check CLI.\n *\n * @param stdout - The Writable stream on which to write the standard output.\n */\nasync function installThemeCheckCLIDependencies(stdout: Writable) {\n const exists = await file.fileExists(themeCheckDirectory())\n\n if (!exists) stdout.write('Installing theme dependencies...')\n await validateRubyEnv()\n await createThemeCheckCLIWorkingDirectory()\n await createThemeCheckGemfile()\n await bundleInstallThemeCheck()\n if (!exists) stdout.write('Installed theme dependencies!')\n}\n\n/**\n * Validate Ruby Enviroment\n * Install RubyCLI and its dependencies\n * Shows a loading spinner if it's the first time installing dependencies\n * or if we are installing a new version of RubyCLI.\n *\n * @param stdout - The Writable stream on which to write the standard output.\n */\nasync function installCLIDependencies(stdout: Writable) {\n const exists = await file.fileExists(shopifyCLIDirectory())\n\n if (!exists) stdout.write('Installing theme dependencies...')\n const usingLocalCLI2 = isTruthy(process.env.SHOPIFY_CLI_2_0_DIRECTORY)\n await validateRubyEnv()\n if (usingLocalCLI2) {\n await bundleInstallLocalShopifyCLI()\n } else {\n await createShopifyCLIWorkingDirectory()\n await createShopifyCLIGemfile()\n await bundleInstallShopifyCLI()\n }\n\n if (!exists) stdout.write('Installed theme dependencies!')\n}\n\n/**\n * A function that validates if the environment in which the CLI is running is set up with Ruby and Bundler.\n */\nasync function validateRubyEnv() {\n await validateRuby()\n await validateBundler()\n}\n\n/**\n * A function that validates if the environment in which the CLI is running is set up with Ruby.\n */\nasync function validateRuby() {\n let version\n try {\n const stdout = await captureOutput(rubyExecutable(), ['-v'])\n version = coerceSemverVersion(stdout)\n } catch {\n throw new AbortError(\n 'Ruby environment not found',\n `Make sure you have Ruby installed on your system. ${\n content`${token.link('Documentation.', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value\n }`,\n )\n }\n\n const isValid = version?.compare(MinRubyVersion)\n if (isValid === -1 || isValid === undefined) {\n throw new AbortError(\n `Ruby version ${content`${token.yellow(version.raw)}`.value} is not supported`,\n `Make sure you have at least Ruby ${content`${token.yellow(MinRubyVersion)}`.value} installed on your system. ${\n content`${token.link('Documentation.', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value\n }`,\n )\n }\n}\n\n/**\n * A function that validates if the environment in which the CLI is running is set up with Bundler.\n */\nasync function validateBundler() {\n let version\n try {\n const stdout = await captureOutput(bundleExecutable(), ['-v'])\n version = coerceSemverVersion(stdout)\n } catch {\n throw new AbortError(\n 'Bundler not found',\n `To install the latest version of Bundler, run ${\n content`${token.genericShellCommand(`${gemExecutable()} install bundler`)}`.value\n }`,\n )\n }\n\n const isValid = version?.compare(MinBundlerVersion)\n if (isValid === -1 || isValid === undefined) {\n throw new AbortError(\n `Bundler version ${content`${token.yellow(version.raw)}`.value} is not supported`,\n `To update to the latest version of Bundler, run ${\n content`${token.genericShellCommand(`${gemExecutable()} install bundler`)}`.value\n }`,\n )\n }\n}\n\n/**\n * It creates the directory where the Ruby CLI will be downloaded along its dependencies.\n */\nasync function createShopifyCLIWorkingDirectory(): Promise<void> {\n return file.mkdir(shopifyCLIDirectory())\n}\n\n/**\n * It creates the directory where the theme-check CLI will be downloaded along its dependencies.\n */\nasync function createThemeCheckCLIWorkingDirectory(): Promise<void> {\n return file.mkdir(themeCheckDirectory())\n}\n\n/**\n * It creates the Gemfile to install The Ruby CLI and the dependencies.\n */\nasync function createShopifyCLIGemfile(): Promise<void> {\n const gemPath = joinPath(shopifyCLIDirectory(), 'Gemfile')\n const gemFileContent = [\"source 'https://rubygems.org'\", `gem 'shopify-cli', '${RubyCLIVersion}'`]\n const {platform} = platformAndArch()\n if (platform === 'windows') {\n // 'wdm' is required by 'listen', see https://github.com/Shopify/cli/issues/780\n gemFileContent.push(\"gem 'wdm', '>= 0.1.0'\")\n }\n await file.writeFile(gemPath, gemFileContent.join('\\n'))\n}\n\n/**\n * It creates the Gemfile to install theme-check and its dependencies.\n */\nasync function createThemeCheckGemfile(): Promise<void> {\n const gemPath = joinPath(themeCheckDirectory(), 'Gemfile')\n await file.writeFile(gemPath, `source 'https://rubygems.org'\\ngem 'theme-check', '${ThemeCheckVersion}'`)\n}\n\n/**\n * It runs bundle install for the dev-managed copy of the Ruby CLI.\n */\nasync function bundleInstallLocalShopifyCLI(): Promise<void> {\n await exec(bundleExecutable(), ['install'], {cwd: shopifyCLIDirectory()})\n}\n\n/**\n * It runs bundle install for the CLI-managed copy of the Ruby CLI.\n */\nasync function bundleInstallShopifyCLI() {\n await exec(bundleExecutable(), ['config', 'set', '--local', 'path', shopifyCLIDirectory()], {\n cwd: shopifyCLIDirectory(),\n })\n await exec(bundleExecutable(), ['install'], {cwd: shopifyCLIDirectory()})\n}\n\n/**\n * It runs bundle install for the CLI-managed copy of theme-check.\n */\nasync function bundleInstallThemeCheck() {\n await exec(bundleExecutable(), ['config', 'set', '--local', 'path', themeCheckDirectory()], {\n cwd: themeCheckDirectory(),\n })\n await exec(bundleExecutable(), ['install'], {cwd: themeCheckDirectory()})\n}\n\n/**\n * It returns the directory where the Ruby CLI is located.\n *\n * @returns The absolute path to the directory.\n */\nfunction shopifyCLIDirectory(): string {\n return (\n process.env.SHOPIFY_CLI_2_0_DIRECTORY ??\n joinPath(pathConstants.directories.cache.vendor.path(), 'ruby-cli', RubyCLIVersion)\n )\n}\n\n/**\n * It returns the path to the directory containing the theme-check CLI.\n *\n * @returns The absolute path to the theme-check directory.\n */\nfunction themeCheckDirectory(): string {\n return joinPath(pathConstants.directories.cache.vendor.path(), 'theme-check', ThemeCheckVersion)\n}\n\n/**\n * It returns the Ruby version present in the envirronment.\n */\nexport async function version(): Promise<string | undefined> {\n const parseOutput = (version: string) => version.match(/ruby (\\d+\\.\\d+\\.\\d+)/)?.[1]\n return captureOutput(rubyExecutable(), ['-v'])\n .then(parseOutput)\n .catch(() => undefined)\n}\n\n/**\n * It returns the Ruby binary path set through the environment variable SHOPIFY_RUBY_BINDIR.\n * This is useful when the CLI is managed by an installer like a Homebrew where we need to\n * point the CLI to the Ruby installation managed by Homebrew.\n *\n * @returns The value of the environment variable.\n */\nfunction getRubyBinDir(): string | undefined {\n return process.env.SHOPIFY_RUBY_BINDIR\n}\n\n/**\n * It returns the path to the \"ruby\" executable.\n *\n * @returns The path to the executable.\n */\nfunction rubyExecutable(): string {\n const rubyBinDir = getRubyBinDir()\n return rubyBinDir ? joinPath(rubyBinDir, 'ruby') : 'ruby'\n}\n\n/**\n * It returns the path to the \"bundle\" executable.\n *\n * @returns The path to the executable.\n */\nfunction bundleExecutable(): string {\n const rubyBinDir = getRubyBinDir()\n return rubyBinDir ? joinPath(rubyBinDir, 'bundle') : 'bundle'\n}\n\n/**\n * It returns the path to the \"gem\"\" executable.\n *\n * @returns The path to the executable.\n */\nfunction gemExecutable(): string {\n const rubyBinDir = getRubyBinDir()\n return rubyBinDir ? joinPath(rubyBinDir, 'gem') : 'gem'\n}\n"]}
@@ -0,0 +1 @@
1
+ export { z as schema } from 'zod';
@@ -0,0 +1,2 @@
1
+ export { z as schema } from 'zod';
2
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/public/node/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,CAAC,IAAI,MAAM,EAAC,MAAM,KAAK,CAAA","sourcesContent":["export {z as schema} from 'zod'\n"]}
@@ -1,8 +1,8 @@
1
1
  import { normalizeStoreFqdn } from './environment/fqdn.js';
2
+ import { BugError } from './error.js';
2
3
  import * as secureStore from '../../private/node/session/store.js';
3
4
  import { exchangeCustomPartnerToken } from '../../private/node/session/exchange.js';
4
5
  import { content, token, debug } from '../../output.js';
5
- import { Bug } from '../../error.js';
6
6
  import { ensureAuthenticated } from '../../private/node/session.js';
7
7
  import { environmentVariables } from '../../private/node/constants.js';
8
8
  /**
@@ -24,7 +24,7 @@ ${token.json(scopes)}
24
24
  }
25
25
  const tokens = await ensureAuthenticated({ partnersApi: { scopes } });
26
26
  if (!tokens.partners) {
27
- throw new Bug('No partners token found after ensuring authenticated');
27
+ throw new BugError('No partners token found after ensuring authenticated');
28
28
  }
29
29
  return tokens.partners;
30
30
  }
@@ -43,7 +43,7 @@ ${token.json(scopes)}
43
43
  `);
44
44
  const tokens = await ensureAuthenticated({ storefrontRendererApi: { scopes } });
45
45
  if (!tokens.storefront) {
46
- throw new Bug('No storefront token found after ensuring authenticated');
46
+ throw new BugError('No storefront token found after ensuring authenticated');
47
47
  }
48
48
  return tokens.storefront;
49
49
  }
@@ -61,7 +61,7 @@ ${token.json(scopes)}
61
61
  `);
62
62
  const tokens = await ensureAuthenticated({ adminApi: { scopes, storeFqdn: store } }, process.env, forceRefresh);
63
63
  if (!tokens.admin) {
64
- throw new Bug('No admin token found after ensuring authenticated');
64
+ throw new BugError('No admin token found after ensuring authenticated');
65
65
  }
66
66
  return tokens.admin;
67
67
  }
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/public/node/session.ts"],"names":[],"mappings":"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","sourcesContent":["import {normalizeStoreFqdn} from './environment/fqdn.js'\nimport * as secureStore from '../../private/node/session/store.js'\nimport {exchangeCustomPartnerToken} from '../../private/node/session/exchange.js'\nimport {content, token, debug} from '../../output.js'\nimport {Bug} from '../../error.js'\nimport {ensureAuthenticated} from '../../private/node/session.js'\nimport {environmentVariables} from '../../private/node/constants.js'\n\n/**\n * Session Object to access the Admin API, includes the token and the store FQDN.\n */\nexport interface AdminSession {\n token: string\n storeFqdn: string\n}\n\n/**\n * Ensure that we have a valid session to access the Partners API.\n * If SHOPIFY_CLI_PARTNERS_TOKEN exists, that token will be used to obtain a valid Partners Token\n * If SHOPIFY_CLI_PARTNERS_TOKEN exists, scopes will be ignored.\n *\n * @param scopes - Optional array of extra scopes to authenticate with.\n * @param env - Optional environment variables to use.\n * @returns The access token for the Partners API.\n */\nexport async function ensureAuthenticatedPartners(scopes: string[] = [], env = process.env): Promise<string> {\n debug(content`Ensuring that the user is authenticated with the Partners API with the following scopes:\n${token.json(scopes)}\n`)\n const envToken = env[environmentVariables.partnersToken]\n if (envToken) {\n return (await exchangeCustomPartnerToken(envToken)).accessToken\n }\n const tokens = await ensureAuthenticated({partnersApi: {scopes}})\n if (!tokens.partners) {\n throw new Bug('No partners token found after ensuring authenticated')\n }\n return tokens.partners\n}\n\n/**\n * Ensure that we have a valid session to access the Storefront API.\n *\n * @param scopes - Optional array of extra scopes to authenticate with.\n * @param password - Optional password to use.\n * @returns The access token for the Storefront API.\n */\nexport async function ensureAuthenticatedStorefront(\n scopes: string[] = [],\n password: string | undefined = undefined,\n): Promise<string> {\n if (password) return password\n\n debug(content`Ensuring that the user is authenticated with the Storefront API with the following scopes:\n${token.json(scopes)}\n`)\n const tokens = await ensureAuthenticated({storefrontRendererApi: {scopes}})\n if (!tokens.storefront) {\n throw new Bug('No storefront token found after ensuring authenticated')\n }\n return tokens.storefront\n}\n\n/**\n * Ensure that we have a valid Admin session for the given store.\n *\n * @param store - Store fqdn to request auth for.\n * @param scopes - Optional array of extra scopes to authenticate with.\n * @param forceRefresh - Optional flag to force a refresh of the token.\n * @returns The access token for the Admin API.\n */\nexport async function ensureAuthenticatedAdmin(\n store: string,\n scopes: string[] = [],\n forceRefresh = false,\n): Promise<AdminSession> {\n debug(content`Ensuring that the user is authenticated with the Admin API with the following scopes for the store ${token.raw(\n store,\n )}:\n${token.json(scopes)}\n`)\n const tokens = await ensureAuthenticated({adminApi: {scopes, storeFqdn: store}}, process.env, forceRefresh)\n if (!tokens.admin) {\n throw new Bug('No admin token found after ensuring authenticated')\n }\n return tokens.admin\n}\n\n/**\n * Ensure that we have a valid session to access the Theme API.\n * If a password is provided, that token will be used against Theme Access API.\n * Otherwise, it will ensure that the user is authenticated with the Admin API.\n *\n * @param store - Store fqdn to request auth for.\n * @param password - Password generated from Theme Access app.\n * @param scopes - Optional array of extra scopes to authenticate with.\n * @param forceRefresh - Optional flag to force a refresh of the token.\n * @returns The access token and store.\n */\nexport async function ensureAuthenticatedThemes(\n store: string,\n password: string | undefined,\n scopes: string[] = [],\n forceRefresh = false,\n): Promise<AdminSession> {\n debug(content`Ensuring that the user is authenticated with the Theme API with the following scopes:\n${token.json(scopes)}\n`)\n if (password) return {token: password, storeFqdn: await normalizeStoreFqdn(store)}\n return ensureAuthenticatedAdmin(store, scopes, forceRefresh)\n}\n\n/**\n * Logout from Shopify.\n *\n * @returns A promise that resolves when the logout is complete.\n */\nexport function logout(): Promise<void> {\n return secureStore.remove()\n}\n"]}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/public/node/session.ts"],"names":[],"mappings":"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","sourcesContent":["import {normalizeStoreFqdn} from './environment/fqdn.js'\nimport {BugError} from './error.js'\nimport * as secureStore from '../../private/node/session/store.js'\nimport {exchangeCustomPartnerToken} from '../../private/node/session/exchange.js'\nimport {content, token, debug} from '../../output.js'\nimport {ensureAuthenticated} from '../../private/node/session.js'\nimport {environmentVariables} from '../../private/node/constants.js'\n\n/**\n * Session Object to access the Admin API, includes the token and the store FQDN.\n */\nexport interface AdminSession {\n token: string\n storeFqdn: string\n}\n\n/**\n * Ensure that we have a valid session to access the Partners API.\n * If SHOPIFY_CLI_PARTNERS_TOKEN exists, that token will be used to obtain a valid Partners Token\n * If SHOPIFY_CLI_PARTNERS_TOKEN exists, scopes will be ignored.\n *\n * @param scopes - Optional array of extra scopes to authenticate with.\n * @param env - Optional environment variables to use.\n * @returns The access token for the Partners API.\n */\nexport async function ensureAuthenticatedPartners(scopes: string[] = [], env = process.env): Promise<string> {\n debug(content`Ensuring that the user is authenticated with the Partners API with the following scopes:\n${token.json(scopes)}\n`)\n const envToken = env[environmentVariables.partnersToken]\n if (envToken) {\n return (await exchangeCustomPartnerToken(envToken)).accessToken\n }\n const tokens = await ensureAuthenticated({partnersApi: {scopes}})\n if (!tokens.partners) {\n throw new BugError('No partners token found after ensuring authenticated')\n }\n return tokens.partners\n}\n\n/**\n * Ensure that we have a valid session to access the Storefront API.\n *\n * @param scopes - Optional array of extra scopes to authenticate with.\n * @param password - Optional password to use.\n * @returns The access token for the Storefront API.\n */\nexport async function ensureAuthenticatedStorefront(\n scopes: string[] = [],\n password: string | undefined = undefined,\n): Promise<string> {\n if (password) return password\n\n debug(content`Ensuring that the user is authenticated with the Storefront API with the following scopes:\n${token.json(scopes)}\n`)\n const tokens = await ensureAuthenticated({storefrontRendererApi: {scopes}})\n if (!tokens.storefront) {\n throw new BugError('No storefront token found after ensuring authenticated')\n }\n return tokens.storefront\n}\n\n/**\n * Ensure that we have a valid Admin session for the given store.\n *\n * @param store - Store fqdn to request auth for.\n * @param scopes - Optional array of extra scopes to authenticate with.\n * @param forceRefresh - Optional flag to force a refresh of the token.\n * @returns The access token for the Admin API.\n */\nexport async function ensureAuthenticatedAdmin(\n store: string,\n scopes: string[] = [],\n forceRefresh = false,\n): Promise<AdminSession> {\n debug(content`Ensuring that the user is authenticated with the Admin API with the following scopes for the store ${token.raw(\n store,\n )}:\n${token.json(scopes)}\n`)\n const tokens = await ensureAuthenticated({adminApi: {scopes, storeFqdn: store}}, process.env, forceRefresh)\n if (!tokens.admin) {\n throw new BugError('No admin token found after ensuring authenticated')\n }\n return tokens.admin\n}\n\n/**\n * Ensure that we have a valid session to access the Theme API.\n * If a password is provided, that token will be used against Theme Access API.\n * Otherwise, it will ensure that the user is authenticated with the Admin API.\n *\n * @param store - Store fqdn to request auth for.\n * @param password - Password generated from Theme Access app.\n * @param scopes - Optional array of extra scopes to authenticate with.\n * @param forceRefresh - Optional flag to force a refresh of the token.\n * @returns The access token and store.\n */\nexport async function ensureAuthenticatedThemes(\n store: string,\n password: string | undefined,\n scopes: string[] = [],\n forceRefresh = false,\n): Promise<AdminSession> {\n debug(content`Ensuring that the user is authenticated with the Theme API with the following scopes:\n${token.json(scopes)}\n`)\n if (password) return {token: password, storeFqdn: await normalizeStoreFqdn(store)}\n return ensureAuthenticatedAdmin(store, scopes, forceRefresh)\n}\n\n/**\n * Logout from Shopify.\n *\n * @returns A promise that resolves when the logout is complete.\n */\nexport function logout(): Promise<void> {\n return secureStore.remove()\n}\n"]}
@@ -1,4 +1,5 @@
1
- import { Abort, ExternalError } from '../../error.js';
1
+ import { AbortError, ExternalError } from './error.js';
2
+ import { cwd } from './path.js';
2
3
  import { shouldDisplayColors, debug } from '../../output.js';
3
4
  import { execa } from 'execa';
4
5
  import treeKill from 'tree-kill';
@@ -45,7 +46,7 @@ export async function exec(command, args, options) {
45
46
  aborted = true;
46
47
  treeKill(pid, (err) => {
47
48
  if (err)
48
- throw new Abort(`Failed to kill process ${pid}: ${err}`);
49
+ throw new AbortError(`Failed to kill process ${pid}: ${err}`);
49
50
  });
50
51
  }
51
52
  });
@@ -91,7 +92,7 @@ function buildExec(command, args, options) {
91
92
  debug(`
92
93
  Running system process:
93
94
  · Command: ${command} ${args.join(' ')}
94
- · Working directory: ${options?.cwd ?? process.cwd()}
95
+ · Working directory: ${options?.cwd ?? cwd()}
95
96
  `);
96
97
  return commandProcess;
97
98
  }
@@ -1 +1 @@
1
- {"version":3,"file":"system.js","sourceRoot":"","sources":["../../../src/public/node/system.ts"],"names":[],"mappings":"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","sourcesContent":["import {AbortSignal} from './abort.js'\nimport {Abort, ExternalError} from '../../error.js'\nimport {shouldDisplayColors, debug} from '../../output.js'\nimport {execa, ExecaChildProcess} from 'execa'\nimport treeKill from 'tree-kill'\nimport type {Writable, Readable} from 'stream'\n\nexport interface ExecOptions {\n cwd?: string\n env?: {[key: string]: string | undefined}\n stdin?: Readable | 'inherit'\n stdout?: Writable | 'inherit'\n stderr?: Writable | 'inherit'\n stdio?: 'inherit'\n input?: string\n signal?: AbortSignal\n}\n\n/**\n * Opens a URL in the user's default browser.\n *\n * @param url - URL to open.\n */\nexport async function openURL(url: string): Promise<void> {\n const externalOpen = await import('open')\n await externalOpen.default(url)\n}\n\n/**\n * Runs a command asynchronously, aggregates the stdout data, and returns it.\n *\n * @param command - Command to be executed.\n * @param args - Arguments to pass to the command.\n * @param options - Optional settings for how to run the command.\n * @returns A promise that resolves with the aggregatted stdout of the command.\n */\nexport async function captureOutput(command: string, args: string[], options?: ExecOptions): Promise<string> {\n const result = await buildExec(command, args, options)\n return result.stdout\n}\n\n/**\n * Runs a command asynchronously.\n *\n * @param command - Command to be executed.\n * @param args - Arguments to pass to the command.\n * @param options - Optional settings for how to run the command.\n */\nexport async function exec(command: string, args: string[], options?: ExecOptions): Promise<void> {\n const commandProcess = buildExec(command, args, options)\n if (options?.stderr && options.stderr !== 'inherit') {\n commandProcess.stderr?.pipe(options.stderr)\n }\n if (options?.stdout && options.stdout !== 'inherit') {\n commandProcess.stdout?.pipe(options.stdout)\n }\n let aborted = false\n options?.signal?.addEventListener('abort', () => {\n const pid = commandProcess.pid\n if (pid) {\n aborted = true\n treeKill(pid, (err) => {\n if (err) throw new Abort(`Failed to kill process ${pid}: ${err}`)\n })\n }\n })\n try {\n await commandProcess\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (processError: any) {\n // Windows will throw an error whenever the process is killed, no matter the reason.\n // The aborted flag tell use that we killed it, so we can ignore the error.\n if (aborted) return\n const abortError = new ExternalError(processError.message, command, args)\n abortError.stack = processError.stack\n throw abortError\n }\n}\n\n/**\n * Runs a command asynchronously.\n *\n * @param command - Command to be executed.\n * @param args - Arguments to pass to the command.\n * @param options - Optional settings for how to run the command.\n * @returns A promise for a result with stdout and stderr properties.\n */\nfunction buildExec(command: string, args: string[], options?: ExecOptions): ExecaChildProcess<string> {\n const env = options?.env ?? process.env\n if (shouldDisplayColors()) {\n env.FORCE_COLOR = '1'\n }\n const commandProcess = execa(command, args, {\n env,\n cwd: options?.cwd,\n input: options?.input,\n stdio: options?.stdio,\n stdin: options?.stdin,\n stdout: options?.stdout === 'inherit' ? 'inherit' : undefined,\n stderr: options?.stderr === 'inherit' ? 'inherit' : undefined,\n // Setting this to false makes it possible to kill the main process\n // and all its sub-processes with Ctrl+C on Windows\n windowsHide: false,\n })\n debug(`\nRunning system process:\n · Command: ${command} ${args.join(' ')}\n · Working directory: ${options?.cwd ?? process.cwd()}\n`)\n return commandProcess\n}\n\n/**\n * Waits for a given number of seconds.\n *\n * @param seconds - Number of seconds to wait.\n */\nexport async function sleep(seconds: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, 1000 * seconds)\n })\n}\n"]}
1
+ {"version":3,"file":"system.js","sourceRoot":"","sources":["../../../src/public/node/system.ts"],"names":[],"mappings":"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","sourcesContent":["import {AbortSignal} from './abort.js'\nimport {AbortError, ExternalError} from './error.js'\nimport {cwd} from './path.js'\nimport {shouldDisplayColors, debug} from '../../output.js'\nimport {execa, ExecaChildProcess} from 'execa'\nimport treeKill from 'tree-kill'\nimport type {Writable, Readable} from 'stream'\n\nexport interface ExecOptions {\n cwd?: string\n env?: {[key: string]: string | undefined}\n stdin?: Readable | 'inherit'\n stdout?: Writable | 'inherit'\n stderr?: Writable | 'inherit'\n stdio?: 'inherit'\n input?: string\n signal?: AbortSignal\n}\n\n/**\n * Opens a URL in the user's default browser.\n *\n * @param url - URL to open.\n */\nexport async function openURL(url: string): Promise<void> {\n const externalOpen = await import('open')\n await externalOpen.default(url)\n}\n\n/**\n * Runs a command asynchronously, aggregates the stdout data, and returns it.\n *\n * @param command - Command to be executed.\n * @param args - Arguments to pass to the command.\n * @param options - Optional settings for how to run the command.\n * @returns A promise that resolves with the aggregatted stdout of the command.\n */\nexport async function captureOutput(command: string, args: string[], options?: ExecOptions): Promise<string> {\n const result = await buildExec(command, args, options)\n return result.stdout\n}\n\n/**\n * Runs a command asynchronously.\n *\n * @param command - Command to be executed.\n * @param args - Arguments to pass to the command.\n * @param options - Optional settings for how to run the command.\n */\nexport async function exec(command: string, args: string[], options?: ExecOptions): Promise<void> {\n const commandProcess = buildExec(command, args, options)\n if (options?.stderr && options.stderr !== 'inherit') {\n commandProcess.stderr?.pipe(options.stderr)\n }\n if (options?.stdout && options.stdout !== 'inherit') {\n commandProcess.stdout?.pipe(options.stdout)\n }\n let aborted = false\n options?.signal?.addEventListener('abort', () => {\n const pid = commandProcess.pid\n if (pid) {\n aborted = true\n treeKill(pid, (err) => {\n if (err) throw new AbortError(`Failed to kill process ${pid}: ${err}`)\n })\n }\n })\n try {\n await commandProcess\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (processError: any) {\n // Windows will throw an error whenever the process is killed, no matter the reason.\n // The aborted flag tell use that we killed it, so we can ignore the error.\n if (aborted) return\n const abortError = new ExternalError(processError.message, command, args)\n abortError.stack = processError.stack\n throw abortError\n }\n}\n\n/**\n * Runs a command asynchronously.\n *\n * @param command - Command to be executed.\n * @param args - Arguments to pass to the command.\n * @param options - Optional settings for how to run the command.\n * @returns A promise for a result with stdout and stderr properties.\n */\nfunction buildExec(command: string, args: string[], options?: ExecOptions): ExecaChildProcess<string> {\n const env = options?.env ?? process.env\n if (shouldDisplayColors()) {\n env.FORCE_COLOR = '1'\n }\n const commandProcess = execa(command, args, {\n env,\n cwd: options?.cwd,\n input: options?.input,\n stdio: options?.stdio,\n stdin: options?.stdin,\n stdout: options?.stdout === 'inherit' ? 'inherit' : undefined,\n stderr: options?.stderr === 'inherit' ? 'inherit' : undefined,\n // Setting this to false makes it possible to kill the main process\n // and all its sub-processes with Ctrl+C on Windows\n windowsHide: false,\n })\n debug(`\nRunning system process:\n · Command: ${command} ${args.join(' ')}\n · Working directory: ${options?.cwd ?? cwd()}\n`)\n return commandProcess\n}\n\n/**\n * Waits for a given number of seconds.\n *\n * @param seconds - Number of seconds to wait.\n */\nexport async function sleep(seconds: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, 1000 * seconds)\n })\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { sleep } from './system.js';
2
+ import { AbortError } from './error.js';
2
3
  import { debug, content, token } from '../../output.js';
3
- import { Abort } from '../../error.js';
4
4
  import * as port from 'get-port-please';
5
5
  /**
6
6
  * Returns an available port in the current environment.
@@ -36,7 +36,7 @@ async function retryOnError(execute, maxTries = 5, waitTimeInSeconds = 1) {
36
36
  await sleep(waitTimeInSeconds);
37
37
  }
38
38
  else {
39
- throw new Abort(error.message);
39
+ throw new AbortError(error.message);
40
40
  }
41
41
  }
42
42
  }
@@ -1 +1 @@
1
- {"version":3,"file":"tcp.js","sourceRoot":"","sources":["../../../src/public/node/tcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,aAAa,CAAA;AACjC,OAAO,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAC,MAAM,iBAAiB,CAAA;AACrD,OAAO,EAAC,KAAK,EAAC,MAAM,gBAAgB,CAAA;AACpC,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAA;AAEvC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,KAAK,CAAC,OAAO,CAAA,0BAA0B,CAAC,CAAA;IACxC,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAA;IACjE,KAAK,CAAC,OAAO,CAAA,yBAAyB,KAAK,CAAC,GAAG,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,CAAC,CAAA;IACnE,OAAO,UAAU,CAAA;AACnB,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,YAAY,CAAI,OAAgB,EAAE,QAAQ,GAAG,CAAC,EAAE,iBAAiB,GAAG,CAAC;IAClF,IAAI,UAAU,GAAG,CAAC,CAAA;IAClB,OAAO,IAAI,EAAE;QACX,IAAI;YACF,4CAA4C;YAC5C,OAAO,MAAM,OAAO,EAAE,CAAA;YACtB,8DAA8D;SAC/D;QAAC,OAAO,KAAU,EAAE;YACnB,IAAI,UAAU,EAAE,GAAG,QAAQ,EAAE;gBAC3B,KAAK,CAAC,OAAO,CAAA,0CAA0C,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;gBACvE,4CAA4C;gBAC5C,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAA;aAC/B;iBAAM;gBACL,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;aAC/B;SACF;KACF;AACH,CAAC","sourcesContent":["import {sleep} from './system.js'\nimport {debug, content, token} from '../../output.js'\nimport {Abort} from '../../error.js'\nimport * as port from 'get-port-please'\n\n/**\n * Returns an available port in the current environment.\n *\n * @returns A promise that resolves with an availabe port.\n * @example\n */\nexport async function getAvailableTCPPort(): Promise<number> {\n debug(content`Getting a random port...`)\n const randomPort = await retryOnError(() => port.getRandomPort())\n debug(content`Random port obtained: ${token.raw(`${randomPort}`)}`)\n return randomPort\n}\n\n/**\n * Given a function, it runs it and retries in case of failiure up to the provided number of times.\n *\n * @param execute - The function to execute.\n * @param maxTries - The maximum retries.\n * @param waitTimeInSeconds - The time to wait between retries.\n */\nasync function retryOnError<T>(execute: () => T, maxTries = 5, waitTimeInSeconds = 1) {\n let retryCount = 1\n while (true) {\n try {\n // eslint-disable-next-line no-await-in-loop\n return await execute()\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n if (retryCount++ < maxTries) {\n debug(content`Unknown problem getting a random port: ${error.message}`)\n // eslint-disable-next-line no-await-in-loop\n await sleep(waitTimeInSeconds)\n } else {\n throw new Abort(error.message)\n }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"tcp.js","sourceRoot":"","sources":["../../../src/public/node/tcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,aAAa,CAAA;AACjC,OAAO,EAAC,UAAU,EAAC,MAAM,YAAY,CAAA;AACrC,OAAO,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAC,MAAM,iBAAiB,CAAA;AACrD,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAA;AAEvC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,KAAK,CAAC,OAAO,CAAA,0BAA0B,CAAC,CAAA;IACxC,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAA;IACjE,KAAK,CAAC,OAAO,CAAA,yBAAyB,KAAK,CAAC,GAAG,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,CAAC,CAAA;IACnE,OAAO,UAAU,CAAA;AACnB,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,YAAY,CAAI,OAAgB,EAAE,QAAQ,GAAG,CAAC,EAAE,iBAAiB,GAAG,CAAC;IAClF,IAAI,UAAU,GAAG,CAAC,CAAA;IAClB,OAAO,IAAI,EAAE;QACX,IAAI;YACF,4CAA4C;YAC5C,OAAO,MAAM,OAAO,EAAE,CAAA;YACtB,8DAA8D;SAC/D;QAAC,OAAO,KAAU,EAAE;YACnB,IAAI,UAAU,EAAE,GAAG,QAAQ,EAAE;gBAC3B,KAAK,CAAC,OAAO,CAAA,0CAA0C,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;gBACvE,4CAA4C;gBAC5C,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAA;aAC/B;iBAAM;gBACL,MAAM,IAAI,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;aACpC;SACF;KACF;AACH,CAAC","sourcesContent":["import {sleep} from './system.js'\nimport {AbortError} from './error.js'\nimport {debug, content, token} from '../../output.js'\nimport * as port from 'get-port-please'\n\n/**\n * Returns an available port in the current environment.\n *\n * @returns A promise that resolves with an availabe port.\n * @example\n */\nexport async function getAvailableTCPPort(): Promise<number> {\n debug(content`Getting a random port...`)\n const randomPort = await retryOnError(() => port.getRandomPort())\n debug(content`Random port obtained: ${token.raw(`${randomPort}`)}`)\n return randomPort\n}\n\n/**\n * Given a function, it runs it and retries in case of failiure up to the provided number of times.\n *\n * @param execute - The function to execute.\n * @param maxTries - The maximum retries.\n * @param waitTimeInSeconds - The time to wait between retries.\n */\nasync function retryOnError<T>(execute: () => T, maxTries = 5, waitTimeInSeconds = 1) {\n let retryCount = 1\n while (true) {\n try {\n // eslint-disable-next-line no-await-in-loop\n return await execute()\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n if (retryCount++ < maxTries) {\n debug(content`Unknown problem getting a random port: ${error.message}`)\n // eslint-disable-next-line no-await-in-loop\n await sleep(waitTimeInSeconds)\n } else {\n throw new AbortError(error.message)\n }\n }\n }\n}\n"]}
@@ -0,0 +1,16 @@
1
+ interface OutputMock {
2
+ output: () => string;
3
+ info: () => string;
4
+ debug: () => string;
5
+ success: () => string;
6
+ completed: () => string;
7
+ warn: () => string;
8
+ error: () => string;
9
+ clear: () => void;
10
+ }
11
+ /**
12
+ * Returns a set of functions to get the outputs ocurred during a test run.
13
+ *
14
+ * @returns An mock object with all the output functions.
15
+ */ export declare function mockAndCaptureOutput(): OutputMock;
16
+ export {};
@@ -1,5 +1,9 @@
1
- import * as output from '../output.js';
2
- export function mockAndCaptureOutput() {
1
+ import * as output from '../../../output.js';
2
+ /**
3
+ * Returns a set of functions to get the outputs ocurred during a test run.
4
+ *
5
+ * @returns An mock object with all the output functions.
6
+ */ export function mockAndCaptureOutput() {
3
7
  return {
4
8
  output: () => (output.collectedLogs.output ?? []).join('\n'),
5
9
  info: () => (output.collectedLogs.info ?? []).join('\n'),
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../../../src/public/node/testing/output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAA;AAa5C;;;;GAIG,CAAC,MAAM,UAAU,oBAAoB;IACtC,OAAO;QACL,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAC5D,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACxD,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAC1D,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAC9D,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAClE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACxD,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAC1D,KAAK,EAAE,GAAG,EAAE;YACV,MAAM,CAAC,kBAAkB,EAAE,CAAA;QAC7B,CAAC;KACF,CAAA;AACH,CAAC","sourcesContent":["import * as output from '../../../output.js'\n\ninterface OutputMock {\n output: () => string\n info: () => string\n debug: () => string\n success: () => string\n completed: () => string\n warn: () => string\n error: () => string\n clear: () => void\n}\n\n/**\n * Returns a set of functions to get the outputs ocurred during a test run.\n *\n * @returns An mock object with all the output functions.\n */ export function mockAndCaptureOutput(): OutputMock {\n return {\n output: () => (output.collectedLogs.output ?? []).join('\\n'),\n info: () => (output.collectedLogs.info ?? []).join('\\n'),\n debug: () => (output.collectedLogs.debug ?? []).join('\\n'),\n success: () => (output.collectedLogs.success ?? []).join('\\n'),\n completed: () => (output.collectedLogs.completed ?? []).join('\\n'),\n warn: () => (output.collectedLogs.warn ?? []).join('\\n'),\n error: () => (output.collectedLogs.error ?? []).join('\\n'),\n clear: () => {\n output.clearCollectedLogs()\n },\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
+ import { FatalError as Fatal } from './error.js';
1
2
  import { OutputProcess } from '../../output.js';
2
- import { Fatal } from '../../error.js';
3
3
  import { AlertProps } from '../../private/node/ui/components/Alert.js';
4
4
  import ScalarDict from '../../private/node/ui/components/Table/ScalarDict.js';
5
5
  import { TableProps } from '../../private/node/ui/components/Table/Table.js';