@shopify/cli-kit 4.9.5 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/dist/cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.d.ts +5 -0
  2. package/dist/cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.js +22 -0
  3. package/dist/cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.js.map +1 -1
  4. package/dist/private/node/api/graphql.d.ts +2 -1
  5. package/dist/private/node/api/graphql.js +12 -1
  6. package/dist/private/node/api/graphql.js.map +1 -1
  7. package/dist/private/node/api.d.ts +2 -0
  8. package/dist/private/node/api.js +49 -22
  9. package/dist/private/node/api.js.map +1 -1
  10. package/dist/private/node/command-json-schema.js +1 -0
  11. package/dist/private/node/command-json-schema.js.map +1 -1
  12. package/dist/private/node/constants.d.ts +1 -0
  13. package/dist/private/node/constants.js +1 -0
  14. package/dist/private/node/constants.js.map +1 -1
  15. package/dist/private/node/dev-instance-output.d.ts +47 -0
  16. package/dist/private/node/dev-instance-output.js +143 -0
  17. package/dist/private/node/dev-instance-output.js.map +1 -0
  18. package/dist/private/node/json-error.d.ts +1 -15
  19. package/dist/private/node/json-error.js +4 -98
  20. package/dist/private/node/json-error.js.map +1 -1
  21. package/dist/private/node/output-context.d.ts +8 -0
  22. package/dist/private/node/output-context.js +10 -0
  23. package/dist/private/node/output-context.js.map +1 -0
  24. package/dist/private/node/output.test.js +4 -4
  25. package/dist/private/node/output.test.js.map +1 -1
  26. package/dist/private/node/session/automation-token.d.ts +50 -0
  27. package/dist/private/node/session/automation-token.js +77 -0
  28. package/dist/private/node/session/automation-token.js.map +1 -0
  29. package/dist/private/node/session/exchange.d.ts +5 -1
  30. package/dist/private/node/session/exchange.js +97 -7
  31. package/dist/private/node/session/exchange.js.map +1 -1
  32. package/dist/private/node/session/permanent-store-domain.d.ts +21 -0
  33. package/dist/private/node/session/permanent-store-domain.js +72 -0
  34. package/dist/private/node/session/permanent-store-domain.js.map +1 -0
  35. package/dist/private/node/session.d.ts +3 -2
  36. package/dist/private/node/session.js +12 -3
  37. package/dist/private/node/session.js.map +1 -1
  38. package/dist/private/node/themes/trust-challenge.d.ts +31 -0
  39. package/dist/private/node/themes/trust-challenge.js +143 -0
  40. package/dist/private/node/themes/trust-challenge.js.map +1 -0
  41. package/dist/private/node/ui/alert.js +1 -1
  42. package/dist/private/node/ui/alert.js.map +1 -1
  43. package/dist/private/node/ui/components/ConcurrentOutput.d.ts +2 -7
  44. package/dist/private/node/ui/components/ConcurrentOutput.js +4 -8
  45. package/dist/private/node/ui/components/ConcurrentOutput.js.map +1 -1
  46. package/dist/private/node/ui/components/LoadingBar.js +9 -15
  47. package/dist/private/node/ui/components/LoadingBar.js.map +1 -1
  48. package/dist/private/node/ui/components/LoadingBar.test.js +45 -107
  49. package/dist/private/node/ui/components/LoadingBar.test.js.map +1 -1
  50. package/dist/private/node/ui/components/LoadingIndicator.d.ts +7 -0
  51. package/dist/private/node/ui/components/LoadingIndicator.js +22 -0
  52. package/dist/private/node/ui/components/LoadingIndicator.js.map +1 -0
  53. package/dist/private/node/ui/components/Table/Table.d.ts +8 -0
  54. package/dist/private/node/ui/components/Table/Table.js +18 -2
  55. package/dist/private/node/ui/components/Table/Table.js.map +1 -1
  56. package/dist/public/common/version.d.ts +1 -1
  57. package/dist/public/common/version.js +1 -1
  58. package/dist/public/common/version.js.map +1 -1
  59. package/dist/public/node/api/admin.js +13 -0
  60. package/dist/public/node/api/admin.js.map +1 -1
  61. package/dist/public/node/api/graphql.js +38 -7
  62. package/dist/public/node/api/graphql.js.map +1 -1
  63. package/dist/public/node/archiver.js +13 -6
  64. package/dist/public/node/archiver.js.map +1 -1
  65. package/dist/public/node/base-command.d.ts +6 -0
  66. package/dist/public/node/base-command.js +97 -16
  67. package/dist/public/node/base-command.js.map +1 -1
  68. package/dist/public/node/dev-instance.d.ts +138 -0
  69. package/dist/public/node/dev-instance.js +365 -0
  70. package/dist/public/node/dev-instance.js.map +1 -0
  71. package/dist/public/node/environment.d.ts +6 -3
  72. package/dist/public/node/environment.js +11 -4
  73. package/dist/public/node/environment.js.map +1 -1
  74. package/dist/public/node/error/index.js +2 -1
  75. package/dist/public/node/error/index.js.map +1 -1
  76. package/dist/public/node/error/schema.d.ts +24 -24
  77. package/dist/public/node/error/serialization.d.ts +8 -0
  78. package/dist/public/node/error/serialization.js +103 -0
  79. package/dist/public/node/error/serialization.js.map +1 -0
  80. package/dist/public/node/graphiql/server.js +18 -2
  81. package/dist/public/node/graphiql/server.js.map +1 -1
  82. package/dist/public/node/is-global.js +2 -1
  83. package/dist/public/node/is-global.js.map +1 -1
  84. package/dist/public/node/notifications-system.d.ts +6 -6
  85. package/dist/public/node/path.d.ts +19 -3
  86. package/dist/public/node/path.js +21 -3
  87. package/dist/public/node/path.js.map +1 -1
  88. package/dist/public/node/session.d.ts +38 -3
  89. package/dist/public/node/session.js +56 -9
  90. package/dist/public/node/session.js.map +1 -1
  91. package/dist/public/node/system.d.ts +4 -0
  92. package/dist/public/node/system.js +39 -9
  93. package/dist/public/node/system.js.map +1 -1
  94. package/dist/public/node/themes/api.d.ts +9 -0
  95. package/dist/public/node/themes/api.js +50 -22
  96. package/dist/public/node/themes/api.js.map +1 -1
  97. package/dist/public/node/themes/theme-manager.d.ts +8 -1
  98. package/dist/public/node/themes/theme-manager.js +1 -1
  99. package/dist/public/node/themes/theme-manager.js.map +1 -1
  100. package/dist/public/node/tree-kill.js +12 -2
  101. package/dist/public/node/tree-kill.js.map +1 -1
  102. package/dist/public/node/ui/components.d.ts +1 -0
  103. package/dist/public/node/ui/components.js +1 -0
  104. package/dist/public/node/ui/components.js.map +1 -1
  105. package/dist/public/node/ui.d.ts +24 -4
  106. package/dist/public/node/ui.js +54 -21
  107. package/dist/public/node/ui.js.map +1 -1
  108. package/dist/public/node/upgrade/output.d.ts +17 -0
  109. package/dist/public/node/upgrade/output.js +51 -0
  110. package/dist/public/node/upgrade/output.js.map +1 -0
  111. package/dist/public/node/upgrade/result.d.ts +8 -0
  112. package/dist/public/node/upgrade/result.js +21 -0
  113. package/dist/public/node/upgrade/result.js.map +1 -0
  114. package/dist/public/node/upgrade/types.d.ts +61 -0
  115. package/dist/public/node/upgrade/types.js +46 -0
  116. package/dist/public/node/upgrade/types.js.map +1 -0
  117. package/dist/public/node/upgrade.d.ts +8 -0
  118. package/dist/public/node/upgrade.js +57 -22
  119. package/dist/public/node/upgrade.js.map +1 -1
  120. package/dist/tsconfig.tsbuildinfo +1 -1
  121. package/package.json +3 -3
  122. package/dist/private/node/ui/components/TextAnimation.d.ts +0 -10
  123. package/dist/private/node/ui/components/TextAnimation.js +0 -56
  124. package/dist/private/node/ui/components/TextAnimation.js.map +0 -1
  125. package/dist/private/node/ui/components/TextAnimation.test.d.ts +0 -1
  126. package/dist/private/node/ui/components/TextAnimation.test.js +0 -73
  127. package/dist/private/node/ui/components/TextAnimation.test.js.map +0 -1
@@ -33,14 +33,38 @@ export async function openURL(url) {
33
33
  return false;
34
34
  const externalOpen = await import('open');
35
35
  try {
36
- await externalOpen.default(url);
37
- return true;
36
+ const subprocess = await externalOpen.default(url);
37
+ return await browserLaunchSucceeded(subprocess);
38
38
  // eslint-disable-next-line no-catch-all/no-catch-all
39
39
  }
40
40
  catch (error) {
41
41
  return false;
42
42
  }
43
43
  }
44
+ /**
45
+ * Waits for the process spawned to open a browser to either start or fail.
46
+ *
47
+ * `open` resolves as soon as it has called `spawn`, before the OS reports whether the
48
+ * launcher exists. A missing launcher (e.g. `xdg-open` in a headless container) is
49
+ * reported later as an `error` event on the child process. Without a listener that
50
+ * event is thrown as an uncaught exception and terminates the CLI, which kills flows
51
+ * such as device-code login that could otherwise carry on with the printed link.
52
+ *
53
+ * @param subprocess - The child process returned by `open`.
54
+ * @returns A promise that resolves true if the process started, false if it failed to start.
55
+ */
56
+ async function browserLaunchSucceeded(subprocess) {
57
+ if (!subprocess || typeof subprocess.once !== 'function')
58
+ return true;
59
+ return new Promise((resolve) => {
60
+ // Keep a permanent listener so a late error can never become an uncaught exception.
61
+ subprocess.on('error', (error) => {
62
+ outputDebug(`Failed to open the browser: ${error.message}`);
63
+ resolve(false);
64
+ });
65
+ subprocess.once('spawn', () => resolve(true));
66
+ });
67
+ }
44
68
  /**
45
69
  * Runs a command asynchronously, aggregates the stdout data, and returns it.
46
70
  *
@@ -56,6 +80,7 @@ export async function captureOutput(command, args, options) {
56
80
  /**
57
81
  * Runs a command asynchronously and returns stdout, stderr, and exit code.
58
82
  * Unlike captureOutput, this function does NOT throw on non-zero exit codes.
83
+ * Startup failures and signal termination still throw an ExternalError.
59
84
  *
60
85
  * @param command - Command to be executed.
61
86
  * @param args - Arguments to pass to the command.
@@ -72,10 +97,13 @@ export async function captureOutput(command, args, options) {
72
97
  */
73
98
  export async function captureOutputWithExitCode(command, args, options) {
74
99
  const result = await buildExec(command, args, options, { reject: false });
100
+ if (result.exitCode === undefined) {
101
+ throw new ExternalError(result instanceof Error ? result.message : 'Command terminated without an exit code.', command, args);
102
+ }
75
103
  return {
76
104
  stdout: result.stdout,
77
105
  stderr: result.stderr,
78
- exitCode: result.exitCode ?? 0,
106
+ exitCode: result.exitCode,
79
107
  };
80
108
  }
