@shopify/cli-kit 3.0.25 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (289) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/assets/auth-error.html +2 -4
  3. package/assets/empty-url.html +2 -4
  4. package/assets/missing-code.html +2 -4
  5. package/assets/missing-state.html +2 -4
  6. package/assets/style.css +5 -8
  7. package/assets/success.html +1 -1
  8. package/dist/abort.d.ts +1 -0
  9. package/dist/abort.js +2 -0
  10. package/dist/abort.js.map +1 -0
  11. package/dist/analytics.d.ts +13 -0
  12. package/dist/analytics.js +111 -0
  13. package/dist/analytics.js.map +1 -0
  14. package/dist/api/admin.d.ts +3 -0
  15. package/dist/api/admin.js +80 -0
  16. package/dist/api/admin.js.map +1 -0
  17. package/dist/api/common.d.ts +11 -0
  18. package/dist/api/common.js +40 -0
  19. package/dist/api/common.js.map +1 -0
  20. package/dist/api/graphql/all_app_extension_registrations.d.ts +14 -0
  21. package/dist/api/graphql/all_app_extension_registrations.js +14 -0
  22. package/dist/api/graphql/all_app_extension_registrations.js.map +1 -0
  23. package/dist/api/graphql/all_orgs.d.ts +12 -0
  24. package/dist/api/graphql/all_orgs.js +14 -0
  25. package/dist/api/graphql/all_orgs.js.map +1 -0
  26. package/dist/api/graphql/all_stores_by_org.d.ts +18 -0
  27. package/dist/api/graphql/all_stores_by_org.js +21 -0
  28. package/dist/api/graphql/all_stores_by_org.js.map +1 -0
  29. package/dist/api/graphql/convert_dev_to_test_store.d.ts +16 -0
  30. package/dist/api/graphql/convert_dev_to_test_store.js +13 -0
  31. package/dist/api/graphql/convert_dev_to_test_store.js.map +1 -0
  32. package/dist/api/graphql/create_app.d.ts +28 -0
  33. package/dist/api/graphql/create_app.js +32 -0
  34. package/dist/api/graphql/create_app.js.map +1 -0
  35. package/dist/api/graphql/create_deployment.d.ts +33 -0
  36. package/dist/api/graphql/create_deployment.js +25 -0
  37. package/dist/api/graphql/create_deployment.js.map +1 -0
  38. package/dist/api/graphql/extension_create.d.ts +30 -0
  39. package/dist/api/graphql/extension_create.js +26 -0
  40. package/dist/api/graphql/extension_create.js.map +1 -0
  41. package/dist/api/graphql/extension_specifications.d.ts +18 -0
  42. package/dist/api/graphql/extension_specifications.js +18 -0
  43. package/dist/api/graphql/extension_specifications.js.map +1 -0
  44. package/dist/api/graphql/find_app.d.ts +13 -0
  45. package/dist/api/graphql/find_app.js +16 -0
  46. package/dist/api/graphql/find_app.js.map +1 -0
  47. package/dist/api/graphql/find_org.d.ts +23 -0
  48. package/dist/api/graphql/find_org.js +26 -0
  49. package/dist/api/graphql/find_org.js.map +1 -0
  50. package/dist/api/graphql/find_org_basic.d.ts +11 -0
  51. package/dist/api/graphql/find_org_basic.js +14 -0
  52. package/dist/api/graphql/find_org_basic.js.map +1 -0
  53. package/dist/api/graphql/find_store_by_domain.d.ts +21 -0
  54. package/dist/api/graphql/find_store_by_domain.js +24 -0
  55. package/dist/api/graphql/find_store_by_domain.js.map +1 -0
  56. package/dist/api/graphql/functions/app_function_set.d.ts +43 -0
  57. package/dist/api/graphql/functions/app_function_set.js +52 -0
  58. package/dist/api/graphql/functions/app_function_set.js.map +1 -0
  59. package/dist/api/graphql/functions/compile_module.d.ts +15 -0
  60. package/dist/api/graphql/functions/compile_module.js +13 -0
  61. package/dist/api/graphql/functions/compile_module.js.map +1 -0
  62. package/dist/api/graphql/functions/function_service_proxy.d.ts +4 -0
  63. package/dist/api/graphql/functions/function_service_proxy.js +7 -0
  64. package/dist/api/graphql/functions/function_service_proxy.js.map +1 -0
  65. package/dist/api/graphql/functions/get_app_functions.d.ts +1 -0
  66. package/dist/api/graphql/functions/get_app_functions.js +10 -0
  67. package/dist/api/graphql/functions/get_app_functions.js.map +1 -0
  68. package/dist/api/graphql/functions/module_compilation_status.d.ts +15 -0
  69. package/dist/api/graphql/functions/module_compilation_status.js +13 -0
  70. package/dist/api/graphql/functions/module_compilation_status.js.map +1 -0
  71. package/dist/api/graphql/functions/module_upload_url_generate.d.ts +18 -0
  72. package/dist/api/graphql/functions/module_upload_url_generate.js +17 -0
  73. package/dist/api/graphql/functions/module_upload_url_generate.js.map +1 -0
  74. package/dist/api/graphql/generate_signed_upload_url.d.ts +15 -0
  75. package/dist/api/graphql/generate_signed_upload_url.js +15 -0
  76. package/dist/api/graphql/generate_signed_upload_url.js.map +1 -0
  77. package/dist/api/graphql/get_variant_id.d.ts +17 -0
  78. package/dist/api/graphql/get_variant_id.js +20 -0
  79. package/dist/api/graphql/get_variant_id.js.map +1 -0
  80. package/dist/api/graphql/index.d.ts +22 -0
  81. package/dist/api/graphql/index.js +23 -0
  82. package/dist/api/graphql/index.js.map +1 -0
  83. package/dist/api/graphql/update_draft.d.ts +33 -0
  84. package/dist/api/graphql/update_draft.js +24 -0
  85. package/dist/api/graphql/update_draft.js.map +1 -0
  86. package/dist/api/graphql/update_urls.d.ts +14 -0
  87. package/dist/api/graphql/update_urls.js +12 -0
  88. package/dist/api/graphql/update_urls.js.map +1 -0
  89. package/dist/api/identity.d.ts +1 -0
  90. package/dist/api/identity.js +32 -0
  91. package/dist/api/identity.js.map +1 -0
  92. package/dist/api/partners.d.ts +25 -0
  93. package/dist/api/partners.js +100 -0
  94. package/dist/api/partners.js.map +1 -0
  95. package/dist/api.d.ts +5 -0
  96. package/dist/api.js +6 -0
  97. package/dist/api.js.map +1 -0
  98. package/dist/cli.d.ts +7 -0
  99. package/dist/cli.js +13 -0
  100. package/dist/cli.js.map +1 -0
  101. package/dist/constants.d.ts +43 -0
  102. package/dist/constants.js +63 -0
  103. package/dist/constants.js.map +1 -0
  104. package/dist/environment/fqdn.d.ts +23 -0
  105. package/dist/environment/fqdn.js +61 -0
  106. package/dist/environment/fqdn.js.map +1 -0
  107. package/dist/environment/local.d.ts +48 -0
  108. package/dist/environment/local.js +82 -0
  109. package/dist/environment/local.js.map +1 -0
  110. package/dist/environment/service.d.ts +17 -0
  111. package/dist/environment/service.js +41 -0
  112. package/dist/environment/service.js.map +1 -0
  113. package/dist/environment/spin.d.ts +47 -0
  114. package/dist/environment/spin.js +83 -0
  115. package/dist/environment/spin.js.map +1 -0
  116. package/dist/environment/utilities.d.ts +6 -0
  117. package/dist/environment/utilities.js +12 -0
  118. package/dist/environment/utilities.js.map +1 -0
  119. package/dist/environment.d.ts +5 -0
  120. package/dist/environment.js +6 -0
  121. package/dist/environment.js.map +1 -0
  122. package/dist/error.d.ts +44 -0
  123. package/dist/error.js +91 -0
  124. package/dist/error.js.map +1 -0
  125. package/dist/file.d.ts +67 -0
  126. package/dist/file.js +165 -0
  127. package/dist/file.js.map +1 -0
  128. package/dist/git.d.ts +15 -0
  129. package/dist/git.js +48 -0
  130. package/dist/git.js.map +1 -0
  131. package/dist/github.d.ts +33 -0
  132. package/dist/github.js +56 -0
  133. package/dist/github.js.map +1 -0
  134. package/dist/haiku.d.ts +1 -0
  135. package/dist/haiku.js +8 -0
  136. package/dist/haiku.js.map +1 -0
  137. package/dist/http/fetch.d.ts +16 -0
  138. package/dist/http/fetch.js +18 -0
  139. package/dist/http/fetch.js.map +1 -0
  140. package/dist/http/formdata.d.ts +3 -0
  141. package/dist/http/formdata.js +6 -0
  142. package/dist/http/formdata.js.map +1 -0
  143. package/dist/http.d.ts +2 -0
  144. package/dist/http.js +3 -0
  145. package/dist/http.js.map +1 -0
  146. package/dist/id.d.ts +6 -0
  147. package/dist/id.js +18 -0
  148. package/dist/id.js.map +1 -0
  149. package/dist/index.d.ts +33 -2179
  150. package/dist/index.js +34 -3264
  151. package/dist/index.js.map +1 -1
  152. package/dist/network/api.d.ts +2 -0
  153. package/dist/network/api.js +2 -0
  154. package/dist/network/api.js.map +1 -0
  155. package/dist/network/service.d.ts +16 -0
  156. package/dist/network/service.js +12 -0
  157. package/dist/network/service.js.map +1 -0
  158. package/dist/{archiver.d.ts → node/archiver.d.ts} +1 -4
  159. package/dist/node/archiver.js +22 -42
  160. package/dist/node/archiver.js.map +1 -1
  161. package/dist/node/checksum.d.ts +20 -0
  162. package/dist/node/checksum.js +32 -0
  163. package/dist/node/checksum.js.map +1 -0
  164. package/dist/node/cli.d.ts +18 -0
  165. package/dist/node/cli.js +96 -0
  166. package/dist/node/cli.js.map +1 -0
  167. package/dist/node/colors.d.ts +1 -0
  168. package/dist/node/colors.js +8 -0
  169. package/dist/node/colors.js.map +1 -0
  170. package/dist/node/dot-env.d.ts +33 -0
  171. package/dist/node/dot-env.js +36 -0
  172. package/dist/node/dot-env.js.map +1 -0
  173. package/dist/node/node-package-manager.d.ts +197 -0
  174. package/dist/node/node-package-manager.js +309 -0
  175. package/dist/node/node-package-manager.js.map +1 -0
  176. package/dist/node/ruby.d.ts +30 -0
  177. package/dist/node/ruby.js +197 -0
  178. package/dist/node/ruby.js.map +1 -0
  179. package/dist/npm.d.ts +27 -0
  180. package/dist/npm.js +20 -0
  181. package/dist/npm.js.map +1 -0
  182. package/dist/os.d.ts +10 -0
  183. package/dist/os.js +70 -0
  184. package/dist/os.js.map +1 -0
  185. package/dist/output.d.ts +149 -0
  186. package/dist/output.js +515 -0
  187. package/dist/output.js.map +1 -0
  188. package/dist/path.d.ts +22 -0
  189. package/dist/path.js +43 -0
  190. package/dist/path.js.map +1 -0
  191. package/dist/plugins.d.ts +9 -0
  192. package/dist/plugins.js +12 -0
  193. package/dist/plugins.js.map +1 -0
  194. package/dist/port.d.ts +5 -0
  195. package/dist/port.js +35 -0
  196. package/dist/port.js.map +1 -0
  197. package/dist/schema.d.ts +1 -0
  198. package/dist/schema.js +2 -0
  199. package/dist/schema.js.map +1 -0
  200. package/dist/secure-store.d.ts +19 -0
  201. package/dist/secure-store.js +63 -0
  202. package/dist/secure-store.js.map +1 -0
  203. package/dist/semver.d.ts +3 -0
  204. package/dist/semver.js +6 -0
  205. package/dist/semver.js.map +1 -0
  206. package/dist/session/authorize.d.ts +7 -0
  207. package/dist/session/authorize.js +40 -0
  208. package/dist/session/authorize.js.map +1 -0
  209. package/dist/session/exchange.d.ts +42 -0
  210. package/dist/session/exchange.js +144 -0
  211. package/dist/session/exchange.js.map +1 -0
  212. package/dist/session/identity.d.ts +3 -0
  213. package/dist/session/identity.js +58 -0
  214. package/dist/session/identity.js.map +1 -0
  215. package/dist/session/post-auth.d.ts +13 -0
  216. package/dist/session/post-auth.js +56 -0
  217. package/dist/session/post-auth.js.map +1 -0
  218. package/dist/session/redirect-listener.d.ts +34 -0
  219. package/dist/session/redirect-listener.js +97 -0
  220. package/dist/session/redirect-listener.js.map +1 -0
  221. package/dist/session/schema.d.ts +174 -0
  222. package/dist/session/schema.js +59 -0
  223. package/dist/session/schema.js.map +1 -0
  224. package/dist/session/scopes.d.ts +16 -0
  225. package/dist/session/scopes.js +53 -0
  226. package/dist/session/scopes.js.map +1 -0
  227. package/dist/session/store.d.ts +24 -0
  228. package/dist/session/store.js +88 -0
  229. package/dist/session/store.js.map +1 -0
  230. package/dist/session/token.d.ts +40 -0
  231. package/dist/session/token.js +22 -0
  232. package/dist/session/token.js.map +1 -0
  233. package/dist/session/validate.d.ts +17 -0
  234. package/dist/session/validate.js +75 -0
  235. package/dist/session/validate.js.map +1 -0
  236. package/dist/session.d.ts +88 -0
  237. package/dist/session.js +251 -0
  238. package/dist/session.js.map +1 -0
  239. package/dist/store/schema.d.ts +3 -0
  240. package/dist/store/schema.js +27 -0
  241. package/dist/store/schema.js.map +1 -0
  242. package/dist/store.d.ts +32 -0
  243. package/dist/store.js +102 -0
  244. package/dist/store.js.map +1 -0
  245. package/dist/string.d.ts +22 -0
  246. package/dist/string.js +38 -0
  247. package/dist/string.js.map +1 -0
  248. package/dist/system.d.ts +53 -0
  249. package/dist/system.js +109 -0
  250. package/dist/system.js.map +1 -0
  251. package/dist/template.d.ts +11 -0
  252. package/dist/template.js +50 -0
  253. package/dist/template.js.map +1 -0
  254. package/dist/testing/output.d.ts +9 -0
  255. package/dist/testing/output.js +15 -0
  256. package/dist/testing/output.js.map +1 -0
  257. package/dist/testing/store.d.ts +7 -0
  258. package/dist/testing/store.js +26 -0
  259. package/dist/testing/store.js.map +1 -0
  260. package/dist/toml.d.ts +3 -0
  261. package/dist/toml.js +8 -0
  262. package/dist/toml.js.map +1 -0
  263. package/dist/tsconfig.tsbuildinfo +1 -0
  264. package/dist/ui/autocomplete.d.ts +7 -0
  265. package/dist/ui/autocomplete.js +43 -0
  266. package/dist/ui/autocomplete.js.map +1 -0
  267. package/dist/ui/input.d.ts +7 -0
  268. package/dist/ui/input.js +48 -0
  269. package/dist/ui/input.js.map +1 -0
  270. package/dist/ui/select.d.ts +6 -0
  271. package/dist/ui/select.js +30 -0
  272. package/dist/ui/select.js.map +1 -0
  273. package/dist/ui.d.ts +36 -0
  274. package/dist/ui.js +124 -0
  275. package/dist/ui.js.map +1 -0
  276. package/dist/version.d.ts +19 -0
  277. package/dist/version.js +34 -0
  278. package/dist/version.js.map +1 -0
  279. package/dist/vscode.d.ts +8 -0
  280. package/dist/vscode.js +36 -0
  281. package/dist/vscode.js.map +1 -0
  282. package/dist/yaml.d.ts +2 -0
  283. package/dist/yaml.js +8 -0
  284. package/dist/yaml.js.map +1 -0
  285. package/package.json +19 -8
  286. package/dist/archiver.d.ts.map +0 -1
  287. package/dist/index.d.ts.map +0 -1
  288. package/dist/local-d0094ffe.js +0 -1344
  289. package/dist/local-d0094ffe.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,3264 +1,34 @@
