@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.
- package/CHANGELOG.md +34 -0
- package/assets/auth-error.html +2 -4
- package/assets/empty-url.html +2 -4
- package/assets/missing-code.html +2 -4
- package/assets/missing-state.html +2 -4
- package/assets/style.css +5 -8
- package/assets/success.html +1 -1
- package/dist/abort.d.ts +1 -0
- package/dist/abort.js +2 -0
- package/dist/abort.js.map +1 -0
- package/dist/analytics.d.ts +13 -0
- package/dist/analytics.js +111 -0
- package/dist/analytics.js.map +1 -0
- package/dist/api/admin.d.ts +3 -0
- package/dist/api/admin.js +80 -0
- package/dist/api/admin.js.map +1 -0
- package/dist/api/common.d.ts +11 -0
- package/dist/api/common.js +40 -0
- package/dist/api/common.js.map +1 -0
- package/dist/api/graphql/all_app_extension_registrations.d.ts +14 -0
- package/dist/api/graphql/all_app_extension_registrations.js +14 -0
- package/dist/api/graphql/all_app_extension_registrations.js.map +1 -0
- package/dist/api/graphql/all_orgs.d.ts +12 -0
- package/dist/api/graphql/all_orgs.js +14 -0
- package/dist/api/graphql/all_orgs.js.map +1 -0
- package/dist/api/graphql/all_stores_by_org.d.ts +18 -0
- package/dist/api/graphql/all_stores_by_org.js +21 -0
- package/dist/api/graphql/all_stores_by_org.js.map +1 -0
- package/dist/api/graphql/convert_dev_to_test_store.d.ts +16 -0
- package/dist/api/graphql/convert_dev_to_test_store.js +13 -0
- package/dist/api/graphql/convert_dev_to_test_store.js.map +1 -0
- package/dist/api/graphql/create_app.d.ts +28 -0
- package/dist/api/graphql/create_app.js +32 -0
- package/dist/api/graphql/create_app.js.map +1 -0
- package/dist/api/graphql/create_deployment.d.ts +33 -0
- package/dist/api/graphql/create_deployment.js +25 -0
- package/dist/api/graphql/create_deployment.js.map +1 -0
- package/dist/api/graphql/extension_create.d.ts +30 -0
- package/dist/api/graphql/extension_create.js +26 -0
- package/dist/api/graphql/extension_create.js.map +1 -0
- package/dist/api/graphql/extension_specifications.d.ts +18 -0
- package/dist/api/graphql/extension_specifications.js +18 -0
- package/dist/api/graphql/extension_specifications.js.map +1 -0
- package/dist/api/graphql/find_app.d.ts +13 -0
- package/dist/api/graphql/find_app.js +16 -0
- package/dist/api/graphql/find_app.js.map +1 -0
- package/dist/api/graphql/find_org.d.ts +23 -0
- package/dist/api/graphql/find_org.js +26 -0
- package/dist/api/graphql/find_org.js.map +1 -0
- package/dist/api/graphql/find_org_basic.d.ts +11 -0
- package/dist/api/graphql/find_org_basic.js +14 -0
- package/dist/api/graphql/find_org_basic.js.map +1 -0
- package/dist/api/graphql/find_store_by_domain.d.ts +21 -0
- package/dist/api/graphql/find_store_by_domain.js +24 -0
- package/dist/api/graphql/find_store_by_domain.js.map +1 -0
- package/dist/api/graphql/functions/app_function_set.d.ts +43 -0
- package/dist/api/graphql/functions/app_function_set.js +52 -0
- package/dist/api/graphql/functions/app_function_set.js.map +1 -0
- package/dist/api/graphql/functions/compile_module.d.ts +15 -0
- package/dist/api/graphql/functions/compile_module.js +13 -0
- package/dist/api/graphql/functions/compile_module.js.map +1 -0
- package/dist/api/graphql/functions/function_service_proxy.d.ts +4 -0
- package/dist/api/graphql/functions/function_service_proxy.js +7 -0
- package/dist/api/graphql/functions/function_service_proxy.js.map +1 -0
- package/dist/api/graphql/functions/get_app_functions.d.ts +1 -0
- package/dist/api/graphql/functions/get_app_functions.js +10 -0
- package/dist/api/graphql/functions/get_app_functions.js.map +1 -0
- package/dist/api/graphql/functions/module_compilation_status.d.ts +15 -0
- package/dist/api/graphql/functions/module_compilation_status.js +13 -0
- package/dist/api/graphql/functions/module_compilation_status.js.map +1 -0
- package/dist/api/graphql/functions/module_upload_url_generate.d.ts +18 -0
- package/dist/api/graphql/functions/module_upload_url_generate.js +17 -0
- package/dist/api/graphql/functions/module_upload_url_generate.js.map +1 -0
- package/dist/api/graphql/generate_signed_upload_url.d.ts +15 -0
- package/dist/api/graphql/generate_signed_upload_url.js +15 -0
- package/dist/api/graphql/generate_signed_upload_url.js.map +1 -0
- package/dist/api/graphql/get_variant_id.d.ts +17 -0
- package/dist/api/graphql/get_variant_id.js +20 -0
- package/dist/api/graphql/get_variant_id.js.map +1 -0
- package/dist/api/graphql/index.d.ts +22 -0
- package/dist/api/graphql/index.js +23 -0
- package/dist/api/graphql/index.js.map +1 -0
- package/dist/api/graphql/update_draft.d.ts +33 -0
- package/dist/api/graphql/update_draft.js +24 -0
- package/dist/api/graphql/update_draft.js.map +1 -0
- package/dist/api/graphql/update_urls.d.ts +14 -0
- package/dist/api/graphql/update_urls.js +12 -0
- package/dist/api/graphql/update_urls.js.map +1 -0
- package/dist/api/identity.d.ts +1 -0
- package/dist/api/identity.js +32 -0
- package/dist/api/identity.js.map +1 -0
- package/dist/api/partners.d.ts +25 -0
- package/dist/api/partners.js +100 -0
- package/dist/api/partners.js.map +1 -0
- package/dist/api.d.ts +5 -0
- package/dist/api.js +6 -0
- package/dist/api.js.map +1 -0
- package/dist/cli.d.ts +7 -0
- package/dist/cli.js +13 -0
- package/dist/cli.js.map +1 -0
- package/dist/constants.d.ts +43 -0
- package/dist/constants.js +63 -0
- package/dist/constants.js.map +1 -0
- package/dist/environment/fqdn.d.ts +23 -0
- package/dist/environment/fqdn.js +61 -0
- package/dist/environment/fqdn.js.map +1 -0
- package/dist/environment/local.d.ts +48 -0
- package/dist/environment/local.js +82 -0
- package/dist/environment/local.js.map +1 -0
- package/dist/environment/service.d.ts +17 -0
- package/dist/environment/service.js +41 -0
- package/dist/environment/service.js.map +1 -0
- package/dist/environment/spin.d.ts +47 -0
- package/dist/environment/spin.js +83 -0
- package/dist/environment/spin.js.map +1 -0
- package/dist/environment/utilities.d.ts +6 -0
- package/dist/environment/utilities.js +12 -0
- package/dist/environment/utilities.js.map +1 -0
- package/dist/environment.d.ts +5 -0
- package/dist/environment.js +6 -0
- package/dist/environment.js.map +1 -0
- package/dist/error.d.ts +44 -0
- package/dist/error.js +91 -0
- package/dist/error.js.map +1 -0
- package/dist/file.d.ts +67 -0
- package/dist/file.js +165 -0
- package/dist/file.js.map +1 -0
- package/dist/git.d.ts +15 -0
- package/dist/git.js +48 -0
- package/dist/git.js.map +1 -0
- package/dist/github.d.ts +33 -0
- package/dist/github.js +56 -0
- package/dist/github.js.map +1 -0
- package/dist/haiku.d.ts +1 -0
- package/dist/haiku.js +8 -0
- package/dist/haiku.js.map +1 -0
- package/dist/http/fetch.d.ts +16 -0
- package/dist/http/fetch.js +18 -0
- package/dist/http/fetch.js.map +1 -0
- package/dist/http/formdata.d.ts +3 -0
- package/dist/http/formdata.js +6 -0
- package/dist/http/formdata.js.map +1 -0
- package/dist/http.d.ts +2 -0
- package/dist/http.js +3 -0
- package/dist/http.js.map +1 -0
- package/dist/id.d.ts +6 -0
- package/dist/id.js +18 -0
- package/dist/id.js.map +1 -0
- package/dist/index.d.ts +33 -2179
- package/dist/index.js +34 -3264
- package/dist/index.js.map +1 -1
- package/dist/network/api.d.ts +2 -0
- package/dist/network/api.js +2 -0
- package/dist/network/api.js.map +1 -0
- package/dist/network/service.d.ts +16 -0
- package/dist/network/service.js +12 -0
- package/dist/network/service.js.map +1 -0
- package/dist/{archiver.d.ts → node/archiver.d.ts} +1 -4
- package/dist/node/archiver.js +22 -42
- package/dist/node/archiver.js.map +1 -1
- package/dist/node/checksum.d.ts +20 -0
- package/dist/node/checksum.js +32 -0
- package/dist/node/checksum.js.map +1 -0
- package/dist/node/cli.d.ts +18 -0
- package/dist/node/cli.js +96 -0
- package/dist/node/cli.js.map +1 -0
- package/dist/node/colors.d.ts +1 -0
- package/dist/node/colors.js +8 -0
- package/dist/node/colors.js.map +1 -0
- package/dist/node/dot-env.d.ts +33 -0
- package/dist/node/dot-env.js +36 -0
- package/dist/node/dot-env.js.map +1 -0
- package/dist/node/node-package-manager.d.ts +197 -0
- package/dist/node/node-package-manager.js +309 -0
- package/dist/node/node-package-manager.js.map +1 -0
- package/dist/node/ruby.d.ts +30 -0
- package/dist/node/ruby.js +197 -0
- package/dist/node/ruby.js.map +1 -0
- package/dist/npm.d.ts +27 -0
- package/dist/npm.js +20 -0
- package/dist/npm.js.map +1 -0
- package/dist/os.d.ts +10 -0
- package/dist/os.js +70 -0
- package/dist/os.js.map +1 -0
- package/dist/output.d.ts +149 -0
- package/dist/output.js +515 -0
- package/dist/output.js.map +1 -0
- package/dist/path.d.ts +22 -0
- package/dist/path.js +43 -0
- package/dist/path.js.map +1 -0
- package/dist/plugins.d.ts +9 -0
- package/dist/plugins.js +12 -0
- package/dist/plugins.js.map +1 -0
- package/dist/port.d.ts +5 -0
- package/dist/port.js +35 -0
- package/dist/port.js.map +1 -0
- package/dist/schema.d.ts +1 -0
- package/dist/schema.js +2 -0
- package/dist/schema.js.map +1 -0
- package/dist/secure-store.d.ts +19 -0
- package/dist/secure-store.js +63 -0
- package/dist/secure-store.js.map +1 -0
- package/dist/semver.d.ts +3 -0
- package/dist/semver.js +6 -0
- package/dist/semver.js.map +1 -0
- package/dist/session/authorize.d.ts +7 -0
- package/dist/session/authorize.js +40 -0
- package/dist/session/authorize.js.map +1 -0
- package/dist/session/exchange.d.ts +42 -0
- package/dist/session/exchange.js +144 -0
- package/dist/session/exchange.js.map +1 -0
- package/dist/session/identity.d.ts +3 -0
- package/dist/session/identity.js +58 -0
- package/dist/session/identity.js.map +1 -0
- package/dist/session/post-auth.d.ts +13 -0
- package/dist/session/post-auth.js +56 -0
- package/dist/session/post-auth.js.map +1 -0
- package/dist/session/redirect-listener.d.ts +34 -0
- package/dist/session/redirect-listener.js +97 -0
- package/dist/session/redirect-listener.js.map +1 -0
- package/dist/session/schema.d.ts +174 -0
- package/dist/session/schema.js +59 -0
- package/dist/session/schema.js.map +1 -0
- package/dist/session/scopes.d.ts +16 -0
- package/dist/session/scopes.js +53 -0
- package/dist/session/scopes.js.map +1 -0
- package/dist/session/store.d.ts +24 -0
- package/dist/session/store.js +88 -0
- package/dist/session/store.js.map +1 -0
- package/dist/session/token.d.ts +40 -0
- package/dist/session/token.js +22 -0
- package/dist/session/token.js.map +1 -0
- package/dist/session/validate.d.ts +17 -0
- package/dist/session/validate.js +75 -0
- package/dist/session/validate.js.map +1 -0
- package/dist/session.d.ts +88 -0
- package/dist/session.js +251 -0
- package/dist/session.js.map +1 -0
- package/dist/store/schema.d.ts +3 -0
- package/dist/store/schema.js +27 -0
- package/dist/store/schema.js.map +1 -0
- package/dist/store.d.ts +32 -0
- package/dist/store.js +102 -0
- package/dist/store.js.map +1 -0
- package/dist/string.d.ts +22 -0
- package/dist/string.js +38 -0
- package/dist/string.js.map +1 -0
- package/dist/system.d.ts +53 -0
- package/dist/system.js +109 -0
- package/dist/system.js.map +1 -0
- package/dist/template.d.ts +11 -0
- package/dist/template.js +50 -0
- package/dist/template.js.map +1 -0
- package/dist/testing/output.d.ts +9 -0
- package/dist/testing/output.js +15 -0
- package/dist/testing/output.js.map +1 -0
- package/dist/testing/store.d.ts +7 -0
- package/dist/testing/store.js +26 -0
- package/dist/testing/store.js.map +1 -0
- package/dist/toml.d.ts +3 -0
- package/dist/toml.js +8 -0
- package/dist/toml.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/ui/autocomplete.d.ts +7 -0
- package/dist/ui/autocomplete.js +43 -0
- package/dist/ui/autocomplete.js.map +1 -0
- package/dist/ui/input.d.ts +7 -0
- package/dist/ui/input.js +48 -0
- package/dist/ui/input.js.map +1 -0
- package/dist/ui/select.d.ts +6 -0
- package/dist/ui/select.js +30 -0
- package/dist/ui/select.js.map +1 -0
- package/dist/ui.d.ts +36 -0
- package/dist/ui.js +124 -0
- package/dist/ui.js.map +1 -0
- package/dist/version.d.ts +19 -0
- package/dist/version.js +34 -0
- package/dist/version.js.map +1 -0
- package/dist/vscode.d.ts +8 -0
- package/dist/vscode.js +36 -0
- package/dist/vscode.js.map +1 -0
- package/dist/yaml.d.ts +2 -0
- package/dist/yaml.js +8 -0
- package/dist/yaml.js.map +1 -0
- package/package.json +19 -8
- package/dist/archiver.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/local-d0094ffe.js +0 -1344
- package/dist/local-d0094ffe.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,3264 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
export
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|