@shopify/cli-kit 3.75.3 → 3.76.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/theme_create.d.ts +21 -0
- package/dist/cli/api/graphql/admin/generated/theme_create.js +85 -0
- package/dist/cli/api/graphql/admin/generated/theme_create.js.map +1 -0
- package/dist/private/node/api/graphql.d.ts +1 -0
- package/dist/private/node/api/graphql.js +34 -4
- package/dist/private/node/api/graphql.js.map +1 -1
- package/dist/private/node/conf-store.d.ts +6 -5
- package/dist/private/node/conf-store.js +1 -1
- package/dist/private/node/conf-store.js.map +1 -1
- package/dist/private/node/session/device-authorization.js +11 -3
- package/dist/private/node/session/device-authorization.js.map +1 -1
- package/dist/private/node/session/validate.js +0 -5
- package/dist/private/node/session/validate.js.map +1 -1
- 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 +3 -3
- package/dist/public/node/api/admin.js.map +1 -1
- package/dist/public/node/api/app-management.d.ts +3 -2
- package/dist/public/node/api/app-management.js +6 -1
- package/dist/public/node/api/app-management.js.map +1 -1
- package/dist/public/node/api/business-platform.d.ts +5 -3
- package/dist/public/node/api/business-platform.js +6 -2
- package/dist/public/node/api/business-platform.js.map +1 -1
- package/dist/public/node/api/graphql.d.ts +8 -0
- package/dist/public/node/api/graphql.js +19 -2
- package/dist/public/node/api/graphql.js.map +1 -1
- package/dist/public/node/api/partners.d.ts +3 -2
- package/dist/public/node/api/partners.js +3 -1
- package/dist/public/node/api/partners.js.map +1 -1
- package/dist/public/node/base-command.js +8 -5
- package/dist/public/node/base-command.js.map +1 -1
- package/dist/public/node/cli.js +5 -4
- package/dist/public/node/cli.js.map +1 -1
- package/dist/public/node/hooks/postrun.js +2 -1
- package/dist/public/node/hooks/postrun.js.map +1 -1
- package/dist/public/node/hooks/prerun.js +3 -0
- package/dist/public/node/hooks/prerun.js.map +1 -1
- package/dist/public/node/notifications-system.d.ts +15 -1
- package/dist/public/node/notifications-system.js +55 -11
- package/dist/public/node/notifications-system.js.map +1 -1
- package/dist/public/node/system.d.ts +3 -1
- package/dist/public/node/system.js +22 -3
- package/dist/public/node/system.js.map +1 -1
- package/dist/public/node/themes/api.d.ts +16 -1
- package/dist/public/node/themes/api.js +34 -114
- package/dist/public/node/themes/api.js.map +1 -1
- package/dist/public/node/themes/theme-manager.js +4 -4
- package/dist/public/node/themes/theme-manager.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -2
- package/dist/private/node/session/identity-token-validation.d.ts +0 -1
- package/dist/private/node/session/identity-token-validation.js +0 -70
- package/dist/private/node/session/identity-token-validation.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-management.js","sourceRoot":"","sources":["../../../../src/public/node/api/app-management.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"app-management.js","sourceRoot":"","sources":["../../../../src/public/node/api/app-management.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,iBAAiB,EAAC,MAAM,cAAc,CAAA;AAC7E,OAAO,EAAC,iBAAiB,EAAC,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAC,sBAAsB,EAAC,MAAM,qDAAqD,CAAA;AAC1F,OAAO,UAAU,MAAM,YAAY,CAAA;AAInC,sEAAsE;AACtE,yEAAyE;AACzE,iDAAiD;AACjD,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC;IAC7B,OAAO,EAAE,GAAG;IACZ,aAAa,EAAE,EAAE;CAClB,CAAC,CAAA;AAEF,KAAK,UAAU,YAAY,CAAC,KAAa,EAAE,KAAa;IACtD,MAAM,GAAG,GAAG,gBAAgB,CAAA;IAC5B,MAAM,IAAI,GAAG,MAAM,iBAAiB,EAAE,CAAA;IACtC,MAAM,GAAG,GAAG,WAAW,IAAI,0CAA0C,KAAK,eAAe,CAAA;IACzF,OAAO;QACL,KAAK;QACL,GAAG;QACH,GAAG;QACH,eAAe,EAAE,EAAC,UAAU,EAAE,kBAAkB,EAAC;KAClD,CAAA;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,KAAa,EACb,KAA6C,EAC7C,KAAa,EACb,SAAsB,EACtB,YAA2B;IAE3B,wEAAwE;IACxE,MAAM,aAAa,GAAG,CAAC,YAAY,EAAE,aAAa,IAAI,EAAE,CAAC,GAAG,KAAK,CAAA;IACjE,MAAM,eAAe,GAAG,YAAY,CAAC,CAAC,CAAC,EAAC,GAAG,YAAY,EAAE,aAAa,EAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAEnF,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAU,KAAK,IAAI,EAAE,CAClD,iBAAiB,CAAsB;QACrC,GAAG,CAAC,MAAM,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACrC,KAAK;QACL,SAAS;QACT,YAAY,EAAE,eAAe;KAC9B,CAAC,CACH,CAAA;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAUD;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAI,QAA4B;IAChE,IAAI,CAAC,QAAQ,CAAC,UAAU;QAAE,OAAM;IAEhC,MAAM,gBAAgB,GAAW,EAAE,CAAA;IACnC,KAAK,MAAM,WAAW,IAAK,QAAQ,CAAC,UAA+B,CAAC,YAAY,EAAE,CAAC;QACjF,IAAI,WAAW,CAAC,kBAAkB,EAAE,CAAC;YACnC,gBAAgB,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,CAAA;QACjE,CAAC;IACH,CAAC;IAED,sBAAsB,CAAC,gBAAgB,CAAC,CAAA;AAC1C,CAAC","sourcesContent":["import {CacheOptions, GraphQLResponse, graphqlRequestDoc} from './graphql.js'\nimport {appManagementFqdn} from '../context/fqdn.js'\nimport {setNextDeprecationDate} from '../../../private/node/context/deprecations-store.js'\nimport Bottleneck from 'bottleneck'\nimport {TypedDocumentNode} from '@graphql-typed-document-node/core'\nimport {Variables} from 'graphql-request'\n\n// API Rate limiter for partners API (Limit is 10 requests per second)\n// Jobs are launched every 150ms to add an extra 50ms margin per request.\n// Only 10 requests can be executed concurrently.\nconst limiter = new Bottleneck({\n minTime: 150,\n maxConcurrent: 10,\n})\n\nasync function setupRequest(orgId: string, token: string) {\n const api = 'App Management'\n const fqdn = await appManagementFqdn()\n const url = `https://${fqdn}/app_management/unstable/organizations/${orgId}/graphql.json`\n return {\n token,\n api,\n url,\n responseOptions: {onResponse: handleDeprecations},\n }\n}\n\n/**\n * Executes an org-scoped GraphQL query against the App Management API. Uses typed documents.\n *\n * @param orgId - The organization ID.\n * @param query - GraphQL query to execute.\n * @param token - Partners token.\n * @param variables - GraphQL variables to pass to the query.\n * @param cacheOptions - Cache options for the request. If not present, the request will not be cached.\n * @returns The response of the query of generic type <T>.\n */\nexport async function appManagementRequestDoc<TResult, TVariables extends Variables>(\n orgId: string,\n query: TypedDocumentNode<TResult, TVariables>,\n token: string,\n variables?: TVariables,\n cacheOptions?: CacheOptions,\n): Promise<TResult> {\n // For app management, we need to cache the response based on the orgId.\n const cacheExtraKey = (cacheOptions?.cacheExtraKey ?? '') + orgId\n const newCacheOptions = cacheOptions ? {...cacheOptions, cacheExtraKey} : undefined\n\n const result = limiter.schedule<TResult>(async () =>\n graphqlRequestDoc<TResult, TVariables>({\n ...(await setupRequest(orgId, token)),\n query,\n variables,\n cacheOptions: newCacheOptions,\n }),\n )\n\n return result\n}\n\ninterface Deprecation {\n supportedUntilDate?: string\n}\n\ninterface WithDeprecations {\n deprecations: Deprecation[]\n}\n\n/**\n * Sets the next deprecation date from [GraphQL response extensions](https://www.apollographql.com/docs/resources/graphql-glossary/#extensions)\n * if `response.extensions.deprecations` objects contain a `supportedUntilDate` (ISO 8601-formatted string).\n *\n * @param response - The response of the query.\n */\nexport function handleDeprecations<T>(response: GraphQLResponse<T>): void {\n if (!response.extensions) return\n\n const deprecationDates: Date[] = []\n for (const deprecation of (response.extensions as WithDeprecations).deprecations) {\n if (deprecation.supportedUntilDate) {\n deprecationDates.push(new Date(deprecation.supportedUntilDate))\n }\n }\n\n setNextDeprecationDate(deprecationDates)\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Exact, GraphQLVariables } from './graphql.js';
|
|
1
|
+
import { CacheOptions, Exact, GraphQLVariables } from './graphql.js';
|
|
2
2
|
import { TypedDocumentNode } from '@graphql-typed-document-node/core';
|
|
3
3
|
import { Variables } from 'graphql-request';
|
|
4
4
|
/**
|
|
@@ -7,18 +7,20 @@ import { Variables } from 'graphql-request';
|
|
|
7
7
|
* @param query - GraphQL query to execute.
|
|
8
8
|
* @param token - Business Platform token.
|
|
9
9
|
* @param variables - GraphQL variables to pass to the query.
|
|
10
|
+
* @param cacheOptions - Cache options for the request. If not present, the request will not be cached.
|
|
10
11
|
* @returns The response of the query of generic type <T>.
|
|
11
12
|
*/
|
|
12
|
-
export declare function businessPlatformRequest<T>(query: string, token: string, variables?: GraphQLVariables): Promise<T>;
|
|
13
|
+
export declare function businessPlatformRequest<T>(query: string, token: string, variables?: GraphQLVariables, cacheOptions?: CacheOptions): Promise<T>;
|
|
13
14
|
/**
|
|
14
15
|
* Executes a GraphQL query against the Business Platform Destinations API. Uses typed documents.
|
|
15
16
|
*
|
|
16
17
|
* @param query - GraphQL query to execute.
|
|
17
18
|
* @param token - Business Platform token.
|
|
18
19
|
* @param variables - GraphQL variables to pass to the query.
|
|
20
|
+
* @param cacheOptions - Cache options for the request. If not present, the request will not be cached.
|
|
19
21
|
* @returns The response of the query of generic type <TResult>.
|
|
20
22
|
*/
|
|
21
|
-
export declare function businessPlatformRequestDoc<TResult, TVariables extends Variables>(query: TypedDocumentNode<TResult, TVariables>, token: string, variables?: TVariables): Promise<TResult>;
|
|
23
|
+
export declare function businessPlatformRequestDoc<TResult, TVariables extends Variables>(query: TypedDocumentNode<TResult, TVariables>, token: string, variables?: TVariables, cacheOptions?: CacheOptions): Promise<TResult>;
|
|
22
24
|
/**
|
|
23
25
|
* Executes a GraphQL query against the Business Platform Organizations API.
|
|
24
26
|
*
|
|
@@ -23,13 +23,15 @@ async function setupRequest(token) {
|
|
|
23
23
|
* @param query - GraphQL query to execute.
|
|
24
24
|
* @param token - Business Platform token.
|
|
25
25
|
* @param variables - GraphQL variables to pass to the query.
|
|
26
|
+
* @param cacheOptions - Cache options for the request. If not present, the request will not be cached.
|
|
26
27
|
* @returns The response of the query of generic type <T>.
|
|
27
28
|
*/
|
|
28
|
-
export async function businessPlatformRequest(query, token, variables) {
|
|
29
|
+
export async function businessPlatformRequest(query, token, variables, cacheOptions) {
|
|
29
30
|
return graphqlRequest({
|
|
30
31
|
...(await setupRequest(token)),
|
|
31
32
|
query,
|
|
32
33
|
variables,
|
|
34
|
+
cacheOptions,
|
|
33
35
|
});
|
|
34
36
|
}
|
|
35
37
|
/**
|
|
@@ -38,13 +40,15 @@ export async function businessPlatformRequest(query, token, variables) {
|
|
|
38
40
|
* @param query - GraphQL query to execute.
|
|
39
41
|
* @param token - Business Platform token.
|
|
40
42
|
* @param variables - GraphQL variables to pass to the query.
|
|
43
|
+
* @param cacheOptions - Cache options for the request. If not present, the request will not be cached.
|
|
41
44
|
* @returns The response of the query of generic type <TResult>.
|
|
42
45
|
*/
|
|
43
|
-
export async function businessPlatformRequestDoc(query, token, variables) {
|
|
46
|
+
export async function businessPlatformRequestDoc(query, token, variables, cacheOptions) {
|
|
44
47
|
return graphqlRequestDoc({
|
|
45
48
|
...(await setupRequest(token)),
|
|
46
49
|
query,
|
|
47
50
|
variables,
|
|
51
|
+
cacheOptions,
|
|
48
52
|
});
|
|
49
53
|
}
|
|
50
54
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"business-platform.js","sourceRoot":"","sources":["../../../../src/public/node/api/business-platform.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"business-platform.js","sourceRoot":"","sources":["../../../../src/public/node/api/business-platform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwC,cAAc,EAAE,iBAAiB,EAAC,MAAM,cAAc,CAAA;AACrG,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAA;AAChD,OAAO,EAAC,oBAAoB,EAAC,MAAM,oBAAoB,CAAA;AAIvD;;;;GAIG;AACH,KAAK,UAAU,YAAY,CAAC,KAAa;IACvC,MAAM,GAAG,GAAG,kBAAkB,CAAA;IAC9B,MAAM,IAAI,GAAG,MAAM,oBAAoB,EAAE,CAAA;IACzC,MAAM,GAAG,GAAG,WAAW,IAAI,mCAAmC,CAAA;IAC9D,OAAO;QACL,KAAK;QACL,GAAG;QACH,GAAG;QACH,eAAe,EAAE,EAAC,UAAU,EAAE,kBAAkB,EAAC;KAClD,CAAA;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,KAAa,EACb,KAAa,EACb,SAA4B,EAC5B,YAA2B;IAE3B,OAAO,cAAc,CAAI;QACvB,GAAG,CAAC,MAAM,YAAY,CAAC,KAAK,CAAC,CAAC;QAC9B,KAAK;QACL,SAAS;QACT,YAAY;KACb,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,KAA6C,EAC7C,KAAa,EACb,SAAsB,EACtB,YAA2B;IAE3B,OAAO,iBAAiB,CAAsB;QAC5C,GAAG,CAAC,MAAM,YAAY,CAAC,KAAK,CAAC,CAAC;QAC9B,KAAK;QACL,SAAS;QACT,YAAY;KACb,CAAC,CAAA;AACJ,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,yBAAyB,CAAC,KAAa,EAAE,cAAsB;IAC5E,MAAM,GAAG,GAAG,kBAAkB,CAAA;IAC9B,MAAM,IAAI,GAAG,MAAM,oBAAoB,EAAE,CAAA;IACzC,MAAM,GAAG,GAAG,WAAW,IAAI,4CAA4C,cAAc,UAAU,CAAA;IAC/F,OAAO;QACL,KAAK;QACL,GAAG;QACH,GAAG;QACH,eAAe,EAAE,EAAC,UAAU,EAAE,kBAAkB,EAAC;KAClD,CAAA;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,oCAAoC,CACxD,KAAa,EACb,KAAa,EACb,cAAsB,EACtB,SAA4B;IAE5B,OAAO,cAAc,CAAI;QACvB,KAAK;QACL,GAAG,CAAC,MAAM,yBAAyB,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;QAC3D,SAAS;KACV,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,uCAAuC,CAC3D,KAA+G,EAC/G,KAAa,EACb,cAAsB,EACtB,SAA4B;IAE5B,OAAO,iBAAiB,CAAC;QACvB,KAAK;QACL,GAAG,CAAC,MAAM,yBAAyB,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;QAC3D,SAAS;KACV,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import {CacheOptions, Exact, GraphQLVariables, graphqlRequest, graphqlRequestDoc} from './graphql.js'\nimport {handleDeprecations} from './partners.js'\nimport {businessPlatformFqdn} from '../context/fqdn.js'\nimport {TypedDocumentNode} from '@graphql-typed-document-node/core'\nimport {Variables} from 'graphql-request'\n\n/**\n * Sets up the request to the Business Platform Destinations API.\n *\n * @param token - Business Platform token.\n */\nasync function setupRequest(token: string) {\n const api = 'BusinessPlatform'\n const fqdn = await businessPlatformFqdn()\n const url = `https://${fqdn}/destinations/api/2020-07/graphql`\n return {\n token,\n api,\n url,\n responseOptions: {onResponse: handleDeprecations},\n }\n}\n\n/**\n * Executes a GraphQL query against the Business Platform Destinations API.\n *\n * @param query - GraphQL query to execute.\n * @param token - Business Platform token.\n * @param variables - GraphQL variables to pass to the query.\n * @param cacheOptions - Cache options for the request. If not present, the request will not be cached.\n * @returns The response of the query of generic type <T>.\n */\nexport async function businessPlatformRequest<T>(\n query: string,\n token: string,\n variables?: GraphQLVariables,\n cacheOptions?: CacheOptions,\n): Promise<T> {\n return graphqlRequest<T>({\n ...(await setupRequest(token)),\n query,\n variables,\n cacheOptions,\n })\n}\n\n/**\n * Executes a GraphQL query against the Business Platform Destinations API. Uses typed documents.\n *\n * @param query - GraphQL query to execute.\n * @param token - Business Platform token.\n * @param variables - GraphQL variables to pass to the query.\n * @param cacheOptions - Cache options for the request. If not present, the request will not be cached.\n * @returns The response of the query of generic type <TResult>.\n */\nexport async function businessPlatformRequestDoc<TResult, TVariables extends Variables>(\n query: TypedDocumentNode<TResult, TVariables>,\n token: string,\n variables?: TVariables,\n cacheOptions?: CacheOptions,\n): Promise<TResult> {\n return graphqlRequestDoc<TResult, TVariables>({\n ...(await setupRequest(token)),\n query,\n variables,\n cacheOptions,\n })\n}\n\n/**\n * Sets up the request to the Business Platform Organizations API.\n *\n * @param token - Business Platform token.\n * @param organizationId - Organization ID as a numeric (non-GID) value.\n */\nasync function setupOrganizationsRequest(token: string, organizationId: string) {\n const api = 'BusinessPlatform'\n const fqdn = await businessPlatformFqdn()\n const url = `https://${fqdn}/organizations/api/unstable/organization/${organizationId}/graphql`\n return {\n token,\n api,\n url,\n responseOptions: {onResponse: handleDeprecations},\n }\n}\n\n/**\n * Executes a GraphQL query against the Business Platform Organizations API.\n *\n * @param query - GraphQL query to execute.\n * @param token - Business Platform token.\n * @param organizationId - Organization ID as a numeric (non-GID) value.\n * @param variables - GraphQL variables to pass to the query.\n * @returns The response of the query of generic type <T>.\n */\nexport async function businessPlatformOrganizationsRequest<T>(\n query: string,\n token: string,\n organizationId: string,\n variables?: GraphQLVariables,\n): Promise<T> {\n return graphqlRequest<T>({\n query,\n ...(await setupOrganizationsRequest(token, organizationId)),\n variables,\n })\n}\n\n/**\n * Executes a GraphQL query against the Business Platform Organizations API. Uses typed documents.\n *\n * @param query - GraphQL query to execute.\n * @param token - Business Platform token.\n * @param organizationId - Organization ID as a numeric value.\n * @param variables - GraphQL variables to pass to the query.\n * @returns The response of the query of generic type <T>.\n */\nexport async function businessPlatformOrganizationsRequestDoc<TResult>(\n query: TypedDocumentNode<TResult, GraphQLVariables> | TypedDocumentNode<TResult, Exact<{[key: string]: never}>>,\n token: string,\n organizationId: string,\n variables?: GraphQLVariables,\n): Promise<TResult> {\n return graphqlRequestDoc({\n query,\n ...(await setupOrganizationsRequest(token, organizationId)),\n variables,\n })\n}\n"]}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ConfSchema, TimeInterval } from '../../../private/node/conf-store.js';
|
|
2
|
+
import { LocalStorage } from '../local-storage.js';
|
|
1
3
|
import { rawRequest, RequestDocument, Variables } from 'graphql-request';
|
|
2
4
|
import { TypedDocumentNode } from '@graphql-typed-document-node/core';
|
|
3
5
|
export type Exact<T extends {
|
|
@@ -9,6 +11,11 @@ export interface GraphQLVariables {
|
|
|
9
11
|
[key: string]: any;
|
|
10
12
|
}
|
|
11
13
|
export type GraphQLResponse<T> = Awaited<ReturnType<typeof rawRequest<T>>>;
|
|
14
|
+
export interface CacheOptions {
|
|
15
|
+
cacheTTL: TimeInterval;
|
|
16
|
+
cacheExtraKey?: string;
|
|
17
|
+
cacheStore?: LocalStorage<ConfSchema>;
|
|
18
|
+
}
|
|
12
19
|
interface GraphQLRequestBaseOptions<TResult> {
|
|
13
20
|
api: string;
|
|
14
21
|
url: string;
|
|
@@ -17,6 +24,7 @@ interface GraphQLRequestBaseOptions<TResult> {
|
|
|
17
24
|
[header: string]: string;
|
|
18
25
|
};
|
|
19
26
|
responseOptions?: GraphQLResponseOptions<TResult>;
|
|
27
|
+
cacheOptions?: CacheOptions;
|
|
20
28
|
}
|
|
21
29
|
export type GraphQLRequestOptions<T> = GraphQLRequestBaseOptions<T> & {
|
|
22
30
|
query: RequestDocument;
|
|
@@ -3,14 +3,17 @@ import { debugLogRequestInfo, errorHandler } from '../../../private/node/api/gra
|
|
|
3
3
|
import { addPublicMetadata, runWithTimer } from '../metadata.js';
|
|
4
4
|
import { retryAwareRequest } from '../../../private/node/api.js';
|
|
5
5
|
import { requestIdsCollection } from '../../../private/node/request-ids.js';
|
|
6
|
+
import { nonRandomUUID } from '../crypto.js';
|
|
7
|
+
import { cacheRetrieveOrRepopulate, timeIntervalToMilliseconds, } from '../../../private/node/conf-store.js';
|
|
6
8
|
import { GraphQLClient, resolveRequestDocument, ClientError, } from 'graphql-request';
|
|
9
|
+
import { CLI_KIT_VERSION } from '@shopify/cli-kit/common/version';
|
|
7
10
|
/**
|
|
8
11
|
* Handles execution of a GraphQL query.
|
|
9
12
|
*
|
|
10
13
|
* @param options - GraphQL request options.
|
|
11
14
|
*/
|
|
12
15
|
async function performGraphQLRequest(options) {
|
|
13
|
-
const { token, addedHeaders, queryAsString, variables, api, url, responseOptions, unauthorizedHandler } = options;
|
|
16
|
+
const { token, addedHeaders, queryAsString, variables, api, url, responseOptions, unauthorizedHandler, cacheOptions } = options;
|
|
14
17
|
const headers = {
|
|
15
18
|
...addedHeaders,
|
|
16
19
|
...buildHeaders(token),
|
|
@@ -36,13 +39,27 @@ async function performGraphQLRequest(options) {
|
|
|
36
39
|
throw error;
|
|
37
40
|
}
|
|
38
41
|
};
|
|
39
|
-
|
|
42
|
+
const executeWithTimer = () => runWithTimer('cmd_all_timing_network_ms')(async () => {
|
|
40
43
|
const response = await retryAwareRequest({ request: performRequest, url }, responseOptions?.handleErrors === false ? undefined : errorHandler(api), unauthorizedHandler);
|
|
41
44
|
if (responseOptions?.onResponse) {
|
|
42
45
|
responseOptions.onResponse(response);
|
|
43
46
|
}
|
|
44
47
|
return response.data;
|
|
45
48
|
});
|
|
49
|
+
// If there is no cache config for this query, just execute it and return the result.
|
|
50
|
+
if (cacheOptions === undefined) {
|
|
51
|
+
return executeWithTimer();
|
|
52
|
+
}
|
|
53
|
+
const { cacheTTL, cacheExtraKey, cacheStore } = cacheOptions;
|
|
54
|
+
// The cache key is a combination of the hashed query and variables, with an optional extra key provided by the user.
|
|
55
|
+
const queryHash = nonRandomUUID(queryAsString);
|
|
56
|
+
const variablesHash = nonRandomUUID(JSON.stringify(variables ?? {}));
|
|
57
|
+
const cacheKey = `q-${queryHash}-${variablesHash}-${CLI_KIT_VERSION}-${cacheExtraKey ?? ''}`;
|
|
58
|
+
const result = await cacheRetrieveOrRepopulate(cacheKey, async () => {
|
|
59
|
+
const result = await executeWithTimer();
|
|
60
|
+
return JSON.stringify(result);
|
|
61
|
+
}, timeIntervalToMilliseconds(cacheTTL), cacheStore);
|
|
62
|
+
return JSON.parse(result);
|
|
46
63
|
}
|
|
47
64
|
async function logLastRequestIdFromResponse(response) {
|
|
48
65
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphql.js","sourceRoot":"","sources":["../../../../src/public/node/api/graphql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,UAAU,EAAC,MAAM,sCAAsC,CAAA;AAC7E,OAAO,EAAC,mBAAmB,EAAE,YAAY,EAAC,MAAM,sCAAsC,CAAA;AACtF,OAAO,EAAC,iBAAiB,EAAE,YAAY,EAAC,MAAM,gBAAgB,CAAA;AAC9D,OAAO,EAAC,iBAAiB,EAAC,MAAM,8BAA8B,CAAA;AAC9D,OAAO,EAAC,oBAAoB,EAAC,MAAM,sCAAsC,CAAA;AACzE,OAAO,EACL,aAAa,EAGb,sBAAsB,EAEtB,WAAW,GACZ,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"graphql.js","sourceRoot":"","sources":["../../../../src/public/node/api/graphql.ts"],"names":[],"mappings":"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","sourcesContent":["import {buildHeaders, httpsAgent} from '../../../private/node/api/headers.js'\nimport {debugLogRequestInfo, errorHandler} from '../../../private/node/api/graphql.js'\nimport {addPublicMetadata, runWithTimer} from '../metadata.js'\nimport {retryAwareRequest} from '../../../private/node/api.js'\nimport {requestIdsCollection} from '../../../private/node/request-ids.js'\nimport {nonRandomUUID} from '../crypto.js'\nimport {\n cacheRetrieveOrRepopulate,\n ConfSchema,\n GraphQLRequestKey,\n TimeInterval,\n timeIntervalToMilliseconds,\n} from '../../../private/node/conf-store.js'\nimport {LocalStorage} from '../local-storage.js'\nimport {\n GraphQLClient,\n rawRequest,\n RequestDocument,\n resolveRequestDocument,\n Variables,\n ClientError,\n} from 'graphql-request'\nimport {TypedDocumentNode} from '@graphql-typed-document-node/core'\nimport {CLI_KIT_VERSION} from '@shopify/cli-kit/common/version'\n\n// to replace TVariable type when there graphql query has no variables\nexport type Exact<T extends {[key: string]: unknown}> = {[K in keyof T]: T[K]}\n\nexport interface GraphQLVariables {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: any\n}\n\nexport type GraphQLResponse<T> = Awaited<ReturnType<typeof rawRequest<T>>>\n\nexport interface CacheOptions {\n cacheTTL: TimeInterval\n cacheExtraKey?: string\n cacheStore?: LocalStorage<ConfSchema>\n}\n\ninterface GraphQLRequestBaseOptions<TResult> {\n api: string\n url: string\n token?: string\n addedHeaders?: {[header: string]: string}\n responseOptions?: GraphQLResponseOptions<TResult>\n cacheOptions?: CacheOptions\n}\n\ntype PerformGraphQLRequestOptions<TResult> = GraphQLRequestBaseOptions<TResult> & {\n queryAsString: string\n variables?: Variables\n unauthorizedHandler?: () => Promise<void>\n}\n\nexport type GraphQLRequestOptions<T> = GraphQLRequestBaseOptions<T> & {\n query: RequestDocument\n variables?: Variables\n unauthorizedHandler?: () => Promise<void>\n}\n\nexport type GraphQLRequestDocOptions<TResult, TVariables> = GraphQLRequestBaseOptions<TResult> & {\n query: TypedDocumentNode<TResult, TVariables> | TypedDocumentNode<TResult, Exact<{[key: string]: never}>>\n variables?: TVariables\n unauthorizedHandler?: () => Promise<void>\n}\n\nexport interface GraphQLResponseOptions<T> {\n handleErrors?: boolean\n onResponse?: (response: GraphQLResponse<T>) => void\n}\n\n/**\n * Handles execution of a GraphQL query.\n *\n * @param options - GraphQL request options.\n */\nasync function performGraphQLRequest<TResult>(options: PerformGraphQLRequestOptions<TResult>) {\n const {token, addedHeaders, queryAsString, variables, api, url, responseOptions, unauthorizedHandler, cacheOptions} =\n options\n const headers = {\n ...addedHeaders,\n ...buildHeaders(token),\n }\n\n debugLogRequestInfo(api, queryAsString, url, variables, headers)\n const clientOptions = {agent: await httpsAgent(), headers}\n const client = new GraphQLClient(url, clientOptions)\n\n const performRequest = async () => {\n let fullResponse: GraphQLResponse<TResult>\n // there is a errorPolicy option which returns rather than throwing on errors, but we _do_ ultimately want to\n // throw.\n try {\n fullResponse = await client.rawRequest<TResult>(queryAsString, variables)\n await logLastRequestIdFromResponse(fullResponse)\n return fullResponse\n } catch (error) {\n if (error instanceof ClientError) {\n // error.response does have a headers property like a normal response, but it's not typed as such.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await logLastRequestIdFromResponse(error.response as any)\n }\n throw error\n }\n }\n\n const executeWithTimer = () =>\n runWithTimer('cmd_all_timing_network_ms')(async () => {\n const response = await retryAwareRequest(\n {request: performRequest, url},\n responseOptions?.handleErrors === false ? undefined : errorHandler(api),\n unauthorizedHandler,\n )\n\n if (responseOptions?.onResponse) {\n responseOptions.onResponse(response)\n }\n\n return response.data\n })\n\n // If there is no cache config for this query, just execute it and return the result.\n if (cacheOptions === undefined) {\n return executeWithTimer()\n }\n\n const {cacheTTL, cacheExtraKey, cacheStore} = cacheOptions\n\n // The cache key is a combination of the hashed query and variables, with an optional extra key provided by the user.\n const queryHash = nonRandomUUID(queryAsString)\n const variablesHash = nonRandomUUID(JSON.stringify(variables ?? {}))\n const cacheKey: GraphQLRequestKey = `q-${queryHash}-${variablesHash}-${CLI_KIT_VERSION}-${cacheExtraKey ?? ''}`\n\n const result = await cacheRetrieveOrRepopulate(\n cacheKey,\n async () => {\n const result = await executeWithTimer()\n return JSON.stringify(result)\n },\n timeIntervalToMilliseconds(cacheTTL),\n cacheStore,\n )\n\n return JSON.parse(result) as TResult\n}\n\nasync function logLastRequestIdFromResponse(response: GraphQLResponse<unknown>) {\n try {\n const requestId = response.headers.get('x-request-id')\n requestIdsCollection.addRequestId(requestId)\n await addPublicMetadata(() => ({\n cmd_all_last_graphql_request_id: requestId ?? undefined,\n }))\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n // no problem if unable to get request ID.\n }\n}\n\n/**\n * Executes a GraphQL query to an endpoint.\n *\n * @param options - GraphQL request options.\n * @returns The response of the query of generic type <T>.\n */\nexport async function graphqlRequest<T>(options: GraphQLRequestOptions<T>): Promise<T> {\n return performGraphQLRequest<T>({\n ...options,\n queryAsString: options.query as string,\n })\n}\n\n/**\n * Executes a GraphQL query to an endpoint. Uses typed documents.\n *\n * @param options - GraphQL request options.\n * @returns The response of the query of generic type <TResult>.\n */\nexport async function graphqlRequestDoc<TResult, TVariables extends Variables>(\n options: GraphQLRequestDocOptions<TResult, TVariables>,\n): Promise<TResult> {\n return performGraphQLRequest<TResult>({\n ...options,\n queryAsString: resolveRequestDocument(options.query).query,\n })\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GraphQLVariables, GraphQLResponse } from './graphql.js';
|
|
1
|
+
import { GraphQLVariables, GraphQLResponse, CacheOptions } from './graphql.js';
|
|
2
2
|
import { TypedDocumentNode } from '@graphql-typed-document-node/core';
|
|
3
3
|
import { Variables } from 'graphql-request';
|
|
4
4
|
/**
|
|
@@ -7,9 +7,10 @@ import { Variables } from 'graphql-request';
|
|
|
7
7
|
* @param query - GraphQL query to execute.
|
|
8
8
|
* @param token - Partners token.
|
|
9
9
|
* @param variables - GraphQL variables to pass to the query.
|
|
10
|
+
* @param cacheOptions - Cache options.
|
|
10
11
|
* @returns The response of the query of generic type <T>.
|
|
11
12
|
*/
|
|
12
|
-
export declare function partnersRequest<T>(query: string, token: string, variables?: GraphQLVariables): Promise<T>;
|
|
13
|
+
export declare function partnersRequest<T>(query: string, token: string, variables?: GraphQLVariables, cacheOptions?: CacheOptions): Promise<T>;
|
|
13
14
|
/**
|
|
14
15
|
* Executes a GraphQL query against the Partners API. Uses typed documents.
|
|
15
16
|
*
|
|
@@ -31,14 +31,16 @@ async function setupRequest(token) {
|
|
|
31
31
|
* @param query - GraphQL query to execute.
|
|
32
32
|
* @param token - Partners token.
|
|
33
33
|
* @param variables - GraphQL variables to pass to the query.
|
|
34
|
+
* @param cacheOptions - Cache options.
|
|
34
35
|
* @returns The response of the query of generic type <T>.
|
|
35
36
|
*/
|
|
36
|
-
export async function partnersRequest(query, token, variables) {
|
|
37
|
+
export async function partnersRequest(query, token, variables, cacheOptions) {
|
|
37
38
|
const opts = await setupRequest(token);
|
|
38
39
|
const result = limiter.schedule(() => graphqlRequest({
|
|
39
40
|
...opts,
|
|
40
41
|
query,
|
|
41
42
|
variables,
|
|
43
|
+
cacheOptions,
|
|
42
44
|
}));
|
|
43
45
|
return result;
|
|
44
46
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"partners.js","sourceRoot":"","sources":["../../../../src/public/node/api/partners.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAqC,iBAAiB,
|
|
1
|
+
{"version":3,"file":"partners.js","sourceRoot":"","sources":["../../../../src/public/node/api/partners.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAqC,iBAAiB,EAAe,MAAM,cAAc,CAAA;AAC/G,OAAO,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAC,sBAAsB,EAAC,MAAM,qDAAqD,CAAA;AAG1F,OAAO,UAAU,MAAM,YAAY,CAAA;AAEnC,sEAAsE;AACtE,yEAAyE;AACzE,iDAAiD;AACjD,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC;IAC7B,OAAO,EAAE,GAAG;IACZ,aAAa,EAAE,EAAE;CAClB,CAAC,CAAA;AAEF;;;;GAIG;AACH,KAAK,UAAU,YAAY,CAAC,KAAa;IACvC,MAAM,GAAG,GAAG,UAAU,CAAA;IACtB,MAAM,IAAI,GAAG,MAAM,YAAY,EAAE,CAAA;IACjC,MAAM,GAAG,GAAG,WAAW,IAAI,kBAAkB,CAAA;IAC7C,OAAO;QACL,KAAK;QACL,GAAG;QACH,GAAG;QACH,eAAe,EAAE,EAAC,UAAU,EAAE,kBAAkB,EAAC;KAClD,CAAA;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,KAAa,EACb,KAAa,EACb,SAA4B,EAC5B,YAA2B;IAE3B,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,CAAA;IACtC,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,CACnC,cAAc,CAAI;QAChB,GAAG,IAAI;QACP,KAAK;QACL,SAAS;QACT,YAAY;KACb,CAAC,CACH,CAAA;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAA6C,EAC7C,KAAa,EACb,SAAsB;IAEtB,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,CAAA;IACtC,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,CACnC,iBAAiB,CAAsB;QACrC,GAAG,IAAI;QACP,KAAK;QACL,SAAS;KACV,CAAC,CACH,CAAA;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAUD;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAI,QAA4B;IAChE,IAAI,CAAC,QAAQ,CAAC,UAAU;QAAE,OAAM;IAEhC,MAAM,gBAAgB,GAAW,EAAE,CAAA;IACnC,KAAK,MAAM,WAAW,IAAK,QAAQ,CAAC,UAA+B,CAAC,YAAY,EAAE,CAAC;QACjF,IAAI,WAAW,CAAC,kBAAkB,EAAE,CAAC;YACnC,gBAAgB,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,CAAA;QACjE,CAAC;IACH,CAAC;IAED,sBAAsB,CAAC,gBAAgB,CAAC,CAAA;AAC1C,CAAC","sourcesContent":["import {graphqlRequest, GraphQLVariables, GraphQLResponse, graphqlRequestDoc, CacheOptions} from './graphql.js'\nimport {partnersFqdn} from '../context/fqdn.js'\nimport {setNextDeprecationDate} from '../../../private/node/context/deprecations-store.js'\nimport {TypedDocumentNode} from '@graphql-typed-document-node/core'\nimport {Variables} from 'graphql-request'\nimport Bottleneck from 'bottleneck'\n\n// API Rate limiter for partners API (Limit is 10 requests per second)\n// Jobs are launched every 150ms to add an extra 50ms margin per request.\n// Only 10 requests can be executed concurrently.\nconst limiter = new Bottleneck({\n minTime: 150,\n maxConcurrent: 10,\n})\n\n/**\n * Sets up the request to the Partners API.\n *\n * @param token - Partners token.\n */\nasync function setupRequest(token: string) {\n const api = 'Partners'\n const fqdn = await partnersFqdn()\n const url = `https://${fqdn}/api/cli/graphql`\n return {\n token,\n api,\n url,\n responseOptions: {onResponse: handleDeprecations},\n }\n}\n\n/**\n * Executes a GraphQL query against the Partners API.\n *\n * @param query - GraphQL query to execute.\n * @param token - Partners token.\n * @param variables - GraphQL variables to pass to the query.\n * @param cacheOptions - Cache options.\n * @returns The response of the query of generic type <T>.\n */\nexport async function partnersRequest<T>(\n query: string,\n token: string,\n variables?: GraphQLVariables,\n cacheOptions?: CacheOptions,\n): Promise<T> {\n const opts = await setupRequest(token)\n const result = limiter.schedule(() =>\n graphqlRequest<T>({\n ...opts,\n query,\n variables,\n cacheOptions,\n }),\n )\n\n return result\n}\n\n/**\n * Executes a GraphQL query against the Partners API. Uses typed documents.\n *\n * @param query - GraphQL query to execute.\n * @param token - Partners token.\n * @param variables - GraphQL variables to pass to the query.\n * @returns The response of the query of generic type <TResult>.\n */\nexport async function partnersRequestDoc<TResult, TVariables extends Variables>(\n query: TypedDocumentNode<TResult, TVariables>,\n token: string,\n variables?: TVariables,\n): Promise<TResult> {\n const opts = await setupRequest(token)\n const result = limiter.schedule(() =>\n graphqlRequestDoc<TResult, TVariables>({\n ...opts,\n query,\n variables,\n }),\n )\n\n return result\n}\n\ninterface Deprecation {\n supportedUntilDate?: string\n}\n\ninterface WithDeprecations {\n deprecations: Deprecation[]\n}\n\n/**\n * Sets the next deprecation date from [GraphQL response extensions](https://www.apollographql.com/docs/resources/graphql-glossary/#extensions)\n * if `response.extensions.deprecations` objects contain a `supportedUntilDate` (ISO 8601-formatted string).\n *\n * @param response - The response of the query.\n */\nexport function handleDeprecations<T>(response: GraphQLResponse<T>): void {\n if (!response.extensions) return\n\n const deprecationDates: Date[] = []\n for (const deprecation of (response.extensions as WithDeprecations).deprecations) {\n if (deprecation.supportedUntilDate) {\n deprecationDates.push(new Date(deprecation.supportedUntilDate))\n }\n }\n\n setNextDeprecationDate(deprecationDates)\n}\n"]}
|
|
@@ -32,7 +32,7 @@ class BaseCommand extends Command {
|
|
|
32
32
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
33
33
|
async init() {
|
|
34
34
|
this.exitWithTimestampWhenEnvVariablePresent();
|
|
35
|
-
setCurrentCommandId(this.id
|
|
35
|
+
setCurrentCommandId(this.id ?? '');
|
|
36
36
|
if (!isDevelopment()) {
|
|
37
37
|
// This function runs just prior to `run`
|
|
38
38
|
await registerCleanBugsnagErrorsFromWithinPlugins(this.config);
|
|
@@ -97,10 +97,13 @@ This flag is required in non-interactive terminal environments, such as a CI env
|
|
|
97
97
|
// If no environment is specified, don't modify the results
|
|
98
98
|
const flags = originalResult.flags;
|
|
99
99
|
const environmentsFileName = this.environmentsFilename();
|
|
100
|
-
if (!flags.environment || !environmentsFileName)
|
|
100
|
+
if (!flags.environment?.length || !environmentsFileName)
|
|
101
|
+
return originalResult;
|
|
102
|
+
// If users pass multiple environments, do not load them and let each command handle it
|
|
103
|
+
if (flags.environment.length > 1)
|
|
101
104
|
return originalResult;
|
|
102
105
|
// If the specified environment isn't found, don't modify the results
|
|
103
|
-
const environment = await loadEnvironment(flags.environment, environmentsFileName, { from: flags.path });
|
|
106
|
+
const environment = await loadEnvironment(flags.environment[0], environmentsFileName, { from: flags.path });
|
|
104
107
|
if (!environment)
|
|
105
108
|
return originalResult;
|
|
106
109
|
// Parse using noDefaultsOptions to derive a list of flags specified as
|
|
@@ -111,11 +114,11 @@ This flag is required in non-interactive terminal environments, such as a CI env
|
|
|
111
114
|
// Replace the original result with this one.
|
|
112
115
|
const result = await super.parse(options, [
|
|
113
116
|
// Need to specify argv default because we're merging with argsFromEnvironment.
|
|
114
|
-
...(argv
|
|
117
|
+
...(argv ?? this.argv),
|
|
115
118
|
...argsFromEnvironment(environment, options, noDefaultsResult),
|
|
116
119
|
]);
|
|
117
120
|
// Report successful application of the environment.
|
|
118
|
-
reportEnvironmentApplication(noDefaultsResult.flags, result.flags, flags.environment, environment);
|
|
121
|
+
reportEnvironmentApplication(noDefaultsResult.flags, result.flags, flags.environment[0], environment);
|
|
119
122
|
return result;
|
|
120
123
|
}
|
|
121
124
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-command.js","sourceRoot":"","sources":["../../../src/public/node/base-command.ts"],"names":[],"mappings":"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","sourcesContent":["import {errorHandler, registerCleanBugsnagErrorsFromWithinPlugins} from './error-handler.js'\nimport {loadEnvironment} from './environments.js'\nimport {isDevelopment} from './context/local.js'\nimport {addPublicMetadata} from './metadata.js'\nimport {AbortError} from './error.js'\nimport {renderInfo, renderWarning} from './ui.js'\nimport {outputContent, outputInfo, outputToken} from './output.js'\nimport {terminalSupportsPrompting} from './system.js'\nimport {hashString} from './crypto.js'\nimport {isTruthy} from './context/utilities.js'\nimport {showNotificationsIfNeeded} from './notifications-system.js'\nimport {setCurrentCommandId} from './global-context.js'\nimport {JsonMap} from '../../private/common/json.js'\nimport {underscore} from '../common/string.js'\nimport {Command, Errors} from '@oclif/core'\nimport {FlagOutput, Input, ParserOutput, FlagInput, ArgOutput} from '@oclif/core/lib/interfaces/parser.js'\n\ninterface EnvironmentFlags {\n environment?: string\n path?: string\n}\n\nabstract class BaseCommand extends Command {\n // eslint-disable-next-line @typescript-eslint/ban-types\n static baseFlags: FlagInput<{}> = {}\n\n // Replace markdown links to plain text like: \"link label\" (url)\n public static descriptionWithoutMarkdown(): string | undefined {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return ((this as any).descriptionWithMarkdown ?? '').replace(/(\\[)(.*?)(])(\\()(.*?)(\\))/gm, '\"$2\" ($5)')\n }\n\n public static analyticsNameOverride(): string | undefined {\n return undefined\n }\n\n public static analyticsStopCommand(): string | undefined {\n return undefined\n }\n\n async catch(error: Error & {skipOclifErrorHandling: boolean}): Promise<void> {\n error.skipOclifErrorHandling = true\n await errorHandler(error, this.config)\n return Errors.handle(error)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected async init(): Promise<any> {\n this.exitWithTimestampWhenEnvVariablePresent()\n setCurrentCommandId(this.id || '')\n if (!isDevelopment()) {\n // This function runs just prior to `run`\n await registerCleanBugsnagErrorsFromWithinPlugins(this.config)\n }\n this.showNpmFlagWarning()\n await showNotificationsIfNeeded()\n return super.init()\n }\n\n // NPM creates an environment variable for every flag passed to a script.\n // This function checks for the presence of any of the available CLI flags\n // and warns the user to use the `--` separator.\n protected showNpmFlagWarning(): void {\n const commandVariables = this.constructor as unknown as {flags: JsonMap}\n const commandFlags = Object.keys(commandVariables.flags || {})\n const possibleNpmEnvVars = commandFlags.map((key) => `npm_config_${underscore(key).replace(/^no_/, '')}`)\n\n if (possibleNpmEnvVars.some((flag) => process.env[flag] !== undefined)) {\n renderWarning({\n body: [\n 'NPM scripts require an extra',\n {command: '--'},\n 'separator to pass the flags. Example:',\n {command: 'npm run dev -- --reset'},\n ],\n })\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\n protected exitWithTimestampWhenEnvVariablePresent() {\n if (isTruthy(process.env.SHOPIFY_CLI_ENV_STARTUP_PERFORMANCE_RUN)) {\n outputInfo(`\n SHOPIFY_CLI_TIMESTAMP_START\n { \"timestamp\": ${Date.now()} }\n SHOPIFY_CLI_TIMESTAMP_END\n `)\n process.exit(0)\n }\n }\n\n protected async parse<\n TFlags extends FlagOutput & {path?: string; verbose?: boolean},\n TGlobalFlags extends FlagOutput,\n TArgs extends ArgOutput,\n >(\n options?: Input<TFlags, TGlobalFlags, TArgs>,\n argv?: string[],\n ): Promise<ParserOutput<TFlags, TGlobalFlags, TArgs> & {argv: string[]}> {\n let result = await super.parse<TFlags, TGlobalFlags, TArgs>(options, argv)\n result = await this.resultWithEnvironment<TFlags, TGlobalFlags, TArgs>(result, options, argv)\n await addFromParsedFlags(result.flags)\n return {...result, ...{argv: result.argv as string[]}}\n }\n\n protected environmentsFilename(): string | undefined {\n // To be re-implemented if needed\n return undefined\n }\n\n protected failMissingNonTTYFlags(flags: FlagOutput, requiredFlags: string[]): void {\n if (terminalSupportsPrompting()) return\n\n requiredFlags.forEach((name: string) => {\n if (!(name in flags)) {\n throw new AbortError(\n outputContent`Flag not specified:\n\n${outputToken.cyan(name)}\n\nThis flag is required in non-interactive terminal environments, such as a CI environment, or when piping input from another process.`,\n 'To resolve this, specify the option in the command, or run the command in an interactive environment such as your local terminal.',\n )\n }\n })\n }\n\n private async resultWithEnvironment<\n TFlags extends FlagOutput & {path?: string; verbose?: boolean},\n TGlobalFlags extends FlagOutput,\n TArgs extends ArgOutput,\n >(\n originalResult: ParserOutput<TFlags, TGlobalFlags, TArgs>,\n options?: Input<TFlags, TGlobalFlags, TArgs>,\n argv?: string[],\n ): Promise<ParserOutput<TFlags, TGlobalFlags, TArgs>> {\n // If no environment is specified, don't modify the results\n const flags = originalResult.flags as EnvironmentFlags\n const environmentsFileName = this.environmentsFilename()\n if (!flags.environment || !environmentsFileName) return originalResult\n\n // If the specified environment isn't found, don't modify the results\n const environment = await loadEnvironment(flags.environment, environmentsFileName, {from: flags.path})\n if (!environment) return originalResult\n\n // Parse using noDefaultsOptions to derive a list of flags specified as\n // command-line arguments.\n const noDefaultsResult = await super.parse<TFlags, TGlobalFlags, TArgs>(noDefaultsOptions(options), argv)\n\n // Add the environment's settings to argv and pass them to `super.parse`. This\n // invokes oclif's validation system without breaking the oclif black box.\n // Replace the original result with this one.\n const result = await super.parse<TFlags, TGlobalFlags, TArgs>(options, [\n // Need to specify argv default because we're merging with argsFromEnvironment.\n ...(argv || this.argv),\n ...argsFromEnvironment<TFlags, TGlobalFlags, TArgs>(environment, options, noDefaultsResult),\n ])\n\n // Report successful application of the environment.\n reportEnvironmentApplication<TFlags, TGlobalFlags, TArgs>(\n noDefaultsResult.flags,\n result.flags,\n flags.environment,\n environment,\n )\n\n return result\n }\n}\n\nexport async function addFromParsedFlags(flags: {path?: string; verbose?: boolean}): Promise<void> {\n await addPublicMetadata(() => ({\n cmd_all_verbose: flags.verbose,\n cmd_all_path_override: flags.path !== undefined,\n cmd_all_path_override_hash: flags.path === undefined ? undefined : hashString(flags.path),\n }))\n}\n\n/**\n * Any flag which is:\n *\n * 1. Present in the final set of flags\n * 2. Specified in the environment\n * 3. Not specified by the user as a command line argument\n *\n * should be reported.\n *\n * It doesn't matter if the environment flag's value was the same as the default; from\n * the user's perspective, they want to know their environment was applied.\n */\nfunction reportEnvironmentApplication<\n TFlags extends FlagOutput,\n TGlobalFlags extends FlagOutput,\n TArgs extends ArgOutput,\n>(\n noDefaultsFlags: ParserOutput<TFlags, TGlobalFlags, TArgs>['flags'],\n flagsWithEnvironments: ParserOutput<TFlags, TGlobalFlags, TArgs>['flags'],\n environmentName: string,\n environment: JsonMap,\n): void {\n const changes: JsonMap = {}\n for (const [name, value] of Object.entries(flagsWithEnvironments)) {\n const userSpecifiedThisFlag = Object.prototype.hasOwnProperty.call(noDefaultsFlags, name)\n const environmentContainsFlag = Object.prototype.hasOwnProperty.call(environment, name)\n if (!userSpecifiedThisFlag && environmentContainsFlag) {\n const valueToReport = name === 'password' ? `********${value.substr(-4)}` : value\n changes[name] = valueToReport\n }\n }\n if (Object.keys(changes).length === 0) return\n\n const items = Object.entries(changes).map(([name, value]) => `${name}: ${value}`)\n renderInfo({\n headline: ['Using applicable flags from', {userInput: environmentName}, 'environment:'],\n body: [{list: {items}}],\n })\n}\n\n/**\n * Strips the defaults from configured flags. For example, if flags contains:\n *\n * ```\n * someFlag: Flags.boolean({\n * description: 'some flag',\n * default: false\n * })\n * ```\n *\n * it becomes:\n *\n * ```\n * someFlag: Flags.boolean({\n * description: 'some flag'\n * })\n * ```\n *\n * If we parse using this configuration, the only specified flags will be those\n * the user actually passed on the command line.\n */\nfunction noDefaultsOptions<TFlags extends FlagOutput, TGlobalFlags extends FlagOutput, TArgs extends ArgOutput>(\n options: Input<TFlags, TGlobalFlags, TArgs> | undefined,\n): Input<TFlags, TGlobalFlags, TArgs> | undefined {\n if (!options?.flags) return options\n return {\n ...options,\n flags: Object.fromEntries(\n Object.entries(options.flags).map(([label, settings]) => {\n const copiedSettings = {...(settings as {default?: unknown})}\n delete copiedSettings.default\n return [label, copiedSettings]\n }),\n ) as FlagInput<TFlags>,\n }\n}\n\n/**\n * Converts the environment's settings to arguments as though passed on the command\n * line, skipping any arguments the user specified on the command line.\n */\nfunction argsFromEnvironment<TFlags extends FlagOutput, TGlobalFlags extends FlagOutput, TArgs extends ArgOutput>(\n environment: JsonMap,\n options: Input<TFlags, TGlobalFlags, TArgs> | undefined,\n noDefaultsResult: ParserOutput<TFlags, TArgs>,\n): string[] {\n const args: string[] = []\n for (const [label, value] of Object.entries(environment)) {\n const flagIsRelevantToCommand = options?.flags && Object.prototype.hasOwnProperty.call(options.flags, label)\n const userSpecifiedThisFlag =\n noDefaultsResult.flags && Object.prototype.hasOwnProperty.call(noDefaultsResult.flags, label)\n if (flagIsRelevantToCommand && !userSpecifiedThisFlag) {\n if (typeof value === 'boolean') {\n if (value) {\n args.push(`--${label}`)\n } else {\n throw new AbortError(\n outputContent`Environments can only specify true for boolean flags. Attempted to set ${outputToken.yellow(\n label,\n )} to false.`,\n )\n }\n } else if (Array.isArray(value)) {\n value.forEach((element) => args.push(`--${label}`, `${element}`))\n } else {\n args.push(`--${label}`, `${value}`)\n }\n }\n }\n return args\n}\n\nexport default BaseCommand\n"]}
|
|
1
|
+
{"version":3,"file":"base-command.js","sourceRoot":"","sources":["../../../src/public/node/base-command.ts"],"names":[],"mappings":"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","sourcesContent":["import {errorHandler, registerCleanBugsnagErrorsFromWithinPlugins} from './error-handler.js'\nimport {loadEnvironment} from './environments.js'\nimport {isDevelopment} from './context/local.js'\nimport {addPublicMetadata} from './metadata.js'\nimport {AbortError} from './error.js'\nimport {renderInfo, renderWarning} from './ui.js'\nimport {outputContent, outputInfo, outputToken} from './output.js'\nimport {terminalSupportsPrompting} from './system.js'\nimport {hashString} from './crypto.js'\nimport {isTruthy} from './context/utilities.js'\nimport {showNotificationsIfNeeded} from './notifications-system.js'\nimport {setCurrentCommandId} from './global-context.js'\nimport {JsonMap} from '../../private/common/json.js'\nimport {underscore} from '../common/string.js'\nimport {Command, Errors} from '@oclif/core'\nimport {FlagOutput, Input, ParserOutput, FlagInput, ArgOutput} from '@oclif/core/lib/interfaces/parser.js'\n\ninterface EnvironmentFlags {\n environment?: string[]\n path?: string\n}\n\nabstract class BaseCommand extends Command {\n // eslint-disable-next-line @typescript-eslint/ban-types\n static baseFlags: FlagInput<{}> = {}\n\n // Replace markdown links to plain text like: \"link label\" (url)\n public static descriptionWithoutMarkdown(): string | undefined {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return ((this as any).descriptionWithMarkdown ?? '').replace(/(\\[)(.*?)(])(\\()(.*?)(\\))/gm, '\"$2\" ($5)')\n }\n\n public static analyticsNameOverride(): string | undefined {\n return undefined\n }\n\n public static analyticsStopCommand(): string | undefined {\n return undefined\n }\n\n async catch(error: Error & {skipOclifErrorHandling: boolean}): Promise<void> {\n error.skipOclifErrorHandling = true\n await errorHandler(error, this.config)\n return Errors.handle(error)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected async init(): Promise<any> {\n this.exitWithTimestampWhenEnvVariablePresent()\n setCurrentCommandId(this.id ?? '')\n if (!isDevelopment()) {\n // This function runs just prior to `run`\n await registerCleanBugsnagErrorsFromWithinPlugins(this.config)\n }\n this.showNpmFlagWarning()\n await showNotificationsIfNeeded()\n return super.init()\n }\n\n // NPM creates an environment variable for every flag passed to a script.\n // This function checks for the presence of any of the available CLI flags\n // and warns the user to use the `--` separator.\n protected showNpmFlagWarning(): void {\n const commandVariables = this.constructor as unknown as {flags: JsonMap}\n const commandFlags = Object.keys(commandVariables.flags || {})\n const possibleNpmEnvVars = commandFlags.map((key) => `npm_config_${underscore(key).replace(/^no_/, '')}`)\n\n if (possibleNpmEnvVars.some((flag) => process.env[flag] !== undefined)) {\n renderWarning({\n body: [\n 'NPM scripts require an extra',\n {command: '--'},\n 'separator to pass the flags. Example:',\n {command: 'npm run dev -- --reset'},\n ],\n })\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\n protected exitWithTimestampWhenEnvVariablePresent() {\n if (isTruthy(process.env.SHOPIFY_CLI_ENV_STARTUP_PERFORMANCE_RUN)) {\n outputInfo(`\n SHOPIFY_CLI_TIMESTAMP_START\n { \"timestamp\": ${Date.now()} }\n SHOPIFY_CLI_TIMESTAMP_END\n `)\n process.exit(0)\n }\n }\n\n protected async parse<\n TFlags extends FlagOutput & {path?: string; verbose?: boolean},\n TGlobalFlags extends FlagOutput,\n TArgs extends ArgOutput,\n >(\n options?: Input<TFlags, TGlobalFlags, TArgs>,\n argv?: string[],\n ): Promise<ParserOutput<TFlags, TGlobalFlags, TArgs> & {argv: string[]}> {\n let result = await super.parse<TFlags, TGlobalFlags, TArgs>(options, argv)\n result = await this.resultWithEnvironment<TFlags, TGlobalFlags, TArgs>(result, options, argv)\n await addFromParsedFlags(result.flags)\n return {...result, ...{argv: result.argv as string[]}}\n }\n\n protected environmentsFilename(): string | undefined {\n // To be re-implemented if needed\n return undefined\n }\n\n protected failMissingNonTTYFlags(flags: FlagOutput, requiredFlags: string[]): void {\n if (terminalSupportsPrompting()) return\n\n requiredFlags.forEach((name: string) => {\n if (!(name in flags)) {\n throw new AbortError(\n outputContent`Flag not specified:\n\n${outputToken.cyan(name)}\n\nThis flag is required in non-interactive terminal environments, such as a CI environment, or when piping input from another process.`,\n 'To resolve this, specify the option in the command, or run the command in an interactive environment such as your local terminal.',\n )\n }\n })\n }\n\n private async resultWithEnvironment<\n TFlags extends FlagOutput & {path?: string; verbose?: boolean},\n TGlobalFlags extends FlagOutput,\n TArgs extends ArgOutput,\n >(\n originalResult: ParserOutput<TFlags, TGlobalFlags, TArgs>,\n options?: Input<TFlags, TGlobalFlags, TArgs>,\n argv?: string[],\n ): Promise<ParserOutput<TFlags, TGlobalFlags, TArgs>> {\n // If no environment is specified, don't modify the results\n const flags = originalResult.flags as EnvironmentFlags\n const environmentsFileName = this.environmentsFilename()\n if (!flags.environment?.length || !environmentsFileName) return originalResult\n\n // If users pass multiple environments, do not load them and let each command handle it\n if (flags.environment.length > 1) return originalResult\n\n // If the specified environment isn't found, don't modify the results\n const environment = await loadEnvironment(flags.environment[0] as string, environmentsFileName, {from: flags.path})\n if (!environment) return originalResult\n\n // Parse using noDefaultsOptions to derive a list of flags specified as\n // command-line arguments.\n const noDefaultsResult = await super.parse<TFlags, TGlobalFlags, TArgs>(noDefaultsOptions(options), argv)\n\n // Add the environment's settings to argv and pass them to `super.parse`. This\n // invokes oclif's validation system without breaking the oclif black box.\n // Replace the original result with this one.\n const result = await super.parse<TFlags, TGlobalFlags, TArgs>(options, [\n // Need to specify argv default because we're merging with argsFromEnvironment.\n ...(argv ?? this.argv),\n ...argsFromEnvironment<TFlags, TGlobalFlags, TArgs>(environment, options, noDefaultsResult),\n ])\n\n // Report successful application of the environment.\n reportEnvironmentApplication<TFlags, TGlobalFlags, TArgs>(\n noDefaultsResult.flags,\n result.flags,\n flags.environment[0] as string,\n environment,\n )\n\n return result\n }\n}\n\nexport async function addFromParsedFlags(flags: {path?: string; verbose?: boolean}): Promise<void> {\n await addPublicMetadata(() => ({\n cmd_all_verbose: flags.verbose,\n cmd_all_path_override: flags.path !== undefined,\n cmd_all_path_override_hash: flags.path === undefined ? undefined : hashString(flags.path),\n }))\n}\n\n/**\n * Any flag which is:\n *\n * 1. Present in the final set of flags\n * 2. Specified in the environment\n * 3. Not specified by the user as a command line argument\n *\n * should be reported.\n *\n * It doesn't matter if the environment flag's value was the same as the default; from\n * the user's perspective, they want to know their environment was applied.\n */\nfunction reportEnvironmentApplication<\n TFlags extends FlagOutput,\n TGlobalFlags extends FlagOutput,\n TArgs extends ArgOutput,\n>(\n noDefaultsFlags: ParserOutput<TFlags, TGlobalFlags, TArgs>['flags'],\n flagsWithEnvironments: ParserOutput<TFlags, TGlobalFlags, TArgs>['flags'],\n environmentName: string,\n environment: JsonMap,\n): void {\n const changes: JsonMap = {}\n for (const [name, value] of Object.entries(flagsWithEnvironments)) {\n const userSpecifiedThisFlag = Object.prototype.hasOwnProperty.call(noDefaultsFlags, name)\n const environmentContainsFlag = Object.prototype.hasOwnProperty.call(environment, name)\n if (!userSpecifiedThisFlag && environmentContainsFlag) {\n const valueToReport = name === 'password' ? `********${value.substr(-4)}` : value\n changes[name] = valueToReport\n }\n }\n if (Object.keys(changes).length === 0) return\n\n const items = Object.entries(changes).map(([name, value]) => `${name}: ${value}`)\n renderInfo({\n headline: ['Using applicable flags from', {userInput: environmentName}, 'environment:'],\n body: [{list: {items}}],\n })\n}\n\n/**\n * Strips the defaults from configured flags. For example, if flags contains:\n *\n * ```\n * someFlag: Flags.boolean({\n * description: 'some flag',\n * default: false\n * })\n * ```\n *\n * it becomes:\n *\n * ```\n * someFlag: Flags.boolean({\n * description: 'some flag'\n * })\n * ```\n *\n * If we parse using this configuration, the only specified flags will be those\n * the user actually passed on the command line.\n */\nfunction noDefaultsOptions<TFlags extends FlagOutput, TGlobalFlags extends FlagOutput, TArgs extends ArgOutput>(\n options: Input<TFlags, TGlobalFlags, TArgs> | undefined,\n): Input<TFlags, TGlobalFlags, TArgs> | undefined {\n if (!options?.flags) return options\n return {\n ...options,\n flags: Object.fromEntries(\n Object.entries(options.flags).map(([label, settings]) => {\n const copiedSettings = {...(settings as {default?: unknown})}\n delete copiedSettings.default\n return [label, copiedSettings]\n }),\n ) as FlagInput<TFlags>,\n }\n}\n\n/**\n * Converts the environment's settings to arguments as though passed on the command\n * line, skipping any arguments the user specified on the command line.\n */\nfunction argsFromEnvironment<TFlags extends FlagOutput, TGlobalFlags extends FlagOutput, TArgs extends ArgOutput>(\n environment: JsonMap,\n options: Input<TFlags, TGlobalFlags, TArgs> | undefined,\n noDefaultsResult: ParserOutput<TFlags, TArgs>,\n): string[] {\n const args: string[] = []\n for (const [label, value] of Object.entries(environment)) {\n const flagIsRelevantToCommand = options?.flags && Object.prototype.hasOwnProperty.call(options.flags, label)\n const userSpecifiedThisFlag =\n noDefaultsResult.flags && Object.prototype.hasOwnProperty.call(noDefaultsResult.flags, label)\n if (flagIsRelevantToCommand && !userSpecifiedThisFlag) {\n if (typeof value === 'boolean') {\n if (value) {\n args.push(`--${label}`)\n } else {\n throw new AbortError(\n outputContent`Environments can only specify true for boolean flags. Attempted to set ${outputToken.yellow(\n label,\n )} to false.`,\n )\n }\n } else if (Array.isArray(value)) {\n value.forEach((element) => args.push(`--${label}`, `${element}`))\n } else {\n args.push(`--${label}`, `${value}`)\n }\n }\n }\n return args\n}\n\nexport default BaseCommand\n"]}
|
package/dist/public/node/cli.js
CHANGED
|
@@ -3,13 +3,13 @@ import { launchCLI as defaultLaunchCli } from './cli-launcher.js';
|
|
|
3
3
|
import { cacheClear } from '../../private/node/conf-store.js';
|
|
4
4
|
import { environmentVariables } from '../../private/node/constants.js';
|
|
5
5
|
import { Flags } from '@oclif/core';
|
|
6
|
-
async function
|
|
6
|
+
async function exitIfOldNodeVersion(versions = process.versions) {
|
|
7
7
|
const nodeVersion = versions.node;
|
|
8
8
|
const nodeMajorVersion = Number(nodeVersion.split('.')[0]);
|
|
9
9
|
const currentSupportedNodeVersion = 18;
|
|
10
10
|
if (nodeMajorVersion < currentSupportedNodeVersion) {
|
|
11
|
-
const {
|
|
12
|
-
|
|
11
|
+
const { renderError } = await import('./ui.js');
|
|
12
|
+
renderError({
|
|
13
13
|
headline: 'Upgrade to a supported Node version now.',
|
|
14
14
|
body: [
|
|
15
15
|
`Node ${nodeMajorVersion} has reached end-of-life and poses security risks. When you upgrade to a`,
|
|
@@ -23,6 +23,7 @@ async function warnIfOldNodeVersion(versions = process.versions) {
|
|
|
23
23
|
"you'll be able to use Shopify CLI without interruption.",
|
|
24
24
|
],
|
|
25
25
|
});
|
|
26
|
+
process.exit(1);
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
function setupEnvironmentVariables(options, argv = process.argv, env = process.env) {
|
|
@@ -57,7 +58,7 @@ export async function runCLI(options, launchCLI = defaultLaunchCli, argv = proce
|
|
|
57
58
|
await addInitToArgvWhenRunningCreateCLI(options, argv);
|
|
58
59
|
}
|
|
59
60
|
forceNoColor(argv, env);
|
|
60
|
-
await
|
|
61
|
+
await exitIfOldNodeVersion(versions);
|
|
61
62
|
return launchCLI({ moduleURL: options.moduleURL });
|
|
62
63
|
}
|
|
63
64
|
async function addInitToArgvWhenRunningCreateCLI(options, argv = process.argv) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../src/public/node/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,wBAAwB,CAAA;AAC/C,OAAO,EAAC,SAAS,IAAI,gBAAgB,EAAC,MAAM,mBAAmB,CAAA;AAC/D,OAAO,EAAC,UAAU,EAAC,MAAM,kCAAkC,CAAA;AAC3D,OAAO,EAAC,oBAAoB,EAAC,MAAM,iCAAiC,CAAA;AACpE,OAAO,EAAC,KAAK,EAAC,MAAM,aAAa,CAAA;AAajC,KAAK,UAAU,oBAAoB,CAAC,WAAmC,OAAO,CAAC,QAAQ;IACrF,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAA;IACjC,MAAM,gBAAgB,GAAG,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAE1D,MAAM,2BAA2B,GAAG,EAAE,CAAA;IACtC,IAAI,gBAAgB,GAAG,2BAA2B,EAAE,CAAC;QACnD,MAAM,EAAC,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../src/public/node/cli.ts"],"names":[],"mappings":"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","sourcesContent":["import {isTruthy} from './context/utilities.js'\nimport {launchCLI as defaultLaunchCli} from './cli-launcher.js'\nimport {cacheClear} from '../../private/node/conf-store.js'\nimport {environmentVariables} from '../../private/node/constants.js'\nimport {Flags} from '@oclif/core'\n\n/**\n * IMPORTANT NOTE: Imports in this module are dynamic to ensure that \"setupEnvironmentVariables\" can dynamically\n * set the DEBUG environment variable before the 'debug' package sets up its configuration when modules\n * are loaded statically.\n */\ninterface RunCLIOptions {\n /** The value of import.meta.url of the CLI executable module */\n moduleURL: string\n development: boolean\n}\n\nasync function exitIfOldNodeVersion(versions: NodeJS.ProcessVersions = process.versions) {\n const nodeVersion = versions.node\n const nodeMajorVersion = Number(nodeVersion.split('.')[0])\n\n const currentSupportedNodeVersion = 18\n if (nodeMajorVersion < currentSupportedNodeVersion) {\n const {renderError} = await import('./ui.js')\n renderError({\n headline: 'Upgrade to a supported Node version now.',\n body: [\n `Node ${nodeMajorVersion} has reached end-of-life and poses security risks. When you upgrade to a`,\n {\n link: {\n url: 'https://nodejs.dev/en/about/previous-releases',\n label: 'supported version',\n },\n },\n {char: ','},\n \"you'll be able to use Shopify CLI without interruption.\",\n ],\n })\n process.exit(1)\n }\n}\n\nfunction setupEnvironmentVariables(\n options: Pick<RunCLIOptions, 'development'>,\n argv: string[] = process.argv,\n env: NodeJS.ProcessEnv = process.env,\n) {\n /**\n * By setting DEBUG=* when --verbose is passed we are increasing the\n * verbosity of oclif. Oclif uses debug (https://www.npmjs.com/package/debug)\n * for logging, and it's configured through the DEBUG= environment variable.\n */\n if (argv.includes('--verbose')) {\n env.DEBUG = env.DEBUG ?? '*'\n }\n if (options.development) {\n env.SHOPIFY_CLI_ENV = env.SHOPIFY_CLI_ENV ?? 'development'\n }\n}\n\nfunction forceNoColor(argv: string[] = process.argv, env: NodeJS.ProcessEnv = process.env) {\n if (\n argv.includes('--no-color') ||\n isTruthy(env.NO_COLOR) ||\n isTruthy(env.SHOPIFY_FLAG_NO_COLOR) ||\n env.TERM === 'dumb'\n ) {\n env.FORCE_COLOR = '0'\n }\n}\n\n/**\n * A function that abstracts away setting up the environment and running\n * a CLI\n * @param options - Options.\n */\nexport async function runCLI(\n options: RunCLIOptions & {runInCreateMode?: boolean},\n launchCLI: (options: {moduleURL: string}) => Promise<void> = defaultLaunchCli,\n argv: string[] = process.argv,\n env: NodeJS.ProcessEnv = process.env,\n versions: NodeJS.ProcessVersions = process.versions,\n): Promise<void> {\n setupEnvironmentVariables(options, argv, env)\n if (options.runInCreateMode) {\n await addInitToArgvWhenRunningCreateCLI(options, argv)\n }\n forceNoColor(argv, env)\n await exitIfOldNodeVersion(versions)\n return launchCLI({moduleURL: options.moduleURL})\n}\n\nasync function addInitToArgvWhenRunningCreateCLI(\n options: Pick<RunCLIOptions, 'moduleURL'>,\n argv: string[] = process.argv,\n): Promise<void> {\n const {findUpAndReadPackageJson} = await import('./node-package-manager.js')\n const {moduleDirectory} = await import('./path.js')\n\n const packageJson = await findUpAndReadPackageJson(moduleDirectory(options.moduleURL))\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const packageName = (packageJson.content as any).name as string\n const name = packageName.replace('@shopify/create-', '')\n const initIndex = argv.findIndex((arg) => arg.includes('init'))\n if (initIndex === -1) {\n const initIndex = argv.findIndex((arg) => arg.match(new RegExp(`bin(\\\\/|\\\\\\\\)+(create-${name}|dev|run)`))) + 1\n argv.splice(initIndex, 0, 'init')\n }\n}\n\n/**\n * A function for create-x CLIs that automatically runs the \"init\" command.\n */\nexport async function runCreateCLI(\n options: RunCLIOptions,\n launchCLI: (options: {moduleURL: string}) => Promise<void> = defaultLaunchCli,\n argv: string[] = process.argv,\n env: NodeJS.ProcessEnv = process.env,\n versions: NodeJS.ProcessVersions = process.versions,\n): Promise<void> {\n return runCLI({...options, runInCreateMode: true}, launchCLI, argv, env, versions)\n}\n\n/**\n * An object that contains the flags that\n * are shared across all the commands.\n */\nexport const globalFlags = {\n 'no-color': Flags.boolean({\n hidden: false,\n description: 'Disable color output.',\n env: 'SHOPIFY_FLAG_NO_COLOR',\n }),\n verbose: Flags.boolean({\n hidden: false,\n description: 'Increase the verbosity of the output.',\n env: 'SHOPIFY_FLAG_VERBOSE',\n }),\n}\n\nexport const jsonFlag = {\n json: Flags.boolean({\n char: 'j',\n description: 'Output the result as JSON.',\n hidden: false,\n default: false,\n env: environmentVariables.json,\n }),\n}\n\n/**\n * Clear the CLI cache, used to store some API responses and handle notifications status\n */\nexport function clearCache(): void {\n cacheClear()\n}\n"]}
|
|
@@ -21,9 +21,10 @@ async function detectStopCommand(commandClass) {
|
|
|
21
21
|
const stopCommand = commandClass.analyticsStopCommand();
|
|
22
22
|
if (stopCommand) {
|
|
23
23
|
const { commandStartOptions } = metadata.getAllSensitiveMetadata();
|
|
24
|
+
if (!commandStartOptions)
|
|
25
|
+
return;
|
|
24
26
|
await metadata.addSensitiveMetadata(() => ({
|
|
25
27
|
commandStartOptions: {
|
|
26
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
27
28
|
...commandStartOptions,
|
|
28
29
|
startTime: currentTime,
|
|
29
30
|
startCommand: stopCommand,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postrun.js","sourceRoot":"","sources":["../../../../src/public/node/hooks/postrun.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,IAAI,gBAAgB,EAAC,MAAM,mBAAmB,CAAA;AAC7D,OAAO,EAAC,oBAAoB,EAAC,MAAM,iBAAiB,CAAA;AACpD,OAAO,EAAC,WAAW,EAAC,MAAM,gCAAgC,CAAA;AAE1D,OAAO,KAAK,QAAQ,MAAM,kCAAkC,CAAA;AAG5D,gGAAgG;AAChG,MAAM,CAAC,MAAM,IAAI,GAAiB,KAAK,EAAE,EAAC,MAAM,EAAE,OAAO,EAAC,EAAE,EAAE;IAC5D,MAAM,iBAAiB,CAAC,OAAoC,CAAC,CAAA;IAC7D,MAAM,oBAAoB,CAAC,EAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAC,CAAC,CAAA;IACpD,gBAAgB,CAAC,OAAO,CAAC,CAAA;IAEzB,MAAM,OAAO,GAAG,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IAC7C,WAAW,CAAC,qBAAqB,OAAO,EAAE,CAAC,CAAA;AAC7C,CAAC,CAAA;AAED;;;;GAIG;AACH,KAAK,UAAU,iBAAiB,CAAC,YAAgD;IAC/E,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAA;IACxC,IAAI,YAAY,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,YAAY,EAAE,sBAAsB,CAAC,EAAE,CAAC;QAC/F,MAAM,WAAW,GAAI,YAAmC,CAAC,oBAAoB,EAAE,CAAA;QAC/E,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,EAAC,mBAAmB,EAAC,GAAG,QAAQ,CAAC,uBAAuB,EAAE,CAAA;YAChE,MAAM,QAAQ,CAAC,oBAAoB,CAAC,GAAG,EAAE,CAAC,CAAC;gBACzC,mBAAmB,EAAE;oBACnB,
|
|
1
|
+
{"version":3,"file":"postrun.js","sourceRoot":"","sources":["../../../../src/public/node/hooks/postrun.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,IAAI,gBAAgB,EAAC,MAAM,mBAAmB,CAAA;AAC7D,OAAO,EAAC,oBAAoB,EAAC,MAAM,iBAAiB,CAAA;AACpD,OAAO,EAAC,WAAW,EAAC,MAAM,gCAAgC,CAAA;AAE1D,OAAO,KAAK,QAAQ,MAAM,kCAAkC,CAAA;AAG5D,gGAAgG;AAChG,MAAM,CAAC,MAAM,IAAI,GAAiB,KAAK,EAAE,EAAC,MAAM,EAAE,OAAO,EAAC,EAAE,EAAE;IAC5D,MAAM,iBAAiB,CAAC,OAAoC,CAAC,CAAA;IAC7D,MAAM,oBAAoB,CAAC,EAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAC,CAAC,CAAA;IACpD,gBAAgB,CAAC,OAAO,CAAC,CAAA;IAEzB,MAAM,OAAO,GAAG,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IAC7C,WAAW,CAAC,qBAAqB,OAAO,EAAE,CAAC,CAAA;AAC7C,CAAC,CAAA;AAED;;;;GAIG;AACH,KAAK,UAAU,iBAAiB,CAAC,YAAgD;IAC/E,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAA;IACxC,IAAI,YAAY,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,YAAY,EAAE,sBAAsB,CAAC,EAAE,CAAC;QAC/F,MAAM,WAAW,GAAI,YAAmC,CAAC,oBAAoB,EAAE,CAAA;QAC/E,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,EAAC,mBAAmB,EAAC,GAAG,QAAQ,CAAC,uBAAuB,EAAE,CAAA;YAChE,IAAI,CAAC,mBAAmB;gBAAE,OAAM;YAChC,MAAM,QAAQ,CAAC,oBAAoB,CAAC,GAAG,EAAE,CAAC,CAAC;gBACzC,mBAAmB,EAAE;oBACnB,GAAG,mBAAmB;oBACtB,SAAS,EAAE,WAAW;oBACtB,YAAY,EAAE,WAAW;iBAC1B;aACF,CAAC,CAAC,CAAA;QACL,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import {postrun as deprecationsHook} from './deprecations.js'\nimport {reportAnalyticsEvent} from '../analytics.js'\nimport {outputDebug} from '../../../public/node/output.js'\nimport BaseCommand from '../base-command.js'\nimport * as metadata from '../../../public/node/metadata.js'\nimport {Command, Hook} from '@oclif/core'\n\n// This hook is called after each successful command run. More info: https://oclif.io/docs/hooks\nexport const hook: Hook.Postrun = async ({config, Command}) => {\n await detectStopCommand(Command as unknown as typeof Command)\n await reportAnalyticsEvent({config, exitMode: 'ok'})\n deprecationsHook(Command)\n\n const command = Command.id.replace(/:/g, ' ')\n outputDebug(`Completed command ${command}`)\n}\n\n/**\n * Override the command name with the stop one for analytics purposes.\n *\n * @param commandClass - Oclif command class.\n */\nasync function detectStopCommand(commandClass: Command.Class | typeof BaseCommand): Promise<void> {\n const currentTime = new Date().getTime()\n if (commandClass && Object.prototype.hasOwnProperty.call(commandClass, 'analyticsStopCommand')) {\n const stopCommand = (commandClass as typeof BaseCommand).analyticsStopCommand()\n if (stopCommand) {\n const {commandStartOptions} = metadata.getAllSensitiveMetadata()\n if (!commandStartOptions) return\n await metadata.addSensitiveMetadata(() => ({\n commandStartOptions: {\n ...commandStartOptions,\n startTime: currentTime,\n startCommand: stopCommand,\n },\n }))\n }\n }\n}\n"]}
|
|
@@ -4,6 +4,7 @@ import { startAnalytics } from '../../../private/node/analytics.js';
|
|
|
4
4
|
import { outputDebug, outputWarn } from '../../../public/node/output.js';
|
|
5
5
|
import { getOutputUpdateCLIReminder } from '../../../public/node/upgrade.js';
|
|
6
6
|
import { runAtMinimumInterval } from '../../../private/node/conf-store.js';
|
|
7
|
+
import { fetchNotificationsInBackground } from '../notifications-system.js';
|
|
7
8
|
// This hook is called before each command run. More info: https://oclif.io/docs/hooks
|
|
8
9
|
export const hook = async (options) => {
|
|
9
10
|
const commandContent = parseCommandContent({
|
|
@@ -15,6 +16,8 @@ export const hook = async (options) => {
|
|
|
15
16
|
await warnOnAvailableUpgrade();
|
|
16
17
|
outputDebug(`Running command ${commandContent.command}`);
|
|
17
18
|
await startAnalytics({ commandContent, args, commandClass: options.Command });
|
|
19
|
+
if (!options.Command.hidden)
|
|
20
|
+
fetchNotificationsInBackground(options.Command.id);
|
|
18
21
|
};
|
|
19
22
|
export function parseCommandContent(cmdInfo) {
|
|
20
23
|
let commandContent = parseCreateCommand(cmdInfo.pluginAlias);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prerun.js","sourceRoot":"","sources":["../../../../src/public/node/hooks/prerun.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,yBAAyB,CAAA;AACvD,OAAO,EAAC,kBAAkB,EAAE,wBAAwB,EAAC,MAAM,4BAA4B,CAAA;AACvF,OAAO,EAAC,cAAc,EAAC,MAAM,oCAAoC,CAAA;AACjE,OAAO,EAAC,WAAW,EAAE,UAAU,EAAC,MAAM,gCAAgC,CAAA;AACtE,OAAO,EAAC,0BAA0B,EAAC,MAAM,iCAAiC,CAAA;AAE1E,OAAO,EAAC,oBAAoB,EAAC,MAAM,qCAAqC,CAAA;
|
|
1
|
+
{"version":3,"file":"prerun.js","sourceRoot":"","sources":["../../../../src/public/node/hooks/prerun.ts"],"names":[],"mappings":"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","sourcesContent":["import {CLI_KIT_VERSION} from '../../common/version.js'\nimport {checkForNewVersion, checkForCachedNewVersion} from '../node-package-manager.js'\nimport {startAnalytics} from '../../../private/node/analytics.js'\nimport {outputDebug, outputWarn} from '../../../public/node/output.js'\nimport {getOutputUpdateCLIReminder} from '../../../public/node/upgrade.js'\nimport Command from '../../../public/node/base-command.js'\nimport {runAtMinimumInterval} from '../../../private/node/conf-store.js'\nimport {fetchNotificationsInBackground} from '../notifications-system.js'\nimport {Hook} from '@oclif/core'\n\nexport declare interface CommandContent {\n command: string\n topic?: string\n alias?: string\n}\n// This hook is called before each command run. More info: https://oclif.io/docs/hooks\nexport const hook: Hook.Prerun = async (options) => {\n const commandContent = parseCommandContent({\n id: options.Command.id,\n aliases: options.Command.aliases,\n pluginAlias: options.Command.plugin?.alias,\n })\n const args = options.argv\n await warnOnAvailableUpgrade()\n outputDebug(`Running command ${commandContent.command}`)\n await startAnalytics({commandContent, args, commandClass: options.Command as unknown as typeof Command})\n if (!options.Command.hidden) fetchNotificationsInBackground(options.Command.id)\n}\n\nexport function parseCommandContent(cmdInfo: {id: string; aliases: string[]; pluginAlias?: string}): CommandContent {\n let commandContent = parseCreateCommand(cmdInfo.pluginAlias)\n if (!commandContent) {\n commandContent = parseNormalCommand(cmdInfo.id, cmdInfo.aliases)\n }\n return commandContent\n}\n\nfunction parseNormalCommand(id: string, aliases: string[]): CommandContent {\n return {\n command: id.replace(/:/g, ' '),\n topic: parseTopic(id),\n alias: findAlias(aliases),\n }\n}\n\n/**\n * Create commands implement Init by default, so the name of the command must be extracted from\n * the plugin/module name. Neither alias or topic are supported\n *\n * @param commandClass - Oclif command configuration\n * @returns Command content with the name of the command or undefined otherwise\n */\nfunction parseCreateCommand(pluginAlias?: string): CommandContent | undefined {\n if (!pluginAlias?.startsWith('@shopify/create-')) {\n return undefined\n }\n\n return {command: pluginAlias.substring(pluginAlias.indexOf('/') + 1)}\n}\n\n/**\n * Commands use this pattern topic:subtopic1:...:subtopicN:command. This method extract the topic and subtopic\n * information replacing the ':' separator with one space\n *\n * @param cmd - Complete command string to extract the topic information\n * @returns The topic name or undefined otherwise\n */\nfunction parseTopic(cmd: string) {\n if (cmd.lastIndexOf(':') === -1) {\n return\n }\n return cmd.slice(0, cmd.lastIndexOf(':')).replace(/:/g, ' ')\n}\n\n/**\n * Identifies if the command was launched using an alias instead of the oficial command name\n *\n * @param aliases - List of possible alias a command has\n * @returns The alias used or undefined otherwise\n */\nfunction findAlias(aliases: string[]) {\n const existingAlias = aliases.find((alias) =>\n alias.split(':').every((aliasToken) => process.argv.includes(aliasToken)),\n )\n if (existingAlias) {\n return existingAlias.replace(/:/g, ' ')\n }\n}\n\n/**\n * Warns the user if there is a new version of the CLI available\n */\nexport async function warnOnAvailableUpgrade(): Promise<void> {\n const cliDependency = '@shopify/cli'\n const currentVersion = CLI_KIT_VERSION\n if (currentVersion.startsWith('0.0.0')) {\n // This is a nightly/snapshot/experimental version, so we don't want to check for updates\n return\n }\n\n // Check in the background, once daily\n // eslint-disable-next-line no-void\n void checkForNewVersion(cliDependency, currentVersion, {cacheExpiryInHours: 24})\n\n // Warn if we previously found a new version\n await runAtMinimumInterval('warn-on-available-upgrade', {days: 1}, async () => {\n const newerVersion = checkForCachedNewVersion(cliDependency, currentVersion)\n if (newerVersion) {\n outputWarn(getOutputUpdateCLIReminder(newerVersion))\n }\n })\n}\n"]}
|