1
- import { c as constants$1, A as Abort, f as fqdn$1, l as local, u as utilities, a as ansiColors, i as isTerminalInteractive, B as Bug, b as content, t as token, d as isTruthy, e as info, g as exists, h as AbortSilent, r as remove$3, j as exec, m as mkdir, k as captureOutput, w as write$1, n as cliKitPackageJson, o as debug$2, v as version$2, p as read$1, q as isDebug, s as analyticsDisabled, x as platformAndArch, y as isShopify, z as stringifyMessage, C as hasGit, D as username, E as moduleDirectory, F as open, G as warn, H as completed, I as isDirectory, J as hasExecutablePermissions, K as copy, L as chmod } from './local-d0094ffe.js';
2
- export { c as constants, M as error, N as file, O as os, P as output, Q as path, R as system } from './local-d0094ffe.js';
3
- import { AbortController, AbortSignal } from 'abort-controller';
4
- import 'commondir';
5
- import { relative, join, dirname, resolve } from 'pathe';
6
- import url$1 from 'url';
7
- import { findUp } from 'find-up';
8
- import glob from 'fast-glob';
9
- import { pathToFileURL } from 'node:url';
10
- import 'env-paths';
11
- import nodeFetch from 'node-fetch';
12
- import FormData from 'form-data';
13
- import enquirer from 'enquirer';
14
- import 'is-interactive';
15
- import 'node:os';
16
- import inquirer from 'inquirer';
17
- import { Listr } from 'listr2';
18
- import { spawn } from 'child_process';
19
- import { Writable } from 'node:stream';
20
- import Conf from 'conf';
21
- import latestVersion from 'latest-version';
22
- import crypto, { randomUUID } from 'crypto';
23
- import { request as request$2, ClientError, gql } from 'graphql-request';
24
- import { ExtendableError } from 'ts-error';
25
- import md5File from 'md5-file';
26
- import { Flags } from '@oclif/core';
27
- import { parse as parse$2, stringify } from 'envfile';
28
- import Fastify__default from 'fastify';
29
- import * as Fastify from 'fastify';
30
- export { Fastify as fastify };
31
- import git$1 from 'simple-git';
32
- import Haikunator from 'haikunator';
33
- import * as port$1 from 'get-port-please';
34
- import { z } from 'zod';
35
- import 'fs-extra';
36
- import 'del';
37
- import tempy from 'tempy';
38
- import 'prettier';
39
- import 'terminal-link';
40
- import 'stacktracey';
41
- import 'color-json';
42
- import 'execa';
43
- import 'node:process';
44
- import { camelCase, paramCase, snakeCase, constantCase } from 'change-case';
45
- import { Liquid } from 'liquidjs';
46
- import * as toml$1 from '@iarna/toml';
47
- import * as yaml$1 from 'js-yaml';
48
- import 'source-map-support';
49
-
50
- var abort = /*#__PURE__*/Object.freeze({
51
- __proto__: null,
52
- Controller: AbortController,
53
- Signal: AbortSignal
54
- });
55
-
56
- var Environment = /* @__PURE__ */ ((Environment2) => {
57
- Environment2["Local"] = "local";
58
- Environment2["Production"] = "production";
59
- Environment2["Spin"] = "spin";
60
- return Environment2;
61
- })(Environment || {});
62
-
63
- function service(value) {
64
- if (value === "local") {
65
- return Environment.Local;
66
- } else if (value === "spin") {
67
- return Environment.Spin;
68
- } else {
69
- return Environment.Production;
70
- }
71
- }
72
- function partners$2(env = process.env) {
73
- return service(env[constants$1.environmentVariables.partnersEnv]);
74
- }
75
- function shopify$1(env = process.env) {
76
- return service(env[constants$1.environmentVariables.shopifyEnv]);
77
- }
78
- function identity$1(env = process.env) {
79
- return service(env[constants$1.environmentVariables.identityEnv]);
80
- }
81
-
82
- var service$1 = /*#__PURE__*/Object.freeze({
83
- __proto__: null,
84
- partners: partners$2,
85
- shopify: shopify$1,
86
- identity: identity$1
87
- });
88
-
89
- const CouldntObtainPartnersSpinFQDNError = new Abort("Couldn't obtain the Spin FQDN for Partners when the CLI is not running from a Spin environment.");
90
- const CouldntObtainIdentitySpinFQDNError = new Abort("Couldn't obtain the Spin FQDN for Identity when the CLI is not running from a Spin environment.");
91
- const CouldntObtainShopifySpinFQDNError = new Abort("Couldn't obtain the Spin FQDN for Shopify when the CLI is not running from a Spin environment.");
92
- const NotProvidedStoreFQDNError = new Abort("Couldn't obtain the Shopify FQDN because the store FQDN was not provided.");
93
- async function partners$1() {
94
- const environment = partners$2();
95
- const productionFqdn = "partners.shopify.com";
96
- switch (environment) {
97
- case "local":
98
- return "partners.myshopify.io";
99
- case "spin":
100
- return `partners.${await fqdn$1()}`;
101
- default:
102
- return productionFqdn;
103
- }
104
- }
105
- async function identity() {
106
- const environment = identity$1();
107
- const productionFqdn = "accounts.shopify.com";
108
- switch (environment) {
109
- case "local":
110
- return "identity.myshopify.io";
111
- case "spin":
112
- return `identity.${await fqdn$1()}`;
113
- default:
114
- return productionFqdn;
115
- }
116
- }
117
- async function shopify(options = {}) {
118
- const environment = shopify$1();
119
- switch (environment) {
120
- case "local":
121
- return "shopify.myshopify.io";
122
- case "spin":
123
- return `identity.${await fqdn$1()}`;
124
- default:
125
- if (options.storeFqdn) {
126
- return options.storeFqdn;
127
- } else {
128
- throw NotProvidedStoreFQDNError;
129
- }
130
- }
131
- }
132
-
133
- var fqdn = /*#__PURE__*/Object.freeze({
134
- __proto__: null,
135
- CouldntObtainPartnersSpinFQDNError: CouldntObtainPartnersSpinFQDNError,
136
- CouldntObtainIdentitySpinFQDNError: CouldntObtainIdentitySpinFQDNError,
137
- CouldntObtainShopifySpinFQDNError: CouldntObtainShopifySpinFQDNError,
138
- NotProvidedStoreFQDNError: NotProvidedStoreFQDNError,
139
- partners: partners$1,
140
- identity: identity,
141
- shopify: shopify
142
- });
143
-
144
- var environment = /*#__PURE__*/Object.freeze({
145
- __proto__: null,
146
- local: local,
147
- service: service$1,
148
- fqdn: fqdn,
149
- utilities: utilities
150
- });
151
-
152
- async function fetch$2(url, init) {
153
- const response = await nodeFetch(url, init);
154
- return response;
155
- }
156
-
157
- function formData() {
158
- return new FormData();
159
- }
160
-
161
- var http = /*#__PURE__*/Object.freeze({
162
- __proto__: null,
163
- fetch: fetch$2,
164
- formData: formData
165
- });
166
-
167
- class AutoComplete extends enquirer.AutoComplete {
168
- constructor(options) {
169
- const originalResult = options.result;
170
- options.result = (value) => {
171
- const answer = this.focused.value || this.focused.name || value;
172
- if (originalResult) {
173
- return originalResult(answer);
174
- }
175
- return answer;
176
- };
177
- super(options);
178
- this.styles.primary = ansiColors.exports.magenta;
179
- this.styles.em = ansiColors.exports.magenta;
180
- }
181
- pointer(_choice, i) {
182
- const color = this.styles.primary;
183
- const showPointer = !this.state.multiple && this.state.index === i;
184
- return showPointer ? color(">") : " ";
185
- }
186
- prefix(_state) {
187
- const color = this.styles.primary.bold;
188
- return this.state.status === "submitted" ? color("\u2714") : color("?");
189
- }
190
- format() {
191
- if (!this.focused)
192
- return this.input;
193
- if (this.options.multiple && this.state.submitted) {
194
- return this.selected.map((ch) => this.styles.primary(ch.message)).join(", ");
195
- }
196
- if (this.state.submitted) {
197
- this.value = this.focused.value;
198
- this.input = this.focused.value;
199
- return this.styles.primary(this.focused.name);
200
- }
201
- return this.input;
202
- }
203
- }
204
-
205
- class Input extends enquirer.StringPrompt {
206
- constructor(options) {
207
- super(options);
208
- this.styles.primary = ansiColors.exports.magenta;
209
- this.styles.submitted = ansiColors.exports.magenta;
210
- this.styles.danger = ansiColors.exports.red;
211
- this.symbols.pointer = "!";
212
- }
213
- prefix(_state) {
214
- const color = this.styles.primary.bold;
215
- return this.state.status === "submitted" ? color("\u2714") : color("?");
216
- }
217
- async render() {
218
- const size = this.state.size;
219
- const prefix = await this.prefix();
220
- const separator = await this.separator();
221
- const message = await this.message();
222
- const color = this.styles.primary;
223
- let prompt = [prefix, message].filter(Boolean).join(" ");
224
- this.state.prompt = prompt;
225
- const output = this.type === "password" ? await this.formatPassword() : await this.format();
226
- const help = await this.error() || await this.hint();
227
- const underline = "\u2594".repeat(Math.max(color.unstyle(output).length - 10, 30));
228
- if (this.state.submitted) {
229
- prompt += ` ${separator} ${output}`;
230
- } else {
231
- prompt += `
232
- ${color(">")} ${output}
233
- ${color(underline)}`;
234
- if (help && !prompt.includes(help))
235
- prompt += ` ${help}`;
236
- }
237
- this.clear(size);
238
- this.write([prompt].filter(Boolean).join("\n"));
239
- this.restore();
240
- }
241
- formatPassword() {
242
- if (!this.keypressed)
243
- return "";
244
- const color = this.state.submitted ? this.styles.primary : this.styles.muted;
245
- return color(this.symbols.asterisk.repeat(this.input.length));
246
- }
247
- }
248
-
249
- class Select extends enquirer.Select {
250
- constructor(options) {
251
- const originalResult = options.result;
252
- options.result = (value) => {
253
- const answer = this.focused.value || this.focused.name || value;
254
- if (originalResult) {
255
- return originalResult(answer);
256
- }
257
- return answer;
258
- };
259
- super(options);
260
- this.styles.primary = ansiColors.exports.magenta;
261
- this.styles.em = ansiColors.exports.magenta;
262
- }
263
- pointer(_choice, i) {
264
- const color = this.styles.primary;
265
- const showPointer = !this.state.multiple && this.state.index === i;
266
- return showPointer ? color(">") : " ";
267
- }
268
- prefix(_state) {
269
- const color = this.styles.primary.bold;
270
- return this.state.status === "submitted" ? color("\u2714") : color("?");
271
- }
272
- }
273
-
274
- const prompt = async (questions, debugForceInquirer = false) => {
275
- if (!isTerminalInteractive() && questions.length !== 0) {
276
- throw new Bug(content`
277
- The CLI prompted in a non-interactive terminal with the following questions:
278
- ${token.json(questions)}
279
- `);
280
- }
281
- if (debugForceInquirer || isTruthy(process.env.SHOPIFY_USE_INQUIRER)) {
282
- const results = [];
283
- for (const question of questions) {
284
- if (question.preface) {
285
- info(question.preface);
286
- }
287
- const questionName = question.name;
288
- const answer = (await inquirer.prompt([convertQuestionForInquirer(question)]))[questionName];
289
- results.push([questionName, answer]);
290
- }
291
- return Object.fromEntries(results);
292
- } else {
293
- const mappedQuestions = questions.map(mapper);
294
- const value = {};
295
- for (const question of mappedQuestions) {
296
- if (question.preface) {
297
- info(question.preface);
298
- }
299
- value[question.name] = await question.run();
300
- }
301
- return value;
302
- }
303
- };
304
- async function nonEmptyDirectoryPrompt(directory) {
305
- if (await exists(directory)) {
306
- const options = [
307
- { name: "No, don\u2019t delete the files", value: "abort" },
308
- { name: "Yes, delete the files", value: "overwrite" }
309
- ];
310
- const relativeDirectory = relative(process.cwd(), directory);
311
- const questions = {
312
- type: "select",
313
- name: "value",
314
- message: `${relativeDirectory} is not an empty directory. Do you want to delete the existing files and continue?`,
315
- choices: options
316
- };
317
- const choice = await prompt([questions]);
318
- if (choice.value === "abort") {
319
- throw new AbortSilent();
320
- }
321
- remove$3(directory);
322
- }
323
- }
324
- const keypress = async () => {
325
- process.stdin.setRawMode(true);
326
- return new Promise((resolve) => process.stdin.once("data", () => {
327
- process.stdin.setRawMode(false);
328
- resolve();
329
- }));
330
- };
331
- function convertQuestionForInquirer(question) {
332
- switch (question.type) {
333
- case "input":
334
- case "password":
335
- return question;
336
- case "select":
337
- case "autocomplete":
338
- return {
339
- ...question,
340
- type: "list"
341
- };
342
- }
343
- }
344
- function mapper(question) {
345
- switch (question.type) {
346
- case "input":
347
- case "password":
348
- return new Input(question);
349
- case "select":
350
- return new Select(question);
351
- case "autocomplete":
352
- return new AutoComplete(question);
353
- default:
354
- return void 0;
355
- }
356
- }
357
-
358
- var ui = /*#__PURE__*/Object.freeze({
359
- __proto__: null,
360
- prompt: prompt,
361
- nonEmptyDirectoryPrompt: nonEmptyDirectoryPrompt,
362
- keypress: keypress,
363
- Listr: Listr
364
- });
365
-
366
- const debug$1 = (
367
- typeof process === 'object' &&
368
- process.env &&
369
- process.env.NODE_DEBUG &&
370
- /\bsemver\b/i.test(process.env.NODE_DEBUG)
371
- ) ? (...args) => console.error('SEMVER', ...args)
372
- : () => {};
373
-
374
- var debug_1 = debug$1;
375
-
376
- // Note: this is the semver.org version of the spec that it implements
377
- // Not necessarily the package version of this code.
378
- const SEMVER_SPEC_VERSION = '2.0.0';
379
-
380
- const MAX_LENGTH$2 = 256;
381
- const MAX_SAFE_INTEGER$1 = Number.MAX_SAFE_INTEGER ||
382
- /* istanbul ignore next */ 9007199254740991;
383
-
384
- // Max safe segment length for coercion.
385
- const MAX_SAFE_COMPONENT_LENGTH = 16;
386
-
387
- var constants = {
388
- SEMVER_SPEC_VERSION,
389
- MAX_LENGTH: MAX_LENGTH$2,
390
- MAX_SAFE_INTEGER: MAX_SAFE_INTEGER$1,
391
- MAX_SAFE_COMPONENT_LENGTH,
392
- };
393
-
394
- var re$3 = {exports: {}};
395
-
396
- (function (module, exports) {
397
- const { MAX_SAFE_COMPONENT_LENGTH } = constants;
398
- const debug = debug_1;
399
- exports = module.exports = {};
400
-
401
- // The actual regexps go on exports.re
402
- const re = exports.re = [];
403
- const src = exports.src = [];
404
- const t = exports.t = {};
405
- let R = 0;
406
-
407
- const createToken = (name, value, isGlobal) => {
408
- const index = R++;
409
- debug(name, index, value);
410
- t[name] = index;
411
- src[index] = value;
412
- re[index] = new RegExp(value, isGlobal ? 'g' : undefined);
413
- };
414
-
415
- // The following Regular Expressions can be used for tokenizing,
416
- // validating, and parsing SemVer version strings.
417
-
418
- // ## Numeric Identifier
419
- // A single `0`, or a non-zero digit followed by zero or more digits.
420
-
421
- createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*');
422
- createToken('NUMERICIDENTIFIERLOOSE', '[0-9]+');
423
-
424
- // ## Non-numeric Identifier
425
- // Zero or more digits, followed by a letter or hyphen, and then zero or
426
- // more letters, digits, or hyphens.
427
-
428
- createToken('NONNUMERICIDENTIFIER', '\\d*[a-zA-Z-][a-zA-Z0-9-]*');
429
-
430
- // ## Main Version
431
- // Three dot-separated numeric identifiers.
432
-
433
- createToken('MAINVERSION', `(${src[t.NUMERICIDENTIFIER]})\\.` +
434
- `(${src[t.NUMERICIDENTIFIER]})\\.` +
435
- `(${src[t.NUMERICIDENTIFIER]})`);
436
-
437
- createToken('MAINVERSIONLOOSE', `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
438
- `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
439
- `(${src[t.NUMERICIDENTIFIERLOOSE]})`);
440
-
441
- // ## Pre-release Version Identifier
442
- // A numeric identifier, or a non-numeric identifier.
443
-
444
- createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NUMERICIDENTIFIER]
445
- }|${src[t.NONNUMERICIDENTIFIER]})`);
446
-
447
- createToken('PRERELEASEIDENTIFIERLOOSE', `(?:${src[t.NUMERICIDENTIFIERLOOSE]
448
- }|${src[t.NONNUMERICIDENTIFIER]})`);
449
-
450
- // ## Pre-release Version
451
- // Hyphen, followed by one or more dot-separated pre-release version
452
- // identifiers.
453
-
454
- createToken('PRERELEASE', `(?:-(${src[t.PRERELEASEIDENTIFIER]
455
- }(?:\\.${src[t.PRERELEASEIDENTIFIER]})*))`);
456
-
457
- createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE]
458
- }(?:\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`);
459
-
460
- // ## Build Metadata Identifier
461
- // Any combination of digits, letters, or hyphens.
462
-
463
- createToken('BUILDIDENTIFIER', '[0-9A-Za-z-]+');
464
-
465
- // ## Build Metadata
466
- // Plus sign, followed by one or more period-separated build metadata
467
- // identifiers.
468
-
469
- createToken('BUILD', `(?:\\+(${src[t.BUILDIDENTIFIER]
470
- }(?:\\.${src[t.BUILDIDENTIFIER]})*))`);
471
-
472
- // ## Full Version String
473
- // A main version, followed optionally by a pre-release version and
474
- // build metadata.
475
-
476
- // Note that the only major, minor, patch, and pre-release sections of
477
- // the version string are capturing groups. The build metadata is not a
478
- // capturing group, because it should not ever be used in version
479
- // comparison.
480
-
481
- createToken('FULLPLAIN', `v?${src[t.MAINVERSION]
482
- }${src[t.PRERELEASE]}?${
483
- src[t.BUILD]}?`);
484
-
485
- createToken('FULL', `^${src[t.FULLPLAIN]}$`);
486
-
487
- // like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
488
- // also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
489
- // common in the npm registry.
490
- createToken('LOOSEPLAIN', `[v=\\s]*${src[t.MAINVERSIONLOOSE]
491
- }${src[t.PRERELEASELOOSE]}?${
492
- src[t.BUILD]}?`);
493
-
494
- createToken('LOOSE', `^${src[t.LOOSEPLAIN]}$`);
495
-
496
- createToken('GTLT', '((?:<|>)?=?)');
497
-
498
- // Something like "2.*" or "1.2.x".
499
- // Note that "x.x" is a valid xRange identifer, meaning "any version"
500
- // Only the first item is strictly required.
501
- createToken('XRANGEIDENTIFIERLOOSE', `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`);
502
- createToken('XRANGEIDENTIFIER', `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`);
503
-
504
- createToken('XRANGEPLAIN', `[v=\\s]*(${src[t.XRANGEIDENTIFIER]})` +
505
- `(?:\\.(${src[t.XRANGEIDENTIFIER]})` +
506
- `(?:\\.(${src[t.XRANGEIDENTIFIER]})` +
507
- `(?:${src[t.PRERELEASE]})?${
508
- src[t.BUILD]}?` +
509
- `)?)?`);
510
-
511
- createToken('XRANGEPLAINLOOSE', `[v=\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})` +
512
- `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` +
513
- `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` +
514
- `(?:${src[t.PRERELEASELOOSE]})?${
515
- src[t.BUILD]}?` +
516
- `)?)?`);
517
-
518
- createToken('XRANGE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAIN]}$`);
519
- createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`);
520
-
521
- // Coercion.
522
- // Extract anything that could conceivably be a part of a valid semver
523
- createToken('COERCE', `${'(^|[^\\d])' +
524
- '(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` +
525
- `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` +
526
- `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` +
527
- `(?:$|[^\\d])`);
528
- createToken('COERCERTL', src[t.COERCE], true);
529
-
530
- // Tilde ranges.
531
- // Meaning is "reasonably at or greater than"
532
- createToken('LONETILDE', '(?:~>?)');
533
-
534
- createToken('TILDETRIM', `(\\s*)${src[t.LONETILDE]}\\s+`, true);
535
- exports.tildeTrimReplace = '$1~';
536
-
537
- createToken('TILDE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`);
538
- createToken('TILDELOOSE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`);
539
-
540
- // Caret ranges.
541
- // Meaning is "at least and backwards compatible with"
542
- createToken('LONECARET', '(?:\\^)');
543
-
544
- createToken('CARETTRIM', `(\\s*)${src[t.LONECARET]}\\s+`, true);
545
- exports.caretTrimReplace = '$1^';
546
-
547
- createToken('CARET', `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`);
548
- createToken('CARETLOOSE', `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`);
549
-
550
- // A simple gt/lt/eq thing, or just "" to indicate "any version"
551
- createToken('COMPARATORLOOSE', `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`);
552
- createToken('COMPARATOR', `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`);
553
-
554
- // An expression to strip any whitespace between the gtlt and the thing
555
- // it modifies, so that `> 1.2.3` ==> `>1.2.3`
556
- createToken('COMPARATORTRIM', `(\\s*)${src[t.GTLT]
557
- }\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true);
558
- exports.comparatorTrimReplace = '$1$2$3';
559
-
560
- // Something like `1.2.3 - 1.2.4`
561
- // Note that these all use the loose form, because they'll be
562
- // checked against either the strict or loose comparator form
563
- // later.
564
- createToken('HYPHENRANGE', `^\\s*(${src[t.XRANGEPLAIN]})` +
565
- `\\s+-\\s+` +
566
- `(${src[t.XRANGEPLAIN]})` +
567
- `\\s*$`);
568
-
569
- createToken('HYPHENRANGELOOSE', `^\\s*(${src[t.XRANGEPLAINLOOSE]})` +
570
- `\\s+-\\s+` +
571
- `(${src[t.XRANGEPLAINLOOSE]})` +
572
- `\\s*$`);
573
-
574
- // Star ranges basically just allow anything at all.
575
- createToken('STAR', '(<|>)?=?\\s*\\*');
576
- // >=0.0.0 is like a star
577
- createToken('GTE0', '^\\s*>=\\s*0\\.0\\.0\\s*$');
578
- createToken('GTE0PRE', '^\\s*>=\\s*0\\.0\\.0-0\\s*$');
579
- } (re$3, re$3.exports));
580
-
581
- // parse out just the options we care about so we always get a consistent
582
- // obj with keys in a consistent order.
583
- const opts = ['includePrerelease', 'loose', 'rtl'];
584
- const parseOptions$2 = options =>
585
- !options ? {}
586
- : typeof options !== 'object' ? { loose: true }
587
- : opts.filter(k => options[k]).reduce((o, k) => {
588
- o[k] = true;
589
- return o
590
- }, {});
591
- var parseOptions_1 = parseOptions$2;
592
-
593
- const numeric = /^[0-9]+$/;
594
- const compareIdentifiers$1 = (a, b) => {
595
- const anum = numeric.test(a);
596
- const bnum = numeric.test(b);
597
-
598
- if (anum && bnum) {
599
- a = +a;
600
- b = +b;
601
- }
602
-
603
- return a === b ? 0
604
- : (anum && !bnum) ? -1
605
- : (bnum && !anum) ? 1
606
- : a < b ? -1
607
- : 1
608
- };
609
-
610
- const rcompareIdentifiers = (a, b) => compareIdentifiers$1(b, a);
611
-
612
- var identifiers = {
613
- compareIdentifiers: compareIdentifiers$1,
614
- rcompareIdentifiers,
615
- };
616
-
617
- const debug = debug_1;
618
- const { MAX_LENGTH: MAX_LENGTH$1, MAX_SAFE_INTEGER } = constants;
619
- const { re: re$2, t: t$2 } = re$3.exports;
620
-
621
- const parseOptions$1 = parseOptions_1;
622
- const { compareIdentifiers } = identifiers;
623
- class SemVer$2 {
624
- constructor (version, options) {
625
- options = parseOptions$1(options);
626
-
627
- if (version instanceof SemVer$2) {
628
- if (version.loose === !!options.loose &&
629
- version.includePrerelease === !!options.includePrerelease) {
630
- return version
631
- } else {
632
- version = version.version;
633
- }
634
- } else if (typeof version !== 'string') {
635
- throw new TypeError(`Invalid Version: ${version}`)
636
- }
637
-
638
- if (version.length > MAX_LENGTH$1) {
639
- throw new TypeError(
640
- `version is longer than ${MAX_LENGTH$1} characters`
641
- )
642
- }
643
-
644
- debug('SemVer', version, options);
645
- this.options = options;
646
- this.loose = !!options.loose;
647
- // this isn't actually relevant for versions, but keep it so that we
648
- // don't run into trouble passing this.options around.
649
- this.includePrerelease = !!options.includePrerelease;
650
-
651
- const m = version.trim().match(options.loose ? re$2[t$2.LOOSE] : re$2[t$2.FULL]);
652
-
653
- if (!m) {
654
- throw new TypeError(`Invalid Version: ${version}`)
655
- }
656
-
657
- this.raw = version;
658
-
659
- // these are actually numbers
660
- this.major = +m[1];
661
- this.minor = +m[2];
662
- this.patch = +m[3];
663
-
664
- if (this.major > MAX_SAFE_INTEGER || this.major < 0) {
665
- throw new TypeError('Invalid major version')
666
- }
667
-
668
- if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) {
669
- throw new TypeError('Invalid minor version')
670
- }
671
-
672
- if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) {
673
- throw new TypeError('Invalid patch version')
674
- }
675
-
676
- // numberify any prerelease numeric ids
677
- if (!m[4]) {
678
- this.prerelease = [];
679
- } else {
680
- this.prerelease = m[4].split('.').map((id) => {
681
- if (/^[0-9]+$/.test(id)) {
682
- const num = +id;
683
- if (num >= 0 && num < MAX_SAFE_INTEGER) {
684
- return num
685
- }
686
- }
687
- return id
688
- });
689
- }
690
-
691
- this.build = m[5] ? m[5].split('.') : [];
692
- this.format();
693
- }
694
-
695
- format () {
696
- this.version = `${this.major}.${this.minor}.${this.patch}`;
697
- if (this.prerelease.length) {
698
- this.version += `-${this.prerelease.join('.')}`;
699
- }
700
- return this.version
701
- }
702
-
703
- toString () {
704
- return this.version
705
- }
706
-
707
- compare (other) {
708
- debug('SemVer.compare', this.version, this.options, other);
709
- if (!(other instanceof SemVer$2)) {
710
- if (typeof other === 'string' && other === this.version) {
711
- return 0
712
- }
713
- other = new SemVer$2(other, this.options);
714
- }
715
-
716
- if (other.version === this.version) {
717
- return 0
718
- }
719
-
720
- return this.compareMain(other) || this.comparePre(other)
721
- }
722
-
723
- compareMain (other) {
724
- if (!(other instanceof SemVer$2)) {
725
- other = new SemVer$2(other, this.options);
726
- }
727
-
728
- return (
729
- compareIdentifiers(this.major, other.major) ||
730
- compareIdentifiers(this.minor, other.minor) ||
731
- compareIdentifiers(this.patch, other.patch)
732
- )
733
- }
734
-
735
- comparePre (other) {
736
- if (!(other instanceof SemVer$2)) {
737
- other = new SemVer$2(other, this.options);
738
- }
739
-
740
- // NOT having a prerelease is > having one
741
- if (this.prerelease.length && !other.prerelease.length) {
742
- return -1
743
- } else if (!this.prerelease.length && other.prerelease.length) {
744
- return 1
745
- } else if (!this.prerelease.length && !other.prerelease.length) {
746
- return 0
747
- }
748
-
749
- let i = 0;
750
- do {
751
- const a = this.prerelease[i];
752
- const b = other.prerelease[i];
753
- debug('prerelease compare', i, a, b);
754
- if (a === undefined && b === undefined) {
755
- return 0
756
- } else if (b === undefined) {
757
- return 1
758
- } else if (a === undefined) {
759
- return -1
760
- } else if (a === b) {
761
- continue
762
- } else {
763
- return compareIdentifiers(a, b)
764
- }
765
- } while (++i)
766
- }
767
-
768
- compareBuild (other) {
769
- if (!(other instanceof SemVer$2)) {
770
- other = new SemVer$2(other, this.options);
771
- }
772
-
773
- let i = 0;
774
- do {
775
- const a = this.build[i];
776
- const b = other.build[i];
777
- debug('prerelease compare', i, a, b);
778
- if (a === undefined && b === undefined) {
779
- return 0
780
- } else if (b === undefined) {
781
- return 1
782
- } else if (a === undefined) {
783
- return -1
784
- } else if (a === b) {
785
- continue
786
- } else {
787
- return compareIdentifiers(a, b)
788
- }
789
- } while (++i)
790
- }
791
-
792
- // preminor will bump the version up to the next minor release, and immediately
793
- // down to pre-release. premajor and prepatch work the same way.
794
- inc (release, identifier) {
795
- switch (release) {
796
- case 'premajor':
797
- this.prerelease.length = 0;
798
- this.patch = 0;
799
- this.minor = 0;
800
- this.major++;
801
- this.inc('pre', identifier);
802
- break
803
- case 'preminor':
804
- this.prerelease.length = 0;
805
- this.patch = 0;
806
- this.minor++;
807
- this.inc('pre', identifier);
808
- break
809
- case 'prepatch':
810
- // If this is already a prerelease, it will bump to the next version
811
- // drop any prereleases that might already exist, since they are not
812
- // relevant at this point.
813
- this.prerelease.length = 0;
814
- this.inc('patch', identifier);
815
- this.inc('pre', identifier);
816
- break
817
- // If the input is a non-prerelease version, this acts the same as
818
- // prepatch.
819
- case 'prerelease':
820
- if (this.prerelease.length === 0) {
821
- this.inc('patch', identifier);
822
- }
823
- this.inc('pre', identifier);
824
- break
825
-
826
- case 'major':
827
- // If this is a pre-major version, bump up to the same major version.
828
- // Otherwise increment major.
829
- // 1.0.0-5 bumps to 1.0.0
830
- // 1.1.0 bumps to 2.0.0
831
- if (
832
- this.minor !== 0 ||
833
- this.patch !== 0 ||
834
- this.prerelease.length === 0
835
- ) {
836
- this.major++;
837
- }
838
- this.minor = 0;
839
- this.patch = 0;
840
- this.prerelease = [];
841
- break
842
- case 'minor':
843
- // If this is a pre-minor version, bump up to the same minor version.
844
- // Otherwise increment minor.
845
- // 1.2.0-5 bumps to 1.2.0
846
- // 1.2.1 bumps to 1.3.0
847
- if (this.patch !== 0 || this.prerelease.length === 0) {
848
- this.minor++;
849
- }
850
- this.patch = 0;
851
- this.prerelease = [];
852
- break
853
- case 'patch':
854
- // If this is not a pre-release version, it will increment the patch.
855
- // If it is a pre-release it will bump up to the same patch version.
856
- // 1.2.0-5 patches to 1.2.0
857
- // 1.2.0 patches to 1.2.1
858
- if (this.prerelease.length === 0) {
859
- this.patch++;
860
- }
861
- this.prerelease = [];
862
- break
863
- // This probably shouldn't be used publicly.
864
- // 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction.
865
- case 'pre':
866
- if (this.prerelease.length === 0) {
867
- this.prerelease = [0];
868
- } else {
869
- let i = this.prerelease.length;
870
- while (--i >= 0) {
871
- if (typeof this.prerelease[i] === 'number') {
872
- this.prerelease[i]++;
873
- i = -2;
874
- }
875
- }
876
- if (i === -1) {
877
- // didn't increment anything
878
- this.prerelease.push(0);
879
- }
880
- }
881
- if (identifier) {
882
- // 1.2.0-beta.1 bumps to 1.2.0-beta.2,
883
- // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
884
- if (compareIdentifiers(this.prerelease[0], identifier) === 0) {
885
- if (isNaN(this.prerelease[1])) {
886
- this.prerelease = [identifier, 0];
887
- }
888
- } else {
889
- this.prerelease = [identifier, 0];
890
- }
891
- }
892
- break
893
-
894
- default:
895
- throw new Error(`invalid increment argument: ${release}`)
896
- }
897
- this.format();
898
- this.raw = this.version;
899
- return this
900
- }
901
- }
902
-
903
- var semver$1 = SemVer$2;
904
-
905
- const { MAX_LENGTH } = constants;
906
- const { re: re$1, t: t$1 } = re$3.exports;
907
- const SemVer$1 = semver$1;
908
-
909
- const parseOptions = parseOptions_1;
910
- const parse$1 = (version, options) => {
911
- options = parseOptions(options);
912
-
913
- if (version instanceof SemVer$1) {
914
- return version
915
- }
916
-
917
- if (typeof version !== 'string') {
918
- return null
919
- }
920
-
921
- if (version.length > MAX_LENGTH) {
922
- return null
923
- }
924
-
925
- const r = options.loose ? re$1[t$1.LOOSE] : re$1[t$1.FULL];
926
- if (!r.test(version)) {
927
- return null
928
- }
929
-
930
- try {
931
- return new SemVer$1(version, options)
932
- } catch (er) {
933
- return null
934
- }
935
- };
936
-
937
- var parse_1 = parse$1;
938
-
939
- const SemVer = semver$1;
940
- const parse = parse_1;
941
- const { re, t } = re$3.exports;
942
-
943
- const coerce = (version, options) => {
944
- if (version instanceof SemVer) {
945
- return version
946
- }
947
-
948
- if (typeof version === 'number') {
949
- version = String(version);
950
- }
951
-
952
- if (typeof version !== 'string') {
953
- return null
954
- }
955
-
956
- options = options || {};
957
-
958
- let match = null;
959
- if (!options.rtl) {
960
- match = version.match(re[t.COERCE]);
961
- } else {
962
- // Find the right-most coercible string that does not share
963
- // a terminus with a more left-ward coercible string.
964
- // Eg, '1.2.3.4' wants to coerce '2.3.4', not '3.4' or '4'
965
- //
966
- // Walk through the string checking with a /g regexp
967
- // Manually set the index so as to pick up overlapping matches.
968
- // Stop when we get a match that ends at the string end, since no
969
- // coercible string can be more right-ward without the same terminus.
970
- let next;
971
- while ((next = re[t.COERCERTL].exec(version)) &&
972
- (!match || match.index + match[0].length !== version.length)
973
- ) {
974
- if (!match ||
975
- next.index + next[0].length !== match.index + match[0].length) {
976
- match = next;
977
- }
978
- re[t.COERCERTL].lastIndex = next.index + next[1].length + next[2].length;
979
- }
980
- // leave it in a clean state
981
- re[t.COERCERTL].lastIndex = -1;
982
- }
983
-
984
- if (match === null) {
985
- return null
986
- }
987
-
988
- return parse(`${match[2]}.${match[3] || '0'}.${match[4] || '0'}`, options)
989
- };
990
- var coerce_1 = coerce;
991
-
992
- var semver = /*#__PURE__*/Object.freeze({
993
- __proto__: null,
994
- Version: semver$1,
995
- coerce: coerce_1
996
- });
997
-
998
- const RubyCLIVersion = "2.16.0";
999
- const ThemeCheckVersion = "1.10.2";
1000
- const MinBundlerVersion = "2.3.8";
1001
- const MinRubyVersion = "2.3.0";
1002
- const MinRubyGemVersion = "2.5.0";
1003
- async function execCLI(args, adminSession) {
1004
- await installCLIDependencies();
1005
- const env = {
1006
- ...process.env,
1007
- SHOPIFY_CLI_ADMIN_AUTH_TOKEN: adminSession?.token,
1008
- SHOPIFY_CLI_STORE: adminSession?.storeFqdn
1009
- };
1010
- spawn("bundle", ["exec", "shopify"].concat(args), {
1011
- stdio: "inherit",
1012
- cwd: shopifyCLIDirectory(),
1013
- shell: true,
1014
- env
1015
- });
1016
- }
1017
- async function execThemeCheckCLI({
1018
- directories,
1019
- args,
1020
- stdout,
1021
- stderr
1022
- }) {
1023
- await installThemeCheckCLIDependencies(stdout);
1024
- const processes = directories.map(async (directory) => {
1025
- const files = await glob(join(directory, "/**/*"));
1026
- const fileCount = files.filter((file2) => !file2.match(/\.toml$/)).length;
1027
- if (fileCount === 0)
1028
- return;
1029
- const customStderr = new Writable({
1030
- write(chunk, ...args2) {
1031
- if (chunk.toString("ascii").match(/^Checking/)) {
1032
- stdout.write(chunk, ...args2);
1033
- } else {
1034
- stderr.write(chunk, ...args2);
1035
- }
1036
- }
1037
- });
1038
- await exec("bundle", ["exec", "theme-check"].concat([directory, ...args || []]), {
1039
- stdout,
1040
- stderr: customStderr,
1041
- cwd: themeCheckDirectory()
1042
- });
1043
- });
1044
- return Promise.all(processes);
1045
- }
1046
- async function installThemeCheckCLIDependencies(stdout) {
1047
- const exists$1 = await exists(themeCheckDirectory());
1048
- if (!exists$1)
1049
- stdout.write("Installing theme dependencies...");
1050
- const list = new Listr([
1051
- {
1052
- title: "Installing theme dependencies",
1053
- task: async () => {
1054
- await validateRubyEnv();
1055
- await createThemeCheckCLIWorkingDirectory();
1056
- await createThemeCheckGemfile();
1057
- await bundleInstallThemeCheck();
1058
- }
1059
- }
1060
- ], { renderer: "silent" });
1061
- await list.run();
1062
- if (!exists$1)
1063
- stdout.write("Installed theme dependencies!");
1064
- }
1065
- async function installCLIDependencies() {
1066
- const exists$1 = await exists(shopifyCLIDirectory());
1067
- const renderer = exists$1 ? "silent" : "default";
1068
- const list = new Listr([
1069
- {
1070
- title: "Installing theme dependencies",
1071
- task: async () => {
1072
- await validateRubyEnv();
1073
- await createShopifyCLIWorkingDirectory();
1074
- await createShopifyCLIGemfile();
1075
- await bundleInstallShopifyCLI();
1076
- }
1077
- }
1078
- ], { renderer });
1079
- await list.run();
1080
- }
1081
- async function validateRubyEnv() {
1082
- await validateRuby();
1083
- await validateRubyGems();
1084
- await validateBundler();
1085
- }
1086
- async function validateRuby() {
1087
- let version2;
1088
- try {
1089
- const stdout = await captureOutput("ruby", ["-v"]);
1090
- version2 = coerce_1(stdout);
1091
- } catch {
1092
- throw new Abort("Ruby environment not found", `Make sure you have Ruby installed on your system: ${content`${token.link("", "https://www.ruby-lang.org/en/documentation/installation/")}`.value}`);
1093
- }
1094
- const isValid = version2?.compare(MinRubyVersion);
1095
- if (isValid === -1 || isValid === void 0) {
1096
- throw new Abort(`Ruby version ${content`${token.yellow(version2.raw)}`.value} is not supported`, `Make sure you have at least Ruby ${content`${token.yellow(MinRubyVersion)}`.value} installed on your system: ${content`${token.link("", "https://www.ruby-lang.org/en/documentation/installation/")}`.value}`);
1097
- }
1098
- }
1099
- async function validateRubyGems() {
1100
- const stdout = await captureOutput("gem", ["-v"]);
1101
- const version2 = coerce_1(stdout);
1102
- const isValid = version2?.compare(MinRubyGemVersion);
1103
- if (isValid === -1 || isValid === void 0) {
1104
- throw new Abort(`RubyGems version ${content`${token.yellow(version2.raw)}`.value} is not supported`, `To update to the latest version of RubyGems, run ${content`${token.genericShellCommand("gem update --system")}`.value}`);
1105
- }
1106
- }
1107
- async function validateBundler() {
1108
- let version2;
1109
- try {
1110
- const stdout = await captureOutput("bundler", ["-v"]);
1111
- version2 = coerce_1(stdout);
1112
- } catch {
1113
- throw new Abort("Bundler not found", `To install the latest version of Bundler, run ${content`${token.genericShellCommand("gem install bundler")}`.value}`);
1114
- }
1115
- const isValid = version2?.compare(MinBundlerVersion);
1116
- if (isValid === -1 || isValid === void 0) {
1117
- throw new Abort(`Bundler version ${content`${token.yellow(version2.raw)}`.value} is not supported`, `To update to the latest version of Bundler, run ${content`${token.genericShellCommand("gem install bundler")}`.value}`);
1118
- }
1119
- }
1120
- function createShopifyCLIWorkingDirectory() {
1121
- return mkdir(shopifyCLIDirectory());
1122
- }
1123
- function createThemeCheckCLIWorkingDirectory() {
1124
- return mkdir(themeCheckDirectory());
1125
- }
1126
- async function createShopifyCLIGemfile() {
1127
- const gemPath = join(shopifyCLIDirectory(), "Gemfile");
1128
- await write$1(gemPath, `source 'https://rubygems.org'
1129
- gem 'shopify-cli', '${RubyCLIVersion}'`);
1130
- }
1131
- async function createThemeCheckGemfile() {
1132
- const gemPath = join(themeCheckDirectory(), "Gemfile");
1133
- await write$1(gemPath, `source 'https://rubygems.org'
1134
- gem 'theme-check', '${ThemeCheckVersion}'`);
1135
- }
1136
- async function bundleInstallShopifyCLI() {
1137
- await exec("bundle", ["config", "set", "--local", "path", shopifyCLIDirectory()], { cwd: shopifyCLIDirectory() });
1138
- await exec("bundle", ["install"], { cwd: shopifyCLIDirectory() });
1139
- }
1140
- async function bundleInstallThemeCheck() {
1141
- await exec("bundle", ["config", "set", "--local", "path", themeCheckDirectory()], { cwd: themeCheckDirectory() });
1142
- await exec("bundle", ["install"], { cwd: themeCheckDirectory() });
1143
- }
1144
- function shopifyCLIDirectory() {
1145
- return join(constants$1.paths.directories.cache.vendor.path(), "ruby-cli", RubyCLIVersion);
1146
- }
1147
- function themeCheckDirectory() {
1148
- return join(constants$1.paths.directories.cache.vendor.path(), "theme-check", ThemeCheckVersion);
1149
- }
1150
- async function version$1() {
1151
- const parseOutput = (version2) => version2.match(/ruby (\d+\.\d+\.\d+)/)?.[1];
1152
- return captureOutput("ruby", ["-v"]).then(parseOutput).catch(() => void 0);
1153
- }
1154
-
1155
- var ruby = /*#__PURE__*/Object.freeze({
1156
- __proto__: null,
1157
- execCLI: execCLI,
1158
- execThemeCheckCLI: execThemeCheckCLI,
1159
- version: version$1
1160
- });
1161
-
1162
- const migrations = {};
1163
- const schema$1 = {
1164
- appInfo: {
1165
- type: "array",
1166
- items: {
1167
- type: "object",
1168
- properties: {
1169
- appId: {
1170
- type: "string"
1171
- },
1172
- orgId: {
1173
- type: "string"
1174
- },
1175
- storeFqdn: {
1176
- type: "string"
1177
- }
1178
- }
1179
- }
1180
- }
1181
- };
1182
- function createConf(projectName = "shopify-cli-kit") {
1183
- return new Conf({
1184
- schema: schema$1,
1185
- migrations,
1186
- projectName,
1187
- projectVersion: cliKitPackageJson.version
1188
- });
1189
- }
1190
- const cliKit = createConf();
1191
- function remove$2() {
1192
- cliKit.clear();
1193
- }
1194
- function getAppInfo(directory, localConf = cliKit) {
1195
- debug$2(content`Reading cached app information for directory ${token.path(directory)}...`);
1196
- const apps = localConf.get("appInfo") ?? [];
1197
- return apps.find((app) => app.directory === directory);
1198
- }
1199
- function setAppInfo(options, localConf = cliKit) {
1200
- debug$2(content`Storing app information for directory ${token.path(options.directory)}:
1201
- ${token.json(options)}
1202
- `);
1203
- const apps = localConf.get("appInfo") ?? [];
1204
- const index = apps.findIndex((saved) => saved.directory === options.directory);
1205
- if (index === -1) {
1206
- apps.push(options);
1207
- } else {
1208
- const app = apps[index];
1209
- apps[index] = {
1210
- appId: options.appId,
1211
- directory: options.directory,
1212
- title: options.title ?? app.title,
1213
- storeFqdn: options.storeFqdn ?? app.storeFqdn,
1214
- orgId: options.orgId ?? app.orgId
1215
- };
1216
- }
1217
- localConf.set("appInfo", apps);
1218
- }
1219
- function clearAppInfo(directory, localConf = cliKit) {
1220
- debug$2(content`Clearing app information for directory ${token.path(directory)}...`);
1221
- const apps = localConf.get("appInfo") ?? [];
1222
- const index = apps.findIndex((saved) => saved.directory === directory);
1223
- if (index !== -1) {
1224
- apps.splice(index, 1);
1225
- }
1226
- localConf.set("appInfo", apps);
1227
- }
1228
- function getTheme(localConf = cliKit) {
1229
- debug$2(content`Getting theme store...`);
1230
- return localConf.get("themeStore");
1231
- }
1232
- function setTheme(store, localConf = cliKit) {
1233
- debug$2(content`Setting theme store...`);
1234
- localConf.set("themeStore", store);
1235
- }
1236
- function getSession(localConf = cliKit) {
1237
- debug$2(content`Getting session store...`);
1238
- return localConf.get("sessionStore");
1239
- }
1240
- function setSession(store, localConf = cliKit) {
1241
- debug$2(content`Setting session store...`);
1242
- localConf.set("sessionStore", store);
1243
- }
1244
- function removeSession(localConf = cliKit) {
1245
- debug$2(content`Removing session store...`);
1246
- localConf.set("sessionStore", "");
1247
- }
1248
-
1249
- var store$2 = /*#__PURE__*/Object.freeze({
1250
- __proto__: null,
1251
- createConf: createConf,
1252
- remove: remove$2,
1253
- getAppInfo: getAppInfo,
1254
- setAppInfo: setAppInfo,
1255
- clearAppInfo: clearAppInfo,
1256
- getTheme: getTheme,
1257
- setTheme: setTheme,
1258
- getSession: getSession,
1259
- setSession: setSession,
1260
- removeSession: removeSession
1261
- });
1262
-
1263
- async function latestNpmPackageVersion(name) {
1264
- debug$2(content`Getting the latest version of NPM package: ${token.raw(name)}`);
1265
- return latestVersion(name);
1266
- }
1267
- function cliVersion() {
1268
- return version$2;
1269
- }
1270
-
1271
- var version = /*#__PURE__*/Object.freeze({
1272
- __proto__: null,
1273
- latestNpmPackageVersion: latestNpmPackageVersion,
1274
- cliVersion: cliVersion
1275
- });
1276
-
1277
- const genericConfigurationFileNames = {
1278
- yarn: {
1279
- lockfile: "yarn.lock"
1280
- },
1281
- pnpm: {
1282
- lockfile: "pnpm-lock.yaml"
1283
- }
1284
- };
1285
- const dependencyManager = ["yarn", "npm", "pnpm"];
1286
- const PackageJsonNotFoundError = (directory) => {
1287
- return new Abort(`The directory ${directory} doesn't have a package.json.`);
1288
- };
1289
- function dependencyManagerUsedForCreating(env = process.env) {
1290
- if (env.npm_config_user_agent?.includes("yarn")) {
1291
- return "yarn";
1292
- } else if (env.npm_config_user_agent?.includes("pnpm")) {
1293
- return "pnpm";
1294
- } else {
1295
- return "npm";
1296
- }
1297
- }
1298
- async function getDependencyManager(directory) {
1299
- debug$2(content`Obtaining the dependency manager in directory ${token.path(directory)}...`);
1300
- const yarnLockPath = join(directory, genericConfigurationFileNames.yarn.lockfile);
1301
- const pnpmLockPath = join(directory, genericConfigurationFileNames.pnpm.lockfile);
1302
- if (await exists(yarnLockPath)) {
1303
- return "yarn";
1304
- } else if (await exists(pnpmLockPath)) {
1305
- return "pnpm";
1306
- } else {
1307
- return "npm";
1308
- }
1309
- }
1310
- async function installNPMDependenciesRecursively(options) {
1311
- const packageJsons = await glob(join(options.directory, "**/package.json"), {
1312
- ignore: [join(options.directory, "node_modules/**/package.json")],
1313
- cwd: options.directory,
1314
- onlyFiles: true,
1315
- deep: options.deep
1316
- });
1317
- const abortController = new AbortController();
1318
- try {
1319
- await Promise.all(packageJsons.map(async (packageJsonPath) => {
1320
- const directory = dirname(packageJsonPath);
1321
- await install(directory, options.dependencyManager, void 0, void 0, abortController.signal);
1322
- }));
1323
- } catch (error) {
1324
- abortController.abort();
1325
- throw error;
1326
- }
1327
- }
1328
- async function install(directory, dependencyManager2, stdout, stderr, signal) {
1329
- const options = { cwd: directory, stdout, stderr, signal };
1330
- await exec(dependencyManager2, ["install"], options);
1331
- }
1332
- async function getPackageName(packageJsonPath) {
1333
- const packageJsonContent = await packageJSONContents(packageJsonPath);
1334
- return packageJsonContent.name;
1335
- }
1336
- async function getDependencies(packageJsonPath) {
1337
- const packageJsonContent = await packageJSONContents(packageJsonPath);
1338
- const dependencies = packageJsonContent.dependencies ?? {};
1339
- const devDependencies = packageJsonContent.devDependencies ?? {};
1340
- return { ...dependencies, ...devDependencies };
1341
- }
1342
- async function checkForNewVersion(dependency, currentVersion) {
1343
- debug$2(content`Checking if there's a version of ${dependency} newer than ${currentVersion}`);
1344
- try {
1345
- const lastVersion = await latestNpmPackageVersion(dependency);
1346
- if (lastVersion && new semver$1(currentVersion).compare(lastVersion) < 0) {
1347
- return lastVersion;
1348
- } else {
1349
- return void 0;
1350
- }
1351
- } catch (error) {
1352
- return void 0;
1353
- }
1354
- }
1355
- function getOutputUpdateCLIReminder(dependencyManager2, version) {
1356
- const updateCommand = token.packagejsonScript(dependencyManager2, "shopify", "upgrade");
1357
- return content`💡 Version ${version} available! Run ${updateCommand}`.value;
1358
- }
1359
- async function packageJSONContents(packageJsonPath) {
1360
- if (!await exists(packageJsonPath)) {
1361
- throw PackageJsonNotFoundError(dirname(packageJsonPath));
1362
- }
1363
- return JSON.parse(await read$1(packageJsonPath));
1364
- }
1365
- async function addNPMDependenciesIfNeeded(dependencies, options, force = false) {
1366
- debug$2(content`Adding the following dependencies if needed:
1367
- ${token.json(dependencies)}
1368
- With options:
1369
- ${token.json(options)}
1370
- `);
1371
- const packageJsonPath = join(options.directory, "package.json");
1372
- if (!await exists(packageJsonPath)) {
1373
- throw PackageJsonNotFoundError(options.directory);
1374
- }
1375
- const existingDependencies = Object.keys(await getDependencies(packageJsonPath));
1376
- let dependenciesToAdd = dependencies;
1377
- if (!force) {
1378
- dependenciesToAdd = dependencies.filter((dep) => {
1379
- return !existingDependencies.includes(dep.name);
1380
- });
1381
- }
1382
- if (dependenciesToAdd.length === 0) {
1383
- return;
1384
- }
1385
- let args;
1386
- const depedenciesWithVersion = dependenciesToAdd.map((dep) => {
1387
- return dep.version ? `${dep.name}@${dep.version}` : dep.name;
1388
- });
1389
- switch (options.dependencyManager) {
1390
- case "npm":
1391
- args = argumentsToAddDependenciesWithNPM(depedenciesWithVersion, options.type);
1392
- break;
1393
- case "yarn":
1394
- args = argumentsToAddDependenciesWithYarn(depedenciesWithVersion, options.type);
1395
- break;
1396
- case "pnpm":
1397
- args = argumentsToAddDependenciesWithPNPM(depedenciesWithVersion, options.type);
1398
- break;
1399
- }
1400
- options.stdout?.write(`Executing...${args.join(" ")}`);
1401
- await exec(options.dependencyManager, args, {
1402
- cwd: options.directory,
1403
- stdout: options.stdout,
1404
- stderr: options.stderr,
1405
- signal: options.signal
1406
- });
1407
- }
1408
- async function addNPMDependenciesWithoutVersionIfNeeded(dependencies, options) {
1409
- await addNPMDependenciesIfNeeded(dependencies.map((dependency) => {
1410
- return { name: dependency, version: void 0 };
1411
- }), options);
1412
- }
1413
- async function addLatestNPMDependencies(dependencies, options) {
1414
- await addNPMDependenciesIfNeeded(dependencies.map((dependency) => {
1415
- return { name: dependency, version: "latest" };
1416
- }), options, true);
1417
- }
1418
- function argumentsToAddDependenciesWithNPM(dependencies, type) {
1419
- let command = ["install"];
1420
- command = command.concat(dependencies);
1421
- switch (type) {
1422
- case "dev":
1423
- command.push("--save-dev");
1424
- break;
1425
- case "peer":
1426
- command.push("--save-peer");
1427
- break;
1428
- case "prod":
1429
- command.push("--save-prod");
1430
- break;
1431
- }
1432
- return command;
1433
- }
1434
- function argumentsToAddDependenciesWithYarn(dependencies, type) {
1435
- let command = ["add"];
1436
- command = command.concat(dependencies);
1437
- switch (type) {
1438
- case "dev":
1439
- command.push("--dev");
1440
- break;
1441
- case "peer":
1442
- command.push("--peer");
1443
- break;
1444
- case "prod":
1445
- command.push("--prod");
1446
- break;
1447
- }
1448
- return command;
1449
- }
1450
- function argumentsToAddDependenciesWithPNPM(dependencies, type) {
1451
- let command = ["add"];
1452
- command = command.concat(dependencies);
1453
- switch (type) {
1454
- case "dev":
1455
- command.push("--save-dev");
1456
- break;
1457
- case "peer":
1458
- command.push("--save-peer");
1459
- break;
1460
- case "prod":
1461
- command.push("--save-prod");
1462
- break;
1463
- }
1464
- return command;
1465
- }
1466
- async function getProjectType(directory) {
1467
- const nodeConfigFile = join(directory, "package.json");
1468
- const rubyConfigFile = join(directory, "Gemfile");
1469
- const phpConfigFile = join(directory, "composer.json");
1470
- if (await exists(nodeConfigFile)) {
1471
- return "node";
1472
- } else if (await exists(rubyConfigFile)) {
1473
- return "ruby";
1474
- } else if (await exists(phpConfigFile)) {
1475
- return "php";
1476
- }
1477
- return void 0;
1478
- }
1479
-
1480
- var dependency = /*#__PURE__*/Object.freeze({
1481
- __proto__: null,
1482
- genericConfigurationFileNames: genericConfigurationFileNames,
1483
- dependencyManager: dependencyManager,
1484
- PackageJsonNotFoundError: PackageJsonNotFoundError,
1485
- dependencyManagerUsedForCreating: dependencyManagerUsedForCreating,
1486
- getDependencyManager: getDependencyManager,
1487
- installNPMDependenciesRecursively: installNPMDependenciesRecursively,
1488
- install: install,
1489
- getPackageName: getPackageName,
1490
- getDependencies: getDependencies,
1491
- checkForNewVersion: checkForNewVersion,
1492
- getOutputUpdateCLIReminder: getOutputUpdateCLIReminder,
1493
- packageJSONContents: packageJSONContents,
1494
- addNPMDependenciesIfNeeded: addNPMDependenciesIfNeeded,
1495
- addNPMDependenciesWithoutVersionIfNeeded: addNPMDependenciesWithoutVersionIfNeeded,
1496
- addLatestNPMDependencies: addLatestNPMDependencies,
1497
- getProjectType: getProjectType
1498
- });
1499
-
1500
- const url = "https://monorail-edge.shopifysvc.com/v1/produce";
1501
- const reportEvent = async (command, args) => {
1502
- if (isDebug() || analyticsDisabled()) {
1503
- return;
1504
- }
1505
- try {
1506
- const currentTime = new Date().getTime();
1507
- const payload = await buildPayload(command, args, currentTime);
1508
- const body = JSON.stringify(payload);
1509
- const headers = buildHeaders$1(currentTime);
1510
- const response = await fetch$2(url, { method: "POST", body, headers });
1511
- if (response.status === 200) {
1512
- debug$2(content`Analytics event sent: ${token.json(payload)}`);
1513
- } else {
1514
- debug$2(`Failed to report usage analytics: ${response.statusText}`);
1515
- }
1516
- } catch (error) {
1517
- let message = "Failed to report usage analytics";
1518
- if (error instanceof Error) {
1519
- message = message.concat(`: ${error.message}`);
1520
- }
1521
- debug$2(message);
1522
- }
1523
- };
1524
- const buildHeaders$1 = (currentTime) => {
1525
- return {
1526
- "Content-Type": "application/json; charset=utf-8",
1527
- "X-Monorail-Edge-Event-Created-At-Ms": currentTime.toString(),
1528
- "X-Monorail-Edge-Event-Sent-At-Ms": currentTime.toString()
1529
- };
1530
- };
1531
- const buildPayload = async (command, args = [], currentTime) => {
1532
- let directory = process.cwd();
1533
- const pathFlagIndex = args.indexOf("--path");
1534
- if (pathFlagIndex >= 0) {
1535
- directory = resolve(args[pathFlagIndex + 1]);
1536
- }
1537
- const appInfo = getAppInfo(directory);
1538
- const { platform, arch } = platformAndArch();
1539
- const rawPartnerId = appInfo?.orgId;
1540
- let partnerIdAsInt;
1541
- if (rawPartnerId !== void 0) {
1542
- partnerIdAsInt = parseInt(rawPartnerId, 10);
1543
- if (isNaN(partnerIdAsInt)) {
1544
- partnerIdAsInt = void 0;
1545
- }
1546
- }
1547
- return {
1548
- schema_id: "app_cli3_command/1.0",
1549
- payload: {
1550
- project_type: await getProjectType(join(directory, "web")),
1551
- command,
1552
- args: args.join(" "),
1553
- time_start: currentTime,
1554
- time_end: currentTime,
1555
- total_time: 0,
1556
- success: true,
1557
- uname: `${platform} ${arch}`,
1558
- cli_version: cliVersion(),
1559
- ruby_version: await version$1() || "",
1560
- node_version: process.version.replace("v", ""),
1561
- is_employee: await isShopify(),
1562
- api_key: appInfo?.appId,
1563
- partner_id: partnerIdAsInt
1564
- }
1565
- };
1566
- };
1567
-
1568
- var analytics = /*#__PURE__*/Object.freeze({
1569
- __proto__: null,
1570
- url: url,
1571
- reportEvent: reportEvent
1572
- });
1573
-
1574
- async function buildHeaders(token) {
1575
- const userAgent = `Shopify CLI; v=${constants$1.versions.cliKit}`;
1576
- await isShopify();
1577
- const headers = {
1578
- "User-Agent": userAgent,
1579
- "Sec-CH-UA-PLATFORM": process.platform,
1580
- "X-Request-Id": randomUUID(),
1581
- authorization: `Bearer ${token}`,
1582
- "X-Shopify-Access-Token": `Bearer ${token}`,
1583
- "Content-Type": "application/json"
1584
- };
1585
- return headers;
1586
- }
1587
- function sanitizedHeadersOutput(headers) {
1588
- const sanitized = {};
1589
- const keywords = ["token", "authorization"];
1590
- Object.keys(headers).forEach((header) => {
1591
- if (keywords.find((keyword) => header.toLocaleLowerCase().includes(keyword)) === void 0) {
1592
- sanitized[header] = headers[header];
1593
- }
1594
- });
1595
- return Object.keys(sanitized).map((header) => {
1596
- return ` - ${header}: ${sanitized[header]}`;
1597
- }).join("\n");
1598
- }
1599
-
1600
- const UnauthorizedAccessError = (store) => {
1601
- const adminLink = token.link(`URL`, `https://${store}/admin`);
1602
- const storeName = store.replace(".myshopify.com", "");
1603
- return new Abort(content`Looks like you need access to this dev store (${token.link(storeName, `https://${store}`)})`, content`• Log in to the store directly from this ${adminLink}. If you're the store owner, then that direct log in should solve your access issue.
1604
- • If you're not the owner, create a dev store staff account for yourself. Then log in directly from the link above.
1605
- `);
1606
- };
1607
- const UnknownError = () => {
1608
- return new Bug(`Unknown error connecting to your store`);
1609
- };
1610
- async function request$1(query, session, variables) {
1611
- const version = await fetchApiVersion(session);
1612
- const url = adminUrl(session.storeFqdn, version);
1613
- const headers = await buildHeaders(session.token);
1614
- debug$2(`
1615
- Sending Admin GraphQL request:
1616
- ${query}
1617
-
1618
- With variables:
1619
- ${variables ? JSON.stringify(variables, null, 2) : ""}
1620
-
1621
- And headers:
1622
- ${sanitizedHeadersOutput(headers)}
1623
- `);
1624
- try {
1625
- const response = await request$2(url, query, variables, headers);
1626
- return response;
1627
- } catch (error) {
1628
- if (error instanceof ClientError) {
1629
- const errorMessage = content`
1630
- The Admin GraphQL API responded unsuccessfully with the HTTP status ${`${error.response.status}`} and errors:
1631
-
1632
- ${token.json(error.response.errors)}
1633
- `;
1634
- const abortError = new Abort(errorMessage.value);
1635
- abortError.stack = error.stack;
1636
- throw abortError;
1637
- } else {
1638
- throw error;
1639
- }
1640
- }
1641
- }
1642
- async function fetchApiVersion(session) {
1643
- const url = adminUrl(session.storeFqdn, "unstable");
1644
- const query = apiVersionQuery();
1645
- const headers = await buildHeaders(session.token);
1646
- debug$2(`
1647
- Sending Admin GraphQL request to URL ${url} with query:
1648
- ${query}
1649
- `);
1650
- const data = await request$2(url, query, {}, headers).catch((err) => {
1651
- throw err.response.status === 403 ? UnauthorizedAccessError(session.storeFqdn) : UnknownError();
1652
- });
1653
- return data.publicApiVersions.filter((item) => item.supported).map((item) => item.handle).sort().reverse()[0];
1654
- }
1655
- function adminUrl(store, version) {
1656
- const realVersion = version || "unstable";
1657
- return `https://${store}/admin/api/${realVersion}/graphql.json`;
1658
- }
1659
- function apiVersionQuery() {
1660
- return gql`
1661
- query {
1662
- publicApiVersions {
1663
- handle
1664
- supported
1665
- }
1666
- }
1667
- `;
1668
- }
1669
-
1670
- var admin = /*#__PURE__*/Object.freeze({
1671
- __proto__: null,
1672
- request: request$1
1673
- });
1674
-
1675
- const FindOrganizationQuery = gql`
1676
- query FindOrganization($id: ID!) {
1677
- organizations(id: $id, first: 1) {
1678
- nodes {
1679
- id
1680
- businessName
1681
- website
1682
- appsNext
1683
- apps(first: 100) {
1684
- nodes {
1685
- id
1686
- title
1687
- apiKey
1688
- organizationId
1689
- apiSecretKeys {
1690
- secret
1691
- }
1692
- appType
1693
- }
1694
- }
1695
- }
1696
- }
1697
- }
1698
- `;
1699
-
1700
- const AllOrganizationsQuery = gql`
1701
- {
1702
- organizations(first: 200) {
1703
- nodes {
1704
- id
1705
- businessName
1706
- website
1707
- appsNext
1708
- }
1709
- }
1710
- }
1711
- `;
1712
-
1713
- const CreateAppQuery = gql`
1714
- mutation AppCreate($org: Int!, $title: String!, $appUrl: Url!, $redir: [Url]!, $type: AppType) {
1715
- appCreate(
1716
- input: {
1717
- organizationID: $org
1718
- title: $title
1719
- applicationUrl: $appUrl
1720
- redirectUrlWhitelist: $redir
1721
- appType: $type
1722
- }
1723
- ) {
1724
- app {
1725
- id
1726
- apiKey
1727
- title
1728
- appType
1729
- applicationUrl
1730
- redirectUrlWhitelist
1731
- apiSecretKeys {
1732
- secret
1733
- }
1734
- appType
1735
- }
1736
- userErrors {
1737
- field
1738
- message
1739
- }
1740
- }
1741
- }
1742
- `;
1743
-
1744
- const UpdateURLsQuery = gql`
1745
- mutation appUpdate($apiKey: String!, $appUrl: Url!, $redir: [Url]!) {
1746
- appUpdate(input: {apiKey: $apiKey, applicationUrl: $appUrl, redirectUrlWhitelist: $redir}) {
1747
- userErrors {
1748
- message
1749
- field
1750
- }
1751
- }
1752
- }
1753
- `;
1754
-
1755
- const FindAppQuery = gql`
1756
- query FindApp($apiKey: String!) {
1757
- app(apiKey: $apiKey) {
1758
- id
1759
- title
1760
- apiKey
1761
- organizationId
1762
- apiSecretKeys {
1763
- secret
1764
- }
1765
- appType
1766
- }
1767
- }
1768
- `;
1769
-
1770
- const ExtensionUpdateDraftMutation = gql`
1771
- mutation ExtensionUpdateDraft($apiKey: String!, $registrationId: ID!, $config: JSON!, $context: String) {
1772
- extensionUpdateDraft(
1773
- input: {apiKey: $apiKey, registrationId: $registrationId, config: $config, context: $context}
1774
- ) {
1775
- extensionVersion {
1776
- registrationId
1777
- context
1778
- lastUserInteractionAt
1779
- location
1780
- validationErrors {
1781
- field
1782
- message
1783
- }
1784
- }
1785
- userErrors {
1786
- field
1787
- message
1788
- }
1789
- }
1790
- }
1791
- `;
1792
-
1793
- const GenerateSignedUploadUrl = gql`
1794
- mutation GenerateSignedUploadUrl($apiKey: String!, $deploymentUuid: String!, $bundleFormat: Int!) {
1795
- deploymentGenerateSignedUploadUrl(
1796
- input: {apiKey: $apiKey, deploymentUuid: $deploymentUuid, bundleFormat: $bundleFormat}
1797
- ) {
1798
- signedUploadUrl
1799
- userErrors {
1800
- field
1801
- message
1802
- }
1803
- }
1804
- }
1805
- `;
1806
-
1807
- const CreateDeployment = gql`
1808
- mutation CreateDeployment($apiKey: String!, $uuid: String!, $bundleUrl: String!, $extensions: [ExtensionSettings!]!) {
1809
- deploymentCreate(input: {apiKey: $apiKey, uuid: $uuid, bundleUrl: $bundleUrl, extensions: $extensions}) {
1810
- deployment {
1811
- uuid
1812
- }
1813
- userErrors {
1814
- message
1815
- field
1816
- }
1817
- }
1818
- }
1819
- `;
1820
-
1821
- const AllStoresByOrganizationQuery = gql`
1822
- query FindOrganization($id: ID!) {
1823
- organizations(id: $id, first: 1) {
1824
- nodes {
1825
- id
1826
- stores(first: 500, archived: false) {
1827
- nodes {
1828
- shopId
1829
- link
1830
- shopDomain
1831
- shopName
1832
- transferDisabled
1833
- convertableToPartnerTest
1834
- }
1835
- }
1836
- }
1837
- }
1838
- }
1839
- `;
1840
-
1841
- const ConvertDevToTestStoreQuery = gql`
1842
- mutation convertDevToTestStore($input: ConvertDevToTestStoreInput!) {
1843
- convertDevToTestStore(input: $input) {
1844
- convertedToTestStore
1845
- userErrors {
1846
- message
1847
- field
1848
- }
1849
- }
1850
- }
1851
- `;
1852
-
1853
- const ExtensionCreateQuery = gql`
1854
- mutation ExtensionCreate($apiKey: String!, $type: ExtensionType!, $title: String!, $config: JSON!, $context: String) {
1855
- extensionCreate(input: {apiKey: $apiKey, type: $type, title: $title, config: $config, context: $context}) {
1856
- extensionRegistration {
1857
- id
1858
- uuid
1859
- type
1860
- title
1861
- draftVersion {
1862
- registrationId
1863
- lastUserInteractionAt
1864
- validationErrors {
1865
- field
1866
- message
1867
- }
1868
- }
1869
- }
1870
- userErrors {
1871
- field
1872
- message
1873
- }
1874
- }
1875
- }
1876
- `;
1877
-
1878
- const ExtensionSpecificationsQuery = gql`
1879
- query fetchSpecifications($api_key: String!) {
1880
- extensionSpecifications(apiKey: $api_key) {
1881
- name
1882
- identifier
1883
- options {
1884
- managementExperience
1885
- }
1886
- features {
1887
- argo {
1888
- surface
1889
- }
1890
- }
1891
- }
1892
- }
1893
- `;
1894
-
1895
- const AllAppExtensionRegistrationsQuery = gql`
1896
- query allAppExtensionRegistrations($apiKey: String!) {
1897
- app(apiKey: $apiKey) {
1898
- extensionRegistrations {
1899
- id
1900
- uuid
1901
- title
1902
- type
1903
- }
1904
- }
1905
- }
1906
- `;
1907
-
1908
- const FindProductVariantQuery = gql`
1909
- query {
1910
- products(first: 1) {
1911
- edges {
1912
- node {
1913
- id
1914
- variants(first: 1) {
1915
- edges {
1916
- node {
1917
- id
1918
- }
1919
- }
1920
- }
1921
- }
1922
- }
1923
- }
1924
- }
1925
- `;
1926
-
1927
- const ScriptServiceProxyQuery = gql`
1928
- query ProxyRequest($api_key: String, $query: String!, $variables: String) {
1929
- scriptServiceProxy(apiKey: $api_key, query: $query, variables: $variables)
1930
- }
1931
- `;
1932
-
1933
- const GetAppFunctionsQuery = gql`
1934
- query GetAppScripts($appKey: String!, $extensionPointName: ExtensionPointName!) {
1935
- appScripts(appKeys: [$appKey], extensionPointName: $extensionPointName) {
1936
- uuid
1937
- title
1938
- }
1939
- }
1940
- `;
1941
-
1942
- const ModuleUploadUrlGenerateMutation = gql`
1943
- mutation moduleUploadUrlGenerate {
1944
- moduleUploadUrlGenerate {
1945
- details {
1946
- url
1947
- headers
1948
- humanizedMaxSize
1949
- }
1950
- userErrors {
1951
- field
1952
- message
1953
- }
1954
- }
1955
- }
1956
- `;
1957
-
1958
- const AppFunctionSetMutation = gql`
1959
- mutation AppScriptSet(
1960
- $uuid: String
1961
- $extensionPointName: ExtensionPointName!
1962
- $title: String!
1963
- $description: String
1964
- $force: Boolean
1965
- $schemaMajorVersion: String
1966
- $schemaMinorVersion: String
1967
- $scriptConfigVersion: String
1968
- $configurationUi: Boolean!
1969
- $configurationDefinition: String
1970
- $moduleUploadUrl: String!
1971
- $library: LibraryInput
1972
- $inputQuery: String
1973
- $appBridge: AppBridgeInput
1974
- $apiVersion: String
1975
- ) {
1976
- appScriptSet(
1977
- uuid: $uuid
1978
- extensionPointName: $extensionPointName
1979
- title: $title
1980
- description: $description
1981
- force: $force
1982
- schemaMajorVersion: $schemaMajorVersion
1983
- schemaMinorVersion: $schemaMinorVersion
1984
- scriptConfigVersion: $scriptConfigVersion
1985
- configurationUi: $configurationUi
1986
- configurationDefinition: $configurationDefinition
1987
- moduleUploadUrl: $moduleUploadUrl
1988
- library: $library
1989
- inputQuery: $inputQuery
1990
- appBridge: $appBridge
1991
- apiVersion: $apiVersion
1992
- ) {
1993
- userErrors {
1994
- field
1995
- message
1996
- tag
1997
- }
1998
- appScript {
1999
- uuid
2000
- appKey
2001
- configSchema
2002
- extensionPointName
2003
- title
2004
- }
2005
- }
2006
- }
2007
- `;
2008
-
2009
- const CompileModuleMutation = gql`
2010
- mutation compileModule($moduleUploadUrl: String!) {
2011
- compileModule(moduleUploadUrl: $moduleUploadUrl) {
2012
- jobId
2013
- userErrors {
2014
- field
2015
- message
2016
- }
2017
- }
2018
- }
2019
- `;
2020
-
2021
- const ModuleCompilationStatusQuery = gql`
2022
- query moduleCompilationStatus($jobId: String!) {
2023
- moduleCompilationStatus(jobId: $jobId) {
2024
- status
2025
- userErrors {
2026
- field
2027
- message
2028
- }
2029
- }
2030
- }
2031
- `;
2032
-
2033
- const FindOrganizationBasicQuery = gql`
2034
- query FindOrganization($id: ID!) {
2035
- organizations(id: $id, first: 1) {
2036
- nodes {
2037
- id
2038
- businessName
2039
- website
2040
- appsNext
2041
- }
2042
- }
2043
- }
2044
- `;
2045
-
2046
- var index = /*#__PURE__*/Object.freeze({
2047
- __proto__: null,
2048
- FindOrganizationQuery: FindOrganizationQuery,
2049
- AllOrganizationsQuery: AllOrganizationsQuery,
2050
- CreateAppQuery: CreateAppQuery,
2051
- UpdateURLsQuery: UpdateURLsQuery,
2052
- FindAppQuery: FindAppQuery,
2053
- ExtensionUpdateDraftMutation: ExtensionUpdateDraftMutation,
2054
- GenerateSignedUploadUrl: GenerateSignedUploadUrl,
2055
- CreateDeployment: CreateDeployment,
2056
- AllStoresByOrganizationQuery: AllStoresByOrganizationQuery,
2057
- ConvertDevToTestStoreQuery: ConvertDevToTestStoreQuery,
2058
- ExtensionCreateQuery: ExtensionCreateQuery,
2059
- ExtensionSpecificationsQuery: ExtensionSpecificationsQuery,
2060
- AllAppExtensionRegistrationsQuery: AllAppExtensionRegistrationsQuery,
2061
- FindProductVariantQuery: FindProductVariantQuery,
2062
- ScriptServiceProxyQuery: ScriptServiceProxyQuery,
2063
- GetAppFunctionsQuery: GetAppFunctionsQuery,
2064
- ModuleUploadUrlGenerateMutation: ModuleUploadUrlGenerateMutation,
2065
- AppFunctionSetMutation: AppFunctionSetMutation,
2066
- CompileModuleMutation: CompileModuleMutation,
2067
- ModuleCompilationStatusQuery: ModuleCompilationStatusQuery,
2068
- FindOrganizationBasicQuery: FindOrganizationBasicQuery
2069
- });
2070
-
2071
- class RequestClientError extends ExtendableError {
2072
- constructor(message, statusCode) {
2073
- super(message);
2074
- this.statusCode = statusCode;
2075
- }
2076
- }
2077
- async function request(query, token$1, variables) {
2078
- const fqdn = await partners$1();
2079
- const url = `https://${fqdn}/api/cli/graphql`;
2080
- const headers = await buildHeaders(token$1);
2081
- debug$2(`
2082
- Sending Partners GraphQL request:
2083
- ${query}
2084
-
2085
- With variables:
2086
- ${variables ? JSON.stringify(variables, null, 2) : ""}
2087
-
2088
- And headers:
2089
- ${sanitizedHeadersOutput(headers)}
2090
- `);
2091
- try {
2092
- const response = await request$2(url, query, variables, headers);
2093
- return response;
2094
- } catch (error) {
2095
- if (error instanceof ClientError) {
2096
- const errorMessage = stringifyMessage(content`
2097
- The Partners GraphQL API responded unsuccessfully with the HTTP status ${`${error.response.status}`} and errors:
2098
-
2099
- ${token.json(error.response.errors)}
2100
- `);
2101
- const mappedError = new RequestClientError(errorMessage, error.response.status);
2102
- mappedError.stack = error.stack;
2103
- throw mappedError;
2104
- } else {
2105
- throw error;
2106
- }
2107
- }
2108
- }
2109
- async function checkIfTokenIsRevoked(token) {
2110
- const query = gql`
2111
- {
2112
- organizations(first: 1) {
2113
- nodes {
2114
- id
2115
- }
2116
- }
2117
- }
2118
- `;
2119
- const fqdn = await partners$1();
2120
- const url = `https://${fqdn}/api/cli/graphql`;
2121
- const headers = await buildHeaders(token);
2122
- try {
2123
- await request$2(url, query, {}, headers);
2124
- return false;
2125
- } catch (error) {
2126
- if (error instanceof ClientError) {
2127
- return error.response.status === 401;
2128
- }
2129
- return false;
2130
- }
2131
- }
2132
- async function functionProxyRequest(apiKey, query, token, variables) {
2133
- const proxyVariables = {
2134
- api_key: apiKey,
2135
- query,
2136
- variables: JSON.stringify(variables) || "{}"
2137
- };
2138
- const proxyQuery = ScriptServiceProxyQuery;
2139
- const res = await request(proxyQuery, token, proxyVariables);
2140
- const json = JSON.parse(res.scriptServiceProxy);
2141
- return json;
2142
- }
2143
-
2144
- var partners = /*#__PURE__*/Object.freeze({
2145
- __proto__: null,
2146
- RequestClientError: RequestClientError,
2147
- request: request,
2148
- checkIfTokenIsRevoked: checkIfTokenIsRevoked,
2149
- functionProxyRequest: functionProxyRequest
2150
- });
2151
-
2152
- var api = /*#__PURE__*/Object.freeze({
2153
- __proto__: null,
2154
- admin: admin,
2155
- partners: partners,
2156
- graphql: index
2157
- });
2158
-
2159
- const InvalidChecksumError = ({ file, expected, got }) => {
2160
- return new Abort(`The validation of ${file} failed. We expected the checksum ${expected}, but got ${got})`);
2161
- };
2162
- async function validateMD5({ file, md5FileURL }) {
2163
- debug$2(`Checking MD5 of file ${token.path(file)} against the MD5 in ${token.link("URL", md5FileURL)}`);
2164
- const md5Digest = await md5File(file);
2165
- const md5Response = await fetch$2(md5FileURL);
2166
- const md5Contents = await md5Response.text();
2167
- const canonicalMD5 = md5Contents.split(" ")[0];
2168
- if (!(canonicalMD5 === md5Digest)) {
2169
- throw InvalidChecksumError({
2170
- file,
2171
- got: md5Digest,
2172
- expected: canonicalMD5
2173
- });
2174
- }
2175
- }
2176
-
2177
- var checksum = /*#__PURE__*/Object.freeze({
2178
- __proto__: null,
2179
- InvalidChecksumError: InvalidChecksumError,
2180
- validateMD5: validateMD5
2181
- });
2182
-
2183
- const globalFlags = {
2184
- verbose: Flags.boolean({
2185
- hidden: false,
2186
- description: "Increase the verbosity of the logs.",
2187
- env: "SHOPIFY_FLAG_VERBOSE"
2188
- })
2189
- };
2190
-
2191
- var cli = /*#__PURE__*/Object.freeze({
2192
- __proto__: null,
2193
- globalFlags: globalFlags
2194
- });
2195
-
2196
- const DotEnvNotFoundError = (path) => {
2197
- return new Abort(`The environment file at ${path} does not exist.`);
2198
- };
2199
- async function read(path) {
2200
- debug$2(content`Reading the .env file at ${token.path(path)}`);
2201
- if (!await exists(path)) {
2202
- throw DotEnvNotFoundError(path);
2203
- }
2204
- const content$1 = await read$1(path);
2205
- return {
2206
- path,
2207
- variables: parse$2(content$1)
2208
- };
2209
- }
2210
- async function write(file) {
2211
- await write$1(file.path, stringify(file.variables));
2212
- }
2213
-
2214
- var dotEnv = /*#__PURE__*/Object.freeze({
2215
- __proto__: null,
2216
- DotEnvNotFoundError: DotEnvNotFoundError,
2217
- read: read,
2218
- write: write
2219
- });
2220
-
2221
- const factory = git$1;
2222
- const GitNotPresentError = () => {
2223
- return new Abort(`Git is necessary in the environment to continue`, content`Install ${token.link("git", "https://git-scm.com/book/en/v2/Getting-Started-Installing-Git")}`);
2224
- };
2225
- async function initializeRepository(directory) {
2226
- debug$2(content`Initializing git repository at ${token.path(directory)}...`);
2227
- await ensurePresentOrAbort();
2228
- await git$1(directory).init();
2229
- }
2230
- async function downloadRepository({
2231
- repoUrl,
2232
- destination,
2233
- progressUpdater,
2234
- shallow
2235
- }) {
2236
- debug$2(content`Git-cloning repository ${repoUrl} into ${token.path(destination)}...`);
2237
- await ensurePresentOrAbort();
2238
- const [repository, branch] = repoUrl.split("#");
2239
- const options = { "--recurse-submodules": null };
2240
- if (branch) {
2241
- options["--branch"] = branch;
2242
- }
2243
- if (shallow) {
2244
- options["--depth"] = 1;
2245
- }
2246
- const progress = ({ stage, progress: progress2, processed, total }) => {
2247
- const updateString = `${stage}, ${processed}/${total} objects (${progress2}% complete)`;
2248
- if (progressUpdater)
2249
- progressUpdater(updateString);
2250
- };
2251
- await git$1({ progress }).clone(repository, destination, options, (err) => {
2252
- if (err) {
2253
- const abortError = new Abort(err.message);
2254
- abortError.stack = err.stack;
2255
- throw abortError;
2256
- }
2257
- });
2258
- }
2259
- async function ensurePresentOrAbort() {
2260
- if (!await hasGit()) {
2261
- throw GitNotPresentError();
2262
- }
2263
- }
2264
-
2265
- var git = /*#__PURE__*/Object.freeze({
2266
- __proto__: null,
2267
- factory: factory,
2268
- GitNotPresentError: GitNotPresentError,
2269
- initializeRepository: initializeRepository,
2270
- downloadRepository: downloadRepository,
2271
- ensurePresentOrAbort: ensurePresentOrAbort
2272
- });
2273
-
2274
- class GitHubClientError extends Error {
2275
- constructor(url, statusCode, bodyJson) {
2276
- super(`The request to GitHub API URL ${url} failed with status code ${statusCode} and the following error message: ${bodyJson.message}`);
2277
- }
2278
- }
2279
- async function getLatestRelease(user, repo, { filter } = { filter: () => true }) {
2280
- debug$2(content`Getting the latest release of GitHub repository ${user}/${repo}...`);
2281
- const url = `https://api.github.com/repos/${user}/${repo}/releases`;
2282
- const fetchResult = await fetch$2(url);
2283
- const jsonBody = await fetchResult.json();
2284
- if (fetchResult.status !== 200) {
2285
- throw new GitHubClientError(url, fetchResult.status, jsonBody);
2286
- }
2287
- return jsonBody.find(filter);
2288
- }
2289
- function parseRepoUrl(src) {
2290
- const match = /^(?:(?:https:\/\/)?([^:/]+\.[^:/]+)\/|git@([^:/]+)[:/]|([^/]+):)?([^/\s]+)\/([^/\s#]+)(?:((?:\/[^/\s#]+)+))?(?:\/)?(?:#(.+))?/.exec(src);
2291
- if (!match) {
2292
- const exampleFormats = [
2293
- "github:user/repo",
2294
- "user/repo/subdirectory",
2295
- "git@github.com:user/repo",
2296
- "user/repo#dev",
2297
- "https://github.com/user/repo"
2298
- ];
2299
- throw new Abort(`Parsing the url ${src} failed. Supported formats are ${exampleFormats.join(", ")}.`);
2300
- }
2301
- const site = match[1] || match[2] || match[3] || "github.com";
2302
- const normalizedSite = site === "github" ? "github.com" : site;
2303
- const user = match[4];
2304
- const name = match[5].replace(/\.git$/, "");
2305
- const subDirectory = match[6]?.slice(1);
2306
- const ref = match[7];
2307
- const branch = ref ? `#${ref}` : "";
2308
- const ssh = `git@${normalizedSite}:${user}/${name}`;
2309
- const http = `https://${normalizedSite}/${user}/${name}`;
2310
- const full = ["https:/", normalizedSite, user, name, subDirectory].join("/").concat(branch);
2311
- return { full, site: normalizedSite, user, name, ref, subDirectory, ssh, http };
2312
- }
2313
- function parseGithubRepoReference(src) {
2314
- const url = new URL(src);
2315
- const branch = url.hash ? url.hash.slice(1) : void 0;
2316
- const [_, user, repo, ...repoPath] = url.pathname.split("/");
2317
- const filePath = repoPath.length > 0 ? repoPath.join("/") : void 0;
2318
- return {
2319
- repoBaseUrl: `${url.origin}/${user}/${repo}`,
2320
- branch,
2321
- filePath
2322
- };
2323
- }
2324
-
2325
- var github = /*#__PURE__*/Object.freeze({
2326
- __proto__: null,
2327
- getLatestRelease: getLatestRelease,
2328
- parseRepoUrl: parseRepoUrl,
2329
- parseGithubRepoReference: parseGithubRepoReference
2330
- });
2331
-
2332
- const haikunator = new Haikunator();
2333
- function generate(suffix) {
2334
- const generated = haikunator.haikunate();
2335
- const [adjective, noun, token] = generated.split("-");
2336
- return [adjective, noun, suffix, token].join("-");
2337
- }
2338
-
2339
- var haiku = /*#__PURE__*/Object.freeze({
2340
- __proto__: null,
2341
- generate: generate
2342
- });
2343
-
2344
- const generateRandomUUID = () => {
2345
- return randomUUID();
2346
- };
2347
- const generateShortId = () => {
2348
- let result = "";
2349
- const characters = "abcdefghijklmnopqrstuvwxyz0123456789";
2350
- const charactersLength = characters.length;
2351
- for (let i = 0; i < 7; i++) {
2352
- result += characters.charAt(Math.floor(Math.random() * charactersLength));
2353
- }
2354
- return result;
2355
- };
2356
-
2357
- var id = /*#__PURE__*/Object.freeze({
2358
- __proto__: null,
2359
- generateRandomUUID: generateRandomUUID,
2360
- generateShortId: generateShortId
2361
- });
2362
-
2363
- async function readPackageJSON(directory) {
2364
- debug$2(content`Reading and decoding the content from package.json at ${token.path(directory)}...`);
2365
- const packagePath = join(directory, "package.json");
2366
- const packageJSON = JSON.parse(await read$1(packagePath));
2367
- return packageJSON;
2368
- }
2369
- async function writePackageJSON(directory, packageJSON) {
2370
- debug$2(content`JSON-encoding and writing content to package.json at ${token.path(directory)}...`);
2371
- const packagePath = join(directory, "package.json");
2372
- await write$1(packagePath, JSON.stringify(packageJSON, null, 2));
2373
- }
2374
- async function updateAppData(packageJSON, name) {
2375
- packageJSON.name = name;
2376
- packageJSON.author = await username() ?? "";
2377
- }
2378
-
2379
- var npm = /*#__PURE__*/Object.freeze({
2380
- __proto__: null,
2381
- readPackageJSON: readPackageJSON,
2382
- writePackageJSON: writePackageJSON,
2383
- updateAppData: updateAppData
2384
- });
2385
-
2386
- const TUNNEL_PLUGINS = ["@shopify/plugin-ngrok"];
2387
- async function lookupTunnelPlugin(plugins) {
2388
- debug$2(content`Looking up the Ngrok tunnel plugin...`);
2389
- const tunnelPlugin = plugins.find((plugin) => TUNNEL_PLUGINS.includes(plugin.name));
2390
- if (!tunnelPlugin)
2391
- return void 0;
2392
- const tunnelPath = pathToFileURL(join(tunnelPlugin.root, "dist/tunnel.js")).toString();
2393
- return import(tunnelPath).catch(() => void 0);
2394
- }
2395
-
2396
- var plugins = /*#__PURE__*/Object.freeze({
2397
- __proto__: null,
2398
- lookupTunnelPlugin: lookupTunnelPlugin
2399
- });
2400
-
2401
- async function getRandomPort() {
2402
- debug$2(content`Getting a random port...`);
2403
- const randomPort = await port$1.getRandomPort();
2404
- debug$2(content`Random port obtained: ${token.raw(`${randomPort}`)}`);
2405
- return randomPort;
2406
- }
2407
-
2408
- var port = /*#__PURE__*/Object.freeze({
2409
- __proto__: null,
2410
- getRandomPort: getRandomPort
2411
- });
2412
-
2413
- var schema = /*#__PURE__*/Object.freeze({
2414
- __proto__: null,
2415
- define: z
2416
- });
2417
-
2418
- function clientId() {
2419
- const environment = identity$1();
2420
- if (environment === Environment.Local) {
2421
- return "e5380e02-312a-7408-5718-e07017e9cf52";
2422
- } else if (environment === Environment.Production) {
2423
- return "fbdb2649-e327-4907-8f67-908d24cfd7e3";
2424
- } else {
2425
- return "e5380e02-312a-7408-5718-e07017e9cf52";
2426
- }
2427
- }
2428
- function applicationId(api) {
2429
- switch (api) {
2430
- case "admin": {
2431
- const environment = shopify$1();
2432
- if (environment === Environment.Local) {
2433
- return "e92482cebb9bfb9fb5a0199cc770fde3de6c8d16b798ee73e36c9d815e070e52";
2434
- } else if (environment === Environment.Production) {
2435
- return "7ee65a63608843c577db8b23c4d7316ea0a01bd2f7594f8a9c06ea668c1b775c";
2436
- } else {
2437
- return "e92482cebb9bfb9fb5a0199cc770fde3de6c8d16b798ee73e36c9d815e070e52";
2438
- }
2439
- }
2440
- case "partners": {
2441
- const environment = partners$2();
2442
- if (environment === Environment.Local) {
2443
- return "df89d73339ac3c6c5f0a98d9ca93260763e384d51d6038da129889c308973978";
2444
- } else if (environment === Environment.Production) {
2445
- return "271e16d403dfa18082ffb3d197bd2b5f4479c3fc32736d69296829cbb28d41a6";
2446
- } else {
2447
- return "df89d73339ac3c6c5f0a98d9ca93260763e384d51d6038da129889c308973978";
2448
- }
2449
- }
2450
- case "storefront-renderer": {
2451
- const environment = shopify$1();
2452
- if (environment === Environment.Local) {
2453
- return "46f603de-894f-488d-9471-5b721280ff49";
2454
- } else if (environment === Environment.Production) {
2455
- return "ee139b3d-5861-4d45-b387-1bc3ada7811c";
2456
- } else {
2457
- return "46f603de-894f-488d-9471-5b721280ff49";
2458
- }
2459
- }
2460
- default:
2461
- throw new Bug(`Application id for API of type: ${api}`);
2462
- }
2463
- }
2464
-
2465
- function validateScopes(requestedScopes, identity) {
2466
- const currentScopes = identity.scopes;
2467
- return requestedScopes.every((scope) => currentScopes.includes(scope));
2468
- }
2469
- async function validateSession(scopes, applications, session) {
2470
- if (!session)
2471
- return "needs_full_auth";
2472
- const scopesAreValid = validateScopes(scopes, session.identity);
2473
- if (!scopesAreValid)
2474
- return "needs_full_auth";
2475
- let tokensAreExpired = isTokenExpired(session.identity);
2476
- let tokensAreRevoked = false;
2477
- if (applications.partnersApi) {
2478
- const appId = applicationId("partners");
2479
- const token = session.applications[appId];
2480
- tokensAreRevoked = tokensAreRevoked || await isPartnersTokenRevoked(token);
2481
- tokensAreExpired = tokensAreExpired || isTokenExpired(token);
2482
- }
2483
- if (applications.storefrontRendererApi) {
2484
- const appId = applicationId("storefront-renderer");
2485
- const token = session.applications[appId];
2486
- tokensAreExpired = tokensAreExpired || isTokenExpired(token);
2487
- }
2488
- if (applications.adminApi) {
2489
- const appId = applicationId("admin");
2490
- const realAppId = `${applications.adminApi.storeFqdn}-${appId}`;
2491
- const token = session.applications[realAppId];
2492
- tokensAreExpired = tokensAreExpired || isTokenExpired(token);
2493
- }
2494
- if (tokensAreRevoked)
2495
- return "needs_full_auth";
2496
- if (tokensAreExpired)
2497
- return "needs_refresh";
2498
- return "ok";
2499
- }
2500
- function isTokenExpired(token) {
2501
- if (!token)
2502
- return true;
2503
- return token.expiresAt < expireThreshold();
2504
- }
2505
- async function isPartnersTokenRevoked(token) {
2506
- if (!token)
2507
- return false;
2508
- return checkIfTokenIsRevoked(token.accessToken);
2509
- }
2510
- function expireThreshold() {
2511
- return new Date(Date.now() + constants$1.session.expirationTimeMarginInMinutes * 60 * 1e3);
2512
- }
2513
-
2514
- const allAPIs = ["admin", "storefront-renderer", "partners"];
2515
-
2516
- function allDefaultScopes(extraScopes = []) {
2517
- let scopes = allAPIs.map(defaultApiScopes).flat();
2518
- scopes = ["openid", ...scopes, ...extraScopes].map(scopeTransform);
2519
- return Array.from(new Set(scopes));
2520
- }
2521
- function apiScopes(api, extraScopes = []) {
2522
- const scopes = ["openid", ...defaultApiScopes(api), ...extraScopes.map(scopeTransform)].map(scopeTransform);
2523
- return Array.from(new Set(scopes));
2524
- }
2525
- function defaultApiScopes(api) {
2526
- switch (api) {
2527
- case "admin":
2528
- return ["graphql", "themes", "collaborator"];
2529
- case "storefront-renderer":
2530
- return ["devtools"];
2531
- case "partners":
2532
- return ["cli"];
2533
- default:
2534
- throw new Bug(`Unknown API: ${api}`);
2535
- }
2536
- }
2537
- function scopeTransform(scope) {
2538
- switch (scope) {
2539
- case "graphql":
2540
- return "https://api.shopify.com/auth/shop.admin.graphql";
2541
- case "themes":
2542
- return "https://api.shopify.com/auth/shop.admin.themes";
2543
- case "collaborator":
2544
- return "https://api.shopify.com/auth/partners.collaborator-relationships.readonly";
2545
- case "cli":
2546
- return "https://api.shopify.com/auth/partners.app.cli.access";
2547
- case "devtools":
2548
- return "https://api.shopify.com/auth/shop.storefront-renderer.devtools";
2549
- default:
2550
- return scope;
2551
- }
2552
- }
2553
-
2554
- class InvalidGrantError extends Error {
2555
- }
2556
- async function exchangeCodeForAccessToken(codeData) {
2557
- const clientId$1 = await clientId();
2558
- const params = {
2559
- grant_type: "authorization_code",
2560
- code: codeData.code,
2561
- redirect_uri: "http://127.0.0.1:3456",
2562
- client_id: clientId$1,
2563
- code_verifier: codeData.codeVerifier
2564
- };
2565
- return tokenRequest(params).then(buildIdentityToken);
2566
- }
2567
- async function exchangeAccessForApplicationTokens(identityToken, scopes, store) {
2568
- const token = identityToken.accessToken;
2569
- const partners = await requestAppToken("partners", token, scopes.partners);
2570
- const storefront = await requestAppToken("storefront-renderer", token, scopes.storefront);
2571
- const result = {
2572
- ...partners,
2573
- ...storefront
2574
- };
2575
- if (store) {
2576
- const admin = await requestAppToken("admin", token, scopes.admin, store);
2577
- Object.assign(result, admin);
2578
- }
2579
- return result;
2580
- }
2581
- async function refreshAccessToken(currentToken) {
2582
- const clientId$1 = await clientId();
2583
- const params = {
2584
- grant_type: "refresh_token",
2585
- access_token: currentToken.accessToken,
2586
- refresh_token: currentToken.refreshToken,
2587
- client_id: clientId$1
2588
- };
2589
- return tokenRequest(params).then(buildIdentityToken);
2590
- }
2591
- async function exchangeCustomPartnerToken(token) {
2592
- const appId = applicationId("partners");
2593
- const newToken = await requestAppToken("partners", token, ["https://api.shopify.com/auth/partners.app.cli.access"]);
2594
- return newToken[appId];
2595
- }
2596
- async function requestAppToken(api, token, scopes = [], store) {
2597
- const appId = applicationId(api);
2598
- const clientId$1 = await clientId();
2599
- const params = {
2600
- grant_type: "urn:ietf:params:oauth:grant-type:token-exchange",
2601
- requested_token_type: "urn:ietf:params:oauth:token-type:access_token",
2602
- subject_token_type: "urn:ietf:params:oauth:token-type:access_token",
2603
- client_id: clientId$1,
2604
- audience: appId,
2605
- scope: scopes.join(" "),
2606
- subject_token: token,
2607
- ...api === "admin" && { destination: `https://${store}/admin` }
2608
- };
2609
- let identifier = appId;
2610
- if (api === "admin" && store) {
2611
- identifier = `${store}-${appId}`;
2612
- }
2613
- const appToken = await tokenRequest(params).then(buildApplicationToken);
2614
- return { [identifier]: appToken };
2615
- }
2616
- async function tokenRequest(params) {
2617
- const fqdn = await identity();
2618
- const url = new URL(`https://${fqdn}/oauth/token`);
2619
- url.search = new URLSearchParams(Object.entries(params)).toString();
2620
- const res = await fetch$2(url.href, { method: "POST" });
2621
- const payload = await res.json();
2622
- if (!res.ok) {
2623
- if (payload.error === "invalid_grant") {
2624
- throw new InvalidGrantError(payload.error_description);
2625
- } else {
2626
- throw new Abort(payload.error_description);
2627
- }
2628
- }
2629
- return payload;
2630
- }
2631
- function buildIdentityToken(result) {
2632
- return {
2633
- accessToken: result.access_token,
2634
- refreshToken: result.refresh_token,
2635
- expiresAt: new Date(Date.now() + result.expires_in * 1e3),
2636
- scopes: result.scope.split(" ")
2637
- };
2638
- }
2639
- function buildApplicationToken(result) {
2640
- return {
2641
- accessToken: result.access_token,
2642
- expiresAt: new Date(Date.now() + result.expires_in * 1e3),
2643
- scopes: result.scope.split(" ")
2644
- };
2645
- }
2646
-
2647
- const HTMLFileNames = ["empty-url.html", "auth-error.html", "missing-code.html", "missing-state.html", "success.html"];
2648
- const StylesheetFilename = "style.css";
2649
- const FaviconFileName = "favicon.svg";
2650
- const getFilePath = async (fileName) => {
2651
- const filePath = await findUp(`assets/${fileName}`, {
2652
- type: "file",
2653
- cwd: moduleDirectory(import.meta.url)
2654
- });
2655
- if (!filePath) {
2656
- throw RedirectPageAssetNotFoundError();
2657
- }
2658
- return filePath;
2659
- };
2660
- const getEmptyUrlHTML = async () => {
2661
- const filePath = await getFilePath(HTMLFileNames[0]);
2662
- return read$1(filePath);
2663
- };
2664
- const getAuthErrorHTML = async () => {
2665
- const filePath = await getFilePath(HTMLFileNames[1]);
2666
- return read$1(filePath);
2667
- };
2668
- const getMissingCodeHTML = async () => {
2669
- const filePath = await getFilePath(HTMLFileNames[2]);
2670
- return read$1(filePath);
2671
- };
2672
- const getMissingStateHTML = async () => {
2673
- const filePath = await getFilePath(HTMLFileNames[3]);
2674
- return read$1(filePath);
2675
- };
2676
- const getSuccessHTML = async () => {
2677
- const filePath = await getFilePath(HTMLFileNames[4]);
2678
- return read$1(filePath);
2679
- };
2680
- const getStylesheet = async () => {
2681
- const filePath = await getFilePath(StylesheetFilename);
2682
- return read$1(filePath);
2683
- };
2684
- const getFavicon = async () => {
2685
- const filePath = await getFilePath(FaviconFileName);
2686
- return read$1(filePath);
2687
- };
2688
- const EmptyUrlString = "We received the authentication redirect but the URL is empty.";
2689
- const MissingCodeString = "The authentication can't continue because the redirect doesn't include the code.";
2690
- const MissingStateString = "The authentication can't continue because the redirect doesn't include the state.";
2691
- const RedirectPageAssetNotFoundError = () => new Bug(`Redirect page asset not found`);
2692
-
2693
- const ResponseTimeoutSeconds = 10;
2694
- const ServerStopDelaySeconds = 0.5;
2695
- class RedirectListener {
2696
- static createServer(callback) {
2697
- const server = Fastify__default().get("*", async (request, reply) => {
2698
- const requestUrl = request.url;
2699
- if (requestUrl === "/favicon.svg") {
2700
- const faviconFile = await getFavicon();
2701
- reply.header("Content-Type", "image/svg+xml").send(faviconFile);
2702
- return {};
2703
- } else if (requestUrl === "/style.css") {
2704
- const stylesheetFile = await getStylesheet();
2705
- reply.header("Content-Type", "text/css").send(stylesheetFile);
2706
- return {};
2707
- }
2708
- const respond = (contents, error, state, code) => {
2709
- reply.header("Content-Type", "text/html").send(contents);
2710
- callback(error, state, code);
2711
- return {};
2712
- };
2713
- if (!requestUrl) {
2714
- const file2 = await getEmptyUrlHTML();
2715
- const err = new Bug(EmptyUrlString);
2716
- return respond(file2, err, void 0, void 0);
2717
- }
2718
- const queryObject = url$1.parse(requestUrl, true).query;
2719
- if (queryObject.error && queryObject.error_description) {
2720
- const file2 = await getAuthErrorHTML();
2721
- const err = new Abort(`${queryObject.error_description}`);
2722
- return respond(file2, err, void 0, void 0);
2723
- }
2724
- if (!queryObject.code) {
2725
- const file2 = await getMissingCodeHTML();
2726
- const err = new Bug(MissingCodeString);
2727
- return respond(file2, err, void 0, void 0);
2728
- }
2729
- if (!queryObject.state) {
2730
- const file2 = await getMissingStateHTML();
2731
- const err = new Bug(MissingStateString);
2732
- return respond(file2, err, void 0, void 0);
2733
- }
2734
- const file = await getSuccessHTML();
2735
- return respond(file, void 0, `${queryObject.code}`, `${queryObject.state}`);
2736
- });
2737
- return server;
2738
- }
2739
- constructor(options) {
2740
- this.port = options.port;
2741
- this.host = options.host;
2742
- this.server = RedirectListener.createServer(options.callback);
2743
- }
2744
- start() {
2745
- this.server.listen({ port: this.port, host: this.host }, () => {
2746
- });
2747
- }
2748
- async stop() {
2749
- await this.server.close();
2750
- }
2751
- }
2752
- async function listenRedirect(host, port, url2) {
2753
- const result = await new Promise((resolve, reject) => {
2754
- const timeout = setTimeout(() => {
2755
- const message = "\nAuto-open timed out. Open the login page: ";
2756
- info(content`${message}${token.link("Log in to Shopify Partners", url2)}\n`);
2757
- }, ResponseTimeoutSeconds * 1e3);
2758
- const callback = async (error, code, state) => {
2759
- clearTimeout(timeout);
2760
- setTimeout(() => {
2761
- redirectListener.stop();
2762
- if (error)
2763
- reject(error);
2764
- else
2765
- resolve({ code, state });
2766
- }, ServerStopDelaySeconds * 1e3);
2767
- };
2768
- const redirectListener = new RedirectListener({ host, port, callback });
2769
- redirectListener.start();
2770
- });
2771
- return result;
2772
- }
2773
-
2774
- function randomHex(size) {
2775
- return crypto.randomBytes(size).toString("hex");
2776
- }
2777
- function generateRandomChallengePair() {
2778
- const codeVerifier = base64URLEncode(crypto.randomBytes(32));
2779
- const codeChallenge = base64URLEncode(sha256(codeVerifier));
2780
- return { codeVerifier, codeChallenge };
2781
- }
2782
- function base64URLEncode(str) {
2783
- return str.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/[=]/g, "");
2784
- }
2785
- function sha256(str) {
2786
- return crypto.createHash("sha256").update(str).digest();
2787
- }
2788
- function capitalize(string) {
2789
- return string.substring(0, 1).toUpperCase() + string.substring(1);
2790
- }
2791
- function normalizeStoreName(store) {
2792
- const storeFqdn = store.replace(/^https?:\/\//, "").replace(/\/$/, "");
2793
- return storeFqdn.includes(".myshopify.com") ? storeFqdn : `${storeFqdn}.myshopify.com`;
2794
- }
2795
-
2796
- var string = /*#__PURE__*/Object.freeze({
2797
- __proto__: null,
2798
- randomHex: randomHex,
2799
- generateRandomChallengePair: generateRandomChallengePair,
2800
- capitalize: capitalize,
2801
- normalizeStoreName: normalizeStoreName,
2802
- camelize: camelCase,
2803
- hyphenize: paramCase,
2804
- underscore: snakeCase,
2805
- constantize: constantCase
2806
- });
2807
-
2808
- const MismatchStateError = new Abort("The state received from the authentication doesn't match the one that initiated the authentication process.");
2809
- async function authorize(scopes, state = randomHex(30)) {
2810
- const port = 3456;
2811
- const host = "127.0.0.1";
2812
- const redirectUri = `http://${host}:${port}`;
2813
- const fqdn = await identity();
2814
- const identityClientId = await clientId();
2815
- let url = `http://${fqdn}/oauth/authorize`;
2816
- const { codeVerifier, codeChallenge } = generateRandomChallengePair();
2817
- const params = {
2818
- client_id: identityClientId,
2819
- scope: scopes.join(" "),
2820
- redirect_uri: redirectUri,
2821
- state,
2822
- response_type: "code",
2823
- code_challenge_method: "S256",
2824
- code_challenge: codeChallenge
2825
- };
2826
- info("\nTo run this command, log in to Shopify Partners.");
2827
- info("\u{1F449} Press any key to open the login page on your browser");
2828
- await keypress();
2829
- url = `${url}?${new URLSearchParams(params).toString()}`;
2830
- open(url);
2831
- const result = await listenRedirect(host, port, url);
2832
- if (result.state !== state) {
2833
- throw MismatchStateError;
2834
- }
2835
- return { code: result.code, codeVerifier };
2836
- }
2837
-
2838
- const DateSchema = z.preprocess((arg) => {
2839
- if (typeof arg === "string" || arg instanceof Date)
2840
- return new Date(arg);
2841
- return null;
2842
- }, z.date());
2843
- const IdentityTokenSchema = z.object({
2844
- accessToken: z.string(),
2845
- refreshToken: z.string(),
2846
- expiresAt: DateSchema,
2847
- scopes: z.array(z.string())
2848
- });
2849
- const ApplicationTokenSchema = z.object({
2850
- accessToken: z.string(),
2851
- expiresAt: DateSchema,
2852
- scopes: z.array(z.string())
2853
- });
2854
- const SessionSchema = z.object({}).catchall(z.object({
2855
- identity: IdentityTokenSchema,
2856
- applications: z.object({}).catchall(ApplicationTokenSchema)
2857
- }));
2858
-
2859
- async function fetch$1(identifier) {
2860
- debug$2(content`Reading ${identifier} from the secure store...`);
2861
- try {
2862
- const keytar = await import('keytar');
2863
- const content = await keytar.getPassword(constants$1.keychain.service, identifier);
2864
- return content;
2865
- } catch (error) {
2866
- throw createAbort(error, "Unable to read from the secure store");
2867
- }
2868
- }
2869
- async function store$1(identifier, content$1) {
2870
- debug$2(content`Updating ${identifier} in the secure store with new content...`);
2871
- try {
2872
- const keytar = await import('keytar');
2873
- await keytar.default.setPassword(constants$1.keychain.service, identifier, content$1);
2874
- } catch (error) {
2875
- throw createAbort(error, "Unable to update the secure store");
2876
- }
2877
- }
2878
- async function remove$1(identifier) {
2879
- debug$2(content`Removing ${identifier} from the secure store...`);
2880
- try {
2881
- const keytar = await import('keytar');
2882
- const result = await keytar.default.deletePassword(constants$1.keychain.service, identifier);
2883
- return result;
2884
- } catch (error) {
2885
- throw createAbort(error, "Unable to remove from the secure store");
2886
- }
2887
- }
2888
- function createAbort(error, message) {
2889
- let newMessage = message;
2890
- let stack = "";
2891
- if (error instanceof Error) {
2892
- newMessage = message.concat(`: ${error.message}`);
2893
- stack = error.stack;
2894
- }
2895
- const abort = new Abort(newMessage);
2896
- abort.stack = stack;
2897
- return abort;
2898
- }
2899
-
2900
- const identifier = "session";
2901
- async function store(session) {
2902
- const jsonSession = JSON.stringify(session);
2903
- if (await secureStoreAvailable()) {
2904
- await store$1(identifier, jsonSession);
2905
- } else {
2906
- setSession(jsonSession);
2907
- }
2908
- }
2909
- async function fetch() {
2910
- let content2;
2911
- if (await secureStoreAvailable()) {
2912
- content2 = await fetch$1(identifier);
2913
- } else {
2914
- content2 = getSession();
2915
- }
2916
- if (!content2) {
2917
- return void 0;
2918
- }
2919
- const contentJson = JSON.parse(content2);
2920
- const parsedSession = await SessionSchema.safeParseAsync(contentJson);
2921
- if (parsedSession.success) {
2922
- return parsedSession.data;
2923
- } else {
2924
- await remove();
2925
- return void 0;
2926
- }
2927
- }
2928
- async function remove() {
2929
- if (await secureStoreAvailable()) {
2930
- await remove$1(identifier);
2931
- } else {
2932
- removeSession();
2933
- }
2934
- }
2935
- async function secureStoreAvailable() {
2936
- try {
2937
- if (platformAndArch().platform === "windows") {
2938
- debug$2(content`Secure store not supported on Windows`);
2939
- return false;
2940
- }
2941
- const keytar = await import('keytar');
2942
- await keytar.default.findCredentials(constants$1.keychain.service);
2943
- debug$2(content`Secure store is available`);
2944
- return true;
2945
- } catch (_error) {
2946
- debug$2(content`Failed to load secure store`);
2947
- return false;
2948
- }
2949
- }
2950
-
2951
- const NoSessionError = new Bug("No session found after ensuring authenticated");
2952
- const MissingPartnerTokenError = new Bug("No partners token found after ensuring authenticated");
2953
- const MissingAdminTokenError = new Bug("No admin token found after ensuring authenticated");
2954
- const MissingStorefrontTokenError = new Bug("No storefront token found after ensuring authenticated");
2955
- const PartnerOrganizationNotFoundError = () => {
2956
- return new Abort(`Couldn't find your Shopify Partners organization`, `Have you confirmed your accounts from the emails you received?`);
2957
- };
2958
- async function ensureAuthenticatedPartners(scopes = [], env = process.env) {
2959
- debug$2(content`Ensuring that the user is authenticated with the Partners API with the following scopes:
2960
- ${token.json(scopes)}
2961
- `);
2962
- const envToken = env[constants$1.environmentVariables.partnersToken];
2963
- if (envToken) {
2964
- return (await exchangeCustomPartnerToken(envToken)).accessToken;
2965
- }
2966
- const tokens = await ensureAuthenticated({ partnersApi: { scopes } });
2967
- if (!tokens.partners) {
2968
- throw MissingPartnerTokenError;
2969
- }
2970
- return tokens.partners;
2971
- }
2972
- async function ensureAuthenticatedStorefront(scopes = []) {
2973
- debug$2(content`Ensuring that the user is authenticated with the Storefront API with the following scopes:
2974
- ${token.json(scopes)}
2975
- `);
2976
- const tokens = await ensureAuthenticated({ storefrontRendererApi: { scopes } });
2977
- if (!tokens.storefront) {
2978
- throw MissingStorefrontTokenError;
2979
- }
2980
- return tokens.storefront;
2981
- }
2982
- async function ensureAuthenticatedAdmin(store, scopes = []) {
2983
- debug$2(content`Ensuring that the user is authenticated with the Admin API with the following scopes for the store ${token.raw(store)}:
2984
- ${token.json(scopes)}
2985
- `);
2986
- const tokens = await ensureAuthenticated({ adminApi: { scopes, storeFqdn: store } });
2987
- if (!tokens.admin) {
2988
- throw MissingAdminTokenError;
2989
- }
2990
- return tokens.admin;
2991
- }
2992
- async function ensureAuthenticated(applications, env = process.env) {
2993
- const fqdn = await identity();
2994
- if (applications.adminApi?.storeFqdn) {
2995
- applications.adminApi.storeFqdn = normalizeStoreName(applications.adminApi.storeFqdn);
2996
- }
2997
- const currentSession = await fetch() || {};
2998
- const fqdnSession = currentSession[fqdn];
2999
- const scopes = getFlattenScopes(applications);
3000
- debug$2(content`Validating existing session against the scopes:
3001
- ${token.json(scopes)}
3002
- For applications:
3003
- ${token.json(applications)}
3004
- `);
3005
- const validationResult = await validateSession(scopes, applications, fqdnSession);
3006
- let newSession = {};
3007
- if (validationResult === "needs_full_auth") {
3008
- debug$2(content`Initiating the full authentication flow...`);
3009
- newSession = await executeCompleteFlow(applications, fqdn);
3010
- } else if (validationResult === "needs_refresh") {
3011
- debug$2(content`The current session is valid but needs refresh. Refreshing...`);
3012
- try {
3013
- newSession = await refreshTokens(fqdnSession.identity, applications, fqdn);
3014
- } catch (error) {
3015
- if (error instanceof InvalidGrantError) {
3016
- newSession = await executeCompleteFlow(applications, fqdn);
3017
- } else {
3018
- throw error;
3019
- }
3020
- }
3021
- }
3022
- const completeSession = { ...currentSession, ...newSession };
3023
- await store(completeSession);
3024
- const tokens = await tokensFor(applications, completeSession, fqdn);
3025
- const envToken = env[constants$1.environmentVariables.partnersToken];
3026
- if (envToken && applications.partnersApi) {
3027
- tokens.partners = (await exchangeCustomPartnerToken(envToken)).accessToken;
3028
- }
3029
- if (!envToken && tokens.partners) {
3030
- await ensureUserHasPartnerAccount(tokens.partners);
3031
- }
3032
- return tokens;
3033
- }
3034
- async function hasPartnerAccount(partnersToken) {
3035
- try {
3036
- await request(gql`
3037
- {
3038
- organizations(first: 1) {
3039
- nodes {
3040
- id
3041
- }
3042
- }
3043
- }
3044
- `, partnersToken);
3045
- return true;
3046
- } catch (error) {
3047
- if (error instanceof RequestClientError && error.statusCode === 404) {
3048
- return false;
3049
- } else {
3050
- return true;
3051
- }
3052
- }
3053
- }
3054
- async function ensureUserHasPartnerAccount(partnersToken) {
3055
- debug$2(content`Verifying that the user has a Partner organization`);
3056
- if (!await hasPartnerAccount(partnersToken)) {
3057
- info(`
3058
- A Shopify Partners organization is needed to proceed.`);
3059
- info(`\u{1F449} Press any key to create one`);
3060
- await keypress();
3061
- open(`https://partners.shopify.com/signup`);
3062
- info(content`👉 Press any key when you have ${token.cyan("created the organization")}`);
3063
- warn(content`Make sure you've confirmed your Shopify and the Partner organization from the email`);
3064
- await keypress();
3065
- if (!await hasPartnerAccount(partnersToken)) {
3066
- throw PartnerOrganizationNotFoundError();
3067
- }
3068
- }
3069
- }
3070
- async function executeCompleteFlow(applications, identityFqdn2) {
3071
- const scopes = getFlattenScopes(applications);
3072
- const exchangeScopes = getExchangeScopes(applications);
3073
- const store = applications.adminApi?.storeFqdn;
3074
- debug$2(content`Authorizing through Identity's website...`);
3075
- const code = await authorize(scopes);
3076
- debug$2(content`Authorization code received. Exchanging it for a CLI token...`);
3077
- const identityToken = await exchangeCodeForAccessToken(code);
3078
- debug$2(content`CLI token received. Exchanging it for application tokens...`);
3079
- const result = await exchangeAccessForApplicationTokens(identityToken, exchangeScopes, store);
3080
- const session = {
3081
- [identityFqdn2]: {
3082
- identity: identityToken,
3083
- applications: result
3084
- }
3085
- };
3086
- completed("Logged in.");
3087
- return session;
3088
- }
3089
- async function refreshTokens(token2, applications, fqdn) {
3090
- const identityToken = await refreshAccessToken(token2);
3091
- const exchangeScopes = getExchangeScopes(applications);
3092
- const applicationTokens = await exchangeAccessForApplicationTokens(identityToken, exchangeScopes, applications.adminApi?.storeFqdn);
3093
- return {
3094
- [fqdn]: {
3095
- identity: identityToken,
3096
- applications: applicationTokens
3097
- }
3098
- };
3099
- }
3100
- async function tokensFor(applications, session, fqdn) {
3101
- const fqdnSession = session[fqdn];
3102
- if (!fqdnSession) {
3103
- throw NoSessionError;
3104
- }
3105
- const tokens = {};
3106
- if (applications.adminApi) {
3107
- const appId = applicationId("admin");
3108
- const realAppId = `${applications.adminApi.storeFqdn}-${appId}`;
3109
- const token2 = fqdnSession.applications[realAppId]?.accessToken;
3110
- if (token2) {
3111
- tokens.admin = { token: token2, storeFqdn: applications.adminApi.storeFqdn };
3112
- }
3113
- }
3114
- if (applications.partnersApi) {
3115
- const appId = applicationId("partners");
3116
- tokens.partners = fqdnSession.applications[appId]?.accessToken;
3117
- }
3118
- if (applications.storefrontRendererApi) {
3119
- const appId = applicationId("storefront-renderer");
3120
- tokens.storefront = fqdnSession.applications[appId]?.accessToken;
3121
- }
3122
- return tokens;
3123
- }
3124
- function getFlattenScopes(apps) {
3125
- const admin = apps.adminApi?.scopes || [];
3126
- const partner = apps.partnersApi?.scopes || [];
3127
- const storefront = apps.storefrontRendererApi?.scopes || [];
3128
- const requestedScopes = [...admin, ...partner, ...storefront];
3129
- return allDefaultScopes(requestedScopes);
3130
- }
3131
- function getExchangeScopes(apps) {
3132
- const adminScope = apps.adminApi?.scopes || [];
3133
- const partnerScope = apps.partnersApi?.scopes || [];
3134
- const storefrontScopes = apps.storefrontRendererApi?.scopes || [];
3135
- return {
3136
- admin: apiScopes("admin", adminScope),
3137
- partners: apiScopes("partners", partnerScope),
3138
- storefront: apiScopes("storefront-renderer", storefrontScopes)
3139
- };
3140
- }
3141
- function logout() {
3142
- return remove();
3143
- }
3144
-
3145
- var session = /*#__PURE__*/Object.freeze({
3146
- __proto__: null,
3147
- PartnerOrganizationNotFoundError: PartnerOrganizationNotFoundError,
3148
- ensureAuthenticatedPartners: ensureAuthenticatedPartners,
3149
- ensureAuthenticatedStorefront: ensureAuthenticatedStorefront,
3150
- ensureAuthenticatedAdmin: ensureAuthenticatedAdmin,
3151
- ensureAuthenticated: ensureAuthenticated,
3152
- hasPartnerAccount: hasPartnerAccount,
3153
- ensureUserHasPartnerAccount: ensureUserHasPartnerAccount,
3154
- logout: logout
3155
- });
3156
-
3157
- function create(templateContent) {
3158
- return (data) => {
3159
- const engine = new Liquid();
3160
- return engine.render(engine.parse(templateContent), data);
3161
- };
3162
- }
3163
- async function recursiveDirectoryCopy(from, to, data) {
3164
- debug$2(content`Copying template from directory ${token.path(from)} to ${token.path(to)}`);
3165
- const templateFiles = await glob(join(from, "**/*"), { dot: true });
3166
- const sortedTemplateFiles = templateFiles.map((path) => path.split("/")).sort((lhs, rhs) => lhs.length < rhs.length ? 1 : -1).map((components) => components.join("/"));
3167
- await Promise.all(sortedTemplateFiles.map(async (templateItemPath) => {
3168
- const outputPath = await create(join(to, relative(from, templateItemPath)))(data);
3169
- if (await isDirectory(templateItemPath)) {
3170
- await mkdir(outputPath);
3171
- } else if (templateItemPath.endsWith(".liquid")) {
3172
- await mkdir(dirname(outputPath));
3173
- const content2 = await read$1(templateItemPath);
3174
- const contentOutput = await create(content2)(data);
3175
- const isExecutable = await hasExecutablePermissions(templateItemPath);
3176
- const outputPathWithoutLiquid = outputPath.replace(".liquid", "");
3177
- await copy(templateItemPath, outputPathWithoutLiquid);
3178
- await write$1(outputPathWithoutLiquid, contentOutput);
3179
- if (isExecutable) {
3180
- await chmod(outputPathWithoutLiquid, 493);
3181
- }
3182
- } else {
3183
- await copy(templateItemPath, outputPath);
3184
- }
3185
- }));
3186
- }
3187
-
3188
- var template = /*#__PURE__*/Object.freeze({
3189
- __proto__: null,
3190
- create: create,
3191
- recursiveDirectoryCopy: recursiveDirectoryCopy
3192
- });
3193
-
3194
- async function directory(callback) {
3195
- const result = await tempy.directory.task(callback, {});
3196
- return result;
3197
- }
3198
-
3199
- var temporary = /*#__PURE__*/Object.freeze({
3200
- __proto__: null,
3201
- directory: directory
3202
- });
3203
-
3204
- function decode$1(input) {
3205
- return toml$1.parse(input);
3206
- }
3207
- function encode$1(content) {
3208
- return toml$1.stringify(content);
3209
- }
3210
-
3211
- var toml = /*#__PURE__*/Object.freeze({
3212
- __proto__: null,
3213
- decode: decode$1,
3214
- encode: encode$1
3215
- });
3216
-
3217
- const isVSCode = async (root = process.cwd()) => {
3218
- debug$2(content`Checking if the directory ${token.path(root)} or any of its parents has a .vscode directory... `);
3219
- const config = await findUp(join(root, ".vscode"), { type: "directory" });
3220
- if (!config) {
3221
- return false;
3222
- }
3223
- return exists(config);
3224
- };
3225
- async function addRecommendedExtensions(directory, recommendations) {
3226
- debug$2(content`Adding VSCode recommended extensions at ${token.path(directory)}:
3227
- ${token.json(recommendations)}
3228
- `);
3229
- const extensionsPath = join(directory, ".vscode/extensions.json");
3230
- if (await isVSCode(directory)) {
3231
- let originalExtensionsJson = { recommendations: [] };
3232
- if (await exists(extensionsPath)) {
3233
- const originalExtensionsFile = await read$1(extensionsPath);
3234
- originalExtensionsJson = JSON.parse(originalExtensionsFile);
3235
- }
3236
- const newExtensionsJson = {
3237
- ...originalExtensionsJson,
3238
- recommendations: [...originalExtensionsJson.recommendations, ...recommendations]
3239
- };
3240
- await write$1(extensionsPath, JSON.stringify(newExtensionsJson, null, 2));
3241
- }
3242
- }
3243
-
3244
- var vscode = /*#__PURE__*/Object.freeze({
3245
- __proto__: null,
3246
- isVSCode: isVSCode,
3247
- addRecommendedExtensions: addRecommendedExtensions
3248
- });
3249
-
3250
- function decode(input) {
3251
- return yaml$1.load(input);
3252
- }
3253
- function encode(content) {
3254
- return yaml$1.dump(content);
3255
- }
3256
-
3257
- var yaml = /*#__PURE__*/Object.freeze({
3258
- __proto__: null,
3259
- decode: decode,
3260
- encode: encode
3261
- });
3262
-
3263
- export { abort, analytics, api, checksum, cli, dependency, dotEnv as dotenv, environment, git, github, haiku, http, id, npm, plugins, port, ruby, schema, semver, session, store$2 as store, string, template, temporary, toml, ui, version, vscode, yaml };
3264
- //# sourceMappingURL=index.js.map
1
+ export { default as constants } from './constants.js';
2
+ export * as abort from './abort.js';
3
+ export * as analytics from './analytics.js';
4
+ export * as api from './api.js';
5
+ export * as cli from './cli.js';
6
+ export * as environment from './environment.js';
7
+ export * as error from './error.js';
8
+ export * as fastify from 'fastify';
9
+ export * as file from './file.js';
10
+ export * as git from './git.js';
11
+ export * as github from './github.js';
12
+ export * as haiku from './haiku.js';
13
+ export * as http from './http.js';
14
+ export * as id from './id.js';
15
+ export * as npm from './npm.js';
16
+ export * as os from './os.js';
17
+ export * as output from './output.js';
18
+ export * as path from './path.js';
19
+ export * as plugins from './plugins.js';
20
+ export * as port from './port.js';
21
+ export * as schema from './schema.js';
22
+ export * as semver from './semver.js';
23
+ export * as session from './session.js';
24
+ export * as store from './store.js';
25
+ export * as string from './string.js';
26
+ export * as system from './system.js';
27
+ export * as template from './template.js';
28
+ export * as toml from './toml.js';
29
+ export * as ui from './ui.js';
30
+ export * as version from './version.js';
31
+ export * as vscode from './vscode.js';
32
+ export * as yaml from './yaml.js';
33
+ export * as outputMocker from './testing/output.js';
34
+ //# sourceMappingURL=index.js.map