81
109
  /**
@@ -127,6 +155,7 @@ function parseCommand(command) {
127
155
  * Runs a command string asynchronously and returns stdout, stderr, and exit code.
128
156
  * Parses the command string into command and arguments (handles quoted strings).
129
157
  * Unlike captureOutput, this function does NOT throw on non-zero exit codes.
158
+ * Startup failures and signal termination still throw an ExternalError.
130
159
  *
131
160
  * @param command - Full command string to be executed (e.g., 'ls -la "my folder"').
132
161
  * @param options - Optional settings for how to run the command.
@@ -177,12 +206,6 @@ export async function exec(command, args, options) {
177
206
  if (options?.background) {
178
207
  commandProcess.unref();
179
208
  }
180
- if (options?.stderr && options.stderr !== 'inherit') {
181
- commandProcess.stderr?.pipe(options.stderr, { end: false });
182
- }
183
- if (options?.stdout && options.stdout !== 'inherit') {
184
- commandProcess.stdout?.pipe(options.stdout, { end: false });
185
- }
186
209
  let aborted = false;
187
210
  options?.signal?.addEventListener('abort', () => {
188
211
  const pid = commandProcess.pid;
@@ -232,6 +255,7 @@ function buildExec(command, args, options, execaOptions) {
232
255
  env,
233
256
  cwd: executionCwd,
234
257
  input: options?.input,
258
+ stripFinalNewline: options?.stripFinalNewline ?? true,
235
259
  stdio: options?.background ? backgroundStdio : options?.stdio,
236
260
  stdin: options?.stdin,
237
261
  stdout: options?.stdout === 'inherit' ? 'inherit' : undefined,
@@ -243,6 +267,12 @@ function buildExec(command, args, options, execaOptions) {
243
267
  cleanup: !options?.background,
244
268
  ...execaOptions,
245
269
  });
270
+ if (options?.stderr && options.stderr !== 'inherit') {
271
+ commandProcess.stderr?.pipe(options.stderr, { end: false });
272
+ }
273
+ if (options?.stdout && options.stdout !== 'inherit') {
274
+ commandProcess.stdout?.pipe(options.stdout, { end: false });
275
+ }
246
276
  outputDebug(`Running system process${options?.background ? ' in background' : ''}:
247
277
  · Command: ${command} ${args.join(' ')}
248
278
  · Working directory: ${executionCwd}
@@ -1 +1 @@
1
- {"version":3,"file":"system.js","sourceRoot":"","sources":["../../../src/public/node/system.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,UAAU,EAAE,aAAa,EAAC,MAAM,YAAY,CAAA;AACpD,OAAO,EAAC,GAAG,EAAE,WAAW,EAAC,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAC,QAAQ,EAAC,MAAM,gBAAgB,CAAA;AACvC,OAAO,EAAC,QAAQ,EAAC,MAAM,wBAAwB,CAAA;AAC/C,OAAO,EAAC,aAAa,EAAC,MAAM,SAAS,CAAA;AACrC,OAAO,EAAC,eAAe,EAAC,MAAM,SAAS,CAAA;AACvC,OAAO,EAAC,mBAAmB,EAAE,WAAW,EAAC,MAAM,aAAa,CAAA;AAC5D,OAAO,EAAC,kBAAkB,EAAC,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAC,eAAe,EAAC,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAC,KAAK,EAAoB,MAAM,OAAO,CAAA;AAC9C,OAAO,kBAAkB,MAAM,qBAAqB,CAAA;AACpD,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAC,SAAS,EAAE,UAAU,EAAE,YAAY,EAAC,MAAM,IAAI,CAAA;AACtD,OAAO,EAAC,OAAO,EAAC,MAAM,IAAI,CAAA;AAC1B,OAAO,EAAC,UAAU,EAAC,MAAM,iBAAiB,CAAA;AAG1C;;;;GAIG;AACH,MAAM,cAAc,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAA;AAyBvC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,GAAW;IACvC,IAAI,eAAe,EAAE,EAAE,CAAC;QACtB,MAAM,IAAI,UAAU,CAClB,+DAA+D,EAC/D,qEAAqE,CACtE,CAAA;IACH,CAAC;IACD,IAAI,kBAAkB,EAAE;QAAE,OAAO,KAAK,CAAA;IAEtC,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAA;IACzC,IAAI,CAAC;QACH,MAAM,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAC/B,OAAO,IAAI,CAAA;QACX,qDAAqD;IACvD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAe,EAAE,IAAc,EAAE,OAAqB;IACxF,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IACtD,OAAO,MAAM,CAAC,MAAM,CAAA;AACtB,CAAC;AAcD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,OAAe,EACf,IAAc,EACd,OAAqB;IAErB,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAC,MAAM,EAAE,KAAK,EAAC,CAAC,CAAA;IACvE,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,CAAC;KAC/B,CAAA;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,YAAY,CAAC,OAAe;IACnC,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,IAAI,OAAO,GAAG,EAAE,CAAA;IAChB,IAAI,OAAO,GAAkB,IAAI,CAAA;IAEjC,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;gBACrB,wBAAwB;gBACxB,OAAO,GAAG,IAAI,CAAA;YAChB,CAAC;iBAAM,CAAC;gBACN,OAAO,IAAI,IAAI,CAAA;YACjB,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YACxC,0BAA0B;YAC1B,OAAO,GAAG,IAAI,CAAA;QAChB,CAAC;aAAM,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YACzC,gDAAgD;YAChD,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;gBACpB,OAAO,GAAG,EAAE,CAAA;YACd,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,IAAI,CAAA;QACjB,CAAC;IACH,CAAC;IAED,8BAA8B;IAC9B,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACtB,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,OAAe,EAAE,OAAqB;IACrF,MAAM,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC,CAAA;IAC5C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,EAAC,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,CAAC,EAAC,CAAA;IAC3D,CAAC;IACD,OAAO,yBAAyB,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;AACtD,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAe,EAAE,OAAqB;IACtE,MAAM,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC,CAAA;IAC5C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,UAAU,CAAC,eAAe,CAAC,CAAA;IACvC,CAAC;IACD,MAAM,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;AAChC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,OAAe,EAAE,IAAc,EAAE,OAAqB;IAC/E,IAAI,OAAO,EAAE,CAAC;QACZ,iGAAiG;QACjG,MAAM,gBAAgB,GAAG,eAAe,EAAE,CAAC,QAAQ,KAAK,SAAS,CAAA;QACjE,OAAO,CAAC,UAAU,GAAG,gBAAgB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAA;IACpE,CAAC;IAED,MAAM,cAAc,GAAG,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IAExD,IAAI,OAAO,EAAE,UAAU,EAAE,CAAC;QACxB,cAAc,CAAC,KAAK,EAAE,CAAA;IACxB,CAAC;IAED,IAAI,OAAO,EAAE,MAAM,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACpD,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAC,GAAG,EAAE,KAAK,EAAC,CAAC,CAAA;IAC3D,CAAC;IACD,IAAI,OAAO,EAAE,MAAM,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACpD,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAC,GAAG,EAAE,KAAK,EAAC,CAAC,CAAA;IAC3D,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,OAAO,EAAE,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;QAC9C,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAA;QAC9B,IAAI,GAAG,EAAE,CAAC;YACR,WAAW,CAAC,mBAAmB,GAAG,KAAK,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YACnE,OAAO,GAAG,IAAI,CAAA;YACd,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;QAC1B,CAAC;IACH,CAAC,CAAC,CAAA;IACF,IAAI,CAAC;QACH,MAAM,cAAc,CAAA;QACpB,8DAA8D;IAChE,CAAC;IAAC,OAAO,YAAiB,EAAE,CAAC;QAC3B,oFAAoF;QACpF,2EAA2E;QAC3E,IAAI,OAAO;YAAE,OAAM;QACnB,IAAI,OAAO,EAAE,oBAAoB,EAAE,CAAC;YAClC,MAAM,OAAO,CAAC,oBAAoB,CAAC,YAAY,CAAC,CAAA;QAClD,CAAC;aAAM,CAAC;YACN,MAAM,UAAU,GAAG,IAAI,aAAa,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;YACzE,UAAU,CAAC,KAAK,GAAG,YAAY,CAAC,KAAK,CAAA;YACrC,MAAM,UAAU,CAAA;QAClB,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,SAAS,CAChB,OAAe,EACf,IAAc,EACd,OAAqB,EACrB,YAA+B;IAE/B,MAAM,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,CAAA;IACvC,IAAI,mBAAmB,EAAE,EAAE,CAAC;QAC1B,GAAG,CAAC,WAAW,GAAG,GAAG,CAAA;IACvB,CAAC;IACD,MAAM,YAAY,GAAG,OAAO,EAAE,GAAG,IAAI,GAAG,EAAE,CAAA;IAC1C,kBAAkB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;IACzC,MAAM,eAAe,GAAG,OAAO,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAW,CAAA;IACzG,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;QAC1C,GAAG;QACH,GAAG,EAAE,YAAY;QACjB,KAAK,EAAE,OAAO,EAAE,KAAK;QACrB,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK;QAC7D,KAAK,EAAE,OAAO,EAAE,KAAK;QACrB,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;QAC7D,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;QAC7D,mEAAmE;QACnE,mDAAmD;QACnD,WAAW,EAAE,KAAK;QAClB,QAAQ,EAAE,OAAO,EAAE,UAAU;QAC7B,OAAO,EAAE,CAAC,OAAO,EAAE,UAAU;QAC7B,GAAG,YAAY;KAChB,CAAC,CAAA;IACF,WAAW,CAAC,yBAAyB,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE;eACnE,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;yBACf,YAAY;CACpC,CAAC,CAAA;IACA,OAAO,cAAc,CAAA;AACvB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,kBAAkB,CAAC,OAAe,EAAE,gBAAwB;IACnE,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAM;IACjC,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,gBAAgB,EAAE,OAAO,CAAC,EAAE,EAAC,OAAO,EAAE,IAAI,EAAC,CAAC,EAAE,CAAC;QACxE,MAAM,QAAQ,GAAG,CAAC,gCAAgC,EAAE,EAAC,OAAO,EAAC,EAAE,iCAAiC,CAAC,CAAA;QACjG,MAAM,IAAI,GAAG,sDAAsD,CAAA;QACnE,aAAa,CAAC,EAAC,QAAQ,EAAE,IAAI,EAAC,CAAC,CAAA;QAC/B,MAAM,IAAI,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;IACtC,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,OAAe;IACzC,MAAM,UAAU,CAAC,IAAI,GAAG,OAAO,CAAC,CAAA;AAClC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B;IACxC,OAAO,kBAAkB,CAAC,MAAM,CAAA;AAClC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB;IACvC,IAAI,eAAe,EAAE,IAAI,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;QAClD,OAAO,KAAK,CAAA;IACd,CAAC;IACD,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC7D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,IAAI;IAClB,OAAO,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;AACjC,CAAC;AASD;;;;;GAKG;AACH,wFAAwF;AACxF,8DAA8D;AAC9D,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,YAAmC,EAAE;IAC/D,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAA;IACvD,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,KAAK,CAAA;IACtC,MAAM,eAAe,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC,eAAe,IAAI,iBAAiB,EAAE,CAAA;IAC9E,IAAI,CAAC,SAAS,CAAC,aAAa,IAAI,OAAO,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/E,OAAO,CAAC,eAAe,EAAE,CAAA;IAC3B,CAAC;IACD,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,SAAS,CAAC,WAAW,IAAI,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAA;QAClF,OAAO,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,KAAK,CAAA;QACnF,qDAAqD;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED,6FAA6F;AAC7F,yEAAyE;AACzE;;;;GAIG;AACH,MAAM,UAAU,iBAAiB;IAC/B,IAAI,UAAU,CAAC,oBAAoB,CAAC,IAAI,UAAU,CAAC,aAAa,CAAC;QAAE,OAAO,IAAI,CAAA;IAC9E,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;QACnE,qDAAqD;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY;IAC1B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,CAAA;QAC1B,OAAO,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAA;QAC3D,qDAAqD;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;QACpB,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,IAAI,IAAI,GAAG,EAAE,CAAA;IACb,IAAI,SAAS,GAAG,CAAC,CAAA;IACjB,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;IACjC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACxC,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;QACjC,SAAS,IAAI,MAAM,CAAC,UAAU,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;QACnD,IAAI,SAAS,GAAG,cAAc,EAAE,CAAC;YAC/B,MAAM,IAAI,UAAU,CAAC,gDAAgD,CAAC,CAAA;QACxE,CAAC;QACD,IAAI,IAAI,WAAW,CAAA;IACrB,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,EAAE,CAAA;AACpB,CAAC","sourcesContent":["import {AbortSignal} from './abort.js'\nimport {AbortError, ExternalError} from './error.js'\nimport {cwd, resolvePath} from './path.js'\nimport {treeKill} from './tree-kill.js'\nimport {isTruthy} from './context/utilities.js'\nimport {renderWarning} from './ui.js'\nimport {platformAndArch} from './os.js'\nimport {shouldDisplayColors, outputDebug} from './output.js'\nimport {isCloudEnvironment} from './context/local.js'\nimport {isInputDisabled} from './no-input.js'\nimport {execa, ExecaChildProcess} from 'execa'\nimport supportsHyperlinks from 'supports-hyperlinks'\nimport which from 'which'\n\nimport {fstatSync, existsSync, readFileSync} from 'fs'\nimport {release} from 'os'\nimport {setTimeout} from 'timers/promises'\nimport type {Writable, Readable} from 'stream'\n\n/**\n * The maximum size of data that can be read from stdin in bytes.\n * This is to prevent memory exhaustion when reading from stdin.\n * 10MB.\n */\nconst MAX_STDIN_SIZE = 10 * 1024 * 1024\n\nexport interface ExecOptions {\n cwd?: string\n env?: Record<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 // Custom handler if process exits with a non-zero code\n externalErrorHandler?: (error: unknown) => Promise<void>\n // Ignored on Windows\n background?: boolean\n}\n\n/**\n * Options passed directly to execa.\n */\ninterface BuildExecOptions {\n /** Whether to throw on non-zero exit codes (default: true). */\n reject?: boolean\n}\n\n/**\n * Opens a URL in the user's default browser.\n *\n * @param url - URL to open.\n * @returns A promise that resolves true if the URL was opened successfully, false otherwise.\n */\nexport async function openURL(url: string): Promise<boolean> {\n if (isInputDisabled()) {\n throw new AbortError(\n 'Opening a browser is unavailable when user input is disabled.',\n 'Remove `--no-input` and run the command in an interactive terminal.',\n )\n }\n if (isCloudEnvironment()) return false\n\n const externalOpen = await import('open')\n try {\n await externalOpen.default(url)\n return true\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n return false\n }\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 * Result from running a command with captureOutputWithExitCode.\n */\nexport interface CaptureOutputResult {\n /** Standard output. */\n stdout: string\n /** Standard error. */\n stderr: string\n /** Exit code (0 = success). */\n exitCode: number\n}\n\n/**\n * Runs a command asynchronously and returns stdout, stderr, and exit code.\n * Unlike captureOutput, this function does NOT throw on non-zero exit codes.\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 stdout, stderr, and exitCode.\n *\n * @example\n * ```typescript\n * const result = await captureOutputWithExitCode('ls', ['-la'])\n * if (result.exitCode !== 0) \\{\n * console.error('Command failed:', result.stderr)\n * \\}\n * ```\n */\nexport async function captureOutputWithExitCode(\n command: string,\n args: string[],\n options?: ExecOptions,\n): Promise<CaptureOutputResult> {\n const result = await buildExec(command, args, options, {reject: false})\n return {\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode ?? 0,\n }\n}\n\n/**\n * Parse a command string into an array of arguments, respecting quoted strings.\n * Handles both single and double quotes, preserving spaces within quoted sections.\n *\n * @param command - The command string to parse (e.g., 'ls -la \"my folder\"').\n * @returns An array of command parts with quotes removed.\n *\n * @example\n * parseCommand('shopify theme push --theme \"My Theme Name\"') // ['shopify', 'theme', 'push', '--theme', 'My Theme Name']\n */\nfunction parseCommand(command: string): string[] {\n const result: string[] = []\n let current = ''\n let inQuote: string | null = null\n\n for (const char of command) {\n if (inQuote) {\n if (char === inQuote) {\n // End of quoted section\n inQuote = null\n } else {\n current += char\n }\n } else if (char === '\"' || char === \"'\") {\n // Start of quoted section\n inQuote = char\n } else if (char === ' ' || char === '\\t') {\n // Whitespace outside quotes - end current token\n if (current) {\n result.push(current)\n current = ''\n }\n } else {\n current += char\n }\n }\n\n // Don't forget the last token\n if (current) {\n result.push(current)\n }\n\n return result\n}\n\n/**\n * Runs a command string asynchronously and returns stdout, stderr, and exit code.\n * Parses the command string into command and arguments (handles quoted strings).\n * Unlike captureOutput, this function does NOT throw on non-zero exit codes.\n *\n * @param command - Full command string to be executed (e.g., 'ls -la \"my folder\"').\n * @param options - Optional settings for how to run the command.\n * @returns A promise that resolves with stdout, stderr, and exitCode.\n *\n * @example\n * ```typescript\n * const result = await captureCommandWithExitCode('shopify theme push --theme \"My Theme\"')\n * if (result.exitCode !== 0) {\n * console.error('Command failed:', result.stderr)\n * }\n * ```\n */\nexport async function captureCommandWithExitCode(command: string, options?: ExecOptions): Promise<CaptureOutputResult> {\n const [cmd, ...args] = parseCommand(command)\n if (!cmd) {\n return {stdout: '', stderr: 'Empty command', exitCode: 1}\n }\n return captureOutputWithExitCode(cmd, args, options)\n}\n\n/**\n * Runs a command string asynchronously (parses command and arguments from the string).\n *\n * @param command - Full command string to be executed (e.g., 'ls -la \"my folder\"').\n * @param options - Optional settings for how to run the command.\n */\nexport async function execCommand(command: string, options?: ExecOptions): Promise<void> {\n const [cmd, ...args] = parseCommand(command)\n if (!cmd) {\n throw new AbortError('Empty command')\n }\n await exec(cmd, args, options)\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 if (options) {\n // Windows opens a new console window when running a command in the background, so we disable it.\n const runningOnWindows = platformAndArch().platform === 'windows'\n options.background = runningOnWindows ? false : options.background\n }\n\n const commandProcess = buildExec(command, args, options)\n\n if (options?.background) {\n commandProcess.unref()\n }\n\n if (options?.stderr && options.stderr !== 'inherit') {\n commandProcess.stderr?.pipe(options.stderr, {end: false})\n }\n if (options?.stdout && options.stdout !== 'inherit') {\n commandProcess.stdout?.pipe(options.stdout, {end: false})\n }\n let aborted = false\n options?.signal?.addEventListener('abort', () => {\n const pid = commandProcess.pid\n if (pid) {\n outputDebug(`Killing process ${pid}: ${command} ${args.join(' ')}`)\n aborted = true\n treeKill(pid, 'SIGTERM')\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 if (options?.externalErrorHandler) {\n await options.externalErrorHandler(processError)\n } else {\n const abortError = new ExternalError(processError.message, command, args)\n abortError.stack = processError.stack\n throw abortError\n }\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 * @param execaOptions - Options passed directly to execa.\n * @returns A promise for a result with stdout and stderr properties.\n */\nfunction buildExec(\n command: string,\n args: string[],\n options?: ExecOptions,\n execaOptions?: BuildExecOptions,\n): ExecaChildProcess {\n const env = options?.env ?? process.env\n if (shouldDisplayColors()) {\n env.FORCE_COLOR = '1'\n }\n const executionCwd = options?.cwd ?? cwd()\n checkCommandSafety(command, executionCwd)\n const backgroundStdio = options?.input === undefined ? 'ignore' : (['pipe', 'ignore', 'ignore'] as const)\n const commandProcess = execa(command, args, {\n env,\n cwd: executionCwd,\n input: options?.input,\n stdio: options?.background ? backgroundStdio : 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 detached: options?.background,\n cleanup: !options?.background,\n ...execaOptions,\n })\n outputDebug(`Running system process${options?.background ? ' in background' : ''}:\n · Command: ${command} ${args.join(' ')}\n · Working directory: ${executionCwd}\n`)\n return commandProcess\n}\n\n/**\n * Refuses a bare command name that matches an executable in the working directory, because that directory may be\n * untrusted and Windows looks there before PATH. The name is looked up as a file in the working directory, with\n * Windows executable extensions, instead of through a search path, which would split a directory whose name contains\n * the path delimiter. Resolving to an absolute path keeps a relative working directory such as `.` from reducing the\n * file to the bare name, which `which` would search for in PATH. A command given as a path runs the file the caller\n * named, so it isn't checked.\n *\n * @param command - The command to run.\n * @param workingDirectory - The directory the command runs in.\n * @throws AbortError when the command matches an executable in the working directory.\n */\nfunction checkCommandSafety(command: string, workingDirectory: string): void {\n if (/[\\\\/]/.test(command)) return\n if (which.sync(resolvePath(workingDirectory, command), {nothrow: true})) {\n const headline = ['Skipped run of unsecure binary', {command}, 'found in the current directory.']\n const body = 'Please remove that file or review your current PATH.'\n renderWarning({headline, body})\n throw new AbortError(headline, body)\n }\n}\n\n/**\n * Waits for a given number of seconds.\n *\n * @param seconds - Number of seconds to wait.\n * @returns A Promise resolving after the number of seconds.\n */\nexport async function sleep(seconds: number): Promise<void> {\n await setTimeout(1000 * seconds)\n}\n\n/**\n * Check if the terminal supports OSC 8 hyperlinks.\n *\n * @returns True if the terminal supports hyperlinks.\n */\nexport function terminalSupportsHyperlinks(): boolean {\n return supportsHyperlinks.stdout\n}\n\n/**\n * Check if standard input and standard error are terminals that support prompting.\n *\n * @returns True if standard input and standard error support prompting.\n */\nexport function terminalSupportsPrompting(): boolean {\n if (isInputDisabled() || isTruthy(process.env.CI)) {\n return false\n }\n return Boolean(process.stdin.isTTY && process.stderr.isTTY)\n}\n\n/**\n * Check if the current environment is a CI environment.\n *\n * @returns True if the current environment is a CI environment.\n */\nexport function isCI(): boolean {\n return isTruthy(process.env.CI)\n}\n\ninterface WslDetectionOverrides {\n platform?: NodeJS.Platform\n kernelRelease?: string\n procVersion?: string\n insideContainer?: boolean\n}\n\n/**\n * Check if the current environment is a WSL environment.\n *\n * @param overrides - Detection inputs, read from the system when not provided. Intended for tests.\n * @returns True if the current environment is a WSL environment.\n */\n// Mirrors https://github.com/sindresorhus/is-wsl: WSL reports \"microsoft\" in the kernel\n// release, but containers running inside WSL shouldn't count.\nexport async function isWsl(overrides: WslDetectionOverrides = {}): Promise<boolean> {\n const platform = overrides.platform ?? process.platform\n if (platform !== 'linux') return false\n const insideContainer = () => overrides.insideContainer ?? isInsideContainer()\n if ((overrides.kernelRelease ?? release()).toLowerCase().includes('microsoft')) {\n return !insideContainer()\n }\n try {\n const procVersion = overrides.procVersion ?? readFileSync('/proc/version', 'utf8')\n return procVersion.toLowerCase().includes('microsoft') ? !insideContainer() : false\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return false\n }\n}\n\n// Mirrors the is-inside-container and is-docker packages: Podman creates /run/.containerenv,\n// Docker creates /.dockerenv or mentions \"docker\" in the process cgroup.\n/**\n * Check if the current process is running inside a container.\n *\n * @returns True if the current process is running inside a container.\n */\nexport function isInsideContainer(): boolean {\n if (existsSync('/run/.containerenv') || existsSync('/.dockerenv')) return true\n try {\n return readFileSync('/proc/self/cgroup', 'utf8').includes('docker')\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return false\n }\n}\n\n/**\n * Check if stdin has piped data available.\n * This distinguishes between actual piped input (e.g., `echo \"query\" | cmd`)\n * and non-TTY environments without input (e.g., CI).\n *\n * @returns True if stdin is receiving piped data or file redirect, false otherwise.\n */\nexport function isStdinPiped(): boolean {\n try {\n const stats = fstatSync(0)\n return stats.isFIFO() || stats.isFile() || stats.isSocket()\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return false\n }\n}\n\n/**\n * Reads all data from stdin and returns it as a string.\n * This is useful for commands that accept input via piping.\n *\n * @example\n * // Usage: echo \"your query\" | shopify app execute\n * const query = await readStdin()\n *\n * @returns A promise that resolves with the stdin content, or undefined if stdin is a TTY.\n */\nexport async function readStdinString(): Promise<string | undefined> {\n if (!isStdinPiped()) {\n return undefined\n }\n\n let data = ''\n let totalSize = 0\n process.stdin.setEncoding('utf8')\n for await (const chunk of process.stdin) {\n const chunkString = String(chunk)\n totalSize += Buffer.byteLength(chunkString, 'utf8')\n if (totalSize > MAX_STDIN_SIZE) {\n throw new AbortError('Stdin input exceeded the maximum allowed size.')\n }\n data += chunkString\n }\n return data.trim()\n}\n"]}
1
+ {"version":3,"file":"system.js","sourceRoot":"","sources":["../../../src/public/node/system.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,UAAU,EAAE,aAAa,EAAC,MAAM,YAAY,CAAA;AACpD,OAAO,EAAC,GAAG,EAAE,WAAW,EAAC,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAC,QAAQ,EAAC,MAAM,gBAAgB,CAAA;AACvC,OAAO,EAAC,QAAQ,EAAC,MAAM,wBAAwB,CAAA;AAC/C,OAAO,EAAC,aAAa,EAAC,MAAM,SAAS,CAAA;AACrC,OAAO,EAAC,eAAe,EAAC,MAAM,SAAS,CAAA;AACvC,OAAO,EAAC,mBAAmB,EAAE,WAAW,EAAC,MAAM,aAAa,CAAA;AAC5D,OAAO,EAAC,kBAAkB,EAAC,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAC,eAAe,EAAC,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAC,KAAK,EAAoB,MAAM,OAAO,CAAA;AAC9C,OAAO,kBAAkB,MAAM,qBAAqB,CAAA;AACpD,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAC,SAAS,EAAE,UAAU,EAAE,YAAY,EAAC,MAAM,IAAI,CAAA;AACtD,OAAO,EAAC,OAAO,EAAC,MAAM,IAAI,CAAA;AAC1B,OAAO,EAAC,UAAU,EAAC,MAAM,iBAAiB,CAAA;AAG1C;;;;GAIG;AACH,MAAM,cAAc,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAA;AA2BvC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,GAAW;IACvC,IAAI,eAAe,EAAE,EAAE,CAAC;QACtB,MAAM,IAAI,UAAU,CAClB,+DAA+D,EAC/D,qEAAqE,CACtE,CAAA;IACH,CAAC;IACD,IAAI,kBAAkB,EAAE;QAAE,OAAO,KAAK,CAAA;IAEtC,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAA;IACzC,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAClD,OAAO,MAAM,sBAAsB,CAAC,UAAU,CAAC,CAAA;QAC/C,qDAAqD;IACvD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,KAAK,UAAU,sBAAsB,CAAC,UAA2C;IAC/E,IAAI,CAAC,UAAU,IAAI,OAAO,UAAU,CAAC,IAAI,KAAK,UAAU;QAAE,OAAO,IAAI,CAAA;IACrE,OAAO,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,EAAE;QACtC,oFAAoF;QACpF,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAY,EAAE,EAAE;YACtC,WAAW,CAAC,+BAA+B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;YAC3D,OAAO,CAAC,KAAK,CAAC,CAAA;QAChB,CAAC,CAAC,CAAA;QACF,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAA;IAC/C,CAAC,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAe,EAAE,IAAc,EAAE,OAAqB;IACxF,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IACtD,OAAO,MAAM,CAAC,MAAM,CAAA;AACtB,CAAC;AAcD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,OAAe,EACf,IAAc,EACd,OAAqB;IAErB,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAC,MAAM,EAAE,KAAK,EAAC,CAAC,CAAA;IACvE,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,IAAI,aAAa,CACrB,MAAM,YAAY,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,0CAA0C,EACrF,OAAO,EACP,IAAI,CACL,CAAA;IACH,CAAC;IACD,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ;KAC1B,CAAA;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,YAAY,CAAC,OAAe;IACnC,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,IAAI,OAAO,GAAG,EAAE,CAAA;IAChB,IAAI,OAAO,GAAkB,IAAI,CAAA;IAEjC,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;gBACrB,wBAAwB;gBACxB,OAAO,GAAG,IAAI,CAAA;YAChB,CAAC;iBAAM,CAAC;gBACN,OAAO,IAAI,IAAI,CAAA;YACjB,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YACxC,0BAA0B;YAC1B,OAAO,GAAG,IAAI,CAAA;QAChB,CAAC;aAAM,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YACzC,gDAAgD;YAChD,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;gBACpB,OAAO,GAAG,EAAE,CAAA;YACd,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,IAAI,CAAA;QACjB,CAAC;IACH,CAAC;IAED,8BAA8B;IAC9B,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACtB,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,OAAe,EAAE,OAAqB;IACrF,MAAM,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC,CAAA;IAC5C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,EAAC,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,CAAC,EAAC,CAAA;IAC3D,CAAC;IACD,OAAO,yBAAyB,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;AACtD,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAe,EAAE,OAAqB;IACtE,MAAM,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC,CAAA;IAC5C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,UAAU,CAAC,eAAe,CAAC,CAAA;IACvC,CAAC;IACD,MAAM,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;AAChC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,OAAe,EAAE,IAAc,EAAE,OAAqB;IAC/E,IAAI,OAAO,EAAE,CAAC;QACZ,iGAAiG;QACjG,MAAM,gBAAgB,GAAG,eAAe,EAAE,CAAC,QAAQ,KAAK,SAAS,CAAA;QACjE,OAAO,CAAC,UAAU,GAAG,gBAAgB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAA;IACpE,CAAC;IAED,MAAM,cAAc,GAAG,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IAExD,IAAI,OAAO,EAAE,UAAU,EAAE,CAAC;QACxB,cAAc,CAAC,KAAK,EAAE,CAAA;IACxB,CAAC;IAED,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,OAAO,EAAE,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;QAC9C,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAA;QAC9B,IAAI,GAAG,EAAE,CAAC;YACR,WAAW,CAAC,mBAAmB,GAAG,KAAK,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YACnE,OAAO,GAAG,IAAI,CAAA;YACd,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;QAC1B,CAAC;IACH,CAAC,CAAC,CAAA;IACF,IAAI,CAAC;QACH,MAAM,cAAc,CAAA;QACpB,8DAA8D;IAChE,CAAC;IAAC,OAAO,YAAiB,EAAE,CAAC;QAC3B,oFAAoF;QACpF,2EAA2E;QAC3E,IAAI,OAAO;YAAE,OAAM;QACnB,IAAI,OAAO,EAAE,oBAAoB,EAAE,CAAC;YAClC,MAAM,OAAO,CAAC,oBAAoB,CAAC,YAAY,CAAC,CAAA;QAClD,CAAC;aAAM,CAAC;YACN,MAAM,UAAU,GAAG,IAAI,aAAa,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;YACzE,UAAU,CAAC,KAAK,GAAG,YAAY,CAAC,KAAK,CAAA;YACrC,MAAM,UAAU,CAAA;QAClB,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,SAAS,CAChB,OAAe,EACf,IAAc,EACd,OAAqB,EACrB,YAA+B;IAE/B,MAAM,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,CAAA;IACvC,IAAI,mBAAmB,EAAE,EAAE,CAAC;QAC1B,GAAG,CAAC,WAAW,GAAG,GAAG,CAAA;IACvB,CAAC;IACD,MAAM,YAAY,GAAG,OAAO,EAAE,GAAG,IAAI,GAAG,EAAE,CAAA;IAC1C,kBAAkB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;IACzC,MAAM,eAAe,GAAG,OAAO,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAW,CAAA;IACzG,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;QAC1C,GAAG;QACH,GAAG,EAAE,YAAY;QACjB,KAAK,EAAE,OAAO,EAAE,KAAK;QACrB,iBAAiB,EAAE,OAAO,EAAE,iBAAiB,IAAI,IAAI;QACrD,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK;QAC7D,KAAK,EAAE,OAAO,EAAE,KAAK;QACrB,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;QAC7D,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;QAC7D,mEAAmE;QACnE,mDAAmD;QACnD,WAAW,EAAE,KAAK;QAClB,QAAQ,EAAE,OAAO,EAAE,UAAU;QAC7B,OAAO,EAAE,CAAC,OAAO,EAAE,UAAU;QAC7B,GAAG,YAAY;KAChB,CAAC,CAAA;IACF,IAAI,OAAO,EAAE,MAAM,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACpD,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAC,GAAG,EAAE,KAAK,EAAC,CAAC,CAAA;IAC3D,CAAC;IACD,IAAI,OAAO,EAAE,MAAM,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACpD,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAC,GAAG,EAAE,KAAK,EAAC,CAAC,CAAA;IAC3D,CAAC;IACD,WAAW,CAAC,yBAAyB,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE;eACnE,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;yBACf,YAAY;CACpC,CAAC,CAAA;IACA,OAAO,cAAc,CAAA;AACvB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,kBAAkB,CAAC,OAAe,EAAE,gBAAwB;IACnE,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAM;IACjC,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,gBAAgB,EAAE,OAAO,CAAC,EAAE,EAAC,OAAO,EAAE,IAAI,EAAC,CAAC,EAAE,CAAC;QACxE,MAAM,QAAQ,GAAG,CAAC,gCAAgC,EAAE,EAAC,OAAO,EAAC,EAAE,iCAAiC,CAAC,CAAA;QACjG,MAAM,IAAI,GAAG,sDAAsD,CAAA;QACnE,aAAa,CAAC,EAAC,QAAQ,EAAE,IAAI,EAAC,CAAC,CAAA;QAC/B,MAAM,IAAI,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;IACtC,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,OAAe;IACzC,MAAM,UAAU,CAAC,IAAI,GAAG,OAAO,CAAC,CAAA;AAClC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B;IACxC,OAAO,kBAAkB,CAAC,MAAM,CAAA;AAClC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB;IACvC,IAAI,eAAe,EAAE,IAAI,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;QAClD,OAAO,KAAK,CAAA;IACd,CAAC;IACD,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC7D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,IAAI;IAClB,OAAO,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;AACjC,CAAC;AASD;;;;;GAKG;AACH,wFAAwF;AACxF,8DAA8D;AAC9D,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,YAAmC,EAAE;IAC/D,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAA;IACvD,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,KAAK,CAAA;IACtC,MAAM,eAAe,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC,eAAe,IAAI,iBAAiB,EAAE,CAAA;IAC9E,IAAI,CAAC,SAAS,CAAC,aAAa,IAAI,OAAO,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/E,OAAO,CAAC,eAAe,EAAE,CAAA;IAC3B,CAAC;IACD,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,SAAS,CAAC,WAAW,IAAI,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAA;QAClF,OAAO,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,KAAK,CAAA;QACnF,qDAAqD;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED,6FAA6F;AAC7F,yEAAyE;AACzE;;;;GAIG;AACH,MAAM,UAAU,iBAAiB;IAC/B,IAAI,UAAU,CAAC,oBAAoB,CAAC,IAAI,UAAU,CAAC,aAAa,CAAC;QAAE,OAAO,IAAI,CAAA;IAC9E,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;QACnE,qDAAqD;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY;IAC1B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,CAAA;QAC1B,OAAO,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAA;QAC3D,qDAAqD;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;QACpB,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,IAAI,IAAI,GAAG,EAAE,CAAA;IACb,IAAI,SAAS,GAAG,CAAC,CAAA;IACjB,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;IACjC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACxC,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;QACjC,SAAS,IAAI,MAAM,CAAC,UAAU,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;QACnD,IAAI,SAAS,GAAG,cAAc,EAAE,CAAC;YAC/B,MAAM,IAAI,UAAU,CAAC,gDAAgD,CAAC,CAAA;QACxE,CAAC;QACD,IAAI,IAAI,WAAW,CAAA;IACrB,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,EAAE,CAAA;AACpB,CAAC","sourcesContent":["import {AbortSignal} from './abort.js'\nimport {AbortError, ExternalError} from './error.js'\nimport {cwd, resolvePath} from './path.js'\nimport {treeKill} from './tree-kill.js'\nimport {isTruthy} from './context/utilities.js'\nimport {renderWarning} from './ui.js'\nimport {platformAndArch} from './os.js'\nimport {shouldDisplayColors, outputDebug} from './output.js'\nimport {isCloudEnvironment} from './context/local.js'\nimport {isInputDisabled} from './no-input.js'\nimport {execa, ExecaChildProcess} from 'execa'\nimport supportsHyperlinks from 'supports-hyperlinks'\nimport which from 'which'\n\nimport {fstatSync, existsSync, readFileSync} from 'fs'\nimport {release} from 'os'\nimport {setTimeout} from 'timers/promises'\nimport type {Writable, Readable} from 'stream'\n\n/**\n * The maximum size of data that can be read from stdin in bytes.\n * This is to prevent memory exhaustion when reading from stdin.\n * 10MB.\n */\nconst MAX_STDIN_SIZE = 10 * 1024 * 1024\n\nexport interface ExecOptions {\n cwd?: string\n env?: Record<string, string | undefined>\n stdin?: Readable | 'inherit'\n stdout?: Writable | 'inherit'\n stderr?: Writable | 'inherit'\n stdio?: 'inherit'\n input?: string\n /** Whether to remove the final newline from captured stdout/stderr (default: true). */\n stripFinalNewline?: boolean\n signal?: AbortSignal\n // Custom handler if process exits with a non-zero code\n externalErrorHandler?: (error: unknown) => Promise<void>\n // Ignored on Windows\n background?: boolean\n}\n\n/**\n * Options passed directly to execa.\n */\ninterface BuildExecOptions {\n /** Whether to throw on non-zero exit codes (default: true). */\n reject?: boolean\n}\n\n/**\n * Opens a URL in the user's default browser.\n *\n * @param url - URL to open.\n * @returns A promise that resolves true if the URL was opened successfully, false otherwise.\n */\nexport async function openURL(url: string): Promise<boolean> {\n if (isInputDisabled()) {\n throw new AbortError(\n 'Opening a browser is unavailable when user input is disabled.',\n 'Remove `--no-input` and run the command in an interactive terminal.',\n )\n }\n if (isCloudEnvironment()) return false\n\n const externalOpen = await import('open')\n try {\n const subprocess = await externalOpen.default(url)\n return await browserLaunchSucceeded(subprocess)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n return false\n }\n}\n\n/**\n * Waits for the process spawned to open a browser to either start or fail.\n *\n * `open` resolves as soon as it has called `spawn`, before the OS reports whether the\n * launcher exists. A missing launcher (e.g. `xdg-open` in a headless container) is\n * reported later as an `error` event on the child process. Without a listener that\n * event is thrown as an uncaught exception and terminates the CLI, which kills flows\n * such as device-code login that could otherwise carry on with the printed link.\n *\n * @param subprocess - The child process returned by `open`.\n * @returns A promise that resolves true if the process started, false if it failed to start.\n */\nasync function browserLaunchSucceeded(subprocess: NodeJS.EventEmitter | undefined): Promise<boolean> {\n if (!subprocess || typeof subprocess.once !== 'function') return true\n return new Promise<boolean>((resolve) => {\n // Keep a permanent listener so a late error can never become an uncaught exception.\n subprocess.on('error', (error: Error) => {\n outputDebug(`Failed to open the browser: ${error.message}`)\n resolve(false)\n })\n subprocess.once('spawn', () => resolve(true))\n })\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 * Result from running a command with captureOutputWithExitCode.\n */\nexport interface CaptureOutputResult {\n /** Standard output. */\n stdout: string\n /** Standard error. */\n stderr: string\n /** Exit code (0 = success). */\n exitCode: number\n}\n\n/**\n * Runs a command asynchronously and returns stdout, stderr, and exit code.\n * Unlike captureOutput, this function does NOT throw on non-zero exit codes.\n * Startup failures and signal termination still throw an ExternalError.\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 stdout, stderr, and exitCode.\n *\n * @example\n * ```typescript\n * const result = await captureOutputWithExitCode('ls', ['-la'])\n * if (result.exitCode !== 0) \\{\n * console.error('Command failed:', result.stderr)\n * \\}\n * ```\n */\nexport async function captureOutputWithExitCode(\n command: string,\n args: string[],\n options?: ExecOptions,\n): Promise<CaptureOutputResult> {\n const result = await buildExec(command, args, options, {reject: false})\n if (result.exitCode === undefined) {\n throw new ExternalError(\n result instanceof Error ? result.message : 'Command terminated without an exit code.',\n command,\n args,\n )\n }\n return {\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode,\n }\n}\n\n/**\n * Parse a command string into an array of arguments, respecting quoted strings.\n * Handles both single and double quotes, preserving spaces within quoted sections.\n *\n * @param command - The command string to parse (e.g., 'ls -la \"my folder\"').\n * @returns An array of command parts with quotes removed.\n *\n * @example\n * parseCommand('shopify theme push --theme \"My Theme Name\"') // ['shopify', 'theme', 'push', '--theme', 'My Theme Name']\n */\nfunction parseCommand(command: string): string[] {\n const result: string[] = []\n let current = ''\n let inQuote: string | null = null\n\n for (const char of command) {\n if (inQuote) {\n if (char === inQuote) {\n // End of quoted section\n inQuote = null\n } else {\n current += char\n }\n } else if (char === '\"' || char === \"'\") {\n // Start of quoted section\n inQuote = char\n } else if (char === ' ' || char === '\\t') {\n // Whitespace outside quotes - end current token\n if (current) {\n result.push(current)\n current = ''\n }\n } else {\n current += char\n }\n }\n\n // Don't forget the last token\n if (current) {\n result.push(current)\n }\n\n return result\n}\n\n/**\n * Runs a command string asynchronously and returns stdout, stderr, and exit code.\n * Parses the command string into command and arguments (handles quoted strings).\n * Unlike captureOutput, this function does NOT throw on non-zero exit codes.\n * Startup failures and signal termination still throw an ExternalError.\n *\n * @param command - Full command string to be executed (e.g., 'ls -la \"my folder\"').\n * @param options - Optional settings for how to run the command.\n * @returns A promise that resolves with stdout, stderr, and exitCode.\n *\n * @example\n * ```typescript\n * const result = await captureCommandWithExitCode('shopify theme push --theme \"My Theme\"')\n * if (result.exitCode !== 0) {\n * console.error('Command failed:', result.stderr)\n * }\n * ```\n */\nexport async function captureCommandWithExitCode(command: string, options?: ExecOptions): Promise<CaptureOutputResult> {\n const [cmd, ...args] = parseCommand(command)\n if (!cmd) {\n return {stdout: '', stderr: 'Empty command', exitCode: 1}\n }\n return captureOutputWithExitCode(cmd, args, options)\n}\n\n/**\n * Runs a command string asynchronously (parses command and arguments from the string).\n *\n * @param command - Full command string to be executed (e.g., 'ls -la \"my folder\"').\n * @param options - Optional settings for how to run the command.\n */\nexport async function execCommand(command: string, options?: ExecOptions): Promise<void> {\n const [cmd, ...args] = parseCommand(command)\n if (!cmd) {\n throw new AbortError('Empty command')\n }\n await exec(cmd, args, options)\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 if (options) {\n // Windows opens a new console window when running a command in the background, so we disable it.\n const runningOnWindows = platformAndArch().platform === 'windows'\n options.background = runningOnWindows ? false : options.background\n }\n\n const commandProcess = buildExec(command, args, options)\n\n if (options?.background) {\n commandProcess.unref()\n }\n\n let aborted = false\n options?.signal?.addEventListener('abort', () => {\n const pid = commandProcess.pid\n if (pid) {\n outputDebug(`Killing process ${pid}: ${command} ${args.join(' ')}`)\n aborted = true\n treeKill(pid, 'SIGTERM')\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 if (options?.externalErrorHandler) {\n await options.externalErrorHandler(processError)\n } else {\n const abortError = new ExternalError(processError.message, command, args)\n abortError.stack = processError.stack\n throw abortError\n }\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 * @param execaOptions - Options passed directly to execa.\n * @returns A promise for a result with stdout and stderr properties.\n */\nfunction buildExec(\n command: string,\n args: string[],\n options?: ExecOptions,\n execaOptions?: BuildExecOptions,\n): ExecaChildProcess {\n const env = options?.env ?? process.env\n if (shouldDisplayColors()) {\n env.FORCE_COLOR = '1'\n }\n const executionCwd = options?.cwd ?? cwd()\n checkCommandSafety(command, executionCwd)\n const backgroundStdio = options?.input === undefined ? 'ignore' : (['pipe', 'ignore', 'ignore'] as const)\n const commandProcess = execa(command, args, {\n env,\n cwd: executionCwd,\n input: options?.input,\n stripFinalNewline: options?.stripFinalNewline ?? true,\n stdio: options?.background ? backgroundStdio : 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 detached: options?.background,\n cleanup: !options?.background,\n ...execaOptions,\n })\n if (options?.stderr && options.stderr !== 'inherit') {\n commandProcess.stderr?.pipe(options.stderr, {end: false})\n }\n if (options?.stdout && options.stdout !== 'inherit') {\n commandProcess.stdout?.pipe(options.stdout, {end: false})\n }\n outputDebug(`Running system process${options?.background ? ' in background' : ''}:\n · Command: ${command} ${args.join(' ')}\n · Working directory: ${executionCwd}\n`)\n return commandProcess\n}\n\n/**\n * Refuses a bare command name that matches an executable in the working directory, because that directory may be\n * untrusted and Windows looks there before PATH. The name is looked up as a file in the working directory, with\n * Windows executable extensions, instead of through a search path, which would split a directory whose name contains\n * the path delimiter. Resolving to an absolute path keeps a relative working directory such as `.` from reducing the\n * file to the bare name, which `which` would search for in PATH. A command given as a path runs the file the caller\n * named, so it isn't checked.\n *\n * @param command - The command to run.\n * @param workingDirectory - The directory the command runs in.\n * @throws AbortError when the command matches an executable in the working directory.\n */\nfunction checkCommandSafety(command: string, workingDirectory: string): void {\n if (/[\\\\/]/.test(command)) return\n if (which.sync(resolvePath(workingDirectory, command), {nothrow: true})) {\n const headline = ['Skipped run of unsecure binary', {command}, 'found in the current directory.']\n const body = 'Please remove that file or review your current PATH.'\n renderWarning({headline, body})\n throw new AbortError(headline, body)\n }\n}\n\n/**\n * Waits for a given number of seconds.\n *\n * @param seconds - Number of seconds to wait.\n * @returns A Promise resolving after the number of seconds.\n */\nexport async function sleep(seconds: number): Promise<void> {\n await setTimeout(1000 * seconds)\n}\n\n/**\n * Check if the terminal supports OSC 8 hyperlinks.\n *\n * @returns True if the terminal supports hyperlinks.\n */\nexport function terminalSupportsHyperlinks(): boolean {\n return supportsHyperlinks.stdout\n}\n\n/**\n * Check if standard input and standard error are terminals that support prompting.\n *\n * @returns True if standard input and standard error support prompting.\n */\nexport function terminalSupportsPrompting(): boolean {\n if (isInputDisabled() || isTruthy(process.env.CI)) {\n return false\n }\n return Boolean(process.stdin.isTTY && process.stderr.isTTY)\n}\n\n/**\n * Check if the current environment is a CI environment.\n *\n * @returns True if the current environment is a CI environment.\n */\nexport function isCI(): boolean {\n return isTruthy(process.env.CI)\n}\n\ninterface WslDetectionOverrides {\n platform?: NodeJS.Platform\n kernelRelease?: string\n procVersion?: string\n insideContainer?: boolean\n}\n\n/**\n * Check if the current environment is a WSL environment.\n *\n * @param overrides - Detection inputs, read from the system when not provided. Intended for tests.\n * @returns True if the current environment is a WSL environment.\n */\n// Mirrors https://github.com/sindresorhus/is-wsl: WSL reports \"microsoft\" in the kernel\n// release, but containers running inside WSL shouldn't count.\nexport async function isWsl(overrides: WslDetectionOverrides = {}): Promise<boolean> {\n const platform = overrides.platform ?? process.platform\n if (platform !== 'linux') return false\n const insideContainer = () => overrides.insideContainer ?? isInsideContainer()\n if ((overrides.kernelRelease ?? release()).toLowerCase().includes('microsoft')) {\n return !insideContainer()\n }\n try {\n const procVersion = overrides.procVersion ?? readFileSync('/proc/version', 'utf8')\n return procVersion.toLowerCase().includes('microsoft') ? !insideContainer() : false\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return false\n }\n}\n\n// Mirrors the is-inside-container and is-docker packages: Podman creates /run/.containerenv,\n// Docker creates /.dockerenv or mentions \"docker\" in the process cgroup.\n/**\n * Check if the current process is running inside a container.\n *\n * @returns True if the current process is running inside a container.\n */\nexport function isInsideContainer(): boolean {\n if (existsSync('/run/.containerenv') || existsSync('/.dockerenv')) return true\n try {\n return readFileSync('/proc/self/cgroup', 'utf8').includes('docker')\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return false\n }\n}\n\n/**\n * Check if stdin has piped data available.\n * This distinguishes between actual piped input (e.g., `echo \"query\" | cmd`)\n * and non-TTY environments without input (e.g., CI).\n *\n * @returns True if stdin is receiving piped data or file redirect, false otherwise.\n */\nexport function isStdinPiped(): boolean {\n try {\n const stats = fstatSync(0)\n return stats.isFIFO() || stats.isFile() || stats.isSocket()\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return false\n }\n}\n\n/**\n * Reads all data from stdin and returns it as a string.\n * This is useful for commands that accept input via piping.\n *\n * @example\n * // Usage: echo \"your query\" | shopify app execute\n * const query = await readStdin()\n *\n * @returns A promise that resolves with the stdin content, or undefined if stdin is a TTY.\n */\nexport async function readStdinString(): Promise<string | undefined> {\n if (!isStdinPiped()) {\n return undefined\n }\n\n let data = ''\n let totalSize = 0\n process.stdin.setEncoding('utf8')\n for await (const chunk of process.stdin) {\n const chunkString = String(chunk)\n totalSize += Buffer.byteLength(chunkString, 'utf8')\n if (totalSize > MAX_STDIN_SIZE) {\n throw new AbortError('Stdin input exceeded the maximum allowed size.')\n }\n data += chunkString\n }\n return data.trim()\n}\n"]}
@@ -34,6 +34,15 @@ export declare function metafieldDefinitionsByOwnerType(type: MetafieldOwnerType
34
34
  };
35
35
  }[]>;
36
36
  export declare function passwordProtected(session: AdminSession): Promise<boolean>;
37
+ /**
38
+ * Whether the error ends a Trust Battery challenge on a theme request. A caller that
39
+ * retries theme requests must rethrow it, or the user is asked to verify again for
40
+ * each attempt.
41
+ *
42
+ * @param error - The error to check.
43
+ * @returns True when the error ends a Trust Battery challenge.
44
+ */
45
+ export declare function isTrustChallengeError(error: unknown): boolean;
37
46
  type OnlineStoreThemeFileBody = {
38
47
  __typename: 'OnlineStoreThemeFileBodyBase64';
39
48
  contentBase64: string;
@@ -10,16 +10,17 @@ import { GetThemeFileBodies } from '../../../cli/api/graphql/admin/generated/get
10
10
  import { GetThemeFileChecksums } from '../../../cli/api/graphql/admin/generated/get_theme_file_checksums.js';
11
11
  import { ThemeFilesUpsert, } from '../../../cli/api/graphql/admin/generated/theme_files_upsert.js';
12
12
  import { ThemeFilesDelete } from '../../../cli/api/graphql/admin/generated/theme_files_delete.js';
13
- import { MetafieldDefinitionsByOwnerType } from '../../../cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.js';
13
+ import { MetafieldDefinitionsByOwnerType, } from '../../../cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.js';
14
14
  import { GetThemes } from '../../../cli/api/graphql/admin/generated/get_themes.js';
15
15
  import { GetTheme } from '../../../cli/api/graphql/admin/generated/get_theme.js';
16
16
  import { FindDevelopmentThemeByName } from '../../../cli/api/graphql/admin/generated/find_development_theme_by_name.js';
17
17
  import { OnlineStorePasswordProtection } from '../../../cli/api/graphql/admin/generated/online_store_password_protection.js';
18
+ import { extractGraphQLErrors } from '../../../private/node/api/graphql.js';
19
+ import { TrustChallengeError, withTrustChallengeRetry } from '../../../private/node/themes/trust-challenge.js';
18
20
  import { adminRequestDoc } from '../api/admin.js';
19
21
  import { AbortError } from '../error.js';
20
22
  import { outputDebug } from '../output.js';
21
23
  import { recordTiming, recordEvent, recordError } from '../analytics.js';
22
- import { ClientError } from 'graphql-request';
23
24
  const SkeletonThemeCdn = 'https://cdn.shopify.com/static/online-store/theme-skeleton.zip';
24
25
  const THEME_API_NETWORK_BEHAVIOUR = {
25
26
  useNetworkLevelRetry: true,
@@ -194,7 +195,7 @@ export async function deleteThemeAssets(id, filenames, session) {
194
195
  for (let i = 0; i < filenames.length; i += batchSize) {
195
196
  const batch = filenames.slice(i, i + batchSize);
196
197
  // eslint-disable-next-line no-await-in-loop
197
- const { themeFilesDelete } = await adminRequestDoc({
198
+ const { themeFilesDelete } = await requestThemeAdminDoc({
198
199
  query: ThemeFilesDelete,
199
200
  session,
200
201
  variables: {
@@ -268,7 +269,7 @@ function prepareFilesForUpload(assets) {
268
269
  });
269
270
  }
270
271
  async function uploadFiles(themeId, files, session) {
271
- return adminRequestDoc({
272
+ return requestThemeAdminDoc({
272
273
  query: ThemeFilesUpsert,
273
274
  session,
274
275
  variables: { themeId: themeGid(themeId), files },
@@ -338,7 +339,7 @@ export async function themeUpdate(id, params, session) {
338
339
  input.name = name;
339
340
  }
340
341
  recordEvent('theme-api:update-theme');
341
- const { themeUpdate } = await adminRequestDoc({
342
+ const { themeUpdate } = await requestThemeAdminDoc({
342
343
  query: ThemeUpdate,
343
344
  session,
344
345
  variables: { id: composeThemeGid(id), input },
@@ -365,7 +366,7 @@ export async function themeUpdate(id, params, session) {
365
366
  }
366
367
  export async function themePublish(id, session) {
367
368
  recordEvent('theme-api:publish-theme');
368
- const { themePublish } = await adminRequestDoc({
369
+ const { themePublish } = await requestThemeAdminDoc({
369
370
  query: ThemePublish,
370
371
  session,
371
372
  variables: { id: composeThemeGid(id) },
@@ -392,7 +393,7 @@ export async function themePublish(id, session) {
392
393
  }
393
394
  export async function themeDelete(id, session) {
394
395
  recordEvent('theme-api:delete-theme');
395
- const { themeDelete } = await adminRequestDoc({
396
+ const { themeDelete } = await requestThemeAdminDoc({
396
397
  query: ThemeDelete,
397
398
  session,
398
399
  variables: { id: composeThemeGid(id) },
@@ -416,7 +417,7 @@ export async function themeDelete(id, session) {
416
417
  export async function themeDuplicate(id, name, session) {
417
418
  let requestId;
418
419
  recordEvent('theme-api:duplicate-theme');
419
- const { themeDuplicate } = await adminRequestDoc({
420
+ const { themeDuplicate } = await requestThemeAdminDoc({
420
421
  query: ThemeDuplicate,
421
422
  session,
422
423
  variables: { id: composeThemeGid(id), name },
@@ -465,12 +466,24 @@ export async function themeDuplicate(id, name, session) {
465
466
  }
466
467
  export async function metafieldDefinitionsByOwnerType(type, session) {
467
468
  recordEvent('theme-api:fetch-metafield-definitions');
468
- const { metafieldDefinitions } = await adminRequestDoc({
469
- query: MetafieldDefinitionsByOwnerType,
470
- session,
471
- variables: { ownerType: type },
472
- });
473
- return metafieldDefinitions.nodes.map((definition) => ({
469
+ const definitions = [];
470
+ let after = null;
471
+ while (true) {
472
+ // eslint-disable-next-line no-await-in-loop
473
+ const { metafieldDefinitions } = await adminRequestDoc({
474
+ query: MetafieldDefinitionsByOwnerType,
475
+ session,
476
+ variables: { ownerType: type, after },
477
+ });
478
+ definitions.push(...metafieldDefinitions.nodes);
479
+ if (!metafieldDefinitions.pageInfo.hasNextPage)
480
+ break;
481
+ const endCursor = metafieldDefinitions.pageInfo.endCursor;
482
+ if (!endCursor || endCursor === after)
483
+ unexpectedGraphQLError('Failed to paginate metafield definitions');
484
+ after = endCursor;
485
+ }
486
+ return definitions.map((definition) => ({
474
487
  key: definition.key,
475
488
  namespace: definition.namespace,
476
489
  name: definition.name,
@@ -496,9 +509,20 @@ export async function passwordProtected(session) {
496
509
  function unexpectedGraphQLError(message) {
497
510
  throw recordError(new AbortError(message));
498
511
  }
512
+ /**
513
+ * Whether the error ends a Trust Battery challenge on a theme request. A caller that
514
+ * retries theme requests must rethrow it, or the user is asked to verify again for
515
+ * each attempt.
516
+ *
517
+ * @param error - The error to check.
518
+ * @returns True when the error ends a Trust Battery challenge.
519
+ */
520
+ export function isTrustChallengeError(error) {
521
+ return error instanceof TrustChallengeError;
522
+ }
499
523
  async function requestThemeAdminDoc(options) {
500
524
  try {
501
- const response = await adminRequestDoc(options);
525
+ const response = await withTrustChallengeRetry(() => adminRequestDoc(options));
502
526
  return response;
503
527
  }
504
528
  catch (error) {
@@ -507,8 +531,6 @@ async function requestThemeAdminDoc(options) {
507
531
  }
508
532
  }
509
533
  function abortIfMissingThemeAccessScope(error) {
510
- if (!(error instanceof ClientError))
511
- return;
512
534
  const requiredAccess = getThemeAccessRequirementForAccessDeniedError(error);
513
535
  if (!requiredAccess)
514
536
  return;
@@ -533,9 +555,18 @@ function abortIfMissingThemeAccessScope(error) {
533
555
  [
534
556
  'For',
535
557
  { command: 'theme push' },
536
- 'and',
558
+ { char: ',' },
537
559
  { command: 'theme dev' },
538
560
  { char: ',' },
561
+ { command: 'theme publish' },
562
+ { char: ',' },
563
+ { command: 'theme delete' },
564
+ { char: ',' },
565
+ { command: 'theme rename' },
566
+ { char: ',' },
567
+ 'and',
568
+ { command: 'theme duplicate' },
569
+ { char: ',' },
539
570
  'add both the',
540
571
  { command: 'read_themes' },
541
572
  'and',
@@ -554,10 +585,7 @@ function abortIfMissingThemeAccessScope(error) {
554
585
  throw recordError(new AbortError(`The authenticated account or access token is missing ${requiredAccess}.`, undefined, nextSteps));
555
586
  }
556
587
  function getThemeAccessRequirementForAccessDeniedError(error) {
557
- const graphQLErrors = error.response.errors;
558
- if (!Array.isArray(graphQLErrors))
559
- return undefined;
560
- const accessDeniedError = graphQLErrors.find((graphQLError) => graphQLError.extensions?.code === 'ACCESS_DENIED');
588
+ const accessDeniedError = extractGraphQLErrors(error).find((graphQLError) => graphQLError.extensions?.code === 'ACCESS_DENIED');
561
589
  if (!accessDeniedError)
562
590
  return undefined;
563
591
  const requiredAccess = accessDeniedError.extensions?.requiredAccess;
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../../src/public/node/themes/api.ts"],"names":[],"mappings":"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","sourcesContent":["import {Result, Checksum, Key, Theme, ThemeAsset, Operation} from './types.js'\nimport {buildTheme} from './factories.js'\nimport {composeThemeGid, parseGid, DEVELOPMENT_THEME_ROLE} from './utils.js'\nimport {ThemeUpdate} from '../../../cli/api/graphql/admin/generated/theme_update.js'\nimport {ThemeDelete} from '../../../cli/api/graphql/admin/generated/theme_delete.js'\nimport {ThemeDuplicate} from '../../../cli/api/graphql/admin/generated/theme_duplicate.js'\nimport {ThemePublish} from '../../../cli/api/graphql/admin/generated/theme_publish.js'\nimport {ThemeCreate} from '../../../cli/api/graphql/admin/generated/theme_create.js'\nimport {GetThemeFileBodies} from '../../../cli/api/graphql/admin/generated/get_theme_file_bodies.js'\nimport {GetThemeFileChecksums} from '../../../cli/api/graphql/admin/generated/get_theme_file_checksums.js'\nimport {\n ThemeFilesUpsert,\n ThemeFilesUpsertMutation,\n} from '../../../cli/api/graphql/admin/generated/theme_files_upsert.js'\nimport {ThemeFilesDelete} from '../../../cli/api/graphql/admin/generated/theme_files_delete.js'\nimport {\n OnlineStoreThemeFileBodyInputType,\n OnlineStoreThemeFilesUpsertFileInput,\n MetafieldOwnerType,\n ThemeRole,\n} from '../../../cli/api/graphql/admin/generated/types.js'\nimport {MetafieldDefinitionsByOwnerType} from '../../../cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.js'\nimport {GetThemes} from '../../../cli/api/graphql/admin/generated/get_themes.js'\nimport {GetTheme} from '../../../cli/api/graphql/admin/generated/get_theme.js'\nimport {FindDevelopmentThemeByName} from '../../../cli/api/graphql/admin/generated/find_development_theme_by_name.js'\nimport {OnlineStorePasswordProtection} from '../../../cli/api/graphql/admin/generated/online_store_password_protection.js'\nimport {RequestModeInput} from '../http.js'\nimport {adminRequestDoc, type AdminRequestOptions} from '../api/admin.js'\nimport {AdminSession} from '../session.js'\nimport {AbortError} from '../error.js'\nimport {outputDebug} from '../output.js'\nimport {recordTiming, recordEvent, recordError} from '../analytics.js'\nimport {ClientError, type Variables} from 'graphql-request'\nimport type {InlineToken, TokenItem} from '../ui.js'\n\nexport type ThemeParams = Partial<Pick<Theme, 'name' | 'role' | 'processing' | 'src'>>\nexport type AssetParams = Pick<ThemeAsset, 'key'> & Partial<Pick<ThemeAsset, 'value' | 'attachment'>>\nconst SkeletonThemeCdn = 'https://cdn.shopify.com/static/online-store/theme-skeleton.zip'\nconst THEME_API_NETWORK_BEHAVIOUR: RequestModeInput = {\n useNetworkLevelRetry: true,\n useAbortSignal: false,\n maxRetryTimeMs: 90 * 1000,\n recordCommandRetries: true,\n}\nconst DEFAULT_THEME_ACCESS_REQUIREMENT = 'the required theme access scope'\n\nexport async function fetchTheme(id: number, session: AdminSession): Promise<Theme | undefined> {\n const gid = composeThemeGid(id)\n recordEvent('theme-api:fetch-theme')\n\n try {\n const {theme} = await adminRequestDoc({\n query: GetTheme,\n session,\n variables: {id: gid},\n responseOptions: {handleErrors: false},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (theme) {\n return buildTheme({\n id: parseGid(theme.id),\n processing: theme.processing,\n role: theme.role.toLowerCase(),\n name: theme.name,\n })\n }\n\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n abortIfMissingThemeAccessScope(error)\n /**\n * Consumers of this and other theme APIs in this file expect either a theme\n * or `undefined`.\n *\n * Error handlers should not inspect GraphQL error messages directly, as\n * they are internationalized.\n */\n recordError(error)\n outputDebug(`Error fetching theme with ID: ${id}`)\n }\n}\n\nexport async function fetchThemes(session: AdminSession): Promise<Theme[]> {\n const themes: Theme[] = []\n let after: string | null = null\n recordEvent('theme-api:fetch-themes')\n\n while (true) {\n // eslint-disable-next-line no-await-in-loop\n const response = await requestThemeAdminDoc({\n query: GetThemes,\n session,\n variables: {after},\n responseOptions: {handleErrors: false},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (!response.themes) {\n unexpectedGraphQLError('Failed to fetch themes')\n }\n const {nodes, pageInfo} = response.themes\n nodes.forEach((theme) => {\n const t = buildTheme({\n id: parseGid(theme.id),\n processing: theme.processing,\n role: theme.role.toLowerCase(),\n name: theme.name,\n })\n if (t) {\n themes.push(t)\n }\n })\n if (!pageInfo.hasNextPage) {\n return themes\n }\n\n after = pageInfo.endCursor as string\n }\n}\n\nexport async function findDevelopmentThemeByName(name: string, session: AdminSession): Promise<Theme | undefined> {\n recordEvent('theme-api:find-development-theme-by-name')\n\n const {themes} = await requestThemeAdminDoc({\n query: FindDevelopmentThemeByName,\n session,\n variables: {name},\n responseOptions: {handleErrors: false},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (!themes) {\n unexpectedGraphQLError('Failed to fetch themes')\n }\n\n if (themes.nodes.length > 1) {\n throw recordError(new AbortError(`More than one development theme is named \"${name}\"`))\n }\n\n if (themes.nodes.length === 1) {\n const {id, processing, role, name} = themes.nodes[0]!\n\n return buildTheme({\n id: parseGid(id),\n processing,\n role: role.toLowerCase(),\n name,\n })\n }\n}\n\nexport async function themeCreate(params: ThemeParams, session: AdminSession): Promise<Theme | undefined> {\n const themeSource = params.src ?? SkeletonThemeCdn\n recordEvent('theme-api:create-theme')\n const {themeCreate} = await requestThemeAdminDoc({\n query: ThemeCreate,\n session,\n variables: {\n name: params.name ?? '',\n source: themeSource,\n role: (params.role ?? DEVELOPMENT_THEME_ROLE).toUpperCase() as ThemeRole,\n },\n responseOptions: {handleErrors: false},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (!themeCreate) {\n unexpectedGraphQLError('Failed to create theme')\n }\n\n const {theme, userErrors} = themeCreate\n if (userErrors.length) {\n const userErrors = themeCreate.userErrors.map((error) => error.message).join(', ')\n throw recordError(new AbortError(userErrors))\n }\n\n if (!theme) {\n unexpectedGraphQLError('Failed to create theme')\n }\n\n return buildTheme({\n id: parseGid(theme.id),\n name: theme.name,\n role: theme.role.toLowerCase(),\n })\n}\n\nexport async function fetchThemeAssets(id: number, filenames: Key[], session: AdminSession): Promise<ThemeAsset[]> {\n const assets: ThemeAsset[] = []\n let after: string | null = null\n recordEvent('theme-api:fetch-assets')\n\n while (true) {\n // eslint-disable-next-line no-await-in-loop\n const response = await requestThemeAdminDoc({\n query: GetThemeFileBodies,\n session,\n variables: {id: themeGid(id), filenames, after},\n responseOptions: {handleErrors: false},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (!response.theme?.files?.nodes || !response.theme?.files?.pageInfo) {\n const userErrors = response.theme?.files?.userErrors.map((error) => error.filename).join(', ')\n unexpectedGraphQLError(`Error fetching assets: ${userErrors}`)\n }\n\n const {nodes, pageInfo} = response.theme.files\n\n assets.push(\n // eslint-disable-next-line no-await-in-loop\n ...(await Promise.all(\n nodes.map(async (file) => {\n const {attachment, value} = await parseThemeFileContent(file.body)\n return {\n attachment,\n key: file.filename,\n checksum: file.checksumMd5 as string,\n value,\n }\n }),\n )),\n )\n\n if (!pageInfo.hasNextPage) {\n return assets\n }\n\n after = pageInfo.endCursor as string\n }\n}\n\nexport async function deleteThemeAssets(id: number, filenames: Key[], session: AdminSession): Promise<Result[]> {\n const batchSize = 50\n const results: Result[] = []\n recordEvent('theme-api:delete-assets')\n\n for (let i = 0; i < filenames.length; i += batchSize) {\n const batch = filenames.slice(i, i + batchSize)\n // eslint-disable-next-line no-await-in-loop\n const {themeFilesDelete} = await adminRequestDoc({\n query: ThemeFilesDelete,\n session,\n variables: {\n themeId: composeThemeGid(id),\n files: batch,\n },\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (!themeFilesDelete) {\n unexpectedGraphQLError('Failed to delete theme assets')\n }\n\n const {deletedThemeFiles, userErrors} = themeFilesDelete\n\n if (deletedThemeFiles) {\n deletedThemeFiles.forEach((file) => {\n results.push({key: file.filename, success: true, operation: Operation.Delete})\n })\n }\n\n if (userErrors.length > 0) {\n userErrors.forEach((error) => {\n if (error.filename) {\n recordError(`Asset deletion failed for ${error.filename}: ${error.message}`)\n results.push({\n key: error.filename,\n success: false,\n operation: Operation.Delete,\n errors: {asset: [error.message]},\n })\n } else {\n unexpectedGraphQLError(`Failed to delete theme assets: ${error.message}`)\n }\n })\n }\n }\n\n return results\n}\n\nexport async function bulkUploadThemeAssets(\n id: number,\n assets: AssetParams[],\n session: AdminSession,\n): Promise<Result[]> {\n const results: Result[] = []\n recordEvent('theme-api:bulk-upload-assets')\n for (let i = 0; i < assets.length; i += 50) {\n const chunk = assets.slice(i, i + 50)\n const files = prepareFilesForUpload(chunk)\n\n recordTiming('theme-api:upload-files')\n // eslint-disable-next-line no-await-in-loop\n const uploadResults = await uploadFiles(id, files, session)\n recordTiming('theme-api:upload-files')\n\n results.push(...processUploadResults(uploadResults))\n }\n return results\n}\n\nfunction prepareFilesForUpload(assets: AssetParams[]): OnlineStoreThemeFilesUpsertFileInput[] {\n return assets.map((asset) => {\n if (asset.attachment) {\n return {\n filename: asset.key,\n body: {\n type: 'BASE64' as const,\n value: asset.attachment,\n },\n }\n } else {\n return {\n filename: asset.key,\n body: {\n type: 'TEXT' as const,\n value: asset.value ?? '',\n },\n }\n }\n })\n}\n\nasync function uploadFiles(\n themeId: number,\n files: {filename: string; body: {type: OnlineStoreThemeFileBodyInputType; value: string}}[],\n session: AdminSession,\n): Promise<ThemeFilesUpsertMutation> {\n return adminRequestDoc({\n query: ThemeFilesUpsert,\n session,\n variables: {themeId: themeGid(themeId), files},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n}\n\nfunction processUploadResults(uploadResults: ThemeFilesUpsertMutation): Result[] {\n const {themeFilesUpsert} = uploadResults\n\n if (!themeFilesUpsert) {\n unexpectedGraphQLError('Failed to upload theme files')\n }\n\n const {upsertedThemeFiles, userErrors} = themeFilesUpsert\n\n const results: Result[] = []\n\n upsertedThemeFiles?.forEach((file) => {\n results.push({\n key: file.filename,\n success: true,\n operation: Operation.Upload,\n })\n })\n\n userErrors.forEach((error) => {\n if (!error.filename) {\n unexpectedGraphQLError(`Error uploading theme files: ${error.message}`)\n }\n recordError(`Asset upload failed for ${error.filename}: ${error.message}`)\n results.push({\n key: error.filename,\n success: false,\n operation: Operation.Upload,\n errors: {asset: [error.message]},\n })\n })\n\n return results\n}\n\nexport async function fetchChecksums(id: number, session: AdminSession): Promise<Checksum[]> {\n const checksums: Checksum[] = []\n let after: string | null = null\n recordEvent('theme-api:fetch-checksums')\n\n while (true) {\n // eslint-disable-next-line no-await-in-loop\n const response = await requestThemeAdminDoc({\n query: GetThemeFileChecksums,\n session,\n variables: {id: themeGid(id), after},\n responseOptions: {handleErrors: false},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (!response?.theme?.files?.nodes || !response?.theme?.files?.pageInfo) {\n const userErrors = response.theme?.files?.userErrors.map((error) => error.filename).join(', ')\n throw recordError(new AbortError(`Failed to fetch checksums for: ${userErrors}`))\n }\n\n const {nodes, pageInfo} = response.theme.files\n\n checksums.push(\n ...nodes.map((file) => ({\n key: file.filename,\n checksum: file.checksumMd5 as string,\n })),\n )\n\n if (!pageInfo.hasNextPage) {\n return checksums\n }\n\n after = pageInfo.endCursor as string\n }\n}\n\nexport async function themeUpdate(id: number, params: ThemeParams, session: AdminSession): Promise<Theme | undefined> {\n const name = params.name\n const input: Record<string, string> = {}\n if (name) {\n input.name = name\n }\n recordEvent('theme-api:update-theme')\n\n const {themeUpdate} = await adminRequestDoc({\n query: ThemeUpdate,\n session,\n variables: {id: composeThemeGid(id), input},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n if (!themeUpdate) {\n // An unexpected error occurred during the GraphQL request execution\n unexpectedGraphQLError('Failed to update theme')\n }\n\n const {theme, userErrors} = themeUpdate\n if (userErrors.length) {\n const userErrors = themeUpdate.userErrors.map((error) => error.message).join(', ')\n throw recordError(new AbortError(userErrors))\n }\n\n if (!theme) {\n // An unexpected error if neither theme nor userErrors are returned\n unexpectedGraphQLError('Failed to update theme')\n }\n\n return buildTheme({\n id: parseGid(theme.id),\n name: theme.name,\n role: theme.role.toLowerCase(),\n })\n}\n\nexport async function themePublish(id: number, session: AdminSession): Promise<Theme | undefined> {\n recordEvent('theme-api:publish-theme')\n const {themePublish} = await adminRequestDoc({\n query: ThemePublish,\n session,\n variables: {id: composeThemeGid(id)},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n if (!themePublish) {\n // An unexpected error occurred during the GraphQL request execution\n unexpectedGraphQLError('Failed to update theme')\n }\n\n const {theme, userErrors} = themePublish\n if (userErrors.length) {\n const userErrors = themePublish.userErrors.map((error) => error.message).join(', ')\n throw recordError(new AbortError(userErrors))\n }\n\n if (!theme) {\n // An unexpected error if neither theme nor userErrors are returned\n unexpectedGraphQLError('Failed to update theme')\n }\n\n return buildTheme({\n id: parseGid(theme.id),\n name: theme.name,\n role: theme.role.toLowerCase(),\n })\n}\n\nexport async function themeDelete(id: number, session: AdminSession): Promise<boolean | undefined> {\n recordEvent('theme-api:delete-theme')\n const {themeDelete} = await adminRequestDoc({\n query: ThemeDelete,\n session,\n variables: {id: composeThemeGid(id)},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n if (!themeDelete) {\n // An unexpected error occurred during the GraphQL request execution\n unexpectedGraphQLError('Failed to update theme')\n }\n\n const {deletedThemeId, userErrors} = themeDelete\n if (userErrors.length) {\n const userErrors = themeDelete.userErrors.map((error) => error.message).join(', ')\n throw recordError(new AbortError(userErrors))\n }\n\n if (!deletedThemeId) {\n // An unexpected error if neither theme nor userErrors are returned\n unexpectedGraphQLError('Failed to update theme')\n }\n\n return true\n}\n\nexport interface ThemeDuplicateResult {\n theme?: Theme\n userErrors: {field?: string[] | null; message: string}[]\n requestId?: string\n}\n\nexport async function themeDuplicate(\n id: number,\n name: string | undefined,\n session: AdminSession,\n): Promise<ThemeDuplicateResult> {\n let requestId: string | undefined\n recordEvent('theme-api:duplicate-theme')\n\n const {themeDuplicate} = await adminRequestDoc({\n query: ThemeDuplicate,\n session,\n variables: {id: composeThemeGid(id), name},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n responseOptions: {\n onResponse: (response) => {\n requestId = response.headers.get('x-request-id') ?? undefined\n },\n },\n })\n\n if (!themeDuplicate) {\n // An unexpected error occurred during the GraphQL request execution\n recordError('Failed to duplicate theme')\n return {\n theme: undefined,\n userErrors: [{message: 'Failed to duplicate theme'}],\n requestId,\n }\n }\n\n const {newTheme, userErrors} = themeDuplicate\n\n if (userErrors.length > 0) {\n return {\n theme: undefined,\n userErrors,\n requestId,\n }\n }\n\n if (!newTheme) {\n // An unexpected error if neither theme nor userErrors are returned\n return {\n theme: undefined,\n userErrors: [{message: 'Failed to duplicate theme'}],\n requestId,\n }\n }\n\n const theme = buildTheme({\n id: parseGid(newTheme.id),\n name: newTheme.name,\n role: newTheme.role.toLowerCase(),\n })\n\n return {\n theme,\n userErrors: [],\n requestId,\n }\n}\n\nexport async function metafieldDefinitionsByOwnerType(type: MetafieldOwnerType, session: AdminSession) {\n recordEvent('theme-api:fetch-metafield-definitions')\n const {metafieldDefinitions} = await adminRequestDoc({\n query: MetafieldDefinitionsByOwnerType,\n session,\n variables: {ownerType: type},\n })\n\n return metafieldDefinitions.nodes.map((definition) => ({\n key: definition.key,\n namespace: definition.namespace,\n name: definition.name,\n description: definition.description,\n type: {\n name: definition.type.name,\n category: definition.type.category,\n },\n }))\n}\n\nexport async function passwordProtected(session: AdminSession): Promise<boolean> {\n recordEvent('theme-api:check-password-protection')\n const {onlineStore} = await adminRequestDoc({\n query: OnlineStorePasswordProtection,\n session,\n })\n if (!onlineStore) {\n unexpectedGraphQLError(\"Unable to get details about the storefront's password protection\")\n }\n\n const {passwordProtection} = onlineStore\n\n return passwordProtection.enabled\n}\n\nfunction unexpectedGraphQLError(message: string): never {\n throw recordError(new AbortError(message))\n}\n\nasync function requestThemeAdminDoc<TResult, TVariables extends Variables>(\n options: AdminRequestOptions<TResult, TVariables>,\n): Promise<TResult> {\n try {\n const response = await adminRequestDoc(options)\n return response\n } catch (error) {\n abortIfMissingThemeAccessScope(error)\n throw error\n }\n}\n\nfunction abortIfMissingThemeAccessScope(error: unknown): void {\n if (!(error instanceof ClientError)) return\n\n const requiredAccess = getThemeAccessRequirementForAccessDeniedError(error)\n if (!requiredAccess) return\n\n const nextSteps: TokenItem<InlineToken>[] = [\n [\n 'If you authenticated with an Admin API access token, update the app or integration that issued the token to include the required theme access scopes, then reauthorize it or generate a new token.',\n ],\n [\n 'For',\n {command: 'theme pull'},\n {char: ','},\n {command: 'theme list'},\n {char: ','},\n 'and',\n {command: 'theme info'},\n {char: ','},\n 'add the',\n {command: 'read_themes'},\n 'scope',\n {char: '.'},\n ],\n [\n 'For',\n {command: 'theme push'},\n 'and',\n {command: 'theme dev'},\n {char: ','},\n 'add both the',\n {command: 'read_themes'},\n 'and',\n {command: 'write_themes'},\n 'scopes',\n {char: '.'},\n ],\n [\n 'If you authenticated with your Shopify account, make sure your staff or collaborator account can access Online Store themes, then run',\n {command: 'shopify auth logout'},\n 'and try again',\n {char: '.'},\n ],\n ['See', {link: {label: 'Shopify access scopes', url: 'https://shopify.dev/api/usage/access-scopes'}}, {char: '.'}],\n ]\n\n throw recordError(\n new AbortError(`The authenticated account or access token is missing ${requiredAccess}.`, undefined, nextSteps),\n )\n}\n\nfunction getThemeAccessRequirementForAccessDeniedError(error: ClientError): string | undefined {\n const graphQLErrors = error.response.errors\n if (!Array.isArray(graphQLErrors)) return undefined\n\n const accessDeniedError = graphQLErrors.find((graphQLError) => graphQLError.extensions?.code === 'ACCESS_DENIED')\n if (!accessDeniedError) return undefined\n\n const requiredAccess = accessDeniedError.extensions?.requiredAccess\n if (typeof requiredAccess !== 'string') return DEFAULT_THEME_ACCESS_REQUIREMENT\n\n return formatThemeAccessRequirement(requiredAccess)\n}\n\nfunction formatThemeAccessRequirement(requiredAccess: string): string {\n const requirement = requiredAccess\n .trim()\n .replace(/\\.$/, '')\n .replace(/^The user needs\\s+/i, '')\n\n return requirement || DEFAULT_THEME_ACCESS_REQUIREMENT\n}\n\nfunction themeGid(id: number): string {\n return `gid://shopify/OnlineStoreTheme/${id}`\n}\n\ntype OnlineStoreThemeFileBody =\n | {__typename: 'OnlineStoreThemeFileBodyBase64'; contentBase64: string}\n | {__typename: 'OnlineStoreThemeFileBodyText'; content: string}\n | {__typename: 'OnlineStoreThemeFileBodyUrl'; url: string}\n\nexport async function parseThemeFileContent(\n body: OnlineStoreThemeFileBody,\n): Promise<{value?: string; attachment?: string}> {\n switch (body.__typename) {\n case 'OnlineStoreThemeFileBodyText':\n return {value: body.content}\n case 'OnlineStoreThemeFileBodyBase64':\n return {attachment: body.contentBase64}\n case 'OnlineStoreThemeFileBodyUrl':\n try {\n // eslint-disable-next-line no-restricted-globals\n const response = await fetch(body.url)\n\n const arrayBuffer = await response.arrayBuffer()\n return {attachment: Buffer.from(arrayBuffer).toString('base64')}\n } catch (error) {\n // Raise error if we can't download the file\n throw recordError(new AbortError(`Error downloading content from URL: ${body.url}`))\n }\n }\n}\n"]}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../../src/public/node/themes/api.ts"],"names":[],"mappings":"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","sourcesContent":["import {Result, Checksum, Key, Theme, ThemeAsset, Operation} from './types.js'\nimport {buildTheme} from './factories.js'\nimport {composeThemeGid, parseGid, DEVELOPMENT_THEME_ROLE} from './utils.js'\nimport {ThemeUpdate} from '../../../cli/api/graphql/admin/generated/theme_update.js'\nimport {ThemeDelete} from '../../../cli/api/graphql/admin/generated/theme_delete.js'\nimport {ThemeDuplicate} from '../../../cli/api/graphql/admin/generated/theme_duplicate.js'\nimport {ThemePublish} from '../../../cli/api/graphql/admin/generated/theme_publish.js'\nimport {ThemeCreate} from '../../../cli/api/graphql/admin/generated/theme_create.js'\nimport {GetThemeFileBodies} from '../../../cli/api/graphql/admin/generated/get_theme_file_bodies.js'\nimport {GetThemeFileChecksums} from '../../../cli/api/graphql/admin/generated/get_theme_file_checksums.js'\nimport {\n ThemeFilesUpsert,\n ThemeFilesUpsertMutation,\n} from '../../../cli/api/graphql/admin/generated/theme_files_upsert.js'\nimport {ThemeFilesDelete} from '../../../cli/api/graphql/admin/generated/theme_files_delete.js'\nimport {\n OnlineStoreThemeFileBodyInputType,\n OnlineStoreThemeFilesUpsertFileInput,\n MetafieldOwnerType,\n ThemeRole,\n} from '../../../cli/api/graphql/admin/generated/types.js'\nimport {\n MetafieldDefinitionsByOwnerType,\n type MetafieldDefinitionsByOwnerTypeQuery,\n} from '../../../cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.js'\nimport {GetThemes} from '../../../cli/api/graphql/admin/generated/get_themes.js'\nimport {GetTheme} from '../../../cli/api/graphql/admin/generated/get_theme.js'\nimport {FindDevelopmentThemeByName} from '../../../cli/api/graphql/admin/generated/find_development_theme_by_name.js'\nimport {OnlineStorePasswordProtection} from '../../../cli/api/graphql/admin/generated/online_store_password_protection.js'\nimport {extractGraphQLErrors} from '../../../private/node/api/graphql.js'\nimport {TrustChallengeError, withTrustChallengeRetry} from '../../../private/node/themes/trust-challenge.js'\nimport {RequestModeInput} from '../http.js'\nimport {adminRequestDoc, type AdminRequestOptions} from '../api/admin.js'\nimport {AdminSession} from '../session.js'\nimport {AbortError} from '../error.js'\nimport {outputDebug} from '../output.js'\nimport {recordTiming, recordEvent, recordError} from '../analytics.js'\nimport {type Variables} from 'graphql-request'\nimport type {InlineToken, TokenItem} from '../ui.js'\n\nexport type ThemeParams = Partial<Pick<Theme, 'name' | 'role' | 'processing' | 'src'>>\nexport type AssetParams = Pick<ThemeAsset, 'key'> & Partial<Pick<ThemeAsset, 'value' | 'attachment'>>\nconst SkeletonThemeCdn = 'https://cdn.shopify.com/static/online-store/theme-skeleton.zip'\nconst THEME_API_NETWORK_BEHAVIOUR: RequestModeInput = {\n useNetworkLevelRetry: true,\n useAbortSignal: false,\n maxRetryTimeMs: 90 * 1000,\n recordCommandRetries: true,\n}\nconst DEFAULT_THEME_ACCESS_REQUIREMENT = 'the required theme access scope'\n\nexport async function fetchTheme(id: number, session: AdminSession): Promise<Theme | undefined> {\n const gid = composeThemeGid(id)\n recordEvent('theme-api:fetch-theme')\n\n try {\n const {theme} = await adminRequestDoc({\n query: GetTheme,\n session,\n variables: {id: gid},\n responseOptions: {handleErrors: false},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (theme) {\n return buildTheme({\n id: parseGid(theme.id),\n processing: theme.processing,\n role: theme.role.toLowerCase(),\n name: theme.name,\n })\n }\n\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n abortIfMissingThemeAccessScope(error)\n /**\n * Consumers of this and other theme APIs in this file expect either a theme\n * or `undefined`.\n *\n * Error handlers should not inspect GraphQL error messages directly, as\n * they are internationalized.\n */\n recordError(error)\n outputDebug(`Error fetching theme with ID: ${id}`)\n }\n}\n\nexport async function fetchThemes(session: AdminSession): Promise<Theme[]> {\n const themes: Theme[] = []\n let after: string | null = null\n recordEvent('theme-api:fetch-themes')\n\n while (true) {\n // eslint-disable-next-line no-await-in-loop\n const response = await requestThemeAdminDoc({\n query: GetThemes,\n session,\n variables: {after},\n responseOptions: {handleErrors: false},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (!response.themes) {\n unexpectedGraphQLError('Failed to fetch themes')\n }\n const {nodes, pageInfo} = response.themes\n nodes.forEach((theme) => {\n const t = buildTheme({\n id: parseGid(theme.id),\n processing: theme.processing,\n role: theme.role.toLowerCase(),\n name: theme.name,\n })\n if (t) {\n themes.push(t)\n }\n })\n if (!pageInfo.hasNextPage) {\n return themes\n }\n\n after = pageInfo.endCursor as string\n }\n}\n\nexport async function findDevelopmentThemeByName(name: string, session: AdminSession): Promise<Theme | undefined> {\n recordEvent('theme-api:find-development-theme-by-name')\n\n const {themes} = await requestThemeAdminDoc({\n query: FindDevelopmentThemeByName,\n session,\n variables: {name},\n responseOptions: {handleErrors: false},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (!themes) {\n unexpectedGraphQLError('Failed to fetch themes')\n }\n\n if (themes.nodes.length > 1) {\n throw recordError(new AbortError(`More than one development theme is named \"${name}\"`))\n }\n\n if (themes.nodes.length === 1) {\n const {id, processing, role, name} = themes.nodes[0]!\n\n return buildTheme({\n id: parseGid(id),\n processing,\n role: role.toLowerCase(),\n name,\n })\n }\n}\n\nexport async function themeCreate(params: ThemeParams, session: AdminSession): Promise<Theme | undefined> {\n const themeSource = params.src ?? SkeletonThemeCdn\n recordEvent('theme-api:create-theme')\n const {themeCreate} = await requestThemeAdminDoc({\n query: ThemeCreate,\n session,\n variables: {\n name: params.name ?? '',\n source: themeSource,\n role: (params.role ?? DEVELOPMENT_THEME_ROLE).toUpperCase() as ThemeRole,\n },\n responseOptions: {handleErrors: false},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (!themeCreate) {\n unexpectedGraphQLError('Failed to create theme')\n }\n\n const {theme, userErrors} = themeCreate\n if (userErrors.length) {\n const userErrors = themeCreate.userErrors.map((error) => error.message).join(', ')\n throw recordError(new AbortError(userErrors))\n }\n\n if (!theme) {\n unexpectedGraphQLError('Failed to create theme')\n }\n\n return buildTheme({\n id: parseGid(theme.id),\n name: theme.name,\n role: theme.role.toLowerCase(),\n })\n}\n\nexport async function fetchThemeAssets(id: number, filenames: Key[], session: AdminSession): Promise<ThemeAsset[]> {\n const assets: ThemeAsset[] = []\n let after: string | null = null\n recordEvent('theme-api:fetch-assets')\n\n while (true) {\n // eslint-disable-next-line no-await-in-loop\n const response = await requestThemeAdminDoc({\n query: GetThemeFileBodies,\n session,\n variables: {id: themeGid(id), filenames, after},\n responseOptions: {handleErrors: false},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (!response.theme?.files?.nodes || !response.theme?.files?.pageInfo) {\n const userErrors = response.theme?.files?.userErrors.map((error) => error.filename).join(', ')\n unexpectedGraphQLError(`Error fetching assets: ${userErrors}`)\n }\n\n const {nodes, pageInfo} = response.theme.files\n\n assets.push(\n // eslint-disable-next-line no-await-in-loop\n ...(await Promise.all(\n nodes.map(async (file) => {\n const {attachment, value} = await parseThemeFileContent(file.body)\n return {\n attachment,\n key: file.filename,\n checksum: file.checksumMd5 as string,\n value,\n }\n }),\n )),\n )\n\n if (!pageInfo.hasNextPage) {\n return assets\n }\n\n after = pageInfo.endCursor as string\n }\n}\n\nexport async function deleteThemeAssets(id: number, filenames: Key[], session: AdminSession): Promise<Result[]> {\n const batchSize = 50\n const results: Result[] = []\n recordEvent('theme-api:delete-assets')\n\n for (let i = 0; i < filenames.length; i += batchSize) {\n const batch = filenames.slice(i, i + batchSize)\n // eslint-disable-next-line no-await-in-loop\n const {themeFilesDelete} = await requestThemeAdminDoc({\n query: ThemeFilesDelete,\n session,\n variables: {\n themeId: composeThemeGid(id),\n files: batch,\n },\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (!themeFilesDelete) {\n unexpectedGraphQLError('Failed to delete theme assets')\n }\n\n const {deletedThemeFiles, userErrors} = themeFilesDelete\n\n if (deletedThemeFiles) {\n deletedThemeFiles.forEach((file) => {\n results.push({key: file.filename, success: true, operation: Operation.Delete})\n })\n }\n\n if (userErrors.length > 0) {\n userErrors.forEach((error) => {\n if (error.filename) {\n recordError(`Asset deletion failed for ${error.filename}: ${error.message}`)\n results.push({\n key: error.filename,\n success: false,\n operation: Operation.Delete,\n errors: {asset: [error.message]},\n })\n } else {\n unexpectedGraphQLError(`Failed to delete theme assets: ${error.message}`)\n }\n })\n }\n }\n\n return results\n}\n\nexport async function bulkUploadThemeAssets(\n id: number,\n assets: AssetParams[],\n session: AdminSession,\n): Promise<Result[]> {\n const results: Result[] = []\n recordEvent('theme-api:bulk-upload-assets')\n for (let i = 0; i < assets.length; i += 50) {\n const chunk = assets.slice(i, i + 50)\n const files = prepareFilesForUpload(chunk)\n\n recordTiming('theme-api:upload-files')\n // eslint-disable-next-line no-await-in-loop\n const uploadResults = await uploadFiles(id, files, session)\n recordTiming('theme-api:upload-files')\n\n results.push(...processUploadResults(uploadResults))\n }\n return results\n}\n\nfunction prepareFilesForUpload(assets: AssetParams[]): OnlineStoreThemeFilesUpsertFileInput[] {\n return assets.map((asset) => {\n if (asset.attachment) {\n return {\n filename: asset.key,\n body: {\n type: 'BASE64' as const,\n value: asset.attachment,\n },\n }\n } else {\n return {\n filename: asset.key,\n body: {\n type: 'TEXT' as const,\n value: asset.value ?? '',\n },\n }\n }\n })\n}\n\nasync function uploadFiles(\n themeId: number,\n files: {filename: string; body: {type: OnlineStoreThemeFileBodyInputType; value: string}}[],\n session: AdminSession,\n): Promise<ThemeFilesUpsertMutation> {\n return requestThemeAdminDoc({\n query: ThemeFilesUpsert,\n session,\n variables: {themeId: themeGid(themeId), files},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n}\n\nfunction processUploadResults(uploadResults: ThemeFilesUpsertMutation): Result[] {\n const {themeFilesUpsert} = uploadResults\n\n if (!themeFilesUpsert) {\n unexpectedGraphQLError('Failed to upload theme files')\n }\n\n const {upsertedThemeFiles, userErrors} = themeFilesUpsert\n\n const results: Result[] = []\n\n upsertedThemeFiles?.forEach((file) => {\n results.push({\n key: file.filename,\n success: true,\n operation: Operation.Upload,\n })\n })\n\n userErrors.forEach((error) => {\n if (!error.filename) {\n unexpectedGraphQLError(`Error uploading theme files: ${error.message}`)\n }\n recordError(`Asset upload failed for ${error.filename}: ${error.message}`)\n results.push({\n key: error.filename,\n success: false,\n operation: Operation.Upload,\n errors: {asset: [error.message]},\n })\n })\n\n return results\n}\n\nexport async function fetchChecksums(id: number, session: AdminSession): Promise<Checksum[]> {\n const checksums: Checksum[] = []\n let after: string | null = null\n recordEvent('theme-api:fetch-checksums')\n\n while (true) {\n // eslint-disable-next-line no-await-in-loop\n const response = await requestThemeAdminDoc({\n query: GetThemeFileChecksums,\n session,\n variables: {id: themeGid(id), after},\n responseOptions: {handleErrors: false},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n\n if (!response?.theme?.files?.nodes || !response?.theme?.files?.pageInfo) {\n const userErrors = response.theme?.files?.userErrors.map((error) => error.filename).join(', ')\n throw recordError(new AbortError(`Failed to fetch checksums for: ${userErrors}`))\n }\n\n const {nodes, pageInfo} = response.theme.files\n\n checksums.push(\n ...nodes.map((file) => ({\n key: file.filename,\n checksum: file.checksumMd5 as string,\n })),\n )\n\n if (!pageInfo.hasNextPage) {\n return checksums\n }\n\n after = pageInfo.endCursor as string\n }\n}\n\nexport async function themeUpdate(id: number, params: ThemeParams, session: AdminSession): Promise<Theme | undefined> {\n const name = params.name\n const input: Record<string, string> = {}\n if (name) {\n input.name = name\n }\n recordEvent('theme-api:update-theme')\n\n const {themeUpdate} = await requestThemeAdminDoc({\n query: ThemeUpdate,\n session,\n variables: {id: composeThemeGid(id), input},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n if (!themeUpdate) {\n // An unexpected error occurred during the GraphQL request execution\n unexpectedGraphQLError('Failed to update theme')\n }\n\n const {theme, userErrors} = themeUpdate\n if (userErrors.length) {\n const userErrors = themeUpdate.userErrors.map((error) => error.message).join(', ')\n throw recordError(new AbortError(userErrors))\n }\n\n if (!theme) {\n // An unexpected error if neither theme nor userErrors are returned\n unexpectedGraphQLError('Failed to update theme')\n }\n\n return buildTheme({\n id: parseGid(theme.id),\n name: theme.name,\n role: theme.role.toLowerCase(),\n })\n}\n\nexport async function themePublish(id: number, session: AdminSession): Promise<Theme | undefined> {\n recordEvent('theme-api:publish-theme')\n const {themePublish} = await requestThemeAdminDoc({\n query: ThemePublish,\n session,\n variables: {id: composeThemeGid(id)},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n if (!themePublish) {\n // An unexpected error occurred during the GraphQL request execution\n unexpectedGraphQLError('Failed to update theme')\n }\n\n const {theme, userErrors} = themePublish\n if (userErrors.length) {\n const userErrors = themePublish.userErrors.map((error) => error.message).join(', ')\n throw recordError(new AbortError(userErrors))\n }\n\n if (!theme) {\n // An unexpected error if neither theme nor userErrors are returned\n unexpectedGraphQLError('Failed to update theme')\n }\n\n return buildTheme({\n id: parseGid(theme.id),\n name: theme.name,\n role: theme.role.toLowerCase(),\n })\n}\n\nexport async function themeDelete(id: number, session: AdminSession): Promise<boolean | undefined> {\n recordEvent('theme-api:delete-theme')\n const {themeDelete} = await requestThemeAdminDoc({\n query: ThemeDelete,\n session,\n variables: {id: composeThemeGid(id)},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n })\n if (!themeDelete) {\n // An unexpected error occurred during the GraphQL request execution\n unexpectedGraphQLError('Failed to update theme')\n }\n\n const {deletedThemeId, userErrors} = themeDelete\n if (userErrors.length) {\n const userErrors = themeDelete.userErrors.map((error) => error.message).join(', ')\n throw recordError(new AbortError(userErrors))\n }\n\n if (!deletedThemeId) {\n // An unexpected error if neither theme nor userErrors are returned\n unexpectedGraphQLError('Failed to update theme')\n }\n\n return true\n}\n\nexport interface ThemeDuplicateResult {\n theme?: Theme\n userErrors: {field?: string[] | null; message: string}[]\n requestId?: string\n}\n\nexport async function themeDuplicate(\n id: number,\n name: string | undefined,\n session: AdminSession,\n): Promise<ThemeDuplicateResult> {\n let requestId: string | undefined\n recordEvent('theme-api:duplicate-theme')\n\n const {themeDuplicate} = await requestThemeAdminDoc({\n query: ThemeDuplicate,\n session,\n variables: {id: composeThemeGid(id), name},\n preferredBehaviour: THEME_API_NETWORK_BEHAVIOUR,\n responseOptions: {\n onResponse: (response) => {\n requestId = response.headers.get('x-request-id') ?? undefined\n },\n },\n })\n\n if (!themeDuplicate) {\n // An unexpected error occurred during the GraphQL request execution\n recordError('Failed to duplicate theme')\n return {\n theme: undefined,\n userErrors: [{message: 'Failed to duplicate theme'}],\n requestId,\n }\n }\n\n const {newTheme, userErrors} = themeDuplicate\n\n if (userErrors.length > 0) {\n return {\n theme: undefined,\n userErrors,\n requestId,\n }\n }\n\n if (!newTheme) {\n // An unexpected error if neither theme nor userErrors are returned\n return {\n theme: undefined,\n userErrors: [{message: 'Failed to duplicate theme'}],\n requestId,\n }\n }\n\n const theme = buildTheme({\n id: parseGid(newTheme.id),\n name: newTheme.name,\n role: newTheme.role.toLowerCase(),\n })\n\n return {\n theme,\n userErrors: [],\n requestId,\n }\n}\n\nexport async function metafieldDefinitionsByOwnerType(type: MetafieldOwnerType, session: AdminSession) {\n recordEvent('theme-api:fetch-metafield-definitions')\n const definitions: MetafieldDefinitionsByOwnerTypeQuery['metafieldDefinitions']['nodes'] = []\n let after: string | null = null\n while (true) {\n // eslint-disable-next-line no-await-in-loop\n const {metafieldDefinitions}: MetafieldDefinitionsByOwnerTypeQuery = await adminRequestDoc({\n query: MetafieldDefinitionsByOwnerType,\n session,\n variables: {ownerType: type, after},\n })\n definitions.push(...metafieldDefinitions.nodes)\n if (!metafieldDefinitions.pageInfo.hasNextPage) break\n const endCursor: string | null | undefined = metafieldDefinitions.pageInfo.endCursor\n if (!endCursor || endCursor === after) unexpectedGraphQLError('Failed to paginate metafield definitions')\n after = endCursor\n }\n\n return definitions.map((definition) => ({\n key: definition.key,\n namespace: definition.namespace,\n name: definition.name,\n description: definition.description,\n type: {\n name: definition.type.name,\n category: definition.type.category,\n },\n }))\n}\n\nexport async function passwordProtected(session: AdminSession): Promise<boolean> {\n recordEvent('theme-api:check-password-protection')\n const {onlineStore} = await adminRequestDoc({\n query: OnlineStorePasswordProtection,\n session,\n })\n if (!onlineStore) {\n unexpectedGraphQLError(\"Unable to get details about the storefront's password protection\")\n }\n\n const {passwordProtection} = onlineStore\n\n return passwordProtection.enabled\n}\n\nfunction unexpectedGraphQLError(message: string): never {\n throw recordError(new AbortError(message))\n}\n\n/**\n * Whether the error ends a Trust Battery challenge on a theme request. A caller that\n * retries theme requests must rethrow it, or the user is asked to verify again for\n * each attempt.\n *\n * @param error - The error to check.\n * @returns True when the error ends a Trust Battery challenge.\n */\nexport function isTrustChallengeError(error: unknown): boolean {\n return error instanceof TrustChallengeError\n}\n\nasync function requestThemeAdminDoc<TResult, TVariables extends Variables>(\n options: AdminRequestOptions<TResult, TVariables>,\n): Promise<TResult> {\n try {\n const response = await withTrustChallengeRetry(() => adminRequestDoc(options))\n return response\n } catch (error) {\n abortIfMissingThemeAccessScope(error)\n throw error\n }\n}\n\nfunction abortIfMissingThemeAccessScope(error: unknown): void {\n const requiredAccess = getThemeAccessRequirementForAccessDeniedError(error)\n if (!requiredAccess) return\n\n const nextSteps: TokenItem<InlineToken>[] = [\n [\n 'If you authenticated with an Admin API access token, update the app or integration that issued the token to include the required theme access scopes, then reauthorize it or generate a new token.',\n ],\n [\n 'For',\n {command: 'theme pull'},\n {char: ','},\n {command: 'theme list'},\n {char: ','},\n 'and',\n {command: 'theme info'},\n {char: ','},\n 'add the',\n {command: 'read_themes'},\n 'scope',\n {char: '.'},\n ],\n [\n 'For',\n {command: 'theme push'},\n {char: ','},\n {command: 'theme dev'},\n {char: ','},\n {command: 'theme publish'},\n {char: ','},\n {command: 'theme delete'},\n {char: ','},\n {command: 'theme rename'},\n {char: ','},\n 'and',\n {command: 'theme duplicate'},\n {char: ','},\n 'add both the',\n {command: 'read_themes'},\n 'and',\n {command: 'write_themes'},\n 'scopes',\n {char: '.'},\n ],\n [\n 'If you authenticated with your Shopify account, make sure your staff or collaborator account can access Online Store themes, then run',\n {command: 'shopify auth logout'},\n 'and try again',\n {char: '.'},\n ],\n ['See', {link: {label: 'Shopify access scopes', url: 'https://shopify.dev/api/usage/access-scopes'}}, {char: '.'}],\n ]\n\n throw recordError(\n new AbortError(`The authenticated account or access token is missing ${requiredAccess}.`, undefined, nextSteps),\n )\n}\n\nfunction getThemeAccessRequirementForAccessDeniedError(error: unknown): string | undefined {\n const accessDeniedError = extractGraphQLErrors(error).find(\n (graphQLError) => graphQLError.extensions?.code === 'ACCESS_DENIED',\n )\n if (!accessDeniedError) return undefined\n\n const requiredAccess = accessDeniedError.extensions?.requiredAccess\n if (typeof requiredAccess !== 'string') return DEFAULT_THEME_ACCESS_REQUIREMENT\n\n return formatThemeAccessRequirement(requiredAccess)\n}\n\nfunction formatThemeAccessRequirement(requiredAccess: string): string {\n const requirement = requiredAccess\n .trim()\n .replace(/\\.$/, '')\n .replace(/^The user needs\\s+/i, '')\n\n return requirement || DEFAULT_THEME_ACCESS_REQUIREMENT\n}\n\nfunction themeGid(id: number): string {\n return `gid://shopify/OnlineStoreTheme/${id}`\n}\n\ntype OnlineStoreThemeFileBody =\n | {__typename: 'OnlineStoreThemeFileBodyBase64'; contentBase64: string}\n | {__typename: 'OnlineStoreThemeFileBodyText'; content: string}\n | {__typename: 'OnlineStoreThemeFileBodyUrl'; url: string}\n\nexport async function parseThemeFileContent(\n body: OnlineStoreThemeFileBody,\n): Promise<{value?: string; attachment?: string}> {\n switch (body.__typename) {\n case 'OnlineStoreThemeFileBodyText':\n return {value: body.content}\n case 'OnlineStoreThemeFileBodyBase64':\n return {attachment: body.contentBase64}\n case 'OnlineStoreThemeFileBodyUrl':\n try {\n // eslint-disable-next-line no-restricted-globals\n const response = await fetch(body.url)\n\n const arrayBuffer = await response.arrayBuffer()\n return {attachment: Buffer.from(arrayBuffer).toString('base64')}\n } catch (error) {\n // Raise error if we can't download the file\n throw recordError(new AbortError(`Error downloading content from URL: ${body.url}`))\n }\n }\n}\n"]}