@shopify/cli-kit 4.9.5 → 5.0.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/dist/cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.d.ts +5 -0
- package/dist/cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.js +22 -0
- package/dist/cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.js.map +1 -1
- package/dist/private/node/api/graphql.d.ts +2 -1
- package/dist/private/node/api/graphql.js +12 -1
- package/dist/private/node/api/graphql.js.map +1 -1
- package/dist/private/node/api.d.ts +2 -0
- package/dist/private/node/api.js +49 -22
- package/dist/private/node/api.js.map +1 -1
- package/dist/private/node/command-json-schema.js +1 -0
- package/dist/private/node/command-json-schema.js.map +1 -1
- package/dist/private/node/constants.d.ts +1 -0
- package/dist/private/node/constants.js +1 -0
- package/dist/private/node/constants.js.map +1 -1
- package/dist/private/node/dev-instance-output.d.ts +47 -0
- package/dist/private/node/dev-instance-output.js +143 -0
- package/dist/private/node/dev-instance-output.js.map +1 -0
- package/dist/private/node/json-error.d.ts +1 -15
- package/dist/private/node/json-error.js +4 -98
- package/dist/private/node/json-error.js.map +1 -1
- package/dist/private/node/output-context.d.ts +8 -0
- package/dist/private/node/output-context.js +10 -0
- package/dist/private/node/output-context.js.map +1 -0
- package/dist/private/node/output.test.js +4 -4
- package/dist/private/node/output.test.js.map +1 -1
- package/dist/private/node/session/automation-token.d.ts +50 -0
- package/dist/private/node/session/automation-token.js +77 -0
- package/dist/private/node/session/automation-token.js.map +1 -0
- package/dist/private/node/session/exchange.d.ts +2 -1
- package/dist/private/node/session/exchange.js +5 -3
- package/dist/private/node/session/exchange.js.map +1 -1
- package/dist/private/node/session/permanent-store-domain.d.ts +21 -0
- package/dist/private/node/session/permanent-store-domain.js +72 -0
- package/dist/private/node/session/permanent-store-domain.js.map +1 -0
- package/dist/private/node/session.d.ts +3 -2
- package/dist/private/node/session.js +12 -3
- package/dist/private/node/session.js.map +1 -1
- package/dist/private/node/themes/trust-challenge.d.ts +31 -0
- package/dist/private/node/themes/trust-challenge.js +143 -0
- package/dist/private/node/themes/trust-challenge.js.map +1 -0
- package/dist/private/node/ui/alert.js +1 -1
- package/dist/private/node/ui/alert.js.map +1 -1
- package/dist/private/node/ui/components/ConcurrentOutput.d.ts +2 -7
- package/dist/private/node/ui/components/ConcurrentOutput.js +4 -8
- package/dist/private/node/ui/components/ConcurrentOutput.js.map +1 -1
- package/dist/private/node/ui/components/LoadingBar.js +9 -15
- package/dist/private/node/ui/components/LoadingBar.js.map +1 -1
- package/dist/private/node/ui/components/LoadingBar.test.js +45 -107
- package/dist/private/node/ui/components/LoadingBar.test.js.map +1 -1
- package/dist/private/node/ui/components/LoadingIndicator.d.ts +7 -0
- package/dist/private/node/ui/components/LoadingIndicator.js +22 -0
- package/dist/private/node/ui/components/LoadingIndicator.js.map +1 -0
- package/dist/public/common/version.d.ts +1 -1
- package/dist/public/common/version.js +1 -1
- package/dist/public/common/version.js.map +1 -1
- package/dist/public/node/api/admin.js +13 -0
- package/dist/public/node/api/admin.js.map +1 -1
- package/dist/public/node/api/graphql.js +38 -7
- package/dist/public/node/api/graphql.js.map +1 -1
- package/dist/public/node/archiver.js +13 -6
- package/dist/public/node/archiver.js.map +1 -1
- package/dist/public/node/base-command.d.ts +6 -0
- package/dist/public/node/base-command.js +97 -16
- package/dist/public/node/base-command.js.map +1 -1
- package/dist/public/node/dev-instance.d.ts +138 -0
- package/dist/public/node/dev-instance.js +365 -0
- package/dist/public/node/dev-instance.js.map +1 -0
- package/dist/public/node/environment.d.ts +6 -3
- package/dist/public/node/environment.js +11 -4
- package/dist/public/node/environment.js.map +1 -1
- package/dist/public/node/error/index.js +2 -1
- package/dist/public/node/error/index.js.map +1 -1
- package/dist/public/node/error/schema.d.ts +24 -24
- package/dist/public/node/error/serialization.d.ts +8 -0
- package/dist/public/node/error/serialization.js +103 -0
- package/dist/public/node/error/serialization.js.map +1 -0
- package/dist/public/node/graphiql/server.js +18 -2
- package/dist/public/node/graphiql/server.js.map +1 -1
- package/dist/public/node/is-global.js +2 -1
- package/dist/public/node/is-global.js.map +1 -1
- package/dist/public/node/notifications-system.d.ts +6 -6
- package/dist/public/node/path.d.ts +19 -3
- package/dist/public/node/path.js +21 -3
- package/dist/public/node/path.js.map +1 -1
- package/dist/public/node/session.d.ts +36 -2
- package/dist/public/node/session.js +48 -4
- package/dist/public/node/session.js.map +1 -1
- package/dist/public/node/system.d.ts +4 -0
- package/dist/public/node/system.js +39 -9
- package/dist/public/node/system.js.map +1 -1
- package/dist/public/node/themes/api.d.ts +9 -0
- package/dist/public/node/themes/api.js +50 -22
- package/dist/public/node/themes/api.js.map +1 -1
- package/dist/public/node/themes/theme-manager.d.ts +8 -1
- package/dist/public/node/themes/theme-manager.js +1 -1
- package/dist/public/node/themes/theme-manager.js.map +1 -1
- package/dist/public/node/tree-kill.js +12 -2
- package/dist/public/node/tree-kill.js.map +1 -1
- package/dist/public/node/ui/components.d.ts +1 -0
- package/dist/public/node/ui/components.js +1 -0
- package/dist/public/node/ui/components.js.map +1 -1
- package/dist/public/node/ui.d.ts +24 -4
- package/dist/public/node/ui.js +41 -18
- package/dist/public/node/ui.js.map +1 -1
- package/dist/public/node/upgrade/output.d.ts +17 -0
- package/dist/public/node/upgrade/output.js +51 -0
- package/dist/public/node/upgrade/output.js.map +1 -0
- package/dist/public/node/upgrade/result.d.ts +8 -0
- package/dist/public/node/upgrade/result.js +21 -0
- package/dist/public/node/upgrade/result.js.map +1 -0
- package/dist/public/node/upgrade/types.d.ts +61 -0
- package/dist/public/node/upgrade/types.js +46 -0
- package/dist/public/node/upgrade/types.js.map +1 -0
- package/dist/public/node/upgrade.d.ts +8 -0
- package/dist/public/node/upgrade.js +57 -22
- package/dist/public/node/upgrade.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/dist/private/node/ui/components/TextAnimation.d.ts +0 -10
- package/dist/private/node/ui/components/TextAnimation.js +0 -56
- package/dist/private/node/ui/components/TextAnimation.js.map +0 -1
- package/dist/private/node/ui/components/TextAnimation.test.d.ts +0 -1
- package/dist/private/node/ui/components/TextAnimation.test.js +0 -73
- package/dist/private/node/ui/components/TextAnimation.test.js.map +0 -1
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { FatalErrorType } from './index.js';
|
|
2
|
+
import { tokenItemToJsonString } from '../../../private/node/ui/components/token-item.js';
|
|
3
|
+
import { unstyled } from '../output.js';
|
|
4
|
+
function externalCommand(error) {
|
|
5
|
+
if (typeof error.command !== 'string' || !Array.isArray(error.args))
|
|
6
|
+
return;
|
|
7
|
+
if (!error.args.every((arg) => typeof arg === 'string'))
|
|
8
|
+
return;
|
|
9
|
+
return { command: error.command, args: error.args };
|
|
10
|
+
}
|
|
11
|
+
function jsonErrorType(error, external) {
|
|
12
|
+
if (error.type === FatalErrorType.Abort) {
|
|
13
|
+
return external ? 'external' : 'abort';
|
|
14
|
+
}
|
|
15
|
+
return 'bug';
|
|
16
|
+
}
|
|
17
|
+
function jsonTokenItem(token) {
|
|
18
|
+
if (token === null || token === undefined)
|
|
19
|
+
return;
|
|
20
|
+
try {
|
|
21
|
+
const message = tokenItemToJsonString(token);
|
|
22
|
+
return typeof message === 'string' ? unstyled(message) : undefined;
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
if (error instanceof TypeError)
|
|
26
|
+
return undefined;
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function jsonTokenItems(items) {
|
|
31
|
+
if (!Array.isArray(items))
|
|
32
|
+
return;
|
|
33
|
+
const renderedItems = items.map(jsonTokenItem).filter((item) => item !== undefined);
|
|
34
|
+
return renderedItems.length > 0 ? renderedItems : undefined;
|
|
35
|
+
}
|
|
36
|
+
function jsonTable(data) {
|
|
37
|
+
if (!Array.isArray(data))
|
|
38
|
+
return;
|
|
39
|
+
return data
|
|
40
|
+
.filter((row) => Array.isArray(row))
|
|
41
|
+
.map((row) => row.map((cell) => jsonTokenItem(cell) ?? ''));
|
|
42
|
+
}
|
|
43
|
+
function jsonCustomSection(section) {
|
|
44
|
+
if (typeof section !== 'object' || section === null || !('body' in section))
|
|
45
|
+
return;
|
|
46
|
+
const title = 'title' in section && typeof section.title === 'string' ? unstyled(section.title) : undefined;
|
|
47
|
+
const sectionBody = section.body;
|
|
48
|
+
const body = typeof sectionBody === 'object' && sectionBody !== null && 'tabularData' in sectionBody
|
|
49
|
+
? jsonTable(sectionBody.tabularData)
|
|
50
|
+
: jsonTokenItem(sectionBody);
|
|
51
|
+
if (body === undefined)
|
|
52
|
+
return;
|
|
53
|
+
return { ...(title ? { title } : {}), body };
|
|
54
|
+
}
|
|
55
|
+
function jsonCustomSections(sections) {
|
|
56
|
+
if (!Array.isArray(sections))
|
|
57
|
+
return;
|
|
58
|
+
const renderedSections = sections
|
|
59
|
+
.map(jsonCustomSection)
|
|
60
|
+
.filter((section) => section !== undefined);
|
|
61
|
+
return renderedSections.length > 0 ? renderedSections : undefined;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Projects an error into the shared JSON error contract, retaining only allowlisted fields.
|
|
65
|
+
*
|
|
66
|
+
* @param source - Error to project.
|
|
67
|
+
* @returns The error classification, message, and available recovery information.
|
|
68
|
+
*/
|
|
69
|
+
export function errorToJson(source) {
|
|
70
|
+
const error = typeof source === 'object' && source !== null ? source : { message: source };
|
|
71
|
+
const external = externalCommand(error);
|
|
72
|
+
const type = jsonErrorType(error, external);
|
|
73
|
+
const formattedMessage = jsonTokenItem(error.formattedMessage);
|
|
74
|
+
const message = formattedMessage ?? (typeof error.message === 'string' ? unstyled(error.message) : 'Unknown error');
|
|
75
|
+
const tryMessage = jsonTokenItem(error.tryMessage);
|
|
76
|
+
const nextSteps = jsonTokenItems(error.nextSteps);
|
|
77
|
+
const customSections = jsonCustomSections(error.customSections);
|
|
78
|
+
const details = error.details;
|
|
79
|
+
const commonFields = {
|
|
80
|
+
message,
|
|
81
|
+
...(typeof error.code === 'string' && error.code.length > 0 ? { code: error.code } : {}),
|
|
82
|
+
...(tryMessage === undefined ? {} : { tryMessage }),
|
|
83
|
+
...(nextSteps === undefined ? {} : { nextSteps }),
|
|
84
|
+
...(customSections === undefined ? {} : { customSections }),
|
|
85
|
+
...(details === undefined ? {} : { details }),
|
|
86
|
+
};
|
|
87
|
+
let jsonError;
|
|
88
|
+
if (type === 'bug') {
|
|
89
|
+
jsonError = {
|
|
90
|
+
type,
|
|
91
|
+
...commonFields,
|
|
92
|
+
...(typeof error.stack === 'string' ? { stack: unstyled(error.stack) } : {}),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
else if (type === 'external' && external) {
|
|
96
|
+
jsonError = { type, ...commonFields, ...external };
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
jsonError = { type: 'abort', ...commonFields };
|
|
100
|
+
}
|
|
101
|
+
return jsonError;
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=serialization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialization.js","sourceRoot":"","sources":["../../../../src/public/node/error/serialization.ts"],"names":[],"mappings":"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","sourcesContent":["import {FatalErrorType} from './index.js'\nimport {tokenItemToJsonString, type TokenItem} from '../../../private/node/ui/components/token-item.js'\nimport {unstyled} from '../output.js'\nimport type {JsonError, JsonErrorCustomSection, JsonErrorType} from './types.js'\n\ninterface FatalErrorLike {\n type?: number\n message?: unknown\n formattedMessage?: unknown\n tryMessage?: unknown\n nextSteps?: unknown\n customSections?: unknown\n stack?: unknown\n command?: unknown\n args?: unknown\n details?: unknown\n code?: unknown\n}\n\ninterface ExternalCommand {\n command: string\n args: string[]\n}\n\nfunction externalCommand(error: FatalErrorLike): ExternalCommand | undefined {\n if (typeof error.command !== 'string' || !Array.isArray(error.args)) return\n if (!error.args.every((arg) => typeof arg === 'string')) return\n\n return {command: error.command, args: error.args}\n}\n\nfunction jsonErrorType(error: FatalErrorLike, external: ExternalCommand | undefined): JsonErrorType {\n if (error.type === FatalErrorType.Abort) {\n return external ? 'external' : 'abort'\n }\n return 'bug'\n}\n\nfunction jsonTokenItem(token: unknown): string | undefined {\n if (token === null || token === undefined) return\n\n try {\n const message = tokenItemToJsonString(token as TokenItem)\n return typeof message === 'string' ? unstyled(message) : undefined\n } catch (error) {\n if (error instanceof TypeError) return undefined\n throw error\n }\n}\n\nfunction jsonTokenItems(items: unknown): string[] | undefined {\n if (!Array.isArray(items)) return\n\n const renderedItems = items.map(jsonTokenItem).filter((item): item is string => item !== undefined)\n return renderedItems.length > 0 ? renderedItems : undefined\n}\n\nfunction jsonTable(data: unknown): string[][] | undefined {\n if (!Array.isArray(data)) return\n\n return data\n .filter((row): row is unknown[] => Array.isArray(row))\n .map((row) => row.map((cell) => jsonTokenItem(cell) ?? ''))\n}\n\nfunction jsonCustomSection(section: unknown): JsonErrorCustomSection | undefined {\n if (typeof section !== 'object' || section === null || !('body' in section)) return\n\n const title = 'title' in section && typeof section.title === 'string' ? unstyled(section.title) : undefined\n const sectionBody = section.body\n const body =\n typeof sectionBody === 'object' && sectionBody !== null && 'tabularData' in sectionBody\n ? jsonTable(sectionBody.tabularData)\n : jsonTokenItem(sectionBody)\n\n if (body === undefined) return\n return {...(title ? {title} : {}), body}\n}\n\nfunction jsonCustomSections(sections: unknown): JsonErrorCustomSection[] | undefined {\n if (!Array.isArray(sections)) return\n\n const renderedSections = sections\n .map(jsonCustomSection)\n .filter((section): section is JsonErrorCustomSection => section !== undefined)\n return renderedSections.length > 0 ? renderedSections : undefined\n}\n\n/**\n * Projects an error into the shared JSON error contract, retaining only allowlisted fields.\n *\n * @param source - Error to project.\n * @returns The error classification, message, and available recovery information.\n */\nexport function errorToJson(source: unknown): JsonError {\n const error: FatalErrorLike = typeof source === 'object' && source !== null ? source : {message: source}\n\n const external = externalCommand(error)\n const type = jsonErrorType(error, external)\n const formattedMessage = jsonTokenItem(error.formattedMessage)\n const message = formattedMessage ?? (typeof error.message === 'string' ? unstyled(error.message) : 'Unknown error')\n const tryMessage = jsonTokenItem(error.tryMessage)\n const nextSteps = jsonTokenItems(error.nextSteps)\n const customSections = jsonCustomSections(error.customSections)\n const details = error.details\n\n const commonFields = {\n message,\n ...(typeof error.code === 'string' && error.code.length > 0 ? {code: error.code} : {}),\n ...(tryMessage === undefined ? {} : {tryMessage}),\n ...(nextSteps === undefined ? {} : {nextSteps}),\n ...(customSections === undefined ? {} : {customSections}),\n ...(details === undefined ? {} : {details}),\n }\n\n let jsonError: JsonError\n if (type === 'bug') {\n jsonError = {\n type,\n ...commonFields,\n ...(typeof error.stack === 'string' ? {stack: unstyled(error.stack)} : {}),\n }\n } else if (type === 'external' && external) {\n jsonError = {type, ...commonFields, ...external}\n } else {\n jsonError = {type: 'abort', ...commonFields}\n }\n\n return jsonError\n}\n"]}
|
|
@@ -40,6 +40,22 @@ export function resolveGraphiQLKey(providedKey, apiSecret, storeFqdn) {
|
|
|
40
40
|
return providedKey?.trim() || deriveGraphiQLKey(apiSecret, storeFqdn);
|
|
41
41
|
}
|
|
42
42
|
const require = createRequire(import.meta.url);
|
|
43
|
+
/**
|
|
44
|
+
* Serializes a value as JSON that is safe to place inside an inline `<script>` element.
|
|
45
|
+
* `JSON.stringify` alone leaves `<`, `>` and `&` as-is, so a value could close the script element early. Escaping
|
|
46
|
+
* them (and the U+2028/U+2029 line separators) as `\uXXXX` sequences keeps the JavaScript value identical.
|
|
47
|
+
*
|
|
48
|
+
* @param value - The value to serialize.
|
|
49
|
+
* @returns A JSON string that can be interpolated into an inline script.
|
|
50
|
+
*/
|
|
51
|
+
function serializeForInlineScript(value) {
|
|
52
|
+
return JSON.stringify(value)
|
|
53
|
+
.replace(/</g, '\\u003c')
|
|
54
|
+
.replace(/>/g, '\\u003e')
|
|
55
|
+
.replace(/&/g, '\\u0026')
|
|
56
|
+
.replace(/\u2028/g, '\\u2028')
|
|
57
|
+
.replace(/\u2029/g, '\\u2029');
|
|
58
|
+
}
|
|
43
59
|
class TokenRefreshError extends AbortError {
|
|
44
60
|
constructor() {
|
|
45
61
|
super('Failed to refresh credentials. Check that your app is installed, and try again.');
|
|
@@ -152,8 +168,8 @@ export function setupGraphiQLServer(options) {
|
|
|
152
168
|
}), {
|
|
153
169
|
url,
|
|
154
170
|
defaultQueries: [{ query: defaultQuery }],
|
|
155
|
-
query: queryParam ?
|
|
156
|
-
variables: variables ?
|
|
171
|
+
query: queryParam ? serializeForInlineScript(queryParam) : undefined,
|
|
172
|
+
variables: variables ? serializeForInlineScript(variables) : undefined,
|
|
157
173
|
});
|
|
158
174
|
}));
|
|
159
175
|
router.post('/graphiql/graphql.json', defineEventHandler(async (event) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../../src/public/node/graphiql/server.ts"],"names":[],"mappings":"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","sourcesContent":["import {defaultQuery, graphiqlTemplate} from './templates/graphiql.js'\nimport {unauthorizedTemplate} from './templates/unauthorized.js'\nimport {filterCustomHeaders} from './utilities.js'\nimport {performActionWithRetryAfterRecovery} from '../../common/retry.js'\nimport {CLI_KIT_VERSION} from '../../common/version.js'\nimport {AbortError} from '../error.js'\nimport {adminUrl, supportedApiVersions} from '../api/admin.js'\nimport {fetch} from '../http.js'\nimport {renderLiquidTemplate} from '../liquid.js'\nimport {outputDebug} from '../output.js'\nimport {containsMutation} from '../graphql.js'\nimport {\n createApp,\n createRouter,\n defineEventHandler,\n getQuery,\n getRequestHeader,\n getRequestHeaders,\n readBody,\n setResponseHeader,\n setResponseStatus,\n toNodeListener,\n} from 'h3'\nimport {createHmac, randomBytes} from 'crypto'\nimport {createServer, Server} from 'http'\nimport {readFileSync} from 'fs'\nimport {Writable} from 'stream'\nimport {createRequire} from 'module'\n\n/**\n * Derives a deterministic GraphiQL authentication key from the app's API secret and store FQDN.\n * The key is stable across dev server restarts (so browser tabs survive restarts)\n * but is not guessable without the app secret.\n *\n * @param apiSecret - The Partners app's client secret used as the HMAC key.\n * @param storeFqdn - The myshopify.com domain the GraphiQL session targets.\n * @returns A 64-character hex string suitable for use as the `?key=` query param.\n */\nexport function deriveGraphiQLKey(apiSecret: string, storeFqdn: string): string {\n return createHmac('sha256', apiSecret).update(`graphiql:${storeFqdn}`).digest('hex')\n}\n\n/**\n * Resolves the GraphiQL authentication key. Uses the explicitly provided key\n * if non-empty, otherwise derives one deterministically from the app secret.\n *\n * @param providedKey - An explicit key supplied by the caller; takes precedence when non-empty.\n * @param apiSecret - The Partners app's client secret, used to derive a stable key as a fallback.\n * @param storeFqdn - The myshopify.com domain the GraphiQL session targets.\n * @returns The resolved key.\n */\nexport function resolveGraphiQLKey(providedKey: string | undefined, apiSecret: string, storeFqdn: string): string {\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- intentional: empty string after trim should fall through to deriveGraphiQLKey\n return providedKey?.trim() || deriveGraphiQLKey(apiSecret, storeFqdn)\n}\n\nconst require = createRequire(import.meta.url)\n\nclass TokenRefreshError extends AbortError {\n constructor() {\n super('Failed to refresh credentials. Check that your app is installed, and try again.')\n }\n}\n\n/**\n * Pluggable strategy for obtaining and refreshing the Admin API access token\n * that the GraphiQL proxy injects into every request.\n *\n * - `getToken` may return a cached token; the proxy calls it for every request.\n * - `refreshToken` (optional) is invoked when the upstream Admin API returns 401.\n * When omitted, the proxy falls back to calling `getToken` again on 401.\n *\n * Implementations must throw `TokenRefreshError` (or any thrown error) when the\n * token cannot be obtained; the proxy renders the unauthorized template in that case.\n */\nexport interface TokenProvider {\n getToken: () => Promise<string>\n refreshToken?: () => Promise<string>\n}\n\n/**\n * Optional app-specific context, used to render the app pill and scopes note in the\n * GraphiQL header and to drive the deterministic key derivation. Pass when the GraphiQL\n * server is hosted as part of `shopify app dev`; omit for app-less use cases such as\n * `shopify store execute`.\n */\nexport interface GraphiQLAppContext {\n appName: string\n appUrl: string\n apiSecret: string\n}\n\nexport interface SetupGraphiQLServerOptions {\n stdout: Writable\n port: number\n storeFqdn: string\n tokenProvider: TokenProvider\n /**\n * Authentication key required as a `?key=` query string on every request. When omitted:\n * - if `appContext` is provided, derived deterministically from `apiSecret` + `storeFqdn`\n * so browser tabs survive dev server restarts.\n * - otherwise, generated randomly per process.\n */\n key?: string\n appContext?: GraphiQLAppContext\n /**\n * When true, the proxy rejects mutation operations with HTTP 400 before forwarding\n * them to the Admin API. Use this to mirror non-interactive safety guarantees in the\n * interactive UI.\n */\n protectMutations?: boolean\n}\n\nexport const MUTATIONS_BLOCKED_MESSAGE = 'Mutations are disabled. Re-run with --allow-mutations to enable mutations.'\n\n/**\n * Starts a local HTTP server that hosts the GraphiQL UI and proxies requests to the\n * Admin API for the configured store. Authentication is delegated to the supplied\n * `tokenProvider`, so the same server can serve both `shopify app dev` and stored-session\n * use cases.\n *\n * @param options - Configuration for the server, including the target store, the\n * pluggable token provider, and the local port to bind to.\n * @returns The underlying Node `http.Server` instance, already listening on `options.port`.\n */\nexport function setupGraphiQLServer(options: SetupGraphiQLServerOptions): Server {\n const {stdout, port, storeFqdn, tokenProvider, key: providedKey, appContext, protectMutations = false} = options\n const key = resolveGraphiQLServerKey(providedKey, appContext, storeFqdn)\n outputDebug(`Setting up GraphiQL HTTP server on port ${port}...`, stdout)\n\n const app = createApp()\n const router = createRouter()\n\n const refreshUpstreamToken = async (): Promise<string> => {\n try {\n outputDebug('refreshing token', stdout)\n return await (tokenProvider.refreshToken ?? tokenProvider.getToken)()\n } catch (_error) {\n throw new TokenRefreshError()\n }\n }\n\n const currentToken = async (): Promise<string> => {\n try {\n return await tokenProvider.getToken()\n } catch (_error) {\n throw new TokenRefreshError()\n }\n }\n\n async function fetchApiVersionsWithTokenRefresh(): Promise<string[]> {\n return performActionWithRetryAfterRecovery(\n async () => supportedApiVersions({storeFqdn, token: await currentToken()}),\n refreshUpstreamToken,\n )\n }\n\n const faviconPath = require.resolve('../../../../assets/graphiql/favicon.ico')\n const faviconContent = readFileSync(faviconPath)\n const stylePath = require.resolve('../../../../assets/graphiql/style.css')\n const styleContent = readFileSync(stylePath, 'utf8')\n\n app.use(\n defineEventHandler((event) => {\n setResponseHeader(event, 'Access-Control-Allow-Origin', '*')\n setResponseHeader(event, 'Access-Control-Allow-Methods', 'GET, OPTIONS')\n setResponseHeader(\n event,\n 'Access-Control-Allow-Headers',\n 'Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, ngrok-skip-browser-warning',\n )\n }),\n )\n\n router.get(\n '/graphiql/ping',\n defineEventHandler(() => 'pong'),\n )\n\n router.get(\n '/graphiql/favicon.ico',\n defineEventHandler((event) => {\n setResponseHeader(event, 'Content-Type', 'image/x-icon')\n return faviconContent\n }),\n )\n\n router.get(\n '/graphiql/simple.css',\n defineEventHandler((event) => {\n setResponseHeader(event, 'Content-Type', 'text/css')\n return styleContent\n }),\n )\n\n router.get(\n '/graphiql/status',\n defineEventHandler(async () => {\n try {\n await fetchApiVersionsWithTokenRefresh()\n return {status: 'OK', storeFqdn, appName: appContext?.appName, appUrl: appContext?.appUrl}\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return {status: 'UNAUTHENTICATED'}\n }\n }),\n )\n\n router.get(\n '/graphiql',\n defineEventHandler(async (event) => {\n outputDebug('Handling /graphiql request', stdout)\n\n const query = getQuery(event)\n\n if (key && query.key !== key) {\n setResponseStatus(event, 404)\n return `Invalid path ${event.path}`\n }\n\n const forwardedProto = getRequestHeader(event, 'x-forwarded-proto')\n const usesHttps = forwardedProto === 'https'\n const host = getRequestHeader(event, 'host')\n const url = `http${usesHttps ? 's' : ''}://${host}`\n\n let apiVersions: string[]\n try {\n apiVersions = await fetchApiVersionsWithTokenRefresh()\n } catch (err) {\n if (err instanceof TokenRefreshError) {\n return renderLiquidTemplate(unauthorizedTemplate({hasAppContext: Boolean(appContext)}), {\n previewUrl: appContext?.appUrl ?? '',\n storeFqdn,\n url,\n })\n }\n throw err\n }\n\n const apiVersion = apiVersions.sort().reverse()[0]!\n\n function decodeQueryString(input: string | undefined) {\n return input ? decodeURIComponent(input).replace(/\\n/g, '\\\\n') : undefined\n }\n\n const queryParam = decodeQueryString(query.query as string | undefined)\n const variables = decodeQueryString(query.variables as string | undefined)\n\n return renderLiquidTemplate(\n graphiqlTemplate({\n apiVersion,\n apiVersions: [...apiVersions, 'unstable'],\n appName: appContext?.appName,\n appUrl: appContext?.appUrl,\n key,\n storeFqdn,\n protectMutations,\n }),\n {\n url,\n defaultQueries: [{query: defaultQuery}],\n query: queryParam ? JSON.stringify(queryParam) : undefined,\n variables: variables ? JSON.stringify(variables) : undefined,\n },\n )\n }),\n )\n\n router.post(\n '/graphiql/graphql.json',\n defineEventHandler(async (event) => {\n outputDebug('Handling /graphiql/graphql.json request', stdout)\n\n const query = getQuery(event)\n\n if (key && query.key !== key) {\n setResponseStatus(event, 404)\n return `Invalid path ${event.path}`\n }\n\n const graphqlUrl = adminUrl(storeFqdn, query.api_version as string)\n try {\n const body = await readBody(event)\n\n if (protectMutations && isMutationRequestBody(body)) {\n setResponseStatus(event, 400)\n return {errors: [{message: MUTATIONS_BLOCKED_MESSAGE}]}\n }\n\n const reqBody = JSON.stringify(body)\n\n const reqHeaders = getRequestHeaders(event)\n const customHeaders = filterCustomHeaders(reqHeaders)\n\n const runRequest = async (token: string) => {\n const headers = {\n ...customHeaders,\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n 'X-Shopify-Access-Token': token,\n 'User-Agent': `ShopifyCLIGraphiQL/${CLI_KIT_VERSION}`,\n }\n\n return fetch(graphqlUrl, {\n method: 'POST',\n headers,\n body: reqBody,\n })\n }\n\n let result = await runRequest(await currentToken())\n if (result.status === 401) {\n outputDebug('Token expired, fetching new token', stdout)\n result = await runRequest(await refreshUpstreamToken())\n }\n\n setResponseHeader(event, 'Content-Type', 'application/json')\n setResponseStatus(event, result.status)\n return result.json()\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error: unknown) {\n setResponseStatus(event, 500)\n if (error instanceof Error) {\n return {errors: [error.message]}\n }\n return {errors: ['Unknown error']}\n }\n }),\n )\n\n app.use(router)\n\n const server = createServer(toNodeListener(app))\n server.listen(port, 'localhost', () => stdout.write(`GraphiQL server started on port ${port}`))\n return server\n}\n\n// Picks the right key based on what the caller supplied:\n// - explicit non-empty key → use it\n// - app context with apiSecret → derive deterministically (stable across restarts)\n// - otherwise → random per-process key (browser tabs won't survive restarts, which is\n// the right tradeoff when there's no stable secret to derive from).\nfunction resolveGraphiQLServerKey(\n providedKey: string | undefined,\n appContext: GraphiQLAppContext | undefined,\n storeFqdn: string,\n): string {\n const trimmed = providedKey?.trim()\n if (trimmed) return trimmed\n if (appContext) return deriveGraphiQLKey(appContext.apiSecret, storeFqdn)\n return randomBytes(32).toString('hex')\n}\n\nfunction isMutationRequestBody(body: unknown): boolean {\n if (typeof body !== 'object' || body === null) return false\n const {query, operationName} = body as {query?: unknown; operationName?: unknown}\n if (typeof query !== 'string') return false\n return containsMutation(query, typeof operationName === 'string' ? operationName : undefined)\n}\n"]}
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../../src/public/node/graphiql/server.ts"],"names":[],"mappings":"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","sourcesContent":["import {defaultQuery, graphiqlTemplate} from './templates/graphiql.js'\nimport {unauthorizedTemplate} from './templates/unauthorized.js'\nimport {filterCustomHeaders} from './utilities.js'\nimport {performActionWithRetryAfterRecovery} from '../../common/retry.js'\nimport {CLI_KIT_VERSION} from '../../common/version.js'\nimport {AbortError} from '../error.js'\nimport {adminUrl, supportedApiVersions} from '../api/admin.js'\nimport {fetch} from '../http.js'\nimport {renderLiquidTemplate} from '../liquid.js'\nimport {outputDebug} from '../output.js'\nimport {containsMutation} from '../graphql.js'\nimport {\n createApp,\n createRouter,\n defineEventHandler,\n getQuery,\n getRequestHeader,\n getRequestHeaders,\n readBody,\n setResponseHeader,\n setResponseStatus,\n toNodeListener,\n} from 'h3'\nimport {createHmac, randomBytes} from 'crypto'\nimport {createServer, Server} from 'http'\nimport {readFileSync} from 'fs'\nimport {Writable} from 'stream'\nimport {createRequire} from 'module'\n\n/**\n * Derives a deterministic GraphiQL authentication key from the app's API secret and store FQDN.\n * The key is stable across dev server restarts (so browser tabs survive restarts)\n * but is not guessable without the app secret.\n *\n * @param apiSecret - The Partners app's client secret used as the HMAC key.\n * @param storeFqdn - The myshopify.com domain the GraphiQL session targets.\n * @returns A 64-character hex string suitable for use as the `?key=` query param.\n */\nexport function deriveGraphiQLKey(apiSecret: string, storeFqdn: string): string {\n return createHmac('sha256', apiSecret).update(`graphiql:${storeFqdn}`).digest('hex')\n}\n\n/**\n * Resolves the GraphiQL authentication key. Uses the explicitly provided key\n * if non-empty, otherwise derives one deterministically from the app secret.\n *\n * @param providedKey - An explicit key supplied by the caller; takes precedence when non-empty.\n * @param apiSecret - The Partners app's client secret, used to derive a stable key as a fallback.\n * @param storeFqdn - The myshopify.com domain the GraphiQL session targets.\n * @returns The resolved key.\n */\nexport function resolveGraphiQLKey(providedKey: string | undefined, apiSecret: string, storeFqdn: string): string {\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- intentional: empty string after trim should fall through to deriveGraphiQLKey\n return providedKey?.trim() || deriveGraphiQLKey(apiSecret, storeFqdn)\n}\n\nconst require = createRequire(import.meta.url)\n\n/**\n * Serializes a value as JSON that is safe to place inside an inline `<script>` element.\n * `JSON.stringify` alone leaves `<`, `>` and `&` as-is, so a value could close the script element early. Escaping\n * them (and the U+2028/U+2029 line separators) as `\\uXXXX` sequences keeps the JavaScript value identical.\n *\n * @param value - The value to serialize.\n * @returns A JSON string that can be interpolated into an inline script.\n */\nfunction serializeForInlineScript(value: unknown): string {\n return JSON.stringify(value)\n .replace(/</g, '\\\\u003c')\n .replace(/>/g, '\\\\u003e')\n .replace(/&/g, '\\\\u0026')\n .replace(/\\u2028/g, '\\\\u2028')\n .replace(/\\u2029/g, '\\\\u2029')\n}\n\nclass TokenRefreshError extends AbortError {\n constructor() {\n super('Failed to refresh credentials. Check that your app is installed, and try again.')\n }\n}\n\n/**\n * Pluggable strategy for obtaining and refreshing the Admin API access token\n * that the GraphiQL proxy injects into every request.\n *\n * - `getToken` may return a cached token; the proxy calls it for every request.\n * - `refreshToken` (optional) is invoked when the upstream Admin API returns 401.\n * When omitted, the proxy falls back to calling `getToken` again on 401.\n *\n * Implementations must throw `TokenRefreshError` (or any thrown error) when the\n * token cannot be obtained; the proxy renders the unauthorized template in that case.\n */\nexport interface TokenProvider {\n getToken: () => Promise<string>\n refreshToken?: () => Promise<string>\n}\n\n/**\n * Optional app-specific context, used to render the app pill and scopes note in the\n * GraphiQL header and to drive the deterministic key derivation. Pass when the GraphiQL\n * server is hosted as part of `shopify app dev`; omit for app-less use cases such as\n * `shopify store execute`.\n */\nexport interface GraphiQLAppContext {\n appName: string\n appUrl: string\n apiSecret: string\n}\n\nexport interface SetupGraphiQLServerOptions {\n stdout: Writable\n port: number\n storeFqdn: string\n tokenProvider: TokenProvider\n /**\n * Authentication key required as a `?key=` query string on every request. When omitted:\n * - if `appContext` is provided, derived deterministically from `apiSecret` + `storeFqdn`\n * so browser tabs survive dev server restarts.\n * - otherwise, generated randomly per process.\n */\n key?: string\n appContext?: GraphiQLAppContext\n /**\n * When true, the proxy rejects mutation operations with HTTP 400 before forwarding\n * them to the Admin API. Use this to mirror non-interactive safety guarantees in the\n * interactive UI.\n */\n protectMutations?: boolean\n}\n\nexport const MUTATIONS_BLOCKED_MESSAGE = 'Mutations are disabled. Re-run with --allow-mutations to enable mutations.'\n\n/**\n * Starts a local HTTP server that hosts the GraphiQL UI and proxies requests to the\n * Admin API for the configured store. Authentication is delegated to the supplied\n * `tokenProvider`, so the same server can serve both `shopify app dev` and stored-session\n * use cases.\n *\n * @param options - Configuration for the server, including the target store, the\n * pluggable token provider, and the local port to bind to.\n * @returns The underlying Node `http.Server` instance, already listening on `options.port`.\n */\nexport function setupGraphiQLServer(options: SetupGraphiQLServerOptions): Server {\n const {stdout, port, storeFqdn, tokenProvider, key: providedKey, appContext, protectMutations = false} = options\n const key = resolveGraphiQLServerKey(providedKey, appContext, storeFqdn)\n outputDebug(`Setting up GraphiQL HTTP server on port ${port}...`, stdout)\n\n const app = createApp()\n const router = createRouter()\n\n const refreshUpstreamToken = async (): Promise<string> => {\n try {\n outputDebug('refreshing token', stdout)\n return await (tokenProvider.refreshToken ?? tokenProvider.getToken)()\n } catch (_error) {\n throw new TokenRefreshError()\n }\n }\n\n const currentToken = async (): Promise<string> => {\n try {\n return await tokenProvider.getToken()\n } catch (_error) {\n throw new TokenRefreshError()\n }\n }\n\n async function fetchApiVersionsWithTokenRefresh(): Promise<string[]> {\n return performActionWithRetryAfterRecovery(\n async () => supportedApiVersions({storeFqdn, token: await currentToken()}),\n refreshUpstreamToken,\n )\n }\n\n const faviconPath = require.resolve('../../../../assets/graphiql/favicon.ico')\n const faviconContent = readFileSync(faviconPath)\n const stylePath = require.resolve('../../../../assets/graphiql/style.css')\n const styleContent = readFileSync(stylePath, 'utf8')\n\n app.use(\n defineEventHandler((event) => {\n setResponseHeader(event, 'Access-Control-Allow-Origin', '*')\n setResponseHeader(event, 'Access-Control-Allow-Methods', 'GET, OPTIONS')\n setResponseHeader(\n event,\n 'Access-Control-Allow-Headers',\n 'Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, ngrok-skip-browser-warning',\n )\n }),\n )\n\n router.get(\n '/graphiql/ping',\n defineEventHandler(() => 'pong'),\n )\n\n router.get(\n '/graphiql/favicon.ico',\n defineEventHandler((event) => {\n setResponseHeader(event, 'Content-Type', 'image/x-icon')\n return faviconContent\n }),\n )\n\n router.get(\n '/graphiql/simple.css',\n defineEventHandler((event) => {\n setResponseHeader(event, 'Content-Type', 'text/css')\n return styleContent\n }),\n )\n\n router.get(\n '/graphiql/status',\n defineEventHandler(async () => {\n try {\n await fetchApiVersionsWithTokenRefresh()\n return {status: 'OK', storeFqdn, appName: appContext?.appName, appUrl: appContext?.appUrl}\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return {status: 'UNAUTHENTICATED'}\n }\n }),\n )\n\n router.get(\n '/graphiql',\n defineEventHandler(async (event) => {\n outputDebug('Handling /graphiql request', stdout)\n\n const query = getQuery(event)\n\n if (key && query.key !== key) {\n setResponseStatus(event, 404)\n return `Invalid path ${event.path}`\n }\n\n const forwardedProto = getRequestHeader(event, 'x-forwarded-proto')\n const usesHttps = forwardedProto === 'https'\n const host = getRequestHeader(event, 'host')\n const url = `http${usesHttps ? 's' : ''}://${host}`\n\n let apiVersions: string[]\n try {\n apiVersions = await fetchApiVersionsWithTokenRefresh()\n } catch (err) {\n if (err instanceof TokenRefreshError) {\n return renderLiquidTemplate(unauthorizedTemplate({hasAppContext: Boolean(appContext)}), {\n previewUrl: appContext?.appUrl ?? '',\n storeFqdn,\n url,\n })\n }\n throw err\n }\n\n const apiVersion = apiVersions.sort().reverse()[0]!\n\n function decodeQueryString(input: string | undefined) {\n return input ? decodeURIComponent(input).replace(/\\n/g, '\\\\n') : undefined\n }\n\n const queryParam = decodeQueryString(query.query as string | undefined)\n const variables = decodeQueryString(query.variables as string | undefined)\n\n return renderLiquidTemplate(\n graphiqlTemplate({\n apiVersion,\n apiVersions: [...apiVersions, 'unstable'],\n appName: appContext?.appName,\n appUrl: appContext?.appUrl,\n key,\n storeFqdn,\n protectMutations,\n }),\n {\n url,\n defaultQueries: [{query: defaultQuery}],\n query: queryParam ? serializeForInlineScript(queryParam) : undefined,\n variables: variables ? serializeForInlineScript(variables) : undefined,\n },\n )\n }),\n )\n\n router.post(\n '/graphiql/graphql.json',\n defineEventHandler(async (event) => {\n outputDebug('Handling /graphiql/graphql.json request', stdout)\n\n const query = getQuery(event)\n\n if (key && query.key !== key) {\n setResponseStatus(event, 404)\n return `Invalid path ${event.path}`\n }\n\n const graphqlUrl = adminUrl(storeFqdn, query.api_version as string)\n try {\n const body = await readBody(event)\n\n if (protectMutations && isMutationRequestBody(body)) {\n setResponseStatus(event, 400)\n return {errors: [{message: MUTATIONS_BLOCKED_MESSAGE}]}\n }\n\n const reqBody = JSON.stringify(body)\n\n const reqHeaders = getRequestHeaders(event)\n const customHeaders = filterCustomHeaders(reqHeaders)\n\n const runRequest = async (token: string) => {\n const headers = {\n ...customHeaders,\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n 'X-Shopify-Access-Token': token,\n 'User-Agent': `ShopifyCLIGraphiQL/${CLI_KIT_VERSION}`,\n }\n\n return fetch(graphqlUrl, {\n method: 'POST',\n headers,\n body: reqBody,\n })\n }\n\n let result = await runRequest(await currentToken())\n if (result.status === 401) {\n outputDebug('Token expired, fetching new token', stdout)\n result = await runRequest(await refreshUpstreamToken())\n }\n\n setResponseHeader(event, 'Content-Type', 'application/json')\n setResponseStatus(event, result.status)\n return result.json()\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error: unknown) {\n setResponseStatus(event, 500)\n if (error instanceof Error) {\n return {errors: [error.message]}\n }\n return {errors: ['Unknown error']}\n }\n }),\n )\n\n app.use(router)\n\n const server = createServer(toNodeListener(app))\n server.listen(port, 'localhost', () => stdout.write(`GraphiQL server started on port ${port}`))\n return server\n}\n\n// Picks the right key based on what the caller supplied:\n// - explicit non-empty key → use it\n// - app context with apiSecret → derive deterministically (stable across restarts)\n// - otherwise → random per-process key (browser tabs won't survive restarts, which is\n// the right tradeoff when there's no stable secret to derive from).\nfunction resolveGraphiQLServerKey(\n providedKey: string | undefined,\n appContext: GraphiQLAppContext | undefined,\n storeFqdn: string,\n): string {\n const trimmed = providedKey?.trim()\n if (trimmed) return trimmed\n if (appContext) return deriveGraphiQLKey(appContext.apiSecret, storeFqdn)\n return randomBytes(32).toString('hex')\n}\n\nfunction isMutationRequestBody(body: unknown): boolean {\n if (typeof body !== 'object' || body === null) return false\n const {query, operationName} = body as {query?: unknown; operationName?: unknown}\n if (typeof query !== 'string') return false\n return containsMutation(query, typeof operationName === 'string' ? operationName : undefined)\n}\n"]}
|
|
@@ -48,9 +48,10 @@ export function currentProcessIsGlobal(argv = process.argv) {
|
|
|
48
48
|
export async function installGlobalShopifyCLI(packageManager) {
|
|
49
49
|
const { outputInfo } = await import('./output.js');
|
|
50
50
|
const { exec } = await import('./system.js');
|
|
51
|
+
const { jsonOutputEnabled } = await import('./environment.js');
|
|
51
52
|
const args = packageManager === 'yarn' ? ['global', 'add', '@shopify/cli@latest'] : ['install', '-g', '@shopify/cli@latest'];
|
|
52
53
|
outputInfo(`Running ${packageManager} ${args.join(' ')}...`);
|
|
53
|
-
await exec(packageManager, args, { stdio: 'inherit' });
|
|
54
|
+
await exec(packageManager, args, jsonOutputEnabled() ? {} : { stdio: 'inherit' });
|
|
54
55
|
}
|
|
55
56
|
/**
|
|
56
57
|
* Prompts the user to install the global CLI.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"is-global.js","sourceRoot":"","sources":["../../../src/public/node/is-global.ts"],"names":[],"mappings":"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","sourcesContent":["import {cwd, dirname, isSubpath, joinPath, sniffForPath} from './path.js'\nimport {isUnitTest} from './context/local.js'\nimport {findPathUpSync, globSync} from './fs.js'\nimport {realpathSync} from 'fs'\nimport type {PackageManager} from './node-package-manager.js'\n\nlet _isGlobal: boolean | undefined\n\n/**\n * Returns true if the current process is running in a global context.\n *\n * @param argv - The arguments passed to the process.\n * @returns `true` if the current process is running in a global context.\n */\nexport function currentProcessIsGlobal(argv = process.argv): boolean {\n // If we are running tests, we need to disable the cache\n try {\n if (_isGlobal !== undefined && !isUnitTest()) return _isGlobal\n\n // Path where the current project is (app/hydrogen)\n const path = sniffForPath() ?? cwd()\n\n const projectDir = getProjectDir(path)\n if (!projectDir) {\n return true\n }\n\n // From node docs: \"The second element [of the array] will be the path to the JavaScript file being executed\"\n const binDir = argv[1] ?? ''\n if (!binDir) {\n return true\n }\n\n // If binDir lives inside projectDir, we are running a local CLI.\n // Use isSubpath (pathe.relative under the hood) instead of a raw\n // string startsWith: projectDir flows through normalizePath and is\n // forward-slash on every platform, while argv[1] is OS-native, so on\n // Windows it arrives backslash-separated and a naive startsWith would\n // misclassify a local install as global.\n const isLocal = isSubpath(projectDir.trim(), binDir)\n\n _isGlobal = !isLocal\n return _isGlobal\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n return false\n }\n}\n\n/**\n * Installs the global Shopify CLI, using the provided package manager.\n *\n * @param packageManager - The package manager to use.\n */\nexport async function installGlobalShopifyCLI(packageManager: PackageManager): Promise<void> {\n const {outputInfo} = await import('./output.js')\n const {exec} = await import('./system.js')\n const args =\n packageManager === 'yarn' ? ['global', 'add', '@shopify/cli@latest'] : ['install', '-g', '@shopify/cli@latest']\n outputInfo(`Running ${packageManager} ${args.join(' ')}...`)\n await exec(packageManager, args, {stdio: 'inherit'})\n}\n\nexport interface InstallGlobalCLIPromptResult {\n install: boolean\n alreadyInstalled: boolean\n}\n/**\n * Prompts the user to install the global CLI.\n *\n * @returns `true` if the user has installed the global CLI.\n */\nexport async function installGlobalCLIPrompt(): Promise<InstallGlobalCLIPromptResult> {\n const {terminalSupportsPrompting} = await import('./system.js')\n if (!terminalSupportsPrompting()) return {install: false, alreadyInstalled: false}\n const {globalCLIVersion} = await import('./version.js')\n if (await globalCLIVersion()) {\n return {install: false, alreadyInstalled: true}\n }\n const {renderSelectPrompt} = await import('./ui.js')\n const result = await renderSelectPrompt({\n message: 'We recommend installing Shopify CLI globally in your system. Would you like to install it now?',\n choices: [\n {value: 'yes', label: 'Yes'},\n {value: 'no', label: 'No, just for this project'},\n ],\n })\n\n return {install: result === 'yes', alreadyInstalled: false}\n}\n\n/**\n * Infers the package manager used by the global CLI.\n *\n * @param argv - The arguments passed to the process.\n * @param env - The environment variables of the process.\n * @returns The package manager used by the global CLI.\n */\nexport function inferPackageManagerForGlobalCLI(argv = process.argv, env = process.env): PackageManager {\n if (!currentProcessIsGlobal(argv)) return 'unknown'\n\n // Check for Homebrew first (most reliable via environment variable)\n if (env.SHOPIFY_HOMEBREW_FORMULA) {\n return 'homebrew'\n }\n\n const processArgv = argv[1] ?? ''\n const symlinkPath = processArgv.toLowerCase()\n\n // Resolve symlinks to get the real path of the binary.\n let realPath = symlinkPath\n try {\n realPath = realpathSync(processArgv).toLowerCase()\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n // fall back to using the original path for detection\n }\n\n // Inspect both the (unresolved) symlink path and the resolved real path. Some\n // package managers — notably bun (`~/.bun/bin/<name>`) — install global binaries\n // as symlinks pointing into a generic `node_modules` directory whose real path\n // no longer contains the package manager name. The original symlink under the\n // PM's bin dir is the most reliable signal in that case.\n const matches = (needle: string) => realPath.includes(needle) || symlinkPath.includes(needle)\n\n if (matches('yarn')) return 'yarn'\n if (matches('pnpm')) return 'pnpm'\n if (matches('bun')) return 'bun'\n\n // Check for Homebrew via Cellar path (resolved symlink)\n if (realPath.includes('/cellar/')) return 'homebrew'\n\n return 'npm'\n}\n\n/**\n * Returns the project directory for the given path.\n *\n * @param directory - The path to search upward from.\n * @returns The project root directory, or undefined if not found.\n */\nexport function getProjectDir(directory: string): string | undefined {\n const configFiles = ['shopify.app{,.*}.toml', 'hydrogen.config.js', 'hydrogen.config.ts']\n const existsConfigFile = (directory: string) => {\n const configPaths = globSync(configFiles.map((file) => joinPath(directory, file)))\n return configPaths.length > 0 ? configPaths[0] : undefined\n }\n try {\n const configFile = findPathUpSync(existsConfigFile, {\n cwd: directory,\n type: 'file',\n })\n if (configFile) return dirname(configFile)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n return undefined\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"is-global.js","sourceRoot":"","sources":["../../../src/public/node/is-global.ts"],"names":[],"mappings":"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","sourcesContent":["import {cwd, dirname, isSubpath, joinPath, sniffForPath} from './path.js'\nimport {isUnitTest} from './context/local.js'\nimport {findPathUpSync, globSync} from './fs.js'\nimport {realpathSync} from 'fs'\nimport type {PackageManager} from './node-package-manager.js'\n\nlet _isGlobal: boolean | undefined\n\n/**\n * Returns true if the current process is running in a global context.\n *\n * @param argv - The arguments passed to the process.\n * @returns `true` if the current process is running in a global context.\n */\nexport function currentProcessIsGlobal(argv = process.argv): boolean {\n // If we are running tests, we need to disable the cache\n try {\n if (_isGlobal !== undefined && !isUnitTest()) return _isGlobal\n\n // Path where the current project is (app/hydrogen)\n const path = sniffForPath() ?? cwd()\n\n const projectDir = getProjectDir(path)\n if (!projectDir) {\n return true\n }\n\n // From node docs: \"The second element [of the array] will be the path to the JavaScript file being executed\"\n const binDir = argv[1] ?? ''\n if (!binDir) {\n return true\n }\n\n // If binDir lives inside projectDir, we are running a local CLI.\n // Use isSubpath (pathe.relative under the hood) instead of a raw\n // string startsWith: projectDir flows through normalizePath and is\n // forward-slash on every platform, while argv[1] is OS-native, so on\n // Windows it arrives backslash-separated and a naive startsWith would\n // misclassify a local install as global.\n const isLocal = isSubpath(projectDir.trim(), binDir)\n\n _isGlobal = !isLocal\n return _isGlobal\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n return false\n }\n}\n\n/**\n * Installs the global Shopify CLI, using the provided package manager.\n *\n * @param packageManager - The package manager to use.\n */\nexport async function installGlobalShopifyCLI(packageManager: PackageManager): Promise<void> {\n const {outputInfo} = await import('./output.js')\n const {exec} = await import('./system.js')\n const {jsonOutputEnabled} = await import('./environment.js')\n const args =\n packageManager === 'yarn' ? ['global', 'add', '@shopify/cli@latest'] : ['install', '-g', '@shopify/cli@latest']\n outputInfo(`Running ${packageManager} ${args.join(' ')}...`)\n await exec(packageManager, args, jsonOutputEnabled() ? {} : {stdio: 'inherit'})\n}\n\nexport interface InstallGlobalCLIPromptResult {\n install: boolean\n alreadyInstalled: boolean\n}\n/**\n * Prompts the user to install the global CLI.\n *\n * @returns `true` if the user has installed the global CLI.\n */\nexport async function installGlobalCLIPrompt(): Promise<InstallGlobalCLIPromptResult> {\n const {terminalSupportsPrompting} = await import('./system.js')\n if (!terminalSupportsPrompting()) return {install: false, alreadyInstalled: false}\n const {globalCLIVersion} = await import('./version.js')\n if (await globalCLIVersion()) {\n return {install: false, alreadyInstalled: true}\n }\n const {renderSelectPrompt} = await import('./ui.js')\n const result = await renderSelectPrompt({\n message: 'We recommend installing Shopify CLI globally in your system. Would you like to install it now?',\n choices: [\n {value: 'yes', label: 'Yes'},\n {value: 'no', label: 'No, just for this project'},\n ],\n })\n\n return {install: result === 'yes', alreadyInstalled: false}\n}\n\n/**\n * Infers the package manager used by the global CLI.\n *\n * @param argv - The arguments passed to the process.\n * @param env - The environment variables of the process.\n * @returns The package manager used by the global CLI.\n */\nexport function inferPackageManagerForGlobalCLI(argv = process.argv, env = process.env): PackageManager {\n if (!currentProcessIsGlobal(argv)) return 'unknown'\n\n // Check for Homebrew first (most reliable via environment variable)\n if (env.SHOPIFY_HOMEBREW_FORMULA) {\n return 'homebrew'\n }\n\n const processArgv = argv[1] ?? ''\n const symlinkPath = processArgv.toLowerCase()\n\n // Resolve symlinks to get the real path of the binary.\n let realPath = symlinkPath\n try {\n realPath = realpathSync(processArgv).toLowerCase()\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n // fall back to using the original path for detection\n }\n\n // Inspect both the (unresolved) symlink path and the resolved real path. Some\n // package managers — notably bun (`~/.bun/bin/<name>`) — install global binaries\n // as symlinks pointing into a generic `node_modules` directory whose real path\n // no longer contains the package manager name. The original symlink under the\n // PM's bin dir is the most reliable signal in that case.\n const matches = (needle: string) => realPath.includes(needle) || symlinkPath.includes(needle)\n\n if (matches('yarn')) return 'yarn'\n if (matches('pnpm')) return 'pnpm'\n if (matches('bun')) return 'bun'\n\n // Check for Homebrew via Cellar path (resolved symlink)\n if (realPath.includes('/cellar/')) return 'homebrew'\n\n return 'npm'\n}\n\n/**\n * Returns the project directory for the given path.\n *\n * @param directory - The path to search upward from.\n * @returns The project root directory, or undefined if not found.\n */\nexport function getProjectDir(directory: string): string | undefined {\n const configFiles = ['shopify.app{,.*}.toml', 'hydrogen.config.js', 'hydrogen.config.ts']\n const existsConfigFile = (directory: string) => {\n const configPaths = globSync(configFiles.map((file) => joinPath(directory, file)))\n return configPaths.length > 0 ? configPaths[0] : undefined\n }\n try {\n const configFile = findPathUpSync(existsConfigFile, {\n cwd: directory,\n type: 'file',\n })\n if (configFile) return dirname(configFile)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (error) {\n return undefined\n }\n}\n"]}
|
|
@@ -26,7 +26,7 @@ declare const NotificationSchema: zod.ZodObject<{
|
|
|
26
26
|
id: string;
|
|
27
27
|
type: "info" | "error" | "warning";
|
|
28
28
|
message: string;
|
|
29
|
-
frequency: "
|
|
29
|
+
frequency: "once" | "always" | "once_a_day" | "once_a_week";
|
|
30
30
|
ownerChannel: string;
|
|
31
31
|
title?: string | undefined;
|
|
32
32
|
cta?: {
|
|
@@ -43,7 +43,7 @@ declare const NotificationSchema: zod.ZodObject<{
|
|
|
43
43
|
id: string;
|
|
44
44
|
type: "info" | "error" | "warning";
|
|
45
45
|
message: string;
|
|
46
|
-
frequency: "
|
|
46
|
+
frequency: "once" | "always" | "once_a_day" | "once_a_week";
|
|
47
47
|
ownerChannel: string;
|
|
48
48
|
title?: string | undefined;
|
|
49
49
|
cta?: {
|
|
@@ -86,7 +86,7 @@ declare const NotificationsSchema: zod.ZodObject<{
|
|
|
86
86
|
id: string;
|
|
87
87
|
type: "info" | "error" | "warning";
|
|
88
88
|
message: string;
|
|
89
|
-
frequency: "
|
|
89
|
+
frequency: "once" | "always" | "once_a_day" | "once_a_week";
|
|
90
90
|
ownerChannel: string;
|
|
91
91
|
title?: string | undefined;
|
|
92
92
|
cta?: {
|
|
@@ -103,7 +103,7 @@ declare const NotificationsSchema: zod.ZodObject<{
|
|
|
103
103
|
id: string;
|
|
104
104
|
type: "info" | "error" | "warning";
|
|
105
105
|
message: string;
|
|
106
|
-
frequency: "
|
|
106
|
+
frequency: "once" | "always" | "once_a_day" | "once_a_week";
|
|
107
107
|
ownerChannel: string;
|
|
108
108
|
title?: string | undefined;
|
|
109
109
|
cta?: {
|
|
@@ -122,7 +122,7 @@ declare const NotificationsSchema: zod.ZodObject<{
|
|
|
122
122
|
id: string;
|
|
123
123
|
type: "info" | "error" | "warning";
|
|
124
124
|
message: string;
|
|
125
|
-
frequency: "
|
|
125
|
+
frequency: "once" | "always" | "once_a_day" | "once_a_week";
|
|
126
126
|
ownerChannel: string;
|
|
127
127
|
title?: string | undefined;
|
|
128
128
|
cta?: {
|
|
@@ -141,7 +141,7 @@ declare const NotificationsSchema: zod.ZodObject<{
|
|
|
141
141
|
id: string;
|
|
142
142
|
type: "info" | "error" | "warning";
|
|
143
143
|
message: string;
|
|
144
|
-
frequency: "
|
|
144
|
+
frequency: "once" | "always" | "once_a_day" | "once_a_week";
|
|
145
145
|
ownerChannel: string;
|
|
146
146
|
title?: string | undefined;
|
|
147
147
|
cta?: {
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { URL } from 'url';
|
|
2
|
+
interface IsSubpathOptions {
|
|
3
|
+
native?: boolean;
|
|
4
|
+
}
|
|
2
5
|
/**
|
|
3
6
|
* Joins a list of paths together.
|
|
4
7
|
*
|
|
@@ -90,13 +93,25 @@ export declare function commonParentDirectory(first: string, second: string): st
|
|
|
90
93
|
*/
|
|
91
94
|
export declare function relativizePath(path: string, dir?: string): string;
|
|
92
95
|
/**
|
|
93
|
-
* Given 2 paths, it returns whether the second path is
|
|
96
|
+
* Given 2 paths, it returns whether the second path is inside or equal to the first path.
|
|
97
|
+
*
|
|
98
|
+
* By default, paths are compared with pathe, which treats `\` as a separator
|
|
99
|
+
* on every platform. This behaviour is kept for backward compatibility.
|
|
100
|
+
*
|
|
101
|
+
* When `native` is true, paths are compared with the current OS's native path
|
|
102
|
+
* semantics, so literal backslashes on POSIX are preserved as filename
|
|
103
|
+
* characters. Use `native: true` for security or containment checks on
|
|
104
|
+
* resolved filesystem paths.
|
|
105
|
+
*
|
|
106
|
+
* Symbolic links are not resolved; use fileRealPath from the fs module first
|
|
107
|
+
* when checking physical containment.
|
|
94
108
|
*
|
|
95
109
|
* @param mainPath - The main path.
|
|
96
110
|
* @param subpath - The subpath.
|
|
97
|
-
* @
|
|
111
|
+
* @param options - Comparison options. Set `native` to true to use the OS's native path semantics. Defaults to false.
|
|
112
|
+
* @returns Whether the subpath is inside or equal to the main path.
|
|
98
113
|
*/
|
|
99
|
-
export declare function isSubpath(mainPath: string, subpath: string): boolean;
|
|
114
|
+
export declare function isSubpath(mainPath: string, subpath: string, options?: IsSubpathOptions): boolean;
|
|
100
115
|
/**
|
|
101
116
|
* Given a module's import.meta.url it returns the directory containing the module.
|
|
102
117
|
*
|
|
@@ -139,3 +154,4 @@ export declare function sniffForJson(argv?: string[]): boolean;
|
|
|
139
154
|
* @returns The sanitized path (may be an empty string if all segments were traversal).
|
|
140
155
|
*/
|
|
141
156
|
export declare function sanitizeRelativePath(input: string, warn: (msg: string) => void): string;
|
|
157
|
+
export {};
|
package/dist/public/node/path.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { relative, dirname as patheDirname, join, normalize, resolve, basename as basenamePathe, extname as extnamePathe, parse, isAbsolute, } from 'pathe';
|
|
2
2
|
import { fileURLToPath } from 'url';
|
|
3
|
+
// eslint-disable-next-line no-restricted-imports -- Native containment must preserve literal POSIX backslashes.
|
|
4
|
+
import { relative as nativeRelative, isAbsolute as nativeIsAbsolute, sep as nativeSeparator } from 'node:path';
|
|
3
5
|
/**
|
|
4
6
|
* Joins a list of paths together.
|
|
5
7
|
*
|
|
@@ -121,13 +123,29 @@ export function relativizePath(path, dir = cwd()) {
|
|
|
121
123
|
}
|
|
122
124
|
}
|
|
123
125
|
/**
|
|
124
|
-
* Given 2 paths, it returns whether the second path is
|
|
126
|
+
* Given 2 paths, it returns whether the second path is inside or equal to the first path.
|
|
127
|
+
*
|
|
128
|
+
* By default, paths are compared with pathe, which treats `\` as a separator
|
|
129
|
+
* on every platform. This behaviour is kept for backward compatibility.
|
|
130
|
+
*
|
|
131
|
+
* When `native` is true, paths are compared with the current OS's native path
|
|
132
|
+
* semantics, so literal backslashes on POSIX are preserved as filename
|
|
133
|
+
* characters. Use `native: true` for security or containment checks on
|
|
134
|
+
* resolved filesystem paths.
|
|
135
|
+
*
|
|
136
|
+
* Symbolic links are not resolved; use fileRealPath from the fs module first
|
|
137
|
+
* when checking physical containment.
|
|
125
138
|
*
|
|
126
139
|
* @param mainPath - The main path.
|
|
127
140
|
* @param subpath - The subpath.
|
|
128
|
-
* @
|
|
141
|
+
* @param options - Comparison options. Set `native` to true to use the OS's native path semantics. Defaults to false.
|
|
142
|
+
* @returns Whether the subpath is inside or equal to the main path.
|
|
129
143
|
*/
|
|
130
|
-
export function isSubpath(mainPath, subpath) {
|
|
144
|
+
export function isSubpath(mainPath, subpath, options = { native: false }) {
|
|
145
|
+
if (options.native) {
|
|
146
|
+
const relativePath = nativeRelative(mainPath, subpath);
|
|
147
|
+
return relativePath !== '..' && !relativePath.startsWith(`..${nativeSeparator}`) && !nativeIsAbsolute(relativePath);
|
|
148
|
+
}
|
|
131
149
|
const relativePath = relative(mainPath, subpath);
|
|
132
150
|
return !relativePath.startsWith('..') && !isAbsolutePath(relativePath);
|
|
133
151
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"path.js","sourceRoot":"","sources":["../../../src/public/node/path.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n relative,\n dirname as patheDirname,\n join,\n normalize,\n resolve,\n basename as basenamePathe,\n extname as extnamePathe,\n parse,\n isAbsolute,\n} from 'pathe'\nimport {fileURLToPath} from 'url'\n// eslint-disable-next-line n/prefer-global/url\nimport type {URL} from 'url'\n\n/**\n * Joins a list of paths together.\n *\n * @param paths - Paths to join.\n * @returns Joined path.\n */\nexport function joinPath(...paths: string[]): string {\n return join(...paths)\n}\n\n/**\n * Normalizes a path.\n *\n * @param path - Path to normalize.\n * @returns Normalized path.\n */\nexport function normalizePath(path: string): string {\n return normalize(path)\n}\n\n/**\n * Resolves a list of paths together.\n *\n * @param paths - Paths to resolve.\n * @returns Resolved path.\n */\nexport function resolvePath(...paths: string[]): string {\n return resolve(...paths)\n}\n\n/**\n * Returns the relative path from one path to another.\n *\n * @param from - Path to resolve from.\n * @param to - Path to resolve to.\n * @returns Relative path.\n */\nexport function relativePath(from: string, to: string): string {\n return relative(from, to)\n}\n\n/**\n * Returns whether the path is absolute.\n *\n * @param path - Path to check.\n * @returns Whether the path is absolute.\n */\nexport function isAbsolutePath(path: string): boolean {\n return isAbsolute(path)\n}\n\n/**\n * Returns the directory name of a path.\n *\n * @param path - Path to get the directory name of.\n * @returns Directory name.\n */\nexport function dirname(path: string): string {\n return patheDirname(path)\n}\n\n/**\n * Returns the base name of a path.\n *\n * @param path - Path to get the base name of.\n * @param ext - Optional extension to remove from the result.\n * @returns Base name.\n */\nexport function basename(path: string, ext?: string): string {\n return basenamePathe(path, ext)\n}\n\n/**\n * Returns the extension of the path.\n *\n * @param path - Path to get the extension of.\n * @returns Extension.\n */\nexport function extname(path: string): string {\n return extnamePathe(path)\n}\n\n/**\n * Parses a path into its components (root, dir, base, ext, name).\n *\n * @param path - Path to parse.\n * @returns Parsed path object.\n */\nexport function parsePath(path: string): {root: string; dir: string; base: string; ext: string; name: string} {\n return parse(path)\n}\n\n/**\n * Returns the longest common parent directory of two absolute paths.\n *\n * @param first - First absolute path.\n * @param second - Second absolute path.\n * @returns The common parent directory, or '/' if they share only the root.\n */\nexport function commonParentDirectory(first: string, second: string): string {\n const firstParts = first.split(/\\/+|\\\\+/)\n const secondParts = second.split(/\\/+|\\\\+/)\n let i = 0\n while (i < firstParts.length && i < secondParts.length && firstParts[i] === secondParts[i]) {\n i++\n }\n return i > 1 ? firstParts.slice(0, i).join('/') : '/'\n}\n\n/**\n * Given an absolute filesystem path, it makes it relative to\n * the current working directory. This is useful when logging paths\n * to allow the users to click on the file and let the OS open it\n * in the editor of choice.\n *\n * @param path - Path to relativize.\n * @param dir - Current working directory.\n * @returns Relativized path.\n */\nexport function relativizePath(path: string, dir: string = cwd()): string {\n const result = commonParentDirectory(path, dir)\n const relativePath = relative(dir, path)\n const relativeComponents = relativePath.split('/').filter((component) => component === '..').length\n if (result === '/' || relativePath === '' || relativeComponents > 2) {\n return path\n } else {\n return relativePath\n }\n}\n\n/**\n * Given 2 paths, it returns whether the second path is a subpath of the first path.\n *\n * @param mainPath - The main path.\n * @param subpath - The subpath.\n * @returns Whether the subpath is a subpath of the main path.\n */\nexport function isSubpath(mainPath: string, subpath: string): boolean {\n const relativePath = relative(mainPath, subpath)\n return !relativePath.startsWith('..') && !isAbsolutePath(relativePath)\n}\n\n/**\n * Given a module's import.meta.url it returns the directory containing the module.\n *\n * @param moduleURL - The value of import.meta.url in the context of the caller module.\n * @returns The path to the directory containing the caller module.\n */\nexport function moduleDirectory(moduleURL: string | URL): string {\n return dirname(fileURLToPath(moduleURL))\n}\n\n/**\n * When running a script using `npm run`, something interesting happens. If the current\n * folder does not have a `package.json` or a `node_modules` folder, npm will traverse\n * the directory tree upwards until it finds one. Then it will run the script and set\n * `process.cwd()` to that folder, while the actual path is stored in the INIT_CWD\n * environment variable (see here: https://docs.npmjs.com/cli/v9/commands/npm-run-script#description).\n *\n * @returns The path to the current working directory.\n */\nexport function cwd(): string {\n // eslint-disable-next-line @shopify/cli/no-process-cwd\n return normalize(process.env.INIT_CWD || process.cwd()) // eslint-disable-line @typescript-eslint/prefer-nullish-coalescing -- empty env var should fall through\n}\n\n/**\n * Tries to get the value of the `--path` argument, if provided.\n *\n * @param argv - The arguments to search for the `--path` argument.\n * @returns The value of the `--path` argument, if provided.\n */\nexport function sniffForPath(argv = process.argv): string | undefined {\n const pathFlagIndex = argv.indexOf('--path')\n if (pathFlagIndex === -1) {\n const pathArg = argv.find((arg) => arg.startsWith('--path='))\n return pathArg?.split('=')[1]\n }\n const pathFlag = argv[pathFlagIndex + 1]\n if (!pathFlag || pathFlag.startsWith('-')) return\n return pathFlag\n}\n\n/**\n * Returns whether the `--json` or `-j` flags are present in the arguments.\n *\n * @param argv - The arguments to search for the `--json` and `-j` flags.\n * @returns Whether the `--json` or `-j` flag is present in the arguments.\n */\nexport function sniffForJson(argv = process.argv): boolean {\n const passthroughIndex = argv.indexOf('--')\n const commandArguments = passthroughIndex === -1 ? argv : argv.slice(0, passthroughIndex)\n return commandArguments.includes('--json') || commandArguments.includes('-j')\n}\n\n/**\n * Removes any `..` traversal segments from a relative path and calls `warn`\n * if any were stripped. Normal `..` that cancel out within the path (e.g.\n * `foo/../bar` → `bar`) are collapsed but never allowed to escape the root.\n * Both `/` and `\\` are treated as separators for cross-platform safety.\n *\n * @param input - The relative path to sanitize.\n * @param warn - Called with a human-readable warning when traversal segments are removed.\n * @returns The sanitized path (may be an empty string if all segments were traversal).\n */\nexport function sanitizeRelativePath(input: string, warn: (msg: string) => void): string {\n const segments = input.replace(/\\\\/g, '/').split('/')\n const stack: string[] = []\n let stripped = false\n for (const seg of segments) {\n if (seg === '..') {\n stripped = true\n stack.pop()\n } else if (seg !== '.') {\n stack.push(seg)\n }\n }\n const result = stack.join('/')\n if (stripped) {\n warn(`Warning: path '${input}' contains '..' traversal — sanitized to '${result || '.'}'\\n`)\n }\n return result\n}\n"]}
|
|
1
|
+
{"version":3,"file":"path.js","sourceRoot":"","sources":["../../../src/public/node/path.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n relative,\n dirname as patheDirname,\n join,\n normalize,\n resolve,\n basename as basenamePathe,\n extname as extnamePathe,\n parse,\n isAbsolute,\n} from 'pathe'\nimport {fileURLToPath} from 'url'\n// eslint-disable-next-line no-restricted-imports -- Native containment must preserve literal POSIX backslashes.\nimport {relative as nativeRelative, isAbsolute as nativeIsAbsolute, sep as nativeSeparator} from 'node:path'\n// eslint-disable-next-line n/prefer-global/url\nimport type {URL} from 'url'\n\ninterface IsSubpathOptions {\n native?: boolean\n}\n\n/**\n * Joins a list of paths together.\n *\n * @param paths - Paths to join.\n * @returns Joined path.\n */\nexport function joinPath(...paths: string[]): string {\n return join(...paths)\n}\n\n/**\n * Normalizes a path.\n *\n * @param path - Path to normalize.\n * @returns Normalized path.\n */\nexport function normalizePath(path: string): string {\n return normalize(path)\n}\n\n/**\n * Resolves a list of paths together.\n *\n * @param paths - Paths to resolve.\n * @returns Resolved path.\n */\nexport function resolvePath(...paths: string[]): string {\n return resolve(...paths)\n}\n\n/**\n * Returns the relative path from one path to another.\n *\n * @param from - Path to resolve from.\n * @param to - Path to resolve to.\n * @returns Relative path.\n */\nexport function relativePath(from: string, to: string): string {\n return relative(from, to)\n}\n\n/**\n * Returns whether the path is absolute.\n *\n * @param path - Path to check.\n * @returns Whether the path is absolute.\n */\nexport function isAbsolutePath(path: string): boolean {\n return isAbsolute(path)\n}\n\n/**\n * Returns the directory name of a path.\n *\n * @param path - Path to get the directory name of.\n * @returns Directory name.\n */\nexport function dirname(path: string): string {\n return patheDirname(path)\n}\n\n/**\n * Returns the base name of a path.\n *\n * @param path - Path to get the base name of.\n * @param ext - Optional extension to remove from the result.\n * @returns Base name.\n */\nexport function basename(path: string, ext?: string): string {\n return basenamePathe(path, ext)\n}\n\n/**\n * Returns the extension of the path.\n *\n * @param path - Path to get the extension of.\n * @returns Extension.\n */\nexport function extname(path: string): string {\n return extnamePathe(path)\n}\n\n/**\n * Parses a path into its components (root, dir, base, ext, name).\n *\n * @param path - Path to parse.\n * @returns Parsed path object.\n */\nexport function parsePath(path: string): {root: string; dir: string; base: string; ext: string; name: string} {\n return parse(path)\n}\n\n/**\n * Returns the longest common parent directory of two absolute paths.\n *\n * @param first - First absolute path.\n * @param second - Second absolute path.\n * @returns The common parent directory, or '/' if they share only the root.\n */\nexport function commonParentDirectory(first: string, second: string): string {\n const firstParts = first.split(/\\/+|\\\\+/)\n const secondParts = second.split(/\\/+|\\\\+/)\n let i = 0\n while (i < firstParts.length && i < secondParts.length && firstParts[i] === secondParts[i]) {\n i++\n }\n return i > 1 ? firstParts.slice(0, i).join('/') : '/'\n}\n\n/**\n * Given an absolute filesystem path, it makes it relative to\n * the current working directory. This is useful when logging paths\n * to allow the users to click on the file and let the OS open it\n * in the editor of choice.\n *\n * @param path - Path to relativize.\n * @param dir - Current working directory.\n * @returns Relativized path.\n */\nexport function relativizePath(path: string, dir: string = cwd()): string {\n const result = commonParentDirectory(path, dir)\n const relativePath = relative(dir, path)\n const relativeComponents = relativePath.split('/').filter((component) => component === '..').length\n if (result === '/' || relativePath === '' || relativeComponents > 2) {\n return path\n } else {\n return relativePath\n }\n}\n\n/**\n * Given 2 paths, it returns whether the second path is inside or equal to the first path.\n *\n * By default, paths are compared with pathe, which treats `\\` as a separator\n * on every platform. This behaviour is kept for backward compatibility.\n *\n * When `native` is true, paths are compared with the current OS's native path\n * semantics, so literal backslashes on POSIX are preserved as filename\n * characters. Use `native: true` for security or containment checks on\n * resolved filesystem paths.\n *\n * Symbolic links are not resolved; use fileRealPath from the fs module first\n * when checking physical containment.\n *\n * @param mainPath - The main path.\n * @param subpath - The subpath.\n * @param options - Comparison options. Set `native` to true to use the OS's native path semantics. Defaults to false.\n * @returns Whether the subpath is inside or equal to the main path.\n */\nexport function isSubpath(mainPath: string, subpath: string, options: IsSubpathOptions = {native: false}): boolean {\n if (options.native) {\n const relativePath = nativeRelative(mainPath, subpath)\n return relativePath !== '..' && !relativePath.startsWith(`..${nativeSeparator}`) && !nativeIsAbsolute(relativePath)\n }\n const relativePath = relative(mainPath, subpath)\n return !relativePath.startsWith('..') && !isAbsolutePath(relativePath)\n}\n\n/**\n * Given a module's import.meta.url it returns the directory containing the module.\n *\n * @param moduleURL - The value of import.meta.url in the context of the caller module.\n * @returns The path to the directory containing the caller module.\n */\nexport function moduleDirectory(moduleURL: string | URL): string {\n return dirname(fileURLToPath(moduleURL))\n}\n\n/**\n * When running a script using `npm run`, something interesting happens. If the current\n * folder does not have a `package.json` or a `node_modules` folder, npm will traverse\n * the directory tree upwards until it finds one. Then it will run the script and set\n * `process.cwd()` to that folder, while the actual path is stored in the INIT_CWD\n * environment variable (see here: https://docs.npmjs.com/cli/v9/commands/npm-run-script#description).\n *\n * @returns The path to the current working directory.\n */\nexport function cwd(): string {\n // eslint-disable-next-line @shopify/cli/no-process-cwd\n return normalize(process.env.INIT_CWD || process.cwd()) // eslint-disable-line @typescript-eslint/prefer-nullish-coalescing -- empty env var should fall through\n}\n\n/**\n * Tries to get the value of the `--path` argument, if provided.\n *\n * @param argv - The arguments to search for the `--path` argument.\n * @returns The value of the `--path` argument, if provided.\n */\nexport function sniffForPath(argv = process.argv): string | undefined {\n const pathFlagIndex = argv.indexOf('--path')\n if (pathFlagIndex === -1) {\n const pathArg = argv.find((arg) => arg.startsWith('--path='))\n return pathArg?.split('=')[1]\n }\n const pathFlag = argv[pathFlagIndex + 1]\n if (!pathFlag || pathFlag.startsWith('-')) return\n return pathFlag\n}\n\n/**\n * Returns whether the `--json` or `-j` flags are present in the arguments.\n *\n * @param argv - The arguments to search for the `--json` and `-j` flags.\n * @returns Whether the `--json` or `-j` flag is present in the arguments.\n */\nexport function sniffForJson(argv = process.argv): boolean {\n const passthroughIndex = argv.indexOf('--')\n const commandArguments = passthroughIndex === -1 ? argv : argv.slice(0, passthroughIndex)\n return commandArguments.includes('--json') || commandArguments.includes('-j')\n}\n\n/**\n * Removes any `..` traversal segments from a relative path and calls `warn`\n * if any were stripped. Normal `..` that cancel out within the path (e.g.\n * `foo/../bar` → `bar`) are collapsed but never allowed to escape the root.\n * Both `/` and `\\` are treated as separators for cross-platform safety.\n *\n * @param input - The relative path to sanitize.\n * @param warn - Called with a human-readable warning when traversal segments are removed.\n * @returns The sanitized path (may be an empty string if all segments were traversal).\n */\nexport function sanitizeRelativePath(input: string, warn: (msg: string) => void): string {\n const segments = input.replace(/\\\\/g, '/').split('/')\n const stack: string[] = []\n let stripped = false\n for (const seg of segments) {\n if (seg === '..') {\n stripped = true\n stack.pop()\n } else if (seg !== '.') {\n stack.push(seg)\n }\n }\n const result = stack.join('/')\n if (stripped) {\n warn(`Warning: path '${input}' contains '..' traversal — sanitized to '${result || '.'}'\\n`)\n }\n return result\n}\n"]}
|
|
@@ -121,6 +121,10 @@ export declare function ensureAuthenticatedAdmin(store: string, scopes?: AdminAP
|
|
|
121
121
|
* If a password is provided, that token will be used against Theme Access API.
|
|
122
122
|
* Otherwise, it will ensure that the user is authenticated with the Admin API.
|
|
123
123
|
*
|
|
124
|
+
* Theme Access passwords only work with the store's permanent `.myshopify.com` domain, so when the password is a
|
|
125
|
+
* Theme Access password the returned session uses the permanent domain of `store`, even if `store` is another of the
|
|
126
|
+
* store's domains.
|
|
127
|
+
*
|
|
124
128
|
* @param store - Store fqdn to request auth for.
|
|
125
129
|
* @param password - Password generated from Theme Access app.
|
|
126
130
|
* @param scopes - Optional array of extra scopes to authenticate with.
|
|
@@ -128,14 +132,44 @@ export declare function ensureAuthenticatedAdmin(store: string, scopes?: AdminAP
|
|
|
128
132
|
* @returns The access token and store.
|
|
129
133
|
*/
|
|
130
134
|
export declare function ensureAuthenticatedThemes(store: string, password: string | undefined, scopes?: AdminAPIScope[], options?: EnsureAuthenticatedAdditionalOptions): Promise<AdminSession>;
|
|
135
|
+
/**
|
|
136
|
+
* Options for `ensureAuthenticatedBusinessPlatform`.
|
|
137
|
+
*/
|
|
138
|
+
export interface EnsureAuthenticatedBusinessPlatformOptions extends EnsureAuthenticatedAdditionalOptions {
|
|
139
|
+
/**
|
|
140
|
+
* Authenticate with the automation token set in the environment, when there is one, instead of the
|
|
141
|
+
* logged-in user. Only commands that support automation tokens opt in; other callers, such as
|
|
142
|
+
* Hydrogen's login, keep using the user's session.
|
|
143
|
+
*/
|
|
144
|
+
allowAutomationToken?: boolean;
|
|
145
|
+
}
|
|
131
146
|
/**
|
|
132
147
|
* Ensure that we have a valid session to access the Business Platform API.
|
|
133
148
|
*
|
|
134
|
-
* @param scopes - Optional array of extra scopes to authenticate with.
|
|
149
|
+
* @param scopes - Optional array of extra scopes to authenticate with. Ignored when an automation token is used.
|
|
135
150
|
* @param options - Optional extra options to use.
|
|
136
151
|
* @returns The access token for the Business Platform API.
|
|
137
152
|
*/
|
|
138
|
-
export declare function ensureAuthenticatedBusinessPlatform(scopes?: BusinessPlatformScope[], options?:
|
|
153
|
+
export declare function ensureAuthenticatedBusinessPlatform(scopes?: BusinessPlatformScope[], options?: EnsureAuthenticatedBusinessPlatformOptions): Promise<string>;
|
|
154
|
+
/**
|
|
155
|
+
* Whether SHOPIFY_SERVICE_ACCOUNT_TOKEN is set, which makes it the automation token the CLI authenticates with.
|
|
156
|
+
*
|
|
157
|
+
* True even when it's empty or set together with another automation token variable. Commands use this to skip logins
|
|
158
|
+
* saved on this machine, and authentication then reports any problem with the variables.
|
|
159
|
+
*
|
|
160
|
+
* @returns True when SHOPIFY_SERVICE_ACCOUNT_TOKEN is set.
|
|
161
|
+
*/
|
|
162
|
+
export declare function isServiceAccountTokenSet(): boolean;
|
|
163
|
+
/**
|
|
164
|
+
* Fails when SHOPIFY_SERVICE_ACCOUNT_TOKEN is set, for commands that can't run with that token.
|
|
165
|
+
*
|
|
166
|
+
* Service account tokens can't log in as a user or call a store's Admin API, so commands that need either
|
|
167
|
+
* refuse to run instead of quietly using the person's own login. `ensureAuthenticated` runs this check before any
|
|
168
|
+
* login. Commands that run on a login saved by `shopify store auth` call it before loading that login.
|
|
169
|
+
*
|
|
170
|
+
* @throws AbortError when SHOPIFY_SERVICE_ACCOUNT_TOKEN is set.
|
|
171
|
+
*/
|
|
172
|
+
export declare function ensureNoServiceAccountToken(): void;
|
|
139
173
|
/**
|
|
140
174
|
* Logout from Shopify.
|
|
141
175
|
*
|