@shopify/cli-kit 3.88.1 → 3.90.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/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/session/device-authorization.js +4 -0
- package/dist/private/node/session/device-authorization.js.map +1 -1
- package/dist/private/node/ui/components/Banner.d.ts +2 -1
- package/dist/private/node/ui/components/Banner.js.map +1 -1
- package/dist/private/node/ui/components/DangerousConfirmationPrompt.js +1 -1
- package/dist/private/node/ui/components/DangerousConfirmationPrompt.js.map +1 -1
- package/dist/private/node/ui/components/LoadingBar.d.ts +1 -1
- package/dist/private/node/ui/components/Prompts/PromptLayout.js +1 -1
- package/dist/private/node/ui/components/Prompts/PromptLayout.js.map +1 -1
- package/dist/private/node/ui/components/SelectInput.d.ts +2 -2
- package/dist/private/node/ui/components/SelectInput.js.map +1 -1
- package/dist/private/node/ui/components/SingleTask.d.ts +3 -1
- package/dist/private/node/ui/components/SingleTask.js +12 -4
- package/dist/private/node/ui/components/SingleTask.js.map +1 -1
- package/dist/private/node/ui/components/Table/Row.d.ts +2 -1
- package/dist/private/node/ui/components/Table/Table.d.ts +2 -1
- package/dist/private/node/ui/components/Tasks.d.ts +1 -1
- package/dist/private/node/ui/components/TextPrompt.js +1 -1
- package/dist/private/node/ui/components/TextPrompt.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.d.ts +13 -0
- package/dist/public/node/api/admin.js +2 -2
- package/dist/public/node/api/admin.js.map +1 -1
- package/dist/public/node/api/graphql.d.ts +1 -0
- package/dist/public/node/api/graphql.js +50 -24
- package/dist/public/node/api/graphql.js.map +1 -1
- package/dist/public/node/context/local.d.ts +7 -0
- package/dist/public/node/context/local.js +9 -0
- package/dist/public/node/context/local.js.map +1 -1
- package/dist/public/node/http.d.ts +1 -1
- package/dist/public/node/http.js.map +1 -1
- package/dist/public/node/notifications-system.js +1 -1
- package/dist/public/node/notifications-system.js.map +1 -1
- package/dist/public/node/ui.d.ts +2 -1
- package/dist/public/node/ui.js +2 -2
- package/dist/public/node/ui.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
|
@@ -41,6 +41,14 @@ export declare function adminRequestDoc<TResult, TVariables extends Variables>(o
|
|
|
41
41
|
* @returns - An array of supported API versions.
|
|
42
42
|
*/
|
|
43
43
|
export declare function supportedApiVersions(session: AdminSession, preferredBehaviour?: RequestModeInput): Promise<string[]>;
|
|
44
|
+
/**
|
|
45
|
+
* GraphQL query to retrieve all API versions.
|
|
46
|
+
*
|
|
47
|
+
* @param session - Shopify admin session including token and Store FQDN.
|
|
48
|
+
* @param preferredBehaviour - Custom request behaviour for retries and timeouts.
|
|
49
|
+
* @returns - An array of supported and unsupported API versions.
|
|
50
|
+
*/
|
|
51
|
+
export declare function fetchApiVersions(session: AdminSession, preferredBehaviour?: RequestModeInput): Promise<ApiVersion[]>;
|
|
44
52
|
/**
|
|
45
53
|
* Returns the Admin API URL for the given store and version.
|
|
46
54
|
*
|
|
@@ -50,6 +58,10 @@ export declare function supportedApiVersions(session: AdminSession, preferredBeh
|
|
|
50
58
|
* @returns - Admin API URL.
|
|
51
59
|
*/
|
|
52
60
|
export declare function adminUrl(store: string, version: string | undefined, session?: AdminSession): string;
|
|
61
|
+
interface ApiVersion {
|
|
62
|
+
handle: string;
|
|
63
|
+
supported: boolean;
|
|
64
|
+
}
|
|
53
65
|
/**
|
|
54
66
|
* Executes a REST request against the Admin API.
|
|
55
67
|
*
|
|
@@ -83,3 +95,4 @@ export interface RestResponse {
|
|
|
83
95
|
[key: string]: string[];
|
|
84
96
|
};
|
|
85
97
|
}
|
|
98
|
+
export {};
|
|
@@ -108,7 +108,7 @@ export async function supportedApiVersions(session, preferredBehaviour) {
|
|
|
108
108
|
* @param preferredBehaviour - Custom request behaviour for retries and timeouts.
|
|
109
109
|
* @returns - An array of supported and unsupported API versions.
|
|
110
110
|
*/
|
|
111
|
-
async function fetchApiVersions(session, preferredBehaviour) {
|
|
111
|
+
export async function fetchApiVersions(session, preferredBehaviour) {
|
|
112
112
|
try {
|
|
113
113
|
const response = await adminRequestDoc({
|
|
114
114
|
query: PublicApiVersions,
|
|
@@ -123,7 +123,7 @@ async function fetchApiVersions(session, preferredBehaviour) {
|
|
|
123
123
|
catch (error) {
|
|
124
124
|
if (error instanceof ClientError && error.response.status === 403) {
|
|
125
125
|
const storeName = session.storeFqdn.replace('.myshopify.com', '');
|
|
126
|
-
throw new AbortError(outputContent `Looks like you don't have access this dev store: (${outputToken.link(storeName, `https://${session.storeFqdn}`)})`, outputContent `If you're not the owner, create a dev store staff account for yourself`);
|
|
126
|
+
throw new AbortError(outputContent `Looks like you don't have access to this dev store: (${outputToken.link(storeName, `https://${session.storeFqdn}`)})`, outputContent `If you're not the owner, create a dev store staff account for yourself`);
|
|
127
127
|
}
|
|
128
128
|
if (error instanceof ClientError && (error.response.status === 401 || error.response.status === 404)) {
|
|
129
129
|
throw new AbortError(`Error connecting to your store ${session.storeFqdn}: ${error.message} ${error.response.status} ${error.response.data}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin.js","sourceRoot":"","sources":["../../../../src/public/node/api/admin.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n graphqlRequest,\n graphqlRequestDoc,\n GraphQLResponseOptions,\n GraphQLVariables,\n UnauthorizedHandler,\n} from './graphql.js'\nimport {AdminSession} from '../session.js'\nimport {outputContent, outputToken} from '../../../public/node/output.js'\nimport {AbortError, BugError} from '../error.js'\nimport {\n restRequestBody,\n restRequestHeaders,\n restRequestUrl,\n isThemeAccessSession,\n} from '../../../private/node/api/rest.js'\nimport {isNetworkError} from '../../../private/node/api.js'\nimport {RequestModeInput, shopifyFetch} from '../http.js'\nimport {PublicApiVersions} from '../../../cli/api/graphql/admin/generated/public_api_versions.js'\n\nimport {themeKitAccessDomain} from '../../../private/node/constants.js'\nimport {serviceEnvironment} from '../../../private/node/context/service.js'\nimport {DevServerCore} from '../vendor/dev_server/index.js'\nimport {ClientError, Variables} from 'graphql-request'\nimport {TypedDocumentNode} from '@graphql-typed-document-node/core'\n\nconst LatestApiVersionByFQDN = new Map<string, string>()\n\n/**\n * Executes a GraphQL query against the Admin API.\n *\n * @param query - GraphQL query to execute.\n * @param session - Shopify admin session including token and Store FQDN.\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 adminRequest<T>(query: string, session: AdminSession, variables?: GraphQLVariables): Promise<T> {\n const api = 'Admin'\n const version = await fetchLatestSupportedApiVersion(session)\n let storeDomain = session.storeFqdn\n const addedHeaders = themeAccessHeaders(session)\n\n if (serviceEnvironment() === 'local') {\n addedHeaders['x-forwarded-host'] = storeDomain\n storeDomain = new DevServerCore().host('app')\n }\n\n const url = adminUrl(storeDomain, version, session)\n return graphqlRequest({query, api, addedHeaders, url, token: session.token, variables})\n}\n\nexport interface AdminRequestOptions<TResult, TVariables extends Variables> {\n /** GraphQL query to execute. */\n query: TypedDocumentNode<TResult, TVariables>\n /** Shopify admin session including token and Store FQDN. */\n session: AdminSession\n /** GraphQL variables to pass to the query. */\n variables?: TVariables\n /** API version. */\n version?: string\n /** Control how API responses will be handled. */\n responseOptions?: GraphQLResponseOptions<TResult>\n /** Custom request behaviour for retries and timeouts. */\n preferredBehaviour?: RequestModeInput\n}\n\n/**\n * Executes a GraphQL query against the Admin API. Uses typed documents.\n *\n * @param options - Admin request options.\n * @returns The response of the query of generic type <TResult>.\n */\nexport async function adminRequestDoc<TResult, TVariables extends Variables>(\n options: AdminRequestOptions<TResult, TVariables>,\n): Promise<TResult> {\n const {query, session, variables, version, responseOptions, preferredBehaviour} = options\n\n let apiVersion = version ?? LatestApiVersionByFQDN.get(session.storeFqdn)\n if (!apiVersion) {\n apiVersion = await fetchLatestSupportedApiVersion(session, preferredBehaviour)\n }\n let storeDomain = session.storeFqdn\n const addedHeaders = themeAccessHeaders(session)\n\n if (serviceEnvironment() === 'local') {\n addedHeaders['x-forwarded-host'] = storeDomain\n storeDomain = new DevServerCore().host('app')\n }\n\n const opts = {\n url: adminUrl(storeDomain, apiVersion, session),\n api: 'Admin',\n token: session.token,\n addedHeaders,\n }\n let unauthorizedHandler: UnauthorizedHandler | undefined\n if ('refresh' in session) {\n unauthorizedHandler = {type: 'token_refresh', handler: session.refresh as () => Promise<{token: string}>}\n }\n const result = graphqlRequestDoc<TResult, TVariables>({\n ...opts,\n query,\n variables,\n responseOptions,\n unauthorizedHandler,\n preferredBehaviour,\n })\n return result\n}\n\nfunction themeAccessHeaders(session: AdminSession): {[header: string]: string} {\n return isThemeAccessSession(session)\n ? {'X-Shopify-Shop': session.storeFqdn, 'X-Shopify-Access-Token': session.token}\n : {}\n}\n\n/**\n * GraphQL query to retrieve the latest supported API version.\n *\n * @param session - Shopify admin session including token and Store FQDN.\n * @param preferredBehaviour - Custom request behaviour for retries and timeouts.\n * @returns - The latest supported API version.\n */\nasync function fetchLatestSupportedApiVersion(\n session: AdminSession,\n preferredBehaviour?: RequestModeInput,\n): Promise<string> {\n const apiVersions = await supportedApiVersions(session, preferredBehaviour)\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const latest = apiVersions.reverse()[0]!\n LatestApiVersionByFQDN.set(session.storeFqdn, latest)\n return latest\n}\n\n/**\n * GraphQL query to retrieve all supported API versions.\n *\n * @param session - Shopify admin session including token and Store FQDN.\n * @param preferredBehaviour - Custom request behaviour for retries and timeouts.\n * @returns - An array of supported API versions.\n */\nexport async function supportedApiVersions(\n session: AdminSession,\n preferredBehaviour?: RequestModeInput,\n): Promise<string[]> {\n const apiVersions = await fetchApiVersions(session, preferredBehaviour)\n return apiVersions\n .filter((item) => item.supported)\n .map((item) => item.handle)\n .sort()\n}\n\n/**\n * GraphQL query to retrieve all API versions.\n *\n * @param session - Shopify admin session including token and Store FQDN.\n * @param preferredBehaviour - Custom request behaviour for retries and timeouts.\n * @returns - An array of supported and unsupported API versions.\n */\nasync function fetchApiVersions(session: AdminSession, preferredBehaviour?: RequestModeInput): Promise<ApiVersion[]> {\n try {\n const response = await adminRequestDoc({\n query: PublicApiVersions,\n session,\n variables: {},\n version: 'unstable',\n responseOptions: {handleErrors: false},\n preferredBehaviour,\n })\n return response.publicApiVersions\n } catch (error) {\n if (error instanceof ClientError && error.response.status === 403) {\n const storeName = session.storeFqdn.replace('.myshopify.com', '')\n throw new AbortError(\n outputContent`Looks like you don't have access this dev store: (${outputToken.link(\n storeName,\n `https://${session.storeFqdn}`,\n )})`,\n outputContent`If you're not the owner, create a dev store staff account for yourself`,\n )\n }\n if (error instanceof ClientError && (error.response.status === 401 || error.response.status === 404)) {\n throw new AbortError(\n `Error connecting to your store ${session.storeFqdn}: ${error.message} ${error.response.status} ${error.response.data}`,\n )\n }\n\n // Check for network-level errors (connection issues, timeouts, DNS failures, TLS/certificate errors, etc.)\n // All network errors should be treated as user-facing errors, not CLI bugs\n // Note: Some of these may have been retried already by lower-level retry logic\n if (isNetworkError(error)) {\n throw new AbortError(\n `Network error connecting to your store ${session.storeFqdn}: ${\n error instanceof Error ? error.message : String(error)\n }`,\n 'Check your internet connection and try again.',\n )\n }\n\n // Unknown errors are likely bugs in the CLI\n throw new BugError(\n `Unknown error connecting to your store ${session.storeFqdn}: ${\n error instanceof Error ? error.message : String(error)\n }`,\n )\n }\n}\n\n/**\n * Returns the Admin API URL for the given store and version.\n *\n * @param store - Store FQDN.\n * @param version - API version.\n * @param session - User session.\n * @returns - Admin API URL.\n */\nexport function adminUrl(store: string, version: string | undefined, session?: AdminSession): string {\n const realVersion = version ?? 'unstable'\n\n const url =\n session && isThemeAccessSession(session)\n ? `https://${themeKitAccessDomain}/cli/admin/api/${realVersion}/graphql.json`\n : `https://${store}/admin/api/${realVersion}/graphql.json`\n return url\n}\n\ninterface ApiVersion {\n handle: string\n supported: boolean\n}\n\n/**\n * Executes a REST request against the Admin API.\n *\n * @param method - Request's HTTP method.\n * @param path - Path of the REST resource.\n * @param session - Shopify Admin session including token and Store FQDN.\n * @param requestBody - Request body of including REST resource specific parameters.\n * @param searchParams - Search params, appended to the URL.\n * @param apiVersion - Admin API version.\n * @returns - The {@link RestResponse}.\n */\nexport async function restRequest<T>(\n method: string,\n path: string,\n session: AdminSession,\n requestBody?: T,\n searchParams: {[name: string]: string} = {},\n apiVersion = 'unstable',\n): Promise<RestResponse> {\n const url = restRequestUrl(session, apiVersion, path, searchParams)\n const body = restRequestBody<T>(requestBody)\n\n const headers = restRequestHeaders(session)\n const response = await shopifyFetch(url, {\n headers,\n method,\n body,\n })\n\n const json = await response.json().catch(() => ({}))\n\n return {\n json,\n status: response.status,\n headers: response.headers.raw(),\n }\n}\n\n/**\n * Respose of a REST request.\n */\nexport interface RestResponse {\n /**\n * REST JSON respose.\n */\n // Using `any` to avoid introducing extra DTO layers.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n json: any\n\n /**\n * HTTP response status.\n */\n status: number\n\n /**\n * HTTP response headers.\n */\n headers: {[key: string]: string[]}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"admin.js","sourceRoot":"","sources":["../../../../src/public/node/api/admin.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n graphqlRequest,\n graphqlRequestDoc,\n GraphQLResponseOptions,\n GraphQLVariables,\n UnauthorizedHandler,\n} from './graphql.js'\nimport {AdminSession} from '../session.js'\nimport {outputContent, outputToken} from '../../../public/node/output.js'\nimport {AbortError, BugError} from '../error.js'\nimport {\n restRequestBody,\n restRequestHeaders,\n restRequestUrl,\n isThemeAccessSession,\n} from '../../../private/node/api/rest.js'\nimport {isNetworkError} from '../../../private/node/api.js'\nimport {RequestModeInput, shopifyFetch} from '../http.js'\nimport {PublicApiVersions} from '../../../cli/api/graphql/admin/generated/public_api_versions.js'\n\nimport {themeKitAccessDomain} from '../../../private/node/constants.js'\nimport {serviceEnvironment} from '../../../private/node/context/service.js'\nimport {DevServerCore} from '../vendor/dev_server/index.js'\nimport {ClientError, Variables} from 'graphql-request'\nimport {TypedDocumentNode} from '@graphql-typed-document-node/core'\n\nconst LatestApiVersionByFQDN = new Map<string, string>()\n\n/**\n * Executes a GraphQL query against the Admin API.\n *\n * @param query - GraphQL query to execute.\n * @param session - Shopify admin session including token and Store FQDN.\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 adminRequest<T>(query: string, session: AdminSession, variables?: GraphQLVariables): Promise<T> {\n const api = 'Admin'\n const version = await fetchLatestSupportedApiVersion(session)\n let storeDomain = session.storeFqdn\n const addedHeaders = themeAccessHeaders(session)\n\n if (serviceEnvironment() === 'local') {\n addedHeaders['x-forwarded-host'] = storeDomain\n storeDomain = new DevServerCore().host('app')\n }\n\n const url = adminUrl(storeDomain, version, session)\n return graphqlRequest({query, api, addedHeaders, url, token: session.token, variables})\n}\n\nexport interface AdminRequestOptions<TResult, TVariables extends Variables> {\n /** GraphQL query to execute. */\n query: TypedDocumentNode<TResult, TVariables>\n /** Shopify admin session including token and Store FQDN. */\n session: AdminSession\n /** GraphQL variables to pass to the query. */\n variables?: TVariables\n /** API version. */\n version?: string\n /** Control how API responses will be handled. */\n responseOptions?: GraphQLResponseOptions<TResult>\n /** Custom request behaviour for retries and timeouts. */\n preferredBehaviour?: RequestModeInput\n}\n\n/**\n * Executes a GraphQL query against the Admin API. Uses typed documents.\n *\n * @param options - Admin request options.\n * @returns The response of the query of generic type <TResult>.\n */\nexport async function adminRequestDoc<TResult, TVariables extends Variables>(\n options: AdminRequestOptions<TResult, TVariables>,\n): Promise<TResult> {\n const {query, session, variables, version, responseOptions, preferredBehaviour} = options\n\n let apiVersion = version ?? LatestApiVersionByFQDN.get(session.storeFqdn)\n if (!apiVersion) {\n apiVersion = await fetchLatestSupportedApiVersion(session, preferredBehaviour)\n }\n let storeDomain = session.storeFqdn\n const addedHeaders = themeAccessHeaders(session)\n\n if (serviceEnvironment() === 'local') {\n addedHeaders['x-forwarded-host'] = storeDomain\n storeDomain = new DevServerCore().host('app')\n }\n\n const opts = {\n url: adminUrl(storeDomain, apiVersion, session),\n api: 'Admin',\n token: session.token,\n addedHeaders,\n }\n let unauthorizedHandler: UnauthorizedHandler | undefined\n if ('refresh' in session) {\n unauthorizedHandler = {type: 'token_refresh', handler: session.refresh as () => Promise<{token: string}>}\n }\n const result = graphqlRequestDoc<TResult, TVariables>({\n ...opts,\n query,\n variables,\n responseOptions,\n unauthorizedHandler,\n preferredBehaviour,\n })\n return result\n}\n\nfunction themeAccessHeaders(session: AdminSession): {[header: string]: string} {\n return isThemeAccessSession(session)\n ? {'X-Shopify-Shop': session.storeFqdn, 'X-Shopify-Access-Token': session.token}\n : {}\n}\n\n/**\n * GraphQL query to retrieve the latest supported API version.\n *\n * @param session - Shopify admin session including token and Store FQDN.\n * @param preferredBehaviour - Custom request behaviour for retries and timeouts.\n * @returns - The latest supported API version.\n */\nasync function fetchLatestSupportedApiVersion(\n session: AdminSession,\n preferredBehaviour?: RequestModeInput,\n): Promise<string> {\n const apiVersions = await supportedApiVersions(session, preferredBehaviour)\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const latest = apiVersions.reverse()[0]!\n LatestApiVersionByFQDN.set(session.storeFqdn, latest)\n return latest\n}\n\n/**\n * GraphQL query to retrieve all supported API versions.\n *\n * @param session - Shopify admin session including token and Store FQDN.\n * @param preferredBehaviour - Custom request behaviour for retries and timeouts.\n * @returns - An array of supported API versions.\n */\nexport async function supportedApiVersions(\n session: AdminSession,\n preferredBehaviour?: RequestModeInput,\n): Promise<string[]> {\n const apiVersions = await fetchApiVersions(session, preferredBehaviour)\n return apiVersions\n .filter((item) => item.supported)\n .map((item) => item.handle)\n .sort()\n}\n\n/**\n * GraphQL query to retrieve all API versions.\n *\n * @param session - Shopify admin session including token and Store FQDN.\n * @param preferredBehaviour - Custom request behaviour for retries and timeouts.\n * @returns - An array of supported and unsupported API versions.\n */\nexport async function fetchApiVersions(\n session: AdminSession,\n preferredBehaviour?: RequestModeInput,\n): Promise<ApiVersion[]> {\n try {\n const response = await adminRequestDoc({\n query: PublicApiVersions,\n session,\n variables: {},\n version: 'unstable',\n responseOptions: {handleErrors: false},\n preferredBehaviour,\n })\n return response.publicApiVersions\n } catch (error) {\n if (error instanceof ClientError && error.response.status === 403) {\n const storeName = session.storeFqdn.replace('.myshopify.com', '')\n throw new AbortError(\n outputContent`Looks like you don't have access to this dev store: (${outputToken.link(\n storeName,\n `https://${session.storeFqdn}`,\n )})`,\n outputContent`If you're not the owner, create a dev store staff account for yourself`,\n )\n }\n if (error instanceof ClientError && (error.response.status === 401 || error.response.status === 404)) {\n throw new AbortError(\n `Error connecting to your store ${session.storeFqdn}: ${error.message} ${error.response.status} ${error.response.data}`,\n )\n }\n\n // Check for network-level errors (connection issues, timeouts, DNS failures, TLS/certificate errors, etc.)\n // All network errors should be treated as user-facing errors, not CLI bugs\n // Note: Some of these may have been retried already by lower-level retry logic\n if (isNetworkError(error)) {\n throw new AbortError(\n `Network error connecting to your store ${session.storeFqdn}: ${\n error instanceof Error ? error.message : String(error)\n }`,\n 'Check your internet connection and try again.',\n )\n }\n\n // Unknown errors are likely bugs in the CLI\n throw new BugError(\n `Unknown error connecting to your store ${session.storeFqdn}: ${\n error instanceof Error ? error.message : String(error)\n }`,\n )\n }\n}\n\n/**\n * Returns the Admin API URL for the given store and version.\n *\n * @param store - Store FQDN.\n * @param version - API version.\n * @param session - User session.\n * @returns - Admin API URL.\n */\nexport function adminUrl(store: string, version: string | undefined, session?: AdminSession): string {\n const realVersion = version ?? 'unstable'\n\n const url =\n session && isThemeAccessSession(session)\n ? `https://${themeKitAccessDomain}/cli/admin/api/${realVersion}/graphql.json`\n : `https://${store}/admin/api/${realVersion}/graphql.json`\n return url\n}\n\ninterface ApiVersion {\n handle: string\n supported: boolean\n}\n\n/**\n * Executes a REST request against the Admin API.\n *\n * @param method - Request's HTTP method.\n * @param path - Path of the REST resource.\n * @param session - Shopify Admin session including token and Store FQDN.\n * @param requestBody - Request body of including REST resource specific parameters.\n * @param searchParams - Search params, appended to the URL.\n * @param apiVersion - Admin API version.\n * @returns - The {@link RestResponse}.\n */\nexport async function restRequest<T>(\n method: string,\n path: string,\n session: AdminSession,\n requestBody?: T,\n searchParams: {[name: string]: string} = {},\n apiVersion = 'unstable',\n): Promise<RestResponse> {\n const url = restRequestUrl(session, apiVersion, path, searchParams)\n const body = restRequestBody<T>(requestBody)\n\n const headers = restRequestHeaders(session)\n const response = await shopifyFetch(url, {\n headers,\n method,\n body,\n })\n\n const json = await response.json().catch(() => ({}))\n\n return {\n json,\n status: response.status,\n headers: response.headers.raw(),\n }\n}\n\n/**\n * Respose of a REST request.\n */\nexport interface RestResponse {\n /**\n * REST JSON respose.\n */\n // Using `any` to avoid introducing extra DTO layers.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n json: any\n\n /**\n * HTTP response status.\n */\n status: number\n\n /**\n * HTTP response headers.\n */\n headers: {[key: string]: string[]}\n}\n"]}
|
|
@@ -47,6 +47,7 @@ export type GraphQLRequestDocOptions<TResult, TVariables> = GraphQLRequestBaseOp
|
|
|
47
47
|
}>>;
|
|
48
48
|
variables?: TVariables;
|
|
49
49
|
unauthorizedHandler?: UnauthorizedHandler;
|
|
50
|
+
autoRateLimitRestore?: boolean;
|
|
50
51
|
};
|
|
51
52
|
export interface GraphQLResponseOptions<T> {
|
|
52
53
|
handleErrors?: boolean;
|
|
@@ -7,7 +7,10 @@ import { nonRandomUUID } from '../crypto.js';
|
|
|
7
7
|
import { cacheRetrieveOrRepopulate, timeIntervalToMilliseconds, } from '../../../private/node/conf-store.js';
|
|
8
8
|
import { abortSignalFromRequestBehaviour, requestMode } from '../http.js';
|
|
9
9
|
import { CLI_KIT_VERSION } from '../../common/version.js';
|
|
10
|
+
import { sleep } from '../system.js';
|
|
11
|
+
import { outputContent, outputDebug } from '../output.js';
|
|
10
12
|
import { GraphQLClient, resolveRequestDocument, ClientError, } from 'graphql-request';
|
|
13
|
+
const MAX_RATE_LIMIT_RESTORE_DELAY_SECONDS = 0.3;
|
|
11
14
|
async function createGraphQLClient({ url, addedHeaders, token, }) {
|
|
12
15
|
const headers = {
|
|
13
16
|
...addedHeaders,
|
|
@@ -19,36 +22,59 @@ async function createGraphQLClient({ url, addedHeaders, token, }) {
|
|
|
19
22
|
headers,
|
|
20
23
|
};
|
|
21
24
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
async function waitForRateLimitRestore(fullResponse) {
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
27
|
+
const cost = fullResponse.extensions?.cost;
|
|
28
|
+
const actualQueryCost = cost?.actualQueryCost;
|
|
29
|
+
const restoreRate = cost?.throttleStatus?.restoreRate;
|
|
30
|
+
if (actualQueryCost && typeof actualQueryCost === 'number' && restoreRate && typeof restoreRate === 'number') {
|
|
31
|
+
const secondsToRestoreRate = actualQueryCost / restoreRate;
|
|
32
|
+
outputDebug(outputContent `Sleeping for ${secondsToRestoreRate.toString()} seconds to restore the rate limit.`);
|
|
33
|
+
await sleep(Math.min(secondsToRestoreRate, MAX_RATE_LIMIT_RESTORE_DELAY_SECONDS));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async function runSingleRawGraphQLRequest(options) {
|
|
37
|
+
const { client, behaviour, queryAsString, variables, autoRateLimitRestore } = options;
|
|
38
|
+
let fullResponse;
|
|
39
|
+
// there is a errorPolicy option which returns rather than throwing on errors, but we _do_ ultimately want to
|
|
40
|
+
// throw.
|
|
41
|
+
try {
|
|
42
|
+
client.setAbortSignal(abortSignalFromRequestBehaviour(behaviour));
|
|
43
|
+
fullResponse = await client.rawRequest(queryAsString, variables);
|
|
44
|
+
await logLastRequestIdFromResponse(fullResponse);
|
|
45
|
+
if (autoRateLimitRestore) {
|
|
46
|
+
await waitForRateLimitRestore(fullResponse);
|
|
47
|
+
}
|
|
48
|
+
return fullResponse;
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
if (error instanceof ClientError) {
|
|
52
|
+
// error.response does have a headers property like a normal response, but it's not typed as such.
|
|
53
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
54
|
+
await logLastRequestIdFromResponse(error.response);
|
|
55
|
+
}
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
27
59
|
async function performGraphQLRequest(options) {
|
|
28
|
-
const { token, addedHeaders, queryAsString, variables, api, url, responseOptions, unauthorizedHandler, cacheOptions } = options;
|
|
60
|
+
const { token, addedHeaders, queryAsString, variables, api, url, responseOptions, unauthorizedHandler, cacheOptions, autoRateLimitRestore, } = options;
|
|
29
61
|
const behaviour = requestMode(options.preferredBehaviour ?? 'default');
|
|
30
62
|
let { headers, client } = await createGraphQLClient({ url, addedHeaders, token });
|
|
31
63
|
debugLogRequestInfo(api, queryAsString, url, variables, headers);
|
|
32
64
|
const rawGraphQLRequest = async () => {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
// throw.
|
|
36
|
-
try {
|
|
37
|
-
// mapping signal to any due to polyfill meaning types don't exactly match (but are functionally equivalent)
|
|
38
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
39
|
-
client.requestConfig.signal = abortSignalFromRequestBehaviour(behaviour);
|
|
40
|
-
fullResponse = await client.rawRequest(queryAsString, variables);
|
|
41
|
-
await logLastRequestIdFromResponse(fullResponse);
|
|
42
|
-
return fullResponse;
|
|
43
|
-
}
|
|
44
|
-
catch (error) {
|
|
45
|
-
if (error instanceof ClientError) {
|
|
46
|
-
// error.response does have a headers property like a normal response, but it's not typed as such.
|
|
65
|
+
return runSingleRawGraphQLRequest({
|
|
66
|
+
client: {
|
|
47
67
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
68
|
+
setAbortSignal: (signal) => {
|
|
69
|
+
client.requestConfig.signal = signal;
|
|
70
|
+
},
|
|
71
|
+
rawRequest: (query, variables) => client.rawRequest(query, variables),
|
|
72
|
+
},
|
|
73
|
+
behaviour,
|
|
74
|
+
queryAsString,
|
|
75
|
+
variables,
|
|
76
|
+
autoRateLimitRestore: autoRateLimitRestore ?? false,
|
|
77
|
+
});
|
|
52
78
|
};
|
|
53
79
|
const tokenRefreshHandler = unauthorizedHandler?.handler;
|
|
54
80
|
const tokenRefreshUnauthorizedHandlerFunction = tokenRefreshHandler
|
|
@@ -1 +1 @@
|
|
|
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 {abortSignalFromRequestBehaviour, requestMode, RequestModeInput} from '../http.js'\nimport {CLI_KIT_VERSION} from '../../common/version.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'\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 RefreshedTokenOnAuthorizedResponse {\n token?: string\n}\n\nexport type RefreshTokenOnAuthorizedResponse = Promise<RefreshedTokenOnAuthorizedResponse>\n\nexport interface UnauthorizedHandler {\n type: 'token_refresh'\n handler: () => RefreshTokenOnAuthorizedResponse\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 preferredBehaviour?: RequestModeInput\n}\n\ntype PerformGraphQLRequestOptions<TResult> = GraphQLRequestBaseOptions<TResult> & {\n queryAsString: string\n variables?: Variables\n unauthorizedHandler?: UnauthorizedHandler\n}\n\nexport type GraphQLRequestOptions<T> = GraphQLRequestBaseOptions<T> & {\n query: RequestDocument\n variables?: Variables\n unauthorizedHandler?: UnauthorizedHandler\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?: UnauthorizedHandler\n}\n\nexport interface GraphQLResponseOptions<T> {\n handleErrors?: boolean\n onResponse?: (response: GraphQLResponse<T>) => void\n}\n\nasync function createGraphQLClient({\n url,\n addedHeaders,\n token,\n}: {\n url: string\n token: string | undefined\n addedHeaders?: {[header: string]: string}\n}) {\n const headers = {\n ...addedHeaders,\n ...buildHeaders(token),\n }\n const clientOptions = {agent: await httpsAgent(), headers}\n\n return {\n client: new GraphQLClient(url, clientOptions),\n headers,\n }\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 behaviour = requestMode(options.preferredBehaviour ?? 'default')\n\n let {headers, client} = await createGraphQLClient({url, addedHeaders, token})\n debugLogRequestInfo(api, queryAsString, url, variables, headers)\n\n const rawGraphQLRequest = 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 // mapping signal to any due to polyfill meaning types don't exactly match (but are functionally equivalent)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n client.requestConfig.signal = abortSignalFromRequestBehaviour(behaviour) as any\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 tokenRefreshHandler = unauthorizedHandler?.handler\n\n const tokenRefreshUnauthorizedHandlerFunction = tokenRefreshHandler\n ? async () => {\n const refreshTokenResult = await tokenRefreshHandler()\n if (refreshTokenResult.token) {\n const {client: newClient, headers: newHeaders} = await createGraphQLClient({\n url,\n addedHeaders,\n token: refreshTokenResult.token,\n })\n client = newClient\n headers = newHeaders\n return true\n } else {\n return false\n }\n }\n : undefined\n\n const request = () =>\n retryAwareRequest(\n {request: rawGraphQLRequest, url, ...behaviour},\n responseOptions?.handleErrors === false ? undefined : errorHandler(api),\n )\n\n const executeWithTimer = () =>\n runWithTimer('cmd_all_timing_network_ms')(async () => {\n let response\n try {\n response = await request()\n } catch (error) {\n if (error instanceof ClientError && error.response.status === 401 && tokenRefreshUnauthorizedHandlerFunction) {\n if (await tokenRefreshUnauthorizedHandlerFunction()) {\n response = await request()\n } else {\n throw error\n }\n } else {\n throw error\n }\n }\n\n if (responseOptions?.onResponse) {\n responseOptions.onResponse(response)\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
|
+
{"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 {abortSignalFromRequestBehaviour, RequestBehaviour, requestMode, RequestModeInput} from '../http.js'\nimport {CLI_KIT_VERSION} from '../../common/version.js'\nimport {sleep} from '../system.js'\nimport {outputContent, outputDebug} from '../output.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'\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 RefreshedTokenOnAuthorizedResponse {\n token?: string\n}\n\nexport type RefreshTokenOnAuthorizedResponse = Promise<RefreshedTokenOnAuthorizedResponse>\n\nexport interface UnauthorizedHandler {\n type: 'token_refresh'\n handler: () => RefreshTokenOnAuthorizedResponse\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 preferredBehaviour?: RequestModeInput\n}\n\ntype PerformGraphQLRequestOptions<TResult> = GraphQLRequestBaseOptions<TResult> & {\n queryAsString: string\n variables?: Variables\n unauthorizedHandler?: UnauthorizedHandler\n autoRateLimitRestore?: boolean\n}\n\nexport type GraphQLRequestOptions<T> = GraphQLRequestBaseOptions<T> & {\n query: RequestDocument\n variables?: Variables\n unauthorizedHandler?: UnauthorizedHandler\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?: UnauthorizedHandler\n autoRateLimitRestore?: boolean\n}\n\ninterface RunRawGraphQLRequestOptions<TResult> {\n client: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n setAbortSignal: (signal: any) => void\n rawRequest: (query: string, variables?: Variables) => Promise<GraphQLResponse<TResult>>\n }\n behaviour: RequestBehaviour\n queryAsString: string\n variables?: Variables\n autoRateLimitRestore: boolean\n}\n\nexport interface GraphQLResponseOptions<T> {\n handleErrors?: boolean\n onResponse?: (response: GraphQLResponse<T>) => void\n}\n\nconst MAX_RATE_LIMIT_RESTORE_DELAY_SECONDS = 0.3\n\nasync function createGraphQLClient({\n url,\n addedHeaders,\n token,\n}: {\n url: string\n token: string | undefined\n addedHeaders?: {[header: string]: string}\n}) {\n const headers = {\n ...addedHeaders,\n ...buildHeaders(token),\n }\n const clientOptions = {agent: await httpsAgent(), headers}\n\n return {\n client: new GraphQLClient(url, clientOptions),\n headers,\n }\n}\n\nasync function waitForRateLimitRestore(fullResponse: GraphQLResponse<unknown>) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const cost = (fullResponse.extensions as any)?.cost\n const actualQueryCost = cost?.actualQueryCost\n const restoreRate = cost?.throttleStatus?.restoreRate\n if (actualQueryCost && typeof actualQueryCost === 'number' && restoreRate && typeof restoreRate === 'number') {\n const secondsToRestoreRate = actualQueryCost / restoreRate\n outputDebug(outputContent`Sleeping for ${secondsToRestoreRate.toString()} seconds to restore the rate limit.`)\n await sleep(Math.min(secondsToRestoreRate, MAX_RATE_LIMIT_RESTORE_DELAY_SECONDS))\n }\n}\n\nasync function runSingleRawGraphQLRequest<TResult>(\n options: RunRawGraphQLRequestOptions<TResult>,\n): Promise<GraphQLResponse<TResult>> {\n const {client, behaviour, queryAsString, variables, autoRateLimitRestore} = options\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 client.setAbortSignal(abortSignalFromRequestBehaviour(behaviour))\n fullResponse = await client.rawRequest(queryAsString, variables)\n await logLastRequestIdFromResponse(fullResponse)\n\n if (autoRateLimitRestore) {\n await waitForRateLimitRestore(fullResponse)\n }\n\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\nasync function performGraphQLRequest<TResult>(options: PerformGraphQLRequestOptions<TResult>) {\n const {\n token,\n addedHeaders,\n queryAsString,\n variables,\n api,\n url,\n responseOptions,\n unauthorizedHandler,\n cacheOptions,\n autoRateLimitRestore,\n } = options\n const behaviour = requestMode(options.preferredBehaviour ?? 'default')\n\n let {headers, client} = await createGraphQLClient({url, addedHeaders, token})\n debugLogRequestInfo(api, queryAsString, url, variables, headers)\n\n const rawGraphQLRequest = async () => {\n return runSingleRawGraphQLRequest({\n client: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n setAbortSignal: (signal: any) => {\n client.requestConfig.signal = signal\n },\n rawRequest: (query: string, variables?: Variables) => client.rawRequest<TResult>(query, variables),\n },\n behaviour,\n queryAsString,\n variables,\n autoRateLimitRestore: autoRateLimitRestore ?? false,\n })\n }\n\n const tokenRefreshHandler = unauthorizedHandler?.handler\n\n const tokenRefreshUnauthorizedHandlerFunction = tokenRefreshHandler\n ? async () => {\n const refreshTokenResult = await tokenRefreshHandler()\n if (refreshTokenResult.token) {\n const {client: newClient, headers: newHeaders} = await createGraphQLClient({\n url,\n addedHeaders,\n token: refreshTokenResult.token,\n })\n client = newClient\n headers = newHeaders\n return true\n } else {\n return false\n }\n }\n : undefined\n\n const request = () =>\n retryAwareRequest(\n {request: rawGraphQLRequest, url, ...behaviour},\n responseOptions?.handleErrors === false ? undefined : errorHandler(api),\n )\n\n const executeWithTimer = () =>\n runWithTimer('cmd_all_timing_network_ms')(async () => {\n let response\n try {\n response = await request()\n } catch (error) {\n if (error instanceof ClientError && error.response.status === 401 && tokenRefreshUnauthorizedHandlerFunction) {\n if (await tokenRefreshUnauthorizedHandlerFunction()) {\n response = await request()\n } else {\n throw error\n }\n } else {\n throw error\n }\n }\n\n if (responseOptions?.onResponse) {\n responseOptions.onResponse(response)\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"]}
|
|
@@ -70,6 +70,13 @@ export declare function alwaysLogMetrics(env?: NodeJS.ProcessEnv): boolean;
|
|
|
70
70
|
* @returns True if SHOPIFY_CLI_1P is truthy.
|
|
71
71
|
*/
|
|
72
72
|
export declare function firstPartyDev(env?: NodeJS.ProcessEnv): boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Returns true if the local dev console should be skipped.
|
|
75
|
+
*
|
|
76
|
+
* @param env - The environment variables from the environment of the current process.
|
|
77
|
+
* @returns True if SHOPIFY_SKIP_LOCAL_DEV_CONSOLE is truthy.
|
|
78
|
+
*/
|
|
79
|
+
export declare function skipLocalDevConsole(env?: NodeJS.ProcessEnv): boolean;
|
|
73
80
|
/**
|
|
74
81
|
* Return gitpodURL if we are running in gitpod.
|
|
75
82
|
* Https://www.gitpod.io/docs/environment-variables#default-environment-variables.
|
|
@@ -101,6 +101,15 @@ export function alwaysLogMetrics(env = process.env) {
|
|
|
101
101
|
export function firstPartyDev(env = process.env) {
|
|
102
102
|
return isTruthy(env[environmentVariables.firstPartyDev]);
|
|
103
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Returns true if the local dev console should be skipped.
|
|
106
|
+
*
|
|
107
|
+
* @param env - The environment variables from the environment of the current process.
|
|
108
|
+
* @returns True if SHOPIFY_SKIP_LOCAL_DEV_CONSOLE is truthy.
|
|
109
|
+
*/
|
|
110
|
+
export function skipLocalDevConsole(env = process.env) {
|
|
111
|
+
return isTruthy(env[environmentVariables.skipLocalDevConsole]);
|
|
112
|
+
}
|
|
104
113
|
/**
|
|
105
114
|
* Return gitpodURL if we are running in gitpod.
|
|
106
115
|
* Https://www.gitpod.io/docs/environment-variables#default-environment-variables.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local.js","sourceRoot":"","sources":["../../../../src/public/node/context/local.ts"],"names":[],"mappings":"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","sourcesContent":["import {isTruthy} from './utilities.js'\nimport {getCIMetadata, isSet, Metadata} from '../../../private/node/context/utilities.js'\nimport {defaultThemeKitAccessDomain, environmentVariables, pathConstants} from '../../../private/node/constants.js'\nimport {fileExists} from '../fs.js'\nimport {exec} from '../system.js'\nimport isInteractive from 'is-interactive'\nimport macaddress from 'macaddress'\nimport {homedir} from 'os'\n\n/**\n * It returns true if the terminal is interactive.\n *\n * @returns True if the terminal is interactive.\n */\nexport function isTerminalInteractive(): boolean {\n return isInteractive()\n}\n\n/**\n * Returns the path to the user's home directory.\n *\n * @returns The path to the user's home directory.\n */\nexport function homeDirectory(): string {\n return homedir()\n}\n\n/**\n * Returns true if the CLI is running in debug mode.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if SHOPIFY_ENV is development.\n */\nexport function isDevelopment(env = process.env): boolean {\n return env[environmentVariables.env] === 'development'\n}\n\n/**\n * Returns true if the CLI is running in verbose mode.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if SHOPIFY_FLAG_VERBOSE is truthy or the flag --verbose has been passed.\n */\nexport function isVerbose(env = process.env): boolean {\n return isTruthy(env[environmentVariables.verbose]) || process.argv.includes('--verbose')\n}\n\n/**\n * Returns true if the environment in which the CLI is running is either\n * a local environment (where dev is present).\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if the CLI is used in a Shopify environment.\n */\nexport async function isShopify(env = process.env): Promise<boolean> {\n if (Object.prototype.hasOwnProperty.call(env, environmentVariables.runAsUser)) {\n return !isTruthy(env[environmentVariables.runAsUser])\n }\n const devInstalled = await fileExists(pathConstants.executables.dev)\n return devInstalled\n}\n\n/**\n * This variable is used when running unit tests to indicate that the CLI's business logic\n * is run as a subject of a unit test. We can use this variable to disable output through\n * the standard streams.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if the SHOPIFY_UNIT_TEST environment variable is truthy.\n */\nexport function isUnitTest(env = process.env): boolean {\n return isTruthy(env[environmentVariables.unitTest])\n}\n\n/**\n * Returns true if reporting analytics is enabled.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True unless SHOPIFY_CLI_NO_ANALYTICS is truthy or debug mode is enabled.\n */\nexport function analyticsDisabled(env = process.env): boolean {\n return isTruthy(env[environmentVariables.noAnalytics]) || isDevelopment(env)\n}\n\n/**\n * Returns true if reporting analytics should always happen, regardless of DEBUG mode etc.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if SHOPIFY_CLI_ALWAYS_LOG_ANALYTICS is truthy.\n */\nexport function alwaysLogAnalytics(env = process.env): boolean {\n return isTruthy(env[environmentVariables.alwaysLogAnalytics])\n}\n\n/**\n * Returns true if reporting metrics should always happen, regardless of DEBUG mode etc.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if SHOPIFY_CLI_ALWAYS_LOG_METRICS is truthy.\n */\nexport function alwaysLogMetrics(env = process.env): boolean {\n return isTruthy(env[environmentVariables.alwaysLogMetrics])\n}\n\n/**\n * Returns true if the CLI User is 1P.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if SHOPIFY_CLI_1P is truthy.\n */\nexport function firstPartyDev(env = process.env): boolean {\n return isTruthy(env[environmentVariables.firstPartyDev])\n}\n\n/**\n * Return gitpodURL if we are running in gitpod.\n * Https://www.gitpod.io/docs/environment-variables#default-environment-variables.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns The gitpod URL.\n */\nexport function gitpodURL(env = process.env): string | undefined {\n return env[environmentVariables.gitpod]\n}\n\n/**\n * Return codespaceURL if we are running in codespaces.\n * Https://docs.github.com/en/codespaces/developing-in-codespaces/default-environment-variables-for-your-codespace#list-of-default-environment-variables.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns The codespace URL.\n */\nexport function codespaceURL(env = process.env): string | undefined {\n return env[environmentVariables.codespaceName]\n}\n\n/**\n * Return codespacePortForwardingDomain if we are running in codespaces.\n * Https://docs.github.com/en/codespaces/developing-in-codespaces/default-environment-variables-for-your-codespace#list-of-default-environment-variables.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns The codespace port forwarding domain.\n */\nexport function codespacePortForwardingDomain(env = process.env): string | undefined {\n return env[environmentVariables.codespacePortForwardingDomain]\n}\n\n/**\n * Checks if the CLI is run from a cloud environment.\n *\n * @param env - Environment variables used when the cli is launched.\n * @returns True in case the CLI is run from a cloud environment.\n */\nexport function isCloudEnvironment(env: NodeJS.ProcessEnv = process.env): boolean {\n return cloudEnvironment(env).platform !== 'localhost'\n}\n\n/**\n * The token used to run a theme command with a custom password.\n *\n * @param env - Environment variables used when the cli is launched.\n * @returns A string with the token.\n */\nexport function themeToken(env = process.env): string | undefined {\n return env[environmentVariables.themeToken]\n}\n\n/**\n * Returns the cloud environment platform name and if the platform support online IDE in case the CLI is run from one of\n * them. Platform name 'localhost' is returned otherwise.\n *\n * @param env - Environment variables used when the cli is launched.\n * @returns Cloud platform information.\n */\nexport function cloudEnvironment(env: NodeJS.ProcessEnv = process.env): {\n platform: 'codespaces' | 'gitpod' | 'cloudShell' | 'localhost'\n editor: boolean\n} {\n if (isSet(env[environmentVariables.codespaces])) {\n return {platform: 'codespaces', editor: true}\n }\n if (isSet(env[environmentVariables.gitpod])) {\n return {platform: 'gitpod', editor: true}\n }\n if (isSet(env[environmentVariables.cloudShell])) {\n return {platform: 'cloudShell', editor: true}\n }\n return {platform: 'localhost', editor: false}\n}\n\n/**\n * Returns whether the environment has Git available.\n *\n * @returns A promise that resolves with the value.\n */\nexport async function hasGit(): Promise<boolean> {\n try {\n await exec('git', ['--version'])\n return true\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return false\n }\n}\n\n/**\n * Gets info on the CI platform the CLI is running on, if applicable.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns The CI platform info.\n */\nexport function ciPlatform(\n env = process.env,\n): {isCI: true; name: string; metadata: Metadata} | {isCI: false; name?: undefined; metadata?: undefined} {\n if (isTruthy(env.CI)) {\n let name = 'unknown'\n if (isSet(env.BITBUCKET_BUILD_NUMBER)) {\n name = 'bitbucket'\n } else if (isTruthy(env.CIRCLECI)) {\n name = 'circleci'\n } else if (isSet(env.GITHUB_ACTION)) {\n name = 'github'\n } else if (isTruthy(env.GITLAB_CI)) {\n name = 'gitlab'\n } else if (isSet(env.BUILDKITE)) {\n name = 'buildkite'\n }\n\n return {\n isCI: true,\n name,\n metadata: getCIMetadata(name, env),\n }\n } else if (isTruthy(env.TF_BUILD)) {\n return {\n isCI: true,\n name: 'azure',\n metadata: getCIMetadata('azure', env),\n }\n }\n return {\n isCI: false,\n }\n}\n\n/**\n * Returns the first mac address found.\n *\n * @returns Mac address.\n */\nexport function macAddress(): Promise<string> {\n return macaddress.one()\n}\n\n/**\n * Get the domain for theme kit access.\n *\n * It can be overridden via the SHOPIFY_CLI_THEME_KIT_ACCESS_DOMAIN environment\n * variable.\n *\n * @param env - The environment variables from the environment of the process.\n *\n * @returns The domain for theme kit access.\n */\nexport function getThemeKitAccessDomain(env = process.env): string {\n const domain = env[environmentVariables.themeKitAccessDomain]\n\n return isSet(domain) ? domain : defaultThemeKitAccessDomain\n}\n\n/**\n * Get the domain to send OTEL metrics to.\n *\n * It can be overridden via the SHOPIFY_CLI_OTEL_EXPORTER_OTLP_ENDPOINT environment variable.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns The domain to send OTEL metrics to.\n */\nexport function opentelemetryDomain(env = process.env): string {\n const domain = env[environmentVariables.otelURL]\n\n return isSet(domain) ? domain : 'https://otlp-http-production-cli.shopifysvc.com'\n}\n\nexport type CIMetadata = Metadata\n"]}
|
|
1
|
+
{"version":3,"file":"local.js","sourceRoot":"","sources":["../../../../src/public/node/context/local.ts"],"names":[],"mappings":"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","sourcesContent":["import {isTruthy} from './utilities.js'\nimport {getCIMetadata, isSet, Metadata} from '../../../private/node/context/utilities.js'\nimport {defaultThemeKitAccessDomain, environmentVariables, pathConstants} from '../../../private/node/constants.js'\nimport {fileExists} from '../fs.js'\nimport {exec} from '../system.js'\nimport isInteractive from 'is-interactive'\nimport macaddress from 'macaddress'\nimport {homedir} from 'os'\n\n/**\n * It returns true if the terminal is interactive.\n *\n * @returns True if the terminal is interactive.\n */\nexport function isTerminalInteractive(): boolean {\n return isInteractive()\n}\n\n/**\n * Returns the path to the user's home directory.\n *\n * @returns The path to the user's home directory.\n */\nexport function homeDirectory(): string {\n return homedir()\n}\n\n/**\n * Returns true if the CLI is running in debug mode.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if SHOPIFY_ENV is development.\n */\nexport function isDevelopment(env = process.env): boolean {\n return env[environmentVariables.env] === 'development'\n}\n\n/**\n * Returns true if the CLI is running in verbose mode.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if SHOPIFY_FLAG_VERBOSE is truthy or the flag --verbose has been passed.\n */\nexport function isVerbose(env = process.env): boolean {\n return isTruthy(env[environmentVariables.verbose]) || process.argv.includes('--verbose')\n}\n\n/**\n * Returns true if the environment in which the CLI is running is either\n * a local environment (where dev is present).\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if the CLI is used in a Shopify environment.\n */\nexport async function isShopify(env = process.env): Promise<boolean> {\n if (Object.prototype.hasOwnProperty.call(env, environmentVariables.runAsUser)) {\n return !isTruthy(env[environmentVariables.runAsUser])\n }\n const devInstalled = await fileExists(pathConstants.executables.dev)\n return devInstalled\n}\n\n/**\n * This variable is used when running unit tests to indicate that the CLI's business logic\n * is run as a subject of a unit test. We can use this variable to disable output through\n * the standard streams.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if the SHOPIFY_UNIT_TEST environment variable is truthy.\n */\nexport function isUnitTest(env = process.env): boolean {\n return isTruthy(env[environmentVariables.unitTest])\n}\n\n/**\n * Returns true if reporting analytics is enabled.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True unless SHOPIFY_CLI_NO_ANALYTICS is truthy or debug mode is enabled.\n */\nexport function analyticsDisabled(env = process.env): boolean {\n return isTruthy(env[environmentVariables.noAnalytics]) || isDevelopment(env)\n}\n\n/**\n * Returns true if reporting analytics should always happen, regardless of DEBUG mode etc.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if SHOPIFY_CLI_ALWAYS_LOG_ANALYTICS is truthy.\n */\nexport function alwaysLogAnalytics(env = process.env): boolean {\n return isTruthy(env[environmentVariables.alwaysLogAnalytics])\n}\n\n/**\n * Returns true if reporting metrics should always happen, regardless of DEBUG mode etc.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if SHOPIFY_CLI_ALWAYS_LOG_METRICS is truthy.\n */\nexport function alwaysLogMetrics(env = process.env): boolean {\n return isTruthy(env[environmentVariables.alwaysLogMetrics])\n}\n\n/**\n * Returns true if the CLI User is 1P.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if SHOPIFY_CLI_1P is truthy.\n */\nexport function firstPartyDev(env = process.env): boolean {\n return isTruthy(env[environmentVariables.firstPartyDev])\n}\n\n/**\n * Returns true if the local dev console should be skipped.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns True if SHOPIFY_SKIP_LOCAL_DEV_CONSOLE is truthy.\n */\nexport function skipLocalDevConsole(env = process.env): boolean {\n return isTruthy(env[environmentVariables.skipLocalDevConsole])\n}\n\n/**\n * Return gitpodURL if we are running in gitpod.\n * Https://www.gitpod.io/docs/environment-variables#default-environment-variables.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns The gitpod URL.\n */\nexport function gitpodURL(env = process.env): string | undefined {\n return env[environmentVariables.gitpod]\n}\n\n/**\n * Return codespaceURL if we are running in codespaces.\n * Https://docs.github.com/en/codespaces/developing-in-codespaces/default-environment-variables-for-your-codespace#list-of-default-environment-variables.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns The codespace URL.\n */\nexport function codespaceURL(env = process.env): string | undefined {\n return env[environmentVariables.codespaceName]\n}\n\n/**\n * Return codespacePortForwardingDomain if we are running in codespaces.\n * Https://docs.github.com/en/codespaces/developing-in-codespaces/default-environment-variables-for-your-codespace#list-of-default-environment-variables.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns The codespace port forwarding domain.\n */\nexport function codespacePortForwardingDomain(env = process.env): string | undefined {\n return env[environmentVariables.codespacePortForwardingDomain]\n}\n\n/**\n * Checks if the CLI is run from a cloud environment.\n *\n * @param env - Environment variables used when the cli is launched.\n * @returns True in case the CLI is run from a cloud environment.\n */\nexport function isCloudEnvironment(env: NodeJS.ProcessEnv = process.env): boolean {\n return cloudEnvironment(env).platform !== 'localhost'\n}\n\n/**\n * The token used to run a theme command with a custom password.\n *\n * @param env - Environment variables used when the cli is launched.\n * @returns A string with the token.\n */\nexport function themeToken(env = process.env): string | undefined {\n return env[environmentVariables.themeToken]\n}\n\n/**\n * Returns the cloud environment platform name and if the platform support online IDE in case the CLI is run from one of\n * them. Platform name 'localhost' is returned otherwise.\n *\n * @param env - Environment variables used when the cli is launched.\n * @returns Cloud platform information.\n */\nexport function cloudEnvironment(env: NodeJS.ProcessEnv = process.env): {\n platform: 'codespaces' | 'gitpod' | 'cloudShell' | 'localhost'\n editor: boolean\n} {\n if (isSet(env[environmentVariables.codespaces])) {\n return {platform: 'codespaces', editor: true}\n }\n if (isSet(env[environmentVariables.gitpod])) {\n return {platform: 'gitpod', editor: true}\n }\n if (isSet(env[environmentVariables.cloudShell])) {\n return {platform: 'cloudShell', editor: true}\n }\n return {platform: 'localhost', editor: false}\n}\n\n/**\n * Returns whether the environment has Git available.\n *\n * @returns A promise that resolves with the value.\n */\nexport async function hasGit(): Promise<boolean> {\n try {\n await exec('git', ['--version'])\n return true\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n return false\n }\n}\n\n/**\n * Gets info on the CI platform the CLI is running on, if applicable.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns The CI platform info.\n */\nexport function ciPlatform(\n env = process.env,\n): {isCI: true; name: string; metadata: Metadata} | {isCI: false; name?: undefined; metadata?: undefined} {\n if (isTruthy(env.CI)) {\n let name = 'unknown'\n if (isSet(env.BITBUCKET_BUILD_NUMBER)) {\n name = 'bitbucket'\n } else if (isTruthy(env.CIRCLECI)) {\n name = 'circleci'\n } else if (isSet(env.GITHUB_ACTION)) {\n name = 'github'\n } else if (isTruthy(env.GITLAB_CI)) {\n name = 'gitlab'\n } else if (isSet(env.BUILDKITE)) {\n name = 'buildkite'\n }\n\n return {\n isCI: true,\n name,\n metadata: getCIMetadata(name, env),\n }\n } else if (isTruthy(env.TF_BUILD)) {\n return {\n isCI: true,\n name: 'azure',\n metadata: getCIMetadata('azure', env),\n }\n }\n return {\n isCI: false,\n }\n}\n\n/**\n * Returns the first mac address found.\n *\n * @returns Mac address.\n */\nexport function macAddress(): Promise<string> {\n return macaddress.one()\n}\n\n/**\n * Get the domain for theme kit access.\n *\n * It can be overridden via the SHOPIFY_CLI_THEME_KIT_ACCESS_DOMAIN environment\n * variable.\n *\n * @param env - The environment variables from the environment of the process.\n *\n * @returns The domain for theme kit access.\n */\nexport function getThemeKitAccessDomain(env = process.env): string {\n const domain = env[environmentVariables.themeKitAccessDomain]\n\n return isSet(domain) ? domain : defaultThemeKitAccessDomain\n}\n\n/**\n * Get the domain to send OTEL metrics to.\n *\n * It can be overridden via the SHOPIFY_CLI_OTEL_EXPORTER_OTLP_ENDPOINT environment variable.\n *\n * @param env - The environment variables from the environment of the current process.\n * @returns The domain to send OTEL metrics to.\n */\nexport function opentelemetryDomain(env = process.env): string {\n const domain = env[environmentVariables.otelURL]\n\n return isSet(domain) ? domain : 'https://otlp-http-production-cli.shopifysvc.com'\n}\n\nexport type CIMetadata = Metadata\n"]}
|
|
@@ -18,7 +18,7 @@ type AutomaticCancellationBehaviour = {
|
|
|
18
18
|
} | {
|
|
19
19
|
useAbortSignal: AbortSignal | (() => AbortSignal);
|
|
20
20
|
};
|
|
21
|
-
type RequestBehaviour = NetworkRetryBehaviour & AutomaticCancellationBehaviour;
|
|
21
|
+
export type RequestBehaviour = NetworkRetryBehaviour & AutomaticCancellationBehaviour;
|
|
22
22
|
export type RequestModeInput = PresetFetchBehaviour | RequestBehaviour;
|
|
23
23
|
/**
|
|
24
24
|
* Specify the behaviour of a network request.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/public/node/http.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-base-to-string */\nimport {dirname} from './path.js'\nimport {createFileWriteStream, fileExistsSync, mkdirSync, unlinkFileSync} from './fs.js'\nimport {runWithTimer} from './metadata.js'\nimport {maxRequestTimeForNetworkCallsMs, skipNetworkLevelRetry} from './environment.js'\nimport {httpsAgent, sanitizedHeadersOutput} from '../../private/node/api/headers.js'\nimport {sanitizeURL} from '../../private/node/api/urls.js'\nimport {outputContent, outputDebug, outputToken} from '../../public/node/output.js'\nimport {NetworkRetryBehaviour, simpleRequestWithDebugLog} from '../../private/node/api.js'\nimport {DEFAULT_MAX_TIME_MS} from '../../private/node/sleep-with-backoff.js'\nimport FormData from 'form-data'\nimport nodeFetch, {RequestInfo, RequestInit, Response} from 'node-fetch'\n\nexport {FetchError, Request, Response} from 'node-fetch'\n\n/**\n * Create a new FormData object.\n *\n * @returns A FormData object.\n */\nexport function formData(): FormData {\n return new FormData()\n}\n\ntype AbortSignal = RequestInit['signal']\n\ntype PresetFetchBehaviour = 'default' | 'non-blocking' | 'slow-request'\n\ntype AutomaticCancellationBehaviour =\n | {\n useAbortSignal: true\n timeoutMs: number\n }\n | {\n useAbortSignal: false\n }\n | {\n useAbortSignal: AbortSignal | (() => AbortSignal)\n }\n\ntype RequestBehaviour = NetworkRetryBehaviour & AutomaticCancellationBehaviour\n\nexport type RequestModeInput = PresetFetchBehaviour | RequestBehaviour\n\n/**\n * Specify the behaviour of a network request.\n *\n * - default: Requests are automatically retried, and are subject to automatic cancellation if they're taking too long.\n * This is generally desirable.\n * - non-blocking: Requests are not retried if they fail with a network error, and are automatically cancelled if\n * they're taking too long. This is good for throwaway requests, like polling or tracking.\n * - slow-request: Requests are not retried if they fail with a network error, and are not automatically cancelled.\n * This is good for slow requests that should be give the chance to complete, and are unlikely to be safe to retry.\n *\n * Some request behaviours may be de-activated by the environment, and this function takes care of that concern. You\n * can also provide a customised request behaviour.\n *\n * @param preset - The preset to use.\n * @param env - Process environment variables.\n * @returns A request behaviour object.\n */\nexport function requestMode(\n preset: RequestModeInput = 'default',\n env: NodeJS.ProcessEnv = process.env,\n): RequestBehaviour {\n const networkLevelRetryIsSupported = !skipNetworkLevelRetry(env)\n switch (preset) {\n case 'default':\n return {\n useNetworkLevelRetry: networkLevelRetryIsSupported,\n maxRetryTimeMs: DEFAULT_MAX_TIME_MS,\n useAbortSignal: true,\n timeoutMs: maxRequestTimeForNetworkCallsMs(env),\n }\n case 'non-blocking':\n return {\n useNetworkLevelRetry: false,\n useAbortSignal: true,\n timeoutMs: maxRequestTimeForNetworkCallsMs(env),\n }\n case 'slow-request':\n return {\n useNetworkLevelRetry: false,\n useAbortSignal: false,\n }\n }\n return {\n ...preset,\n useNetworkLevelRetry: networkLevelRetryIsSupported && preset.useNetworkLevelRetry,\n } as RequestBehaviour\n}\n\ninterface FetchOptions {\n url: RequestInfo\n behaviour: RequestBehaviour\n init?: RequestInit\n logRequest: boolean\n useHttpsAgent: boolean\n}\n\n/**\n * Create an AbortSignal for automatic request cancellation, from a request behaviour.\n *\n * @param behaviour - The request behaviour.\n * @returns An AbortSignal.\n */\nexport function abortSignalFromRequestBehaviour(behaviour: RequestBehaviour): AbortSignal {\n let signal: AbortSignal\n if (behaviour.useAbortSignal === true) {\n signal = AbortSignal.timeout(behaviour.timeoutMs)\n } else if (behaviour.useAbortSignal && typeof behaviour.useAbortSignal === 'function') {\n signal = behaviour.useAbortSignal()\n } else if (behaviour.useAbortSignal) {\n signal = behaviour.useAbortSignal\n }\n return signal\n}\n\nasync function innerFetch({url, behaviour, init, logRequest, useHttpsAgent}: FetchOptions): Promise<Response> {\n if (logRequest) {\n outputDebug(outputContent`Sending ${init?.method ?? 'GET'} request to URL ${sanitizeURL(url.toString())}\nWith request headers:\n${sanitizedHeadersOutput((init?.headers ?? {}) as {[header: string]: string})}\n`)\n }\n\n let agent: RequestInit['agent']\n if (useHttpsAgent) {\n agent = await httpsAgent()\n }\n\n const request = async () => {\n // each time we make the request, we need to potentially reset the abort signal, as the request logic may make\n // the same request multiple times.\n let signal = abortSignalFromRequestBehaviour(behaviour)\n\n // it's possible to provide a signal through the request's init structure.\n if (init?.signal) {\n signal = init.signal\n }\n\n return nodeFetch(url, {...init, agent, signal})\n }\n\n return runWithTimer('cmd_all_timing_network_ms')(async () => {\n return simpleRequestWithDebugLog({\n url: url.toString(),\n request,\n ...behaviour,\n })\n })\n}\n\n/**\n * An interface that abstracts way node-fetch. When Node has built-in\n * support for \"fetch\" in the standard library, we can drop the node-fetch\n * dependency from here.\n * Note that we are exposing types from \"node-fetch\". The reason being is that\n * they are consistent with the Web API so if we drop node-fetch in the future\n * it won't require changes from the callers.\n *\n * The CLI's fetch function supports special behaviours, like automatic retries. These are disabled by default through\n * this function.\n *\n * @param url - This defines the resource that you wish to fetch.\n * @param init - An object containing any custom settings that you want to apply to the request.\n * @param preferredBehaviour - A request behaviour object that overrides the default behaviour.\n * @returns A promise that resolves with the response.\n */\nexport async function fetch(\n url: RequestInfo,\n init?: RequestInit,\n preferredBehaviour?: RequestModeInput,\n): Promise<Response> {\n const options = {\n url,\n init,\n logRequest: false,\n useHttpsAgent: false,\n // all special behaviours are disabled by default\n behaviour: preferredBehaviour ? requestMode(preferredBehaviour) : requestMode('non-blocking'),\n } as const\n\n return innerFetch(options)\n}\n\n/**\n * A fetch function to use with Shopify services. The function ensures the right\n * TLS configuragion is used based on the environment in which the service is running\n * (e.g. Local). NB: headers/auth are the responsibility of the caller.\n *\n * By default, the CLI's fetch function's special behaviours, like automatic retries, are enabled.\n *\n * @param url - This defines the resource that you wish to fetch.\n * @param init - An object containing any custom settings that you want to apply to the request.\n * @param preferredBehaviour - A request behaviour object that overrides the default behaviour.\n * @returns A promise that resolves with the response.\n */\nexport async function shopifyFetch(\n url: RequestInfo,\n init?: RequestInit,\n preferredBehaviour?: RequestModeInput,\n): Promise<Response> {\n const options = {\n url,\n init,\n logRequest: true,\n useHttpsAgent: true,\n // special behaviours enabled by default\n behaviour: preferredBehaviour ? requestMode(preferredBehaviour) : requestMode(),\n }\n\n return innerFetch(options)\n}\n\n/**\n * Download a file from a URL to a local path.\n *\n * @param url - The URL to download from.\n * @param to - The local path to download to.\n * @returns - A promise that resolves with the local path.\n */\nexport function downloadFile(url: string, to: string): Promise<string> {\n const sanitizedUrl = sanitizeURL(url)\n outputDebug(`Downloading ${sanitizedUrl} to ${to}`)\n\n return runWithTimer('cmd_all_timing_network_ms')(() => {\n return new Promise<string>((resolve, reject) => {\n if (!fileExistsSync(dirname(to))) {\n mkdirSync(dirname(to))\n }\n\n const file = createFileWriteStream(to)\n\n // if we can't remove the file for some reason (seen on windows), that's ok -- it's in a temporary directory\n const tryToRemoveFile = () => {\n try {\n unlinkFileSync(to)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (err: unknown) {\n outputDebug(outputContent`Failed to remove file ${outputToken.path(to)}: ${outputToken.raw(String(err))}`)\n }\n }\n\n file.on('finish', () => {\n file.close()\n resolve(to)\n })\n\n file.on('error', (err) => {\n tryToRemoveFile()\n reject(err)\n })\n\n nodeFetch(url, {redirect: 'follow'})\n .then((res) => {\n res.body?.pipe(file)\n })\n .catch((err) => {\n tryToRemoveFile()\n reject(err)\n })\n })\n })\n}\n"]}
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/public/node/http.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-base-to-string */\nimport {dirname} from './path.js'\nimport {createFileWriteStream, fileExistsSync, mkdirSync, unlinkFileSync} from './fs.js'\nimport {runWithTimer} from './metadata.js'\nimport {maxRequestTimeForNetworkCallsMs, skipNetworkLevelRetry} from './environment.js'\nimport {httpsAgent, sanitizedHeadersOutput} from '../../private/node/api/headers.js'\nimport {sanitizeURL} from '../../private/node/api/urls.js'\nimport {outputContent, outputDebug, outputToken} from '../../public/node/output.js'\nimport {NetworkRetryBehaviour, simpleRequestWithDebugLog} from '../../private/node/api.js'\nimport {DEFAULT_MAX_TIME_MS} from '../../private/node/sleep-with-backoff.js'\nimport FormData from 'form-data'\nimport nodeFetch, {RequestInfo, RequestInit, Response} from 'node-fetch'\n\nexport {FetchError, Request, Response} from 'node-fetch'\n\n/**\n * Create a new FormData object.\n *\n * @returns A FormData object.\n */\nexport function formData(): FormData {\n return new FormData()\n}\n\ntype AbortSignal = RequestInit['signal']\n\ntype PresetFetchBehaviour = 'default' | 'non-blocking' | 'slow-request'\n\ntype AutomaticCancellationBehaviour =\n | {\n useAbortSignal: true\n timeoutMs: number\n }\n | {\n useAbortSignal: false\n }\n | {\n useAbortSignal: AbortSignal | (() => AbortSignal)\n }\n\nexport type RequestBehaviour = NetworkRetryBehaviour & AutomaticCancellationBehaviour\n\nexport type RequestModeInput = PresetFetchBehaviour | RequestBehaviour\n\n/**\n * Specify the behaviour of a network request.\n *\n * - default: Requests are automatically retried, and are subject to automatic cancellation if they're taking too long.\n * This is generally desirable.\n * - non-blocking: Requests are not retried if they fail with a network error, and are automatically cancelled if\n * they're taking too long. This is good for throwaway requests, like polling or tracking.\n * - slow-request: Requests are not retried if they fail with a network error, and are not automatically cancelled.\n * This is good for slow requests that should be give the chance to complete, and are unlikely to be safe to retry.\n *\n * Some request behaviours may be de-activated by the environment, and this function takes care of that concern. You\n * can also provide a customised request behaviour.\n *\n * @param preset - The preset to use.\n * @param env - Process environment variables.\n * @returns A request behaviour object.\n */\nexport function requestMode(\n preset: RequestModeInput = 'default',\n env: NodeJS.ProcessEnv = process.env,\n): RequestBehaviour {\n const networkLevelRetryIsSupported = !skipNetworkLevelRetry(env)\n switch (preset) {\n case 'default':\n return {\n useNetworkLevelRetry: networkLevelRetryIsSupported,\n maxRetryTimeMs: DEFAULT_MAX_TIME_MS,\n useAbortSignal: true,\n timeoutMs: maxRequestTimeForNetworkCallsMs(env),\n }\n case 'non-blocking':\n return {\n useNetworkLevelRetry: false,\n useAbortSignal: true,\n timeoutMs: maxRequestTimeForNetworkCallsMs(env),\n }\n case 'slow-request':\n return {\n useNetworkLevelRetry: false,\n useAbortSignal: false,\n }\n }\n return {\n ...preset,\n useNetworkLevelRetry: networkLevelRetryIsSupported && preset.useNetworkLevelRetry,\n } as RequestBehaviour\n}\n\ninterface FetchOptions {\n url: RequestInfo\n behaviour: RequestBehaviour\n init?: RequestInit\n logRequest: boolean\n useHttpsAgent: boolean\n}\n\n/**\n * Create an AbortSignal for automatic request cancellation, from a request behaviour.\n *\n * @param behaviour - The request behaviour.\n * @returns An AbortSignal.\n */\nexport function abortSignalFromRequestBehaviour(behaviour: RequestBehaviour): AbortSignal {\n let signal: AbortSignal\n if (behaviour.useAbortSignal === true) {\n signal = AbortSignal.timeout(behaviour.timeoutMs)\n } else if (behaviour.useAbortSignal && typeof behaviour.useAbortSignal === 'function') {\n signal = behaviour.useAbortSignal()\n } else if (behaviour.useAbortSignal) {\n signal = behaviour.useAbortSignal\n }\n return signal\n}\n\nasync function innerFetch({url, behaviour, init, logRequest, useHttpsAgent}: FetchOptions): Promise<Response> {\n if (logRequest) {\n outputDebug(outputContent`Sending ${init?.method ?? 'GET'} request to URL ${sanitizeURL(url.toString())}\nWith request headers:\n${sanitizedHeadersOutput((init?.headers ?? {}) as {[header: string]: string})}\n`)\n }\n\n let agent: RequestInit['agent']\n if (useHttpsAgent) {\n agent = await httpsAgent()\n }\n\n const request = async () => {\n // each time we make the request, we need to potentially reset the abort signal, as the request logic may make\n // the same request multiple times.\n let signal = abortSignalFromRequestBehaviour(behaviour)\n\n // it's possible to provide a signal through the request's init structure.\n if (init?.signal) {\n signal = init.signal\n }\n\n return nodeFetch(url, {...init, agent, signal})\n }\n\n return runWithTimer('cmd_all_timing_network_ms')(async () => {\n return simpleRequestWithDebugLog({\n url: url.toString(),\n request,\n ...behaviour,\n })\n })\n}\n\n/**\n * An interface that abstracts way node-fetch. When Node has built-in\n * support for \"fetch\" in the standard library, we can drop the node-fetch\n * dependency from here.\n * Note that we are exposing types from \"node-fetch\". The reason being is that\n * they are consistent with the Web API so if we drop node-fetch in the future\n * it won't require changes from the callers.\n *\n * The CLI's fetch function supports special behaviours, like automatic retries. These are disabled by default through\n * this function.\n *\n * @param url - This defines the resource that you wish to fetch.\n * @param init - An object containing any custom settings that you want to apply to the request.\n * @param preferredBehaviour - A request behaviour object that overrides the default behaviour.\n * @returns A promise that resolves with the response.\n */\nexport async function fetch(\n url: RequestInfo,\n init?: RequestInit,\n preferredBehaviour?: RequestModeInput,\n): Promise<Response> {\n const options = {\n url,\n init,\n logRequest: false,\n useHttpsAgent: false,\n // all special behaviours are disabled by default\n behaviour: preferredBehaviour ? requestMode(preferredBehaviour) : requestMode('non-blocking'),\n } as const\n\n return innerFetch(options)\n}\n\n/**\n * A fetch function to use with Shopify services. The function ensures the right\n * TLS configuragion is used based on the environment in which the service is running\n * (e.g. Local). NB: headers/auth are the responsibility of the caller.\n *\n * By default, the CLI's fetch function's special behaviours, like automatic retries, are enabled.\n *\n * @param url - This defines the resource that you wish to fetch.\n * @param init - An object containing any custom settings that you want to apply to the request.\n * @param preferredBehaviour - A request behaviour object that overrides the default behaviour.\n * @returns A promise that resolves with the response.\n */\nexport async function shopifyFetch(\n url: RequestInfo,\n init?: RequestInit,\n preferredBehaviour?: RequestModeInput,\n): Promise<Response> {\n const options = {\n url,\n init,\n logRequest: true,\n useHttpsAgent: true,\n // special behaviours enabled by default\n behaviour: preferredBehaviour ? requestMode(preferredBehaviour) : requestMode(),\n }\n\n return innerFetch(options)\n}\n\n/**\n * Download a file from a URL to a local path.\n *\n * @param url - The URL to download from.\n * @param to - The local path to download to.\n * @returns - A promise that resolves with the local path.\n */\nexport function downloadFile(url: string, to: string): Promise<string> {\n const sanitizedUrl = sanitizeURL(url)\n outputDebug(`Downloading ${sanitizedUrl} to ${to}`)\n\n return runWithTimer('cmd_all_timing_network_ms')(() => {\n return new Promise<string>((resolve, reject) => {\n if (!fileExistsSync(dirname(to))) {\n mkdirSync(dirname(to))\n }\n\n const file = createFileWriteStream(to)\n\n // if we can't remove the file for some reason (seen on windows), that's ok -- it's in a temporary directory\n const tryToRemoveFile = () => {\n try {\n unlinkFileSync(to)\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (err: unknown) {\n outputDebug(outputContent`Failed to remove file ${outputToken.path(to)}: ${outputToken.raw(String(err))}`)\n }\n }\n\n file.on('finish', () => {\n file.close()\n resolve(to)\n })\n\n file.on('error', (err) => {\n tryToRemoveFile()\n reject(err)\n })\n\n nodeFetch(url, {redirect: 'follow'})\n .then((res) => {\n res.body?.pipe(file)\n })\n .catch((err) => {\n tryToRemoveFile()\n reject(err)\n })\n })\n })\n}\n"]}
|
|
@@ -89,7 +89,7 @@ async function renderNotifications(notifications) {
|
|
|
89
89
|
notifications.slice(0, 2).forEach((notification) => {
|
|
90
90
|
const content = {
|
|
91
91
|
headline: notification.title,
|
|
92
|
-
body: notification.message.
|
|
92
|
+
body: notification.message.replace(/\\n/g, '\n'),
|
|
93
93
|
link: notification.cta,
|
|
94
94
|
};
|
|
95
95
|
switch (notification.type) {
|