@shopify/cli-kit 3.80.6 → 3.81.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/analytics.js +4 -4
- package/dist/private/node/analytics.js.map +1 -1
- package/dist/private/node/api/rest.d.ts +1 -1
- package/dist/private/node/api/rest.js.map +1 -1
- package/dist/private/node/api.d.ts +1 -1
- package/dist/private/node/api.js +3 -9
- package/dist/private/node/api.js.map +1 -1
- package/dist/private/node/conf-store.js +1 -1
- package/dist/private/node/conf-store.js.map +1 -1
- package/dist/private/node/constants.d.ts +0 -2
- package/dist/private/node/constants.js +0 -2
- package/dist/private/node/constants.js.map +1 -1
- package/dist/private/node/output.d.ts +22 -0
- package/dist/private/node/output.js +47 -0
- package/dist/private/node/output.js.map +1 -0
- package/dist/private/node/session/exchange.js +1 -1
- package/dist/private/node/session/exchange.js.map +1 -1
- package/dist/private/node/session/scopes.js +3 -1
- package/dist/private/node/session/scopes.js.map +1 -1
- package/dist/private/node/session/validate.js +1 -1
- package/dist/private/node/session/validate.js.map +1 -1
- package/dist/private/node/session.d.ts +1 -1
- package/dist/private/node/session.js +3 -4
- package/dist/private/node/session.js.map +1 -1
- package/dist/private/node/sleep-with-backoff.js +1 -1
- package/dist/private/node/sleep-with-backoff.js.map +1 -1
- package/dist/private/node/ui/alert.js +1 -8
- package/dist/private/node/ui/alert.js.map +1 -1
- package/dist/private/node/ui/components/Banner.test.js +1 -1
- package/dist/private/node/ui/components/Banner.test.js.map +1 -1
- package/dist/private/node/ui/components/TextPrompt.test.js +1 -1
- package/dist/private/node/ui/components/TextPrompt.test.js.map +1 -1
- package/dist/private/node/ui.d.ts +1 -1
- package/dist/private/node/ui.js +6 -8
- package/dist/private/node/ui.js.map +1 -1
- package/dist/public/common/ts/json-narrowing.js +1 -1
- package/dist/public/common/ts/json-narrowing.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 +2 -2
- package/dist/public/node/api/admin.js.map +1 -1
- package/dist/public/node/api/app-dev.d.ts +16 -4
- package/dist/public/node/api/app-dev.js +7 -9
- package/dist/public/node/api/app-dev.js.map +1 -1
- package/dist/public/node/api/app-management.d.ts +17 -4
- package/dist/public/node/api/app-management.js +9 -13
- package/dist/public/node/api/app-management.js.map +1 -1
- package/dist/public/node/api/business-platform.d.ts +28 -16
- package/dist/public/node/api/business-platform.js +19 -25
- package/dist/public/node/api/business-platform.js.map +1 -1
- package/dist/public/node/api/functions.d.ts +16 -3
- package/dist/public/node/api/functions.js +6 -9
- package/dist/public/node/api/functions.js.map +1 -1
- package/dist/public/node/api/graphql.d.ts +10 -2
- package/dist/public/node/api/graphql.js +52 -10
- package/dist/public/node/api/graphql.js.map +1 -1
- package/dist/public/node/api/partners.d.ts +5 -3
- package/dist/public/node/api/partners.js +7 -3
- package/dist/public/node/api/partners.js.map +1 -1
- package/dist/public/node/api/rest-api-throttler.js +1 -1
- package/dist/public/node/api/rest-api-throttler.js.map +1 -1
- package/dist/public/node/api/webhooks.d.ts +13 -5
- package/dist/public/node/api/webhooks.js +7 -9
- package/dist/public/node/api/webhooks.js.map +1 -1
- package/dist/public/node/archiver.js +1 -2
- package/dist/public/node/archiver.js.map +1 -1
- package/dist/public/node/base-command.d.ts +5 -0
- package/dist/public/node/base-command.js +27 -10
- package/dist/public/node/base-command.js.map +1 -1
- package/dist/public/node/context/local.d.ts +0 -14
- package/dist/public/node/context/local.js +0 -18
- package/dist/public/node/context/local.js.map +1 -1
- package/dist/public/node/environments.d.ts +2 -0
- package/dist/public/node/environments.js +26 -11
- package/dist/public/node/environments.js.map +1 -1
- package/dist/public/node/hooks/deprecations.js +1 -1
- package/dist/public/node/hooks/deprecations.js.map +1 -1
- package/dist/public/node/json-schema.js +30 -11
- package/dist/public/node/json-schema.js.map +1 -1
- package/dist/public/node/logs.js +2 -2
- package/dist/public/node/logs.js.map +1 -1
- package/dist/public/node/node-package-manager.js +12 -4
- package/dist/public/node/node-package-manager.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/output.d.ts +16 -26
- package/dist/public/node/output.js +24 -55
- package/dist/public/node/output.js.map +1 -1
- package/dist/public/node/themes/api.d.ts +2 -2
- package/dist/public/node/themes/api.js +8 -5
- package/dist/public/node/themes/api.js.map +1 -1
- package/dist/public/node/themes/conf.d.ts +2 -2
- package/dist/public/node/themes/conf.js +2 -2
- package/dist/public/node/themes/conf.js.map +1 -1
- package/dist/public/node/themes/factories.d.ts +1 -1
- package/dist/public/node/themes/factories.js.map +1 -1
- package/dist/public/node/themes/theme-manager.d.ts +3 -3
- package/dist/public/node/themes/theme-manager.js +2 -2
- package/dist/public/node/themes/theme-manager.js.map +1 -1
- package/dist/public/node/themes/urls.d.ts +2 -2
- package/dist/public/node/themes/urls.js.map +1 -1
- package/dist/public/node/themes/utils.d.ts +1 -1
- package/dist/public/node/themes/utils.js +1 -1
- package/dist/public/node/themes/utils.js.map +1 -1
- package/dist/public/node/ui.d.ts +0 -13
- package/dist/public/node/ui.js +2 -18
- package/dist/public/node/ui.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -4
|
@@ -3,10 +3,10 @@ import { hashString } from '../../public/node/crypto.js';
|
|
|
3
3
|
import { getPackageManager, packageManagerFromUserAgent } from '../../public/node/node-package-manager.js';
|
|
4
4
|
import * as metadata from '../../public/node/metadata.js';
|
|
5
5
|
import { platformAndArch } from '../../public/node/os.js';
|
|
6
|
-
import { ciPlatform, cloudEnvironment, macAddress } from '
|
|
7
|
-
import { cwd } from '
|
|
8
|
-
import { currentProcessIsGlobal } from '
|
|
9
|
-
import { isWsl } from '
|
|
6
|
+
import { ciPlatform, cloudEnvironment, macAddress } from '../../public/node/context/local.js';
|
|
7
|
+
import { cwd } from '../../public/node/path.js';
|
|
8
|
+
import { currentProcessIsGlobal } from '../../public/node/is-global.js';
|
|
9
|
+
import { isWsl } from '../../public/node/system.js';
|
|
10
10
|
export async function startAnalytics({ commandContent, args, currentTime = new Date().getTime(), commandClass, }) {
|
|
11
11
|
let startCommand = commandContent.command;
|
|
12
12
|
if (commandClass && Object.prototype.hasOwnProperty.call(commandClass, 'analyticsNameOverride')) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../../src/private/node/analytics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,qBAAqB,EAAC,MAAM,cAAc,CAAA;AAClD,OAAO,EAAC,UAAU,EAAC,MAAM,6BAA6B,CAAA;AACtD,OAAO,EAAC,iBAAiB,EAAE,2BAA2B,EAAC,MAAM,2CAA2C,CAAA;AAGxG,OAAO,KAAK,QAAQ,MAAM,+BAA+B,CAAA;AACzD,OAAO,EAAC,eAAe,EAAC,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../../src/private/node/analytics.ts"],"names":[],"mappings":"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","sourcesContent":["import {getLastSeenAuthMethod} from './session.js'\nimport {hashString} from '../../public/node/crypto.js'\nimport {getPackageManager, packageManagerFromUserAgent} from '../../public/node/node-package-manager.js'\nimport BaseCommand from '../../public/node/base-command.js'\nimport {CommandContent} from '../../public/node/hooks/prerun.js'\nimport * as metadata from '../../public/node/metadata.js'\nimport {platformAndArch} from '../../public/node/os.js'\nimport {ciPlatform, cloudEnvironment, macAddress} from '../../public/node/context/local.js'\nimport {cwd} from '../../public/node/path.js'\nimport {currentProcessIsGlobal} from '../../public/node/is-global.js'\nimport {isWsl} from '../../public/node/system.js'\nimport {Command, Interfaces} from '@oclif/core'\n\ninterface StartOptions {\n commandContent: CommandContent\n args: string[]\n currentTime?: number\n commandClass?: Command.Class | typeof BaseCommand\n}\n\nexport async function startAnalytics({\n commandContent,\n args,\n currentTime = new Date().getTime(),\n commandClass,\n}: StartOptions): Promise<void> {\n let startCommand: string = commandContent.command\n if (commandClass && Object.prototype.hasOwnProperty.call(commandClass, 'analyticsNameOverride')) {\n startCommand = (commandClass as typeof BaseCommand).analyticsNameOverride() ?? commandContent.command\n }\n\n let pluginName = commandClass?.plugin?.name\n if (commandClass && 'customPluginName' in commandClass) {\n pluginName = commandClass.customPluginName as string\n }\n\n await metadata.addSensitiveMetadata(() => ({\n commandStartOptions: {\n startTime: currentTime,\n startCommand,\n startArgs: args,\n },\n }))\n\n await metadata.addPublicMetadata(() => ({\n cmd_all_launcher: packageManagerFromUserAgent(),\n cmd_all_alias_used: commandContent.alias,\n cmd_all_topic: commandContent.topic,\n cmd_all_plugin: pluginName,\n cmd_all_force: flagIncluded('force', commandClass) ? args.includes('--force') : undefined,\n }))\n}\n\ninterface EnvironmentData {\n uname: string\n env_ci: boolean\n env_ci_platform?: string\n env_plugin_installed_any_custom: boolean\n env_plugin_installed_shopify: string\n env_shell: string\n env_web_ide: string | undefined\n env_device_id: string\n env_cloud: string\n env_package_manager: string\n env_is_global: boolean\n env_auth_method: string\n env_is_wsl: boolean\n}\n\nexport async function getEnvironmentData(config: Interfaces.Config): Promise<EnvironmentData> {\n const ciplatform = ciPlatform()\n\n const pluginNames = getPluginNames(config)\n const shopifyPlugins = pluginNames.filter((plugin) => plugin.startsWith('@shopify/'))\n\n const {platform, arch} = platformAndArch()\n\n return {\n uname: `${platform} ${arch}`,\n env_ci: ciplatform.isCI,\n env_ci_platform: ciplatform.name,\n env_plugin_installed_any_custom: pluginNames.length !== shopifyPlugins.length,\n env_plugin_installed_shopify: JSON.stringify(shopifyPlugins),\n env_shell: config.shell,\n env_web_ide: cloudEnvironment().editor ? cloudEnvironment().platform : undefined,\n env_device_id: hashString(await macAddress()),\n env_cloud: cloudEnvironment().platform,\n env_package_manager: await getPackageManager(cwd()),\n env_is_global: currentProcessIsGlobal(),\n env_auth_method: await getLastSeenAuthMethod(),\n env_is_wsl: await isWsl(),\n }\n}\n\nexport async function getSensitiveEnvironmentData(config: Interfaces.Config) {\n return {\n env_plugin_installed_all: JSON.stringify(getPluginNames(config)),\n }\n}\n\nfunction getPluginNames(config: Interfaces.Config) {\n const pluginNames = [...config.plugins.keys()]\n return pluginNames.sort().filter((plugin) => !plugin.startsWith('@oclif/'))\n}\n\nfunction flagIncluded(flag: string, commandClass?: Command.Class | typeof BaseCommand) {\n if (!commandClass) return false\n\n const commandFlags = commandClass.flags ?? {}\n return Object.keys(commandFlags).includes(flag)\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AdminSession } from '
|
|
1
|
+
import { AdminSession } from '../../../public/node/session.js';
|
|
2
2
|
export declare function restRequestBody<T>(requestBody?: T): string | undefined;
|
|
3
3
|
export declare function restRequestUrl(session: AdminSession, apiVersion: string, path: string, searchParams?: {
|
|
4
4
|
[name: string]: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rest.js","sourceRoot":"","sources":["../../../../src/private/node/api/rest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,cAAc,CAAA;AACzC,OAAO,EAAC,oBAAoB,EAAC,MAAM,iBAAiB,CAAA;AAGpD,MAAM,UAAU,eAAe,CAAI,WAAe;IAChD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAM;IACR,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAA;AACpC,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,OAAqB,EACrB,UAAkB,EAClB,IAAY,EACZ,eAAyC,EAAE;IAE3C,MAAM,GAAG,GAAG,IAAI,GAAG,CACjB,oBAAoB,CAAC,OAAO,CAAC;QAC3B,CAAC,CAAC,WAAW,oBAAoB,kBAAkB,UAAU,GAAG,IAAI,OAAO;QAC3E,CAAC,CAAC,WAAW,OAAO,CAAC,SAAS,cAAc,UAAU,GAAG,IAAI,OAAO,CACvE,CAAA;IACD,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE;QACrD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;IACnC,CAAC,CAAC,CAAA;IAEF,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAA;AACvB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAqB;IACtD,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAA;IAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAA;IAC3B,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAE3C,IAAI,oBAAoB,CAAC,OAAO,CAAC,EAAE,CAAC;QAClC,OAAO,CAAC,gBAAgB,CAAC,GAAG,KAAK,CAAA;QACjC,OAAO,CAAC,wBAAwB,CAAC,GAAG,KAAK,CAAA;IAC3C,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAAqB;IACxD,OAAO,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;AAC5C,CAAC","sourcesContent":["import {buildHeaders} from './headers.js'\nimport {themeKitAccessDomain} from '../constants.js'\nimport {AdminSession} from '
|
|
1
|
+
{"version":3,"file":"rest.js","sourceRoot":"","sources":["../../../../src/private/node/api/rest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,cAAc,CAAA;AACzC,OAAO,EAAC,oBAAoB,EAAC,MAAM,iBAAiB,CAAA;AAGpD,MAAM,UAAU,eAAe,CAAI,WAAe;IAChD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAM;IACR,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAA;AACpC,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,OAAqB,EACrB,UAAkB,EAClB,IAAY,EACZ,eAAyC,EAAE;IAE3C,MAAM,GAAG,GAAG,IAAI,GAAG,CACjB,oBAAoB,CAAC,OAAO,CAAC;QAC3B,CAAC,CAAC,WAAW,oBAAoB,kBAAkB,UAAU,GAAG,IAAI,OAAO;QAC3E,CAAC,CAAC,WAAW,OAAO,CAAC,SAAS,cAAc,UAAU,GAAG,IAAI,OAAO,CACvE,CAAA;IACD,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE;QACrD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;IACnC,CAAC,CAAC,CAAA;IAEF,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAA;AACvB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAqB;IACtD,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAA;IAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAA;IAC3B,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAE3C,IAAI,oBAAoB,CAAC,OAAO,CAAC,EAAE,CAAC;QAClC,OAAO,CAAC,gBAAgB,CAAC,GAAG,KAAK,CAAA;QACjC,OAAO,CAAC,wBAAwB,CAAC,GAAG,KAAK,CAAA;IAC3C,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAAqB;IACxD,OAAO,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;AAC5C,CAAC","sourcesContent":["import {buildHeaders} from './headers.js'\nimport {themeKitAccessDomain} from '../constants.js'\nimport {AdminSession} from '../../../public/node/session.js'\n\nexport function restRequestBody<T>(requestBody?: T) {\n if (!requestBody) {\n return\n }\n return JSON.stringify(requestBody)\n}\n\nexport function restRequestUrl(\n session: AdminSession,\n apiVersion: string,\n path: string,\n searchParams: {[name: string]: string} = {},\n) {\n const url = new URL(\n isThemeAccessSession(session)\n ? `https://${themeKitAccessDomain}/cli/admin/api/${apiVersion}${path}.json`\n : `https://${session.storeFqdn}/admin/api/${apiVersion}${path}.json`,\n )\n Object.entries(searchParams).forEach(([name, value]) => {\n url.searchParams.set(name, value)\n })\n\n return url.toString()\n}\n\nexport function restRequestHeaders(session: AdminSession) {\n const store = session.storeFqdn\n const token = session.token\n const headers = buildHeaders(session.token)\n\n if (isThemeAccessSession(session)) {\n headers['X-Shopify-Shop'] = store\n headers['X-Shopify-Access-Token'] = token\n }\n\n return headers\n}\n\nexport function isThemeAccessSession(session: AdminSession) {\n return session.token.startsWith('shptka_')\n}\n"]}
|
|
@@ -35,7 +35,7 @@ export declare function simpleRequestWithDebugLog<T extends {
|
|
|
35
35
|
export declare function retryAwareRequest<T extends {
|
|
36
36
|
headers: Headers;
|
|
37
37
|
status: number;
|
|
38
|
-
}>(requestOptions: RequestOptions<T>, errorHandler?: (error: unknown, requestId: string | undefined) => unknown,
|
|
38
|
+
}>(requestOptions: RequestOptions<T>, errorHandler?: (error: unknown, requestId: string | undefined) => unknown, retryOptions?: {
|
|
39
39
|
limitRetriesTo?: number;
|
|
40
40
|
defaultDelayMs?: number;
|
|
41
41
|
scheduleDelay: (fn: () => void, delay: number) => void;
|
package/dist/private/node/api.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { sanitizedHeadersOutput } from './api/headers.js';
|
|
2
2
|
import { sanitizeURL } from './api/urls.js';
|
|
3
3
|
import { sleepWithBackoffUntil } from './sleep-with-backoff.js';
|
|
4
|
-
import { outputDebug } from '
|
|
4
|
+
import { outputDebug } from '../../public/node/output.js';
|
|
5
5
|
import { ClientError } from 'graphql-request';
|
|
6
6
|
import { performance } from 'perf_hooks';
|
|
7
7
|
export const allAPIs = ['admin', 'storefront-renderer', 'partners', 'business-platform', 'app-management'];
|
|
@@ -213,7 +213,7 @@ ${result.sanitizedHeaders}
|
|
|
213
213
|
* @param retryOptions - Options for the retry
|
|
214
214
|
* @returns The response from the request
|
|
215
215
|
*/
|
|
216
|
-
export async function retryAwareRequest(requestOptions, errorHandler,
|
|
216
|
+
export async function retryAwareRequest(requestOptions, errorHandler, retryOptions = {
|
|
217
217
|
scheduleDelay: setTimeout,
|
|
218
218
|
}) {
|
|
219
219
|
let retriesUsed = 0;
|
|
@@ -247,13 +247,7 @@ ${result.sanitizedHeaders}
|
|
|
247
247
|
}
|
|
248
248
|
}
|
|
249
249
|
else if (result.status === 'unauthorized') {
|
|
250
|
-
|
|
251
|
-
// eslint-disable-next-line no-await-in-loop
|
|
252
|
-
await unauthorizedHandler();
|
|
253
|
-
}
|
|
254
|
-
else {
|
|
255
|
-
throw result.clientError;
|
|
256
|
-
}
|
|
250
|
+
throw result.clientError;
|
|
257
251
|
}
|
|
258
252
|
if (limitRetriesTo <= retriesUsed) {
|
|
259
253
|
outputDebug(`${limitRetriesTo} retries exhausted for request to ${result.sanitizedUrl}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/private/node/api.ts"],"names":[],"mappings":"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","sourcesContent":["import {sanitizedHeadersOutput} from './api/headers.js'\nimport {sanitizeURL} from './api/urls.js'\nimport {sleepWithBackoffUntil} from './sleep-with-backoff.js'\nimport {outputDebug} from '@shopify/cli-kit/node/output'\nimport {Headers} from 'form-data'\nimport {ClientError} from 'graphql-request'\nimport {performance} from 'perf_hooks'\n\nexport type API = 'admin' | 'storefront-renderer' | 'partners' | 'business-platform' | 'app-management'\n\nexport const allAPIs: API[] = ['admin', 'storefront-renderer', 'partners', 'business-platform', 'app-management']\n\nconst DEFAULT_RETRY_DELAY_MS = 1000\nconst DEFAULT_RETRY_LIMIT = 10\n\nexport type NetworkRetryBehaviour =\n | {\n useNetworkLevelRetry: true\n maxRetryTimeMs: number\n }\n | {\n useNetworkLevelRetry: false\n }\n\ntype RequestOptions<T> = {\n request: () => Promise<T>\n url: string\n} & NetworkRetryBehaviour\n\nconst interestingResponseHeaders = new Set([\n 'cache-control',\n 'content-type',\n 'etag',\n 'x-request-id',\n 'server-timing',\n 'retry-after',\n])\n\nfunction responseHeaderIsInteresting(header: string): boolean {\n return interestingResponseHeaders.has(header)\n}\n\ninterface CommonResponse {\n duration: number\n sanitizedHeaders: string\n sanitizedUrl: string\n requestId?: string\n}\n\ntype OkResponse<T> = CommonResponse & {status: 'ok'; response: T}\ntype ClientErrorResponse = CommonResponse & {status: 'client-error'; clientError: ClientError}\ntype UnknownErrorResponse = CommonResponse & {status: 'unknown-error'; error: unknown}\ntype CanRetryErrorResponse = CommonResponse & {\n status: 'can-retry'\n clientError: ClientError\n delayMs: number | undefined\n}\ntype UnauthorizedErrorResponse = CommonResponse & {\n status: 'unauthorized'\n clientError: ClientError\n delayMs: number | undefined\n}\n\ntype VerboseResponse<T> =\n | OkResponse<T>\n | ClientErrorResponse\n | UnknownErrorResponse\n | CanRetryErrorResponse\n | UnauthorizedErrorResponse\n\nfunction isARetryableNetworkError(error: unknown): boolean {\n if (error instanceof Error) {\n const networkErrorMessages = [\n 'socket hang up',\n 'ECONNRESET',\n 'ECONNABORTED',\n 'ENOTFOUND',\n 'ENETUNREACH',\n 'network socket disonnected',\n 'ETIMEDOUT',\n 'ECONNREFUSED',\n 'EAI_FAIL',\n 'The operation was aborted.',\n ]\n const anyMatches = networkErrorMessages.some((issueMessage) => error.message.includes(issueMessage))\n return anyMatches\n }\n return false\n}\n\nasync function runRequestWithNetworkLevelRetry<T extends {headers: Headers; status: number}>(\n requestOptions: RequestOptions<T>,\n): Promise<T> {\n if (!requestOptions.useNetworkLevelRetry) {\n return requestOptions.request()\n }\n\n let lastSeenError: unknown\n\n for await (const _delayMs of sleepWithBackoffUntil(requestOptions.maxRetryTimeMs)) {\n try {\n return await requestOptions.request()\n } catch (err) {\n lastSeenError = err\n if (!isARetryableNetworkError(err)) {\n throw err\n }\n outputDebug(`Retrying request to ${requestOptions.url} due to network error ${err}`)\n }\n }\n throw lastSeenError\n}\n\nasync function makeVerboseRequest<T extends {headers: Headers; status: number}>(\n requestOptions: RequestOptions<T>,\n): Promise<VerboseResponse<T>> {\n const t0 = performance.now()\n let duration = 0\n const responseHeaders: {[key: string]: string} = {}\n const sanitizedUrl = sanitizeURL(requestOptions.url)\n let response: T = {} as T\n try {\n response = await runRequestWithNetworkLevelRetry(requestOptions)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n response.headers.forEach((value: any, key: any) => {\n if (responseHeaderIsInteresting(key)) responseHeaders[key] = value\n })\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (err) {\n const t1 = performance.now()\n duration = Math.round(t1 - t0)\n\n if (err instanceof ClientError) {\n if (err.response.headers) {\n for (const [key, value] of err.response.headers as Iterable<[string, string]>) {\n if (responseHeaderIsInteresting(key)) responseHeaders[key] = value\n }\n }\n const sanitizedHeaders = sanitizedHeadersOutput(responseHeaders)\n\n if (errorsIncludeStatus429(err)) {\n let delayMs: number | undefined\n\n try {\n delayMs = responseHeaders['retry-after'] ? Number.parseInt(responseHeaders['retry-after'], 10) : undefined\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n // ignore errors in extracting retry-after header\n }\n return {\n status: 'can-retry',\n clientError: err,\n duration,\n sanitizedHeaders,\n sanitizedUrl,\n requestId: responseHeaders['x-request-id'],\n delayMs,\n }\n } else if (err.response.status === 401) {\n return {\n status: 'unauthorized',\n clientError: err,\n duration,\n sanitizedHeaders,\n sanitizedUrl,\n requestId: responseHeaders['x-request-id'],\n delayMs: 500,\n }\n }\n\n return {\n status: 'client-error',\n clientError: err,\n duration,\n sanitizedHeaders,\n sanitizedUrl,\n requestId: responseHeaders['x-request-id'],\n }\n }\n return {\n status: 'unknown-error',\n error: err,\n duration,\n sanitizedHeaders: sanitizedHeadersOutput(responseHeaders),\n sanitizedUrl,\n requestId: responseHeaders['x-request-id'],\n }\n }\n const t1 = performance.now()\n duration = Math.round(t1 - t0)\n return {\n status: 'ok',\n response,\n duration,\n sanitizedHeaders: sanitizedHeadersOutput(responseHeaders),\n sanitizedUrl,\n requestId: responseHeaders['x-request-id'],\n }\n}\n\nfunction errorsIncludeStatus429(error: ClientError): boolean {\n if (error.response.status === 429) {\n return true\n }\n\n // GraphQL returns a 401 with a string error message when auth fails\n // Therefore error.response.errors can be a string or GraphQLError[]\n if (typeof error.response.errors === 'string') {\n return false\n }\n return error.response.errors?.some((error) => error.extensions?.code === '429') ?? false\n}\n\nexport async function simpleRequestWithDebugLog<T extends {headers: Headers; status: number}>(\n requestOptions: RequestOptions<T>,\n errorHandler?: (error: unknown, requestId: string | undefined) => unknown,\n): Promise<T> {\n const result = await makeVerboseRequest(requestOptions)\n\n outputDebug(`Request to ${result.sanitizedUrl} completed in ${result.duration} ms\nWith response headers:\n${result.sanitizedHeaders}\n `)\n\n switch (result.status) {\n case 'ok': {\n return result.response\n }\n case 'client-error': {\n if (errorHandler) {\n throw errorHandler(result.clientError, result.requestId)\n } else {\n throw result.clientError\n }\n }\n case 'unknown-error': {\n if (errorHandler) {\n throw errorHandler(result.error, result.requestId)\n } else {\n throw result.error\n }\n }\n case 'can-retry': {\n if (errorHandler) {\n throw errorHandler(result.clientError, result.requestId)\n } else {\n throw result.clientError\n }\n }\n case 'unauthorized': {\n if (errorHandler) {\n throw errorHandler(result.clientError, result.requestId)\n } else {\n throw result.clientError\n }\n }\n }\n}\n\n/**\n * Makes a HTTP request to some API, retrying if response headers indicate a retryable error.\n *\n * If a request fails with a 429, the retry-after header determines a delay before an automatic retry is performed.\n *\n * If unauthorizedHandler is provided, then it will be called in the case of a 401 and a retry performed. This allows\n * for a token refresh for instance.\n *\n * If there's a network error, e.g. DNS fails to resolve, then API calls are automatically retried.\n *\n * @param request - A function that returns a promise of the response\n * @param url - The URL to request\n * @param errorHandler - A function that handles errors\n * @param unauthorizedHandler - A function that handles unauthorized errors\n * @param retryOptions - Options for the retry\n * @returns The response from the request\n */\nexport async function retryAwareRequest<T extends {headers: Headers; status: number}>(\n requestOptions: RequestOptions<T>,\n errorHandler?: (error: unknown, requestId: string | undefined) => unknown,\n unauthorizedHandler?: () => Promise<void>,\n retryOptions: {\n limitRetriesTo?: number\n defaultDelayMs?: number\n scheduleDelay: (fn: () => void, delay: number) => void\n } = {\n scheduleDelay: setTimeout,\n },\n): Promise<T> {\n let retriesUsed = 0\n const limitRetriesTo = retryOptions.limitRetriesTo ?? DEFAULT_RETRY_LIMIT\n\n let result = await makeVerboseRequest(requestOptions)\n\n outputDebug(`Request to ${result.sanitizedUrl} completed in ${result.duration} ms\nWith response headers:\n${result.sanitizedHeaders}\n `)\n\n while (true) {\n if (result.status === 'ok') {\n if (retriesUsed > 0) {\n outputDebug(`Request to ${result.sanitizedUrl} succeeded after ${retriesUsed} retries`)\n }\n return result.response\n } else if (result.status === 'client-error') {\n if (errorHandler) {\n throw errorHandler(result.clientError, result.requestId)\n } else {\n throw result.clientError\n }\n } else if (result.status === 'unknown-error') {\n if (errorHandler) {\n throw errorHandler(result.error, result.requestId)\n } else {\n throw result.error\n }\n } else if (result.status === 'unauthorized') {\n if (unauthorizedHandler) {\n // eslint-disable-next-line no-await-in-loop\n await unauthorizedHandler()\n } else {\n throw result.clientError\n }\n }\n\n if (limitRetriesTo <= retriesUsed) {\n outputDebug(`${limitRetriesTo} retries exhausted for request to ${result.sanitizedUrl}`)\n if (errorHandler) {\n throw errorHandler(result.clientError, result.requestId)\n } else {\n throw result.clientError\n }\n }\n retriesUsed += 1\n\n // prefer to wait based on a header if given; the caller's preference if not; and a default if neither.\n const retryDelayMs = result.delayMs ?? retryOptions.defaultDelayMs ?? DEFAULT_RETRY_DELAY_MS\n outputDebug(`Scheduling retry request #${retriesUsed} to ${result.sanitizedUrl} in ${retryDelayMs} ms`)\n\n // eslint-disable-next-line no-await-in-loop\n result = await new Promise<VerboseResponse<T>>((resolve) => {\n retryOptions.scheduleDelay(() => {\n resolve(makeVerboseRequest(requestOptions))\n }, retryDelayMs)\n })\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/private/node/api.ts"],"names":[],"mappings":"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","sourcesContent":["import {sanitizedHeadersOutput} from './api/headers.js'\nimport {sanitizeURL} from './api/urls.js'\nimport {sleepWithBackoffUntil} from './sleep-with-backoff.js'\nimport {outputDebug} from '../../public/node/output.js'\nimport {Headers} from 'form-data'\nimport {ClientError} from 'graphql-request'\nimport {performance} from 'perf_hooks'\n\nexport type API = 'admin' | 'storefront-renderer' | 'partners' | 'business-platform' | 'app-management'\n\nexport const allAPIs: API[] = ['admin', 'storefront-renderer', 'partners', 'business-platform', 'app-management']\n\nconst DEFAULT_RETRY_DELAY_MS = 1000\nconst DEFAULT_RETRY_LIMIT = 10\n\nexport type NetworkRetryBehaviour =\n | {\n useNetworkLevelRetry: true\n maxRetryTimeMs: number\n }\n | {\n useNetworkLevelRetry: false\n }\n\ntype RequestOptions<T> = {\n request: () => Promise<T>\n url: string\n} & NetworkRetryBehaviour\n\nconst interestingResponseHeaders = new Set([\n 'cache-control',\n 'content-type',\n 'etag',\n 'x-request-id',\n 'server-timing',\n 'retry-after',\n])\n\nfunction responseHeaderIsInteresting(header: string): boolean {\n return interestingResponseHeaders.has(header)\n}\n\ninterface CommonResponse {\n duration: number\n sanitizedHeaders: string\n sanitizedUrl: string\n requestId?: string\n}\n\ntype OkResponse<T> = CommonResponse & {status: 'ok'; response: T}\ntype ClientErrorResponse = CommonResponse & {status: 'client-error'; clientError: ClientError}\ntype UnknownErrorResponse = CommonResponse & {status: 'unknown-error'; error: unknown}\ntype CanRetryErrorResponse = CommonResponse & {\n status: 'can-retry'\n clientError: ClientError\n delayMs: number | undefined\n}\ntype UnauthorizedErrorResponse = CommonResponse & {\n status: 'unauthorized'\n clientError: ClientError\n delayMs: number | undefined\n}\n\ntype VerboseResponse<T> =\n | OkResponse<T>\n | ClientErrorResponse\n | UnknownErrorResponse\n | CanRetryErrorResponse\n | UnauthorizedErrorResponse\n\nfunction isARetryableNetworkError(error: unknown): boolean {\n if (error instanceof Error) {\n const networkErrorMessages = [\n 'socket hang up',\n 'ECONNRESET',\n 'ECONNABORTED',\n 'ENOTFOUND',\n 'ENETUNREACH',\n 'network socket disonnected',\n 'ETIMEDOUT',\n 'ECONNREFUSED',\n 'EAI_FAIL',\n 'The operation was aborted.',\n ]\n const anyMatches = networkErrorMessages.some((issueMessage) => error.message.includes(issueMessage))\n return anyMatches\n }\n return false\n}\n\nasync function runRequestWithNetworkLevelRetry<T extends {headers: Headers; status: number}>(\n requestOptions: RequestOptions<T>,\n): Promise<T> {\n if (!requestOptions.useNetworkLevelRetry) {\n return requestOptions.request()\n }\n\n let lastSeenError: unknown\n\n for await (const _delayMs of sleepWithBackoffUntil(requestOptions.maxRetryTimeMs)) {\n try {\n return await requestOptions.request()\n } catch (err) {\n lastSeenError = err\n if (!isARetryableNetworkError(err)) {\n throw err\n }\n outputDebug(`Retrying request to ${requestOptions.url} due to network error ${err}`)\n }\n }\n throw lastSeenError\n}\n\nasync function makeVerboseRequest<T extends {headers: Headers; status: number}>(\n requestOptions: RequestOptions<T>,\n): Promise<VerboseResponse<T>> {\n const t0 = performance.now()\n let duration = 0\n const responseHeaders: {[key: string]: string} = {}\n const sanitizedUrl = sanitizeURL(requestOptions.url)\n let response: T = {} as T\n try {\n response = await runRequestWithNetworkLevelRetry(requestOptions)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n response.headers.forEach((value: any, key: any) => {\n if (responseHeaderIsInteresting(key)) responseHeaders[key] = value\n })\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (err) {\n const t1 = performance.now()\n duration = Math.round(t1 - t0)\n\n if (err instanceof ClientError) {\n if (err.response.headers) {\n for (const [key, value] of err.response.headers as Iterable<[string, string]>) {\n if (responseHeaderIsInteresting(key)) responseHeaders[key] = value\n }\n }\n const sanitizedHeaders = sanitizedHeadersOutput(responseHeaders)\n\n if (errorsIncludeStatus429(err)) {\n let delayMs: number | undefined\n\n try {\n delayMs = responseHeaders['retry-after'] ? Number.parseInt(responseHeaders['retry-after'], 10) : undefined\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n // ignore errors in extracting retry-after header\n }\n return {\n status: 'can-retry',\n clientError: err,\n duration,\n sanitizedHeaders,\n sanitizedUrl,\n requestId: responseHeaders['x-request-id'],\n delayMs,\n }\n } else if (err.response.status === 401) {\n return {\n status: 'unauthorized',\n clientError: err,\n duration,\n sanitizedHeaders,\n sanitizedUrl,\n requestId: responseHeaders['x-request-id'],\n delayMs: 500,\n }\n }\n\n return {\n status: 'client-error',\n clientError: err,\n duration,\n sanitizedHeaders,\n sanitizedUrl,\n requestId: responseHeaders['x-request-id'],\n }\n }\n return {\n status: 'unknown-error',\n error: err,\n duration,\n sanitizedHeaders: sanitizedHeadersOutput(responseHeaders),\n sanitizedUrl,\n requestId: responseHeaders['x-request-id'],\n }\n }\n const t1 = performance.now()\n duration = Math.round(t1 - t0)\n return {\n status: 'ok',\n response,\n duration,\n sanitizedHeaders: sanitizedHeadersOutput(responseHeaders),\n sanitizedUrl,\n requestId: responseHeaders['x-request-id'],\n }\n}\n\nfunction errorsIncludeStatus429(error: ClientError): boolean {\n if (error.response.status === 429) {\n return true\n }\n\n // GraphQL returns a 401 with a string error message when auth fails\n // Therefore error.response.errors can be a string or GraphQLError[]\n if (typeof error.response.errors === 'string') {\n return false\n }\n return error.response.errors?.some((error) => error.extensions?.code === '429') ?? false\n}\n\nexport async function simpleRequestWithDebugLog<T extends {headers: Headers; status: number}>(\n requestOptions: RequestOptions<T>,\n errorHandler?: (error: unknown, requestId: string | undefined) => unknown,\n): Promise<T> {\n const result = await makeVerboseRequest(requestOptions)\n\n outputDebug(`Request to ${result.sanitizedUrl} completed in ${result.duration} ms\nWith response headers:\n${result.sanitizedHeaders}\n `)\n\n switch (result.status) {\n case 'ok': {\n return result.response\n }\n case 'client-error': {\n if (errorHandler) {\n throw errorHandler(result.clientError, result.requestId)\n } else {\n throw result.clientError\n }\n }\n case 'unknown-error': {\n if (errorHandler) {\n throw errorHandler(result.error, result.requestId)\n } else {\n throw result.error\n }\n }\n case 'can-retry': {\n if (errorHandler) {\n throw errorHandler(result.clientError, result.requestId)\n } else {\n throw result.clientError\n }\n }\n case 'unauthorized': {\n if (errorHandler) {\n throw errorHandler(result.clientError, result.requestId)\n } else {\n throw result.clientError\n }\n }\n }\n}\n\n/**\n * Makes a HTTP request to some API, retrying if response headers indicate a retryable error.\n *\n * If a request fails with a 429, the retry-after header determines a delay before an automatic retry is performed.\n *\n * If unauthorizedHandler is provided, then it will be called in the case of a 401 and a retry performed. This allows\n * for a token refresh for instance.\n *\n * If there's a network error, e.g. DNS fails to resolve, then API calls are automatically retried.\n *\n * @param request - A function that returns a promise of the response\n * @param url - The URL to request\n * @param errorHandler - A function that handles errors\n * @param unauthorizedHandler - A function that handles unauthorized errors\n * @param retryOptions - Options for the retry\n * @returns The response from the request\n */\nexport async function retryAwareRequest<T extends {headers: Headers; status: number}>(\n requestOptions: RequestOptions<T>,\n errorHandler?: (error: unknown, requestId: string | undefined) => unknown,\n retryOptions: {\n limitRetriesTo?: number\n defaultDelayMs?: number\n scheduleDelay: (fn: () => void, delay: number) => void\n } = {\n scheduleDelay: setTimeout,\n },\n): Promise<T> {\n let retriesUsed = 0\n const limitRetriesTo = retryOptions.limitRetriesTo ?? DEFAULT_RETRY_LIMIT\n\n let result = await makeVerboseRequest(requestOptions)\n\n outputDebug(`Request to ${result.sanitizedUrl} completed in ${result.duration} ms\nWith response headers:\n${result.sanitizedHeaders}\n `)\n\n while (true) {\n if (result.status === 'ok') {\n if (retriesUsed > 0) {\n outputDebug(`Request to ${result.sanitizedUrl} succeeded after ${retriesUsed} retries`)\n }\n return result.response\n } else if (result.status === 'client-error') {\n if (errorHandler) {\n throw errorHandler(result.clientError, result.requestId)\n } else {\n throw result.clientError\n }\n } else if (result.status === 'unknown-error') {\n if (errorHandler) {\n throw errorHandler(result.error, result.requestId)\n } else {\n throw result.error\n }\n } else if (result.status === 'unauthorized') {\n throw result.clientError\n }\n\n if (limitRetriesTo <= retriesUsed) {\n outputDebug(`${limitRetriesTo} retries exhausted for request to ${result.sanitizedUrl}`)\n if (errorHandler) {\n throw errorHandler(result.clientError, result.requestId)\n } else {\n throw result.clientError\n }\n }\n retriesUsed += 1\n\n // prefer to wait based on a header if given; the caller's preference if not; and a default if neither.\n const retryDelayMs = result.delayMs ?? retryOptions.defaultDelayMs ?? DEFAULT_RETRY_DELAY_MS\n outputDebug(`Scheduling retry request #${retriesUsed} to ${result.sanitizedUrl} in ${retryDelayMs} ms`)\n\n // eslint-disable-next-line no-await-in-loop\n result = await new Promise<VerboseResponse<T>>((resolve) => {\n retryOptions.scheduleDelay(() => {\n resolve(makeVerboseRequest(requestOptions))\n }, retryDelayMs)\n })\n }\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isUnitTest } from '../../public/node/context/local.js';
|
|
2
2
|
import { LocalStorage } from '../../public/node/local-storage.js';
|
|
3
|
-
import { outputContent, outputDebug } from '
|
|
3
|
+
import { outputContent, outputDebug } from '../../public/node/output.js';
|
|
4
4
|
let _instance;
|
|
5
5
|
/**
|
|
6
6
|
* CLIKIT Store.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conf-store.js","sourceRoot":"","sources":["../../../src/private/node/conf-store.ts"],"names":[],"mappings":"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","sourcesContent":["import {isUnitTest} from '../../public/node/context/local.js'\nimport {LocalStorage} from '../../public/node/local-storage.js'\nimport {outputContent, outputDebug} from '@shopify/cli-kit/node/output'\n\ninterface CacheValue<T> {\n value: T\n timestamp: number\n}\n\nexport type PackageVersionKey = `npm-package-${string}`\nexport type NotificationsKey = `notifications-${string}`\nexport type NotificationKey = `notification-${string}`\nexport type GraphQLRequestKey = `q-${string}-${string}-${string}`\ntype MostRecentOccurrenceKey = `most-recent-occurrence-${string}`\ntype RateLimitKey = `rate-limited-occurrences-${string}`\n\ntype ExportedKey = PackageVersionKey | NotificationsKey | NotificationKey | GraphQLRequestKey\n\ninterface Cache {\n [packageVersionKey: PackageVersionKey]: CacheValue<string>\n [notifications: NotificationsKey]: CacheValue<string>\n [notification: NotificationKey]: CacheValue<string>\n [graphQLRequestKey: GraphQLRequestKey]: CacheValue<string>\n [mostRecentOccurrenceKey: MostRecentOccurrenceKey]: CacheValue<boolean>\n [rateLimitKey: RateLimitKey]: CacheValue<number[]>\n}\n\nexport interface ConfSchema {\n sessionStore: string\n cache?: Cache\n}\n\nlet _instance: LocalStorage<ConfSchema> | undefined\n\n/**\n * CLIKIT Store.\n *\n * @returns CLIKitStore.\n */\nfunction cliKitStore() {\n if (!_instance) {\n _instance = new LocalStorage<ConfSchema>({projectName: `shopify-cli-kit${isUnitTest() ? '-test' : ''}`})\n }\n return _instance\n}\n\n/**\n * Get session.\n *\n * @returns Session.\n */\nexport function getSession(config: LocalStorage<ConfSchema> = cliKitStore()): string | undefined {\n outputDebug(outputContent`Getting session store...`)\n return config.get('sessionStore')\n}\n\n/**\n * Set session.\n *\n * @param session - Session.\n */\nexport function setSession(session: string, config: LocalStorage<ConfSchema> = cliKitStore()): void {\n outputDebug(outputContent`Setting session store...`)\n config.set('sessionStore', session)\n}\n\n/**\n * Remove session.\n */\nexport function removeSession(config: LocalStorage<ConfSchema> = cliKitStore()): void {\n outputDebug(outputContent`Removing session store...`)\n config.delete('sessionStore')\n}\n\ntype CacheValueForKey<TKey extends keyof Cache> = NonNullable<Cache[TKey]>['value']\n\n/**\n * Fetch from cache, or run the provided function to get the value, and cache it\n * before returning it.\n * @param key - The key to use for the cache.\n * @param fn - The function to run to get the value to cache, if a cache miss occurs.\n * @param timeout - The maximum valid age of a cached value, in milliseconds.\n * If the cached value is older than this, it will be refreshed.\n * @returns The value from the cache or the result of the function.\n */\nexport async function cacheRetrieveOrRepopulate(\n key: ExportedKey,\n fn: () => Promise<CacheValueForKey<typeof key>>,\n timeout?: number,\n config = cliKitStore(),\n): Promise<CacheValueForKey<typeof key>> {\n const cached = cacheRetrieve(key, config)\n\n if (cached?.value !== undefined && (timeout === undefined || Date.now() - cached.timestamp < timeout)) {\n return cached.value\n }\n\n const value = await fn()\n cacheStore(key, value, config)\n return value\n}\n\nexport function cacheStore(key: ExportedKey, value: string, config = cliKitStore()): void {\n const cache: Cache = config.get('cache') || {}\n cache[key] = {value, timestamp: Date.now()}\n config.set('cache', cache)\n}\n\n/**\n * Fetch from cache if already populated, otherwise return undefined.\n * @param key - The key to use for the cache.\n * @returns The chache element.\n */\nexport function cacheRetrieve(key: ExportedKey, config = cliKitStore()): CacheValue<string> | undefined {\n const cache: Cache = config.get('cache') || {}\n return cache[key]\n}\n\nexport function cacheClear(config = cliKitStore()): void {\n config.delete('cache')\n}\n\nexport interface TimeInterval {\n days?: number\n hours?: number\n minutes?: number\n seconds?: number\n}\n\nexport function timeIntervalToMilliseconds({days = 0, hours = 0, minutes = 0, seconds = 0}: TimeInterval): number {\n return (days * 24 * 60 * 60 + hours * 60 * 60 + minutes * 60 + seconds) * 1000\n}\n\n/**\n * Execute a task only if the most recent occurrence of the task is older than the specified timeout.\n * @param key - The key to use for the cache.\n * @param timeout - The maximum valid age of the most recent occurrence, expressed as an object with\n * days, hours, minutes, and seconds properties.\n * If the most recent occurrence is older than this, the task will be executed.\n * @param task - The task to run if the most recent occurrence is older than the timeout.\n * @returns true if the task was run, or false if the task was not run.\n */\nexport async function runAtMinimumInterval(\n key: string,\n timeout: TimeInterval,\n task: () => Promise<void>,\n config = cliKitStore(),\n): Promise<boolean> {\n const cache: Cache = config.get('cache') || {}\n const cacheKey: MostRecentOccurrenceKey = `most-recent-occurrence-${key}`\n const cached = cache[cacheKey]\n\n if (cached?.value !== undefined && Date.now() - cached.timestamp < timeIntervalToMilliseconds(timeout)) {\n return false\n }\n\n await task()\n cache[cacheKey] = {value: true, timestamp: Date.now()}\n config.set('cache', cache)\n return true\n}\n\ninterface RunWithRateLimitOptions {\n /**\n * The key to use for the cache.\n */\n key: string\n\n /**\n * The number of times the task can be run within the limit\n */\n limit: number\n\n /**\n * The window of time after which the rate limit is refreshed,\n * expressed as an object with days, hours, minutes, and seconds properties.\n * If the most recent occurrence is older than this, the task will be executed.\n */\n timeout: TimeInterval\n\n /**\n * The task to run if the most recent occurrence is older than the timeout.\n */\n task: () => Promise<void>\n}\n\n/**\n * Execute a task with a time-based rate limit. The rate limit is enforced by\n * checking how many times that task has been executed in a window of time ending\n * at the current time. If the task has been executed more than the allowed number\n * of times in that window, the task will not be executed.\n *\n * Note that this function has side effects, as it will also remove events prior\n * to the window of time that is being checked.\n * @param options - The options for the rate limiting.\n * @returns true, or undefined if the task was not run.\n */\nexport async function runWithRateLimit(options: RunWithRateLimitOptions, config = cliKitStore()): Promise<boolean> {\n const {key, limit, timeout, task} = options\n const cache: Cache = config.get('cache') || {}\n const cacheKey: RateLimitKey = `rate-limited-occurrences-${key}`\n const cached = cache[cacheKey]\n const now = Date.now()\n\n if (cached?.value) {\n // First sweep through the cache and eliminate old events\n const windowStart = now - timeIntervalToMilliseconds(timeout)\n const occurrences = cached.value.filter((occurrence) => occurrence >= windowStart)\n\n // Now check that the number of occurrences within the interval is below the limit\n if (occurrences.length >= limit) {\n // First remove the old occurrences from the cache\n cache[cacheKey] = {value: occurrences, timestamp: Date.now()}\n config.set('cache', cache)\n\n return false\n }\n\n await task()\n cache[cacheKey] = {value: [...occurrences, now], timestamp: now}\n } else {\n await task()\n cache[cacheKey] = {value: [now], timestamp: now}\n }\n config.set('cache', cache)\n\n return true\n}\n\nexport function getConfigStoreForPartnerStatus() {\n return new LocalStorage<{[partnerToken: string]: {status: true; checkedAt: string}}>({\n projectName: 'shopify-cli-kit-partner-status',\n })\n}\n\nexport function getCachedPartnerAccountStatus(partnersToken: string): true | null {\n if (!partnersToken) return null\n const store = getConfigStoreForPartnerStatus()\n\n const hasPartnerAccount = store.get(partnersToken)\n if (hasPartnerAccount) {\n // this never needs to expire\n return true\n }\n return null\n}\n\nexport function setCachedPartnerAccountStatus(partnersToken: string) {\n const store = getConfigStoreForPartnerStatus()\n\n store.set(partnersToken, {status: true, checkedAt: new Date().toISOString()})\n}\n"]}
|
|
1
|
+
{"version":3,"file":"conf-store.js","sourceRoot":"","sources":["../../../src/private/node/conf-store.ts"],"names":[],"mappings":"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","sourcesContent":["import {isUnitTest} from '../../public/node/context/local.js'\nimport {LocalStorage} from '../../public/node/local-storage.js'\nimport {outputContent, outputDebug} from '../../public/node/output.js'\n\ninterface CacheValue<T> {\n value: T\n timestamp: number\n}\n\nexport type PackageVersionKey = `npm-package-${string}`\nexport type NotificationsKey = `notifications-${string}`\nexport type NotificationKey = `notification-${string}`\nexport type GraphQLRequestKey = `q-${string}-${string}-${string}`\ntype MostRecentOccurrenceKey = `most-recent-occurrence-${string}`\ntype RateLimitKey = `rate-limited-occurrences-${string}`\n\ntype ExportedKey = PackageVersionKey | NotificationsKey | NotificationKey | GraphQLRequestKey\n\ninterface Cache {\n [packageVersionKey: PackageVersionKey]: CacheValue<string>\n [notifications: NotificationsKey]: CacheValue<string>\n [notification: NotificationKey]: CacheValue<string>\n [graphQLRequestKey: GraphQLRequestKey]: CacheValue<string>\n [mostRecentOccurrenceKey: MostRecentOccurrenceKey]: CacheValue<boolean>\n [rateLimitKey: RateLimitKey]: CacheValue<number[]>\n}\n\nexport interface ConfSchema {\n sessionStore: string\n cache?: Cache\n}\n\nlet _instance: LocalStorage<ConfSchema> | undefined\n\n/**\n * CLIKIT Store.\n *\n * @returns CLIKitStore.\n */\nfunction cliKitStore() {\n if (!_instance) {\n _instance = new LocalStorage<ConfSchema>({projectName: `shopify-cli-kit${isUnitTest() ? '-test' : ''}`})\n }\n return _instance\n}\n\n/**\n * Get session.\n *\n * @returns Session.\n */\nexport function getSession(config: LocalStorage<ConfSchema> = cliKitStore()): string | undefined {\n outputDebug(outputContent`Getting session store...`)\n return config.get('sessionStore')\n}\n\n/**\n * Set session.\n *\n * @param session - Session.\n */\nexport function setSession(session: string, config: LocalStorage<ConfSchema> = cliKitStore()): void {\n outputDebug(outputContent`Setting session store...`)\n config.set('sessionStore', session)\n}\n\n/**\n * Remove session.\n */\nexport function removeSession(config: LocalStorage<ConfSchema> = cliKitStore()): void {\n outputDebug(outputContent`Removing session store...`)\n config.delete('sessionStore')\n}\n\ntype CacheValueForKey<TKey extends keyof Cache> = NonNullable<Cache[TKey]>['value']\n\n/**\n * Fetch from cache, or run the provided function to get the value, and cache it\n * before returning it.\n * @param key - The key to use for the cache.\n * @param fn - The function to run to get the value to cache, if a cache miss occurs.\n * @param timeout - The maximum valid age of a cached value, in milliseconds.\n * If the cached value is older than this, it will be refreshed.\n * @returns The value from the cache or the result of the function.\n */\nexport async function cacheRetrieveOrRepopulate(\n key: ExportedKey,\n fn: () => Promise<CacheValueForKey<typeof key>>,\n timeout?: number,\n config = cliKitStore(),\n): Promise<CacheValueForKey<typeof key>> {\n const cached = cacheRetrieve(key, config)\n\n if (cached?.value !== undefined && (timeout === undefined || Date.now() - cached.timestamp < timeout)) {\n return cached.value\n }\n\n const value = await fn()\n cacheStore(key, value, config)\n return value\n}\n\nexport function cacheStore(key: ExportedKey, value: string, config = cliKitStore()): void {\n const cache: Cache = config.get('cache') || {}\n cache[key] = {value, timestamp: Date.now()}\n config.set('cache', cache)\n}\n\n/**\n * Fetch from cache if already populated, otherwise return undefined.\n * @param key - The key to use for the cache.\n * @returns The chache element.\n */\nexport function cacheRetrieve(key: ExportedKey, config = cliKitStore()): CacheValue<string> | undefined {\n const cache: Cache = config.get('cache') || {}\n return cache[key]\n}\n\nexport function cacheClear(config = cliKitStore()): void {\n config.delete('cache')\n}\n\nexport interface TimeInterval {\n days?: number\n hours?: number\n minutes?: number\n seconds?: number\n}\n\nexport function timeIntervalToMilliseconds({days = 0, hours = 0, minutes = 0, seconds = 0}: TimeInterval): number {\n return (days * 24 * 60 * 60 + hours * 60 * 60 + minutes * 60 + seconds) * 1000\n}\n\n/**\n * Execute a task only if the most recent occurrence of the task is older than the specified timeout.\n * @param key - The key to use for the cache.\n * @param timeout - The maximum valid age of the most recent occurrence, expressed as an object with\n * days, hours, minutes, and seconds properties.\n * If the most recent occurrence is older than this, the task will be executed.\n * @param task - The task to run if the most recent occurrence is older than the timeout.\n * @returns true if the task was run, or false if the task was not run.\n */\nexport async function runAtMinimumInterval(\n key: string,\n timeout: TimeInterval,\n task: () => Promise<void>,\n config = cliKitStore(),\n): Promise<boolean> {\n const cache: Cache = config.get('cache') || {}\n const cacheKey: MostRecentOccurrenceKey = `most-recent-occurrence-${key}`\n const cached = cache[cacheKey]\n\n if (cached?.value !== undefined && Date.now() - cached.timestamp < timeIntervalToMilliseconds(timeout)) {\n return false\n }\n\n await task()\n cache[cacheKey] = {value: true, timestamp: Date.now()}\n config.set('cache', cache)\n return true\n}\n\ninterface RunWithRateLimitOptions {\n /**\n * The key to use for the cache.\n */\n key: string\n\n /**\n * The number of times the task can be run within the limit\n */\n limit: number\n\n /**\n * The window of time after which the rate limit is refreshed,\n * expressed as an object with days, hours, minutes, and seconds properties.\n * If the most recent occurrence is older than this, the task will be executed.\n */\n timeout: TimeInterval\n\n /**\n * The task to run if the most recent occurrence is older than the timeout.\n */\n task: () => Promise<void>\n}\n\n/**\n * Execute a task with a time-based rate limit. The rate limit is enforced by\n * checking how many times that task has been executed in a window of time ending\n * at the current time. If the task has been executed more than the allowed number\n * of times in that window, the task will not be executed.\n *\n * Note that this function has side effects, as it will also remove events prior\n * to the window of time that is being checked.\n * @param options - The options for the rate limiting.\n * @returns true, or undefined if the task was not run.\n */\nexport async function runWithRateLimit(options: RunWithRateLimitOptions, config = cliKitStore()): Promise<boolean> {\n const {key, limit, timeout, task} = options\n const cache: Cache = config.get('cache') || {}\n const cacheKey: RateLimitKey = `rate-limited-occurrences-${key}`\n const cached = cache[cacheKey]\n const now = Date.now()\n\n if (cached?.value) {\n // First sweep through the cache and eliminate old events\n const windowStart = now - timeIntervalToMilliseconds(timeout)\n const occurrences = cached.value.filter((occurrence) => occurrence >= windowStart)\n\n // Now check that the number of occurrences within the interval is below the limit\n if (occurrences.length >= limit) {\n // First remove the old occurrences from the cache\n cache[cacheKey] = {value: occurrences, timestamp: Date.now()}\n config.set('cache', cache)\n\n return false\n }\n\n await task()\n cache[cacheKey] = {value: [...occurrences, now], timestamp: now}\n } else {\n await task()\n cache[cacheKey] = {value: [now], timestamp: now}\n }\n config.set('cache', cache)\n\n return true\n}\n\nexport function getConfigStoreForPartnerStatus() {\n return new LocalStorage<{[partnerToken: string]: {status: true; checkedAt: string}}>({\n projectName: 'shopify-cli-kit-partner-status',\n })\n}\n\nexport function getCachedPartnerAccountStatus(partnersToken: string): true | null {\n if (!partnersToken) return null\n const store = getConfigStoreForPartnerStatus()\n\n const hasPartnerAccount = store.get(partnersToken)\n if (hasPartnerAccount) {\n // this never needs to expire\n return true\n }\n return null\n}\n\nexport function setCachedPartnerAccountStatus(partnersToken: string) {\n const store = getConfigStoreForPartnerStatus()\n\n store.set(partnersToken, {status: true, checkedAt: new Date().toISOString()})\n}\n"]}
|
|
@@ -25,8 +25,6 @@ export const environmentVariables = {
|
|
|
25
25
|
themeToken: 'SHOPIFY_CLI_THEME_TOKEN',
|
|
26
26
|
unitTest: 'SHOPIFY_UNIT_TEST',
|
|
27
27
|
verbose: 'SHOPIFY_FLAG_VERBOSE',
|
|
28
|
-
noThemeBundling: 'SHOPIFY_CLI_NO_THEME_BUNDLING',
|
|
29
|
-
bundledThemeCLI: 'SHOPIFY_CLI_BUNDLED_THEME_CLI',
|
|
30
28
|
// Variables to detect if the CLI is running in a cloud environment
|
|
31
29
|
codespaces: 'CODESPACES',
|
|
32
30
|
codespaceName: 'CODESPACE_NAME',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/private/node/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,2BAA2B,CAAA;AAClD,OAAO,QAAQ,MAAM,WAAW,CAAA;AAEhC,MAAM,UAAU,GAAG,aAAa,CAAA;AAEhC,MAAM,WAAW,GAAG,GAAG,EAAE;IACvB,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,CAAA;IACjE,OAAO,QAAQ,CAAC,UAAU,CAAC,CAAC,KAAK,CAAA;AACnC,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,EAAE;IAC7B,OAAO,QAAQ,CAAC,UAAU,CAAC,CAAC,GAAG,CAAA;AACjC,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,kBAAkB,EAAE,kCAAkC;IACtD,gBAAgB,EAAE,gCAAgC;IAClD,UAAU,EAAE,yBAAyB;IACrC,iBAAiB,EAAE,iCAAiC;IACpD,GAAG,EAAE,iBAAiB;IACtB,aAAa,EAAE,oBAAoB;IACnC,WAAW,EAAE,0BAA0B;IACvC,aAAa,EAAE,4BAA4B;IAC3C,SAAS,EAAE,qBAAqB;IAChC,UAAU,EAAE,qBAAqB;IACjC,eAAe,EAAE,+BAA+B;IAChD,YAAY,EAAE,eAAe;IAC7B,UAAU,EAAE,yBAAyB;IACrC,QAAQ,EAAE,mBAAmB;IAC7B,OAAO,EAAE,sBAAsB;IAC/B,
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/private/node/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,2BAA2B,CAAA;AAClD,OAAO,QAAQ,MAAM,WAAW,CAAA;AAEhC,MAAM,UAAU,GAAG,aAAa,CAAA;AAEhC,MAAM,WAAW,GAAG,GAAG,EAAE;IACvB,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,CAAA;IACjE,OAAO,QAAQ,CAAC,UAAU,CAAC,CAAC,KAAK,CAAA;AACnC,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,EAAE;IAC7B,OAAO,QAAQ,CAAC,UAAU,CAAC,CAAC,GAAG,CAAA;AACjC,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,kBAAkB,EAAE,kCAAkC;IACtD,gBAAgB,EAAE,gCAAgC;IAClD,UAAU,EAAE,yBAAyB;IACrC,iBAAiB,EAAE,iCAAiC;IACpD,GAAG,EAAE,iBAAiB;IACtB,aAAa,EAAE,oBAAoB;IACnC,WAAW,EAAE,0BAA0B;IACvC,aAAa,EAAE,4BAA4B;IAC3C,SAAS,EAAE,qBAAqB;IAChC,UAAU,EAAE,qBAAqB;IACjC,eAAe,EAAE,+BAA+B;IAChD,YAAY,EAAE,eAAe;IAC7B,UAAU,EAAE,yBAAyB;IACrC,QAAQ,EAAE,mBAAmB;IAC7B,OAAO,EAAE,sBAAsB;IAC/B,mEAAmE;IACnE,UAAU,EAAE,YAAY;IACxB,aAAa,EAAE,gBAAgB;IAC/B,6BAA6B,EAAE,0CAA0C;IACzE,MAAM,EAAE,sBAAsB;IAC9B,UAAU,EAAE,aAAa;IACzB,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,aAAa;IAC1B,WAAW,EAAE,eAAe;IAC5B,YAAY,EAAE,0BAA0B;IACxC,aAAa,EAAE,4BAA4B;IAC3C,YAAY,EAAE,2BAA2B;IACzC,OAAO,EAAE,yCAAyC;IAClD,oBAAoB,EAAE,qCAAqC;IAC3D,IAAI,EAAE,mBAAmB;IACzB,mBAAmB,EAAE,oCAAoC;IACzD,qBAAqB,EAAE,sCAAsC;IAC7D,6BAA6B,EAAE,gDAAgD;CAChF,CAAA;AAED,MAAM,CAAC,MAAM,2BAA2B,GAAG,kCAAkC,CAAA;AAE7E,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,WAAW,EAAE,cAAc;CAC5B,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,WAAW,EAAE;QACX,GAAG,EAAE,kBAAkB;KACxB;IACD,WAAW,EAAE;QACX,KAAK,EAAE;YACL,IAAI,EAAE,GAAG,EAAE;gBACT,OAAO,WAAW,EAAE,CAAA;YACtB,CAAC;YACD,MAAM,EAAE;gBACN,IAAI,EAAE,GAAG,EAAE;oBACT,OAAO,QAAQ,CAAC,WAAW,EAAE,EAAE,QAAQ,CAAC,CAAA;gBAC1C,CAAC;gBACD,QAAQ,EAAE,GAAG,EAAE;oBACb,OAAO,QAAQ,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAA;gBACtD,CAAC;aACF;SACF;KACF;CACF,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,6BAA6B,EAAE,CAAC;CACjC,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,kCAAkC,CAAA;AAE/D,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAC,IAAI,EAAE,CAAC,EAAC,EAAC,CAAA;AAElE,MAAM,CAAC,MAAM,oBAAoB,GAC/B,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,oBAAoB,CAAC,IAAI,2BAA2B,CAAA","sourcesContent":["import {joinPath} from '../../public/node/path.js'\nimport envPaths from 'env-paths'\n\nconst identifier = 'shopify-cli'\n\nconst cacheFolder = () => {\n if (process.env.XDG_CACHE_HOME) return process.env.XDG_CACHE_HOME\n return envPaths(identifier).cache\n}\n\nexport const logsFolder = () => {\n return envPaths(identifier).log\n}\n\nexport const environmentVariables = {\n alwaysLogAnalytics: 'SHOPIFY_CLI_ALWAYS_LOG_ANALYTICS',\n alwaysLogMetrics: 'SHOPIFY_CLI_ALWAYS_LOG_METRICS',\n deviceAuth: 'SHOPIFY_CLI_DEVICE_AUTH',\n enableCliRedirect: 'SHOPIFY_CLI_ENABLE_CLI_REDIRECT',\n env: 'SHOPIFY_CLI_ENV',\n firstPartyDev: 'SHOPIFY_CLI_1P_DEV',\n noAnalytics: 'SHOPIFY_CLI_NO_ANALYTICS',\n partnersToken: 'SHOPIFY_CLI_PARTNERS_TOKEN',\n runAsUser: 'SHOPIFY_RUN_AS_USER',\n serviceEnv: 'SHOPIFY_SERVICE_ENV',\n skipCliRedirect: 'SHOPIFY_CLI_SKIP_CLI_REDIRECT',\n spinInstance: 'SPIN_INSTANCE',\n themeToken: 'SHOPIFY_CLI_THEME_TOKEN',\n unitTest: 'SHOPIFY_UNIT_TEST',\n verbose: 'SHOPIFY_FLAG_VERBOSE',\n // Variables to detect if the CLI is running in a cloud environment\n codespaces: 'CODESPACES',\n codespaceName: 'CODESPACE_NAME',\n codespacePortForwardingDomain: 'GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN',\n gitpod: 'GITPOD_WORKSPACE_URL',\n cloudShell: 'CLOUD_SHELL',\n spin: 'SPIN',\n spinAppPort: 'SERVER_PORT',\n spinAppHost: 'SPIN_APP_HOST',\n organization: 'SHOPIFY_CLI_ORGANIZATION',\n identityToken: 'SHOPIFY_CLI_IDENTITY_TOKEN',\n refreshToken: 'SHOPIFY_CLI_REFRESH_TOKEN',\n otelURL: 'SHOPIFY_CLI_OTEL_EXPORTER_OTLP_ENDPOINT',\n themeKitAccessDomain: 'SHOPIFY_CLI_THEME_KIT_ACCESS_DOMAIN',\n json: 'SHOPIFY_FLAG_JSON',\n neverUsePartnersApi: 'SHOPIFY_CLI_NEVER_USE_PARTNERS_API',\n skipNetworkLevelRetry: 'SHOPIFY_CLI_SKIP_NETWORK_LEVEL_RETRY',\n maxRequestTimeForNetworkCalls: 'SHOPIFY_CLI_MAX_REQUEST_TIME_FOR_NETWORK_CALLS',\n}\n\nexport const defaultThemeKitAccessDomain = 'theme-kit-access.shopifyapps.com'\n\nexport const systemEnvironmentVariables = {\n backendPort: 'BACKEND_PORT',\n}\n\nexport const pathConstants = {\n executables: {\n dev: '/opt/dev/bin/dev',\n },\n directories: {\n cache: {\n path: () => {\n return cacheFolder()\n },\n vendor: {\n path: () => {\n return joinPath(cacheFolder(), 'vendor')\n },\n binaries: () => {\n return joinPath(cacheFolder(), 'vendor', 'binaries')\n },\n },\n },\n },\n}\n\nexport const sessionConstants = {\n expirationTimeMarginInMinutes: 4,\n}\n\nexport const bugsnagApiKey = '9e1e6889176fd0c795d5c659225e0fae'\n\nexport const reportingRateLimit = {limit: 300, timeout: {days: 1}}\n\nexport const themeKitAccessDomain =\n process.env[environmentVariables.themeKitAccessDomain] ?? defaultThemeKitAccessDomain\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { OutputMessage, LogLevel, Logger } from '../../public/node/output.js';
|
|
2
|
+
/**
|
|
3
|
+
* Prints a log message in the console to stdout.
|
|
4
|
+
*
|
|
5
|
+
* @param message - The message to print.
|
|
6
|
+
*/
|
|
7
|
+
export declare function consoleLog(message: string): void;
|
|
8
|
+
/**
|
|
9
|
+
* Prints a warning message in the console to stderr.
|
|
10
|
+
*
|
|
11
|
+
* @param message - The message to print.
|
|
12
|
+
*/
|
|
13
|
+
export declare function consoleWarn(message: string): void;
|
|
14
|
+
/**
|
|
15
|
+
* Logs an unformatted message at the given log level.
|
|
16
|
+
* Note: By default, messages are sent through the standard error.
|
|
17
|
+
*
|
|
18
|
+
* @param content - The content to be output to the user.
|
|
19
|
+
* @param logLevel - The log level associated with the message.
|
|
20
|
+
* @param logger - The logging function to use to output to the user.
|
|
21
|
+
*/
|
|
22
|
+
export declare function output(content: OutputMessage, logLevel?: LogLevel, logger?: Logger): void;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { isUnitTest } from '../../public/node/context/local.js';
|
|
2
|
+
import { collectLog, stringifyMessage, outputWhereAppropriate, shouldDisplayColors, unstyled, } from '../../public/node/output.js';
|
|
3
|
+
/**
|
|
4
|
+
* Returns a colored or uncolored version of a message, depending on the environment.
|
|
5
|
+
*
|
|
6
|
+
* @param message - The message to color or not.
|
|
7
|
+
* @returns The message with or without colors.
|
|
8
|
+
*/
|
|
9
|
+
function withOrWithoutStyle(message) {
|
|
10
|
+
if (shouldDisplayColors()) {
|
|
11
|
+
return message;
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
return unstyled(message);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Prints a log message in the console to stdout.
|
|
19
|
+
*
|
|
20
|
+
* @param message - The message to print.
|
|
21
|
+
*/
|
|
22
|
+
export function consoleLog(message) {
|
|
23
|
+
process.stdout.write(`${withOrWithoutStyle(message)}\n`);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Prints a warning message in the console to stderr.
|
|
27
|
+
*
|
|
28
|
+
* @param message - The message to print.
|
|
29
|
+
*/
|
|
30
|
+
export function consoleWarn(message) {
|
|
31
|
+
process.stderr.write(`${withOrWithoutStyle(message)}\n`);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Logs an unformatted message at the given log level.
|
|
35
|
+
* Note: By default, messages are sent through the standard error.
|
|
36
|
+
*
|
|
37
|
+
* @param content - The content to be output to the user.
|
|
38
|
+
* @param logLevel - The log level associated with the message.
|
|
39
|
+
* @param logger - The logging function to use to output to the user.
|
|
40
|
+
*/
|
|
41
|
+
export function output(content, logLevel = 'info', logger = consoleWarn) {
|
|
42
|
+
if (isUnitTest())
|
|
43
|
+
collectLog(logLevel, content);
|
|
44
|
+
const message = stringifyMessage(content);
|
|
45
|
+
outputWhereAppropriate(logLevel, logger, message);
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../../src/private/node/output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,oCAAoC,CAAA;AAC7D,OAAO,EAGL,UAAU,EACV,gBAAgB,EAChB,sBAAsB,EAEtB,mBAAmB,EACnB,QAAQ,GACT,MAAM,6BAA6B,CAAA;AAEpC;;;;;GAKG;AACH,SAAS,kBAAkB,CAAC,OAAe;IACzC,IAAI,mBAAmB,EAAE,EAAE,CAAC;QAC1B,OAAO,OAAO,CAAA;IAChB,CAAC;SAAM,CAAC;QACN,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAA;IAC1B,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,OAAe;IACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;AAC1D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;AAC1D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,MAAM,CAAC,OAAsB,EAAE,WAAqB,MAAM,EAAE,SAAiB,WAAW;IACtG,IAAI,UAAU,EAAE;QAAE,UAAU,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;IAC/C,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;IACzC,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;AACnD,CAAC","sourcesContent":["import {isUnitTest} from '../../public/node/context/local.js'\nimport {\n OutputMessage,\n LogLevel,\n collectLog,\n stringifyMessage,\n outputWhereAppropriate,\n Logger,\n shouldDisplayColors,\n unstyled,\n} from '../../public/node/output.js'\n\n/**\n * Returns a colored or uncolored version of a message, depending on the environment.\n *\n * @param message - The message to color or not.\n * @returns The message with or without colors.\n */\nfunction withOrWithoutStyle(message: string): string {\n if (shouldDisplayColors()) {\n return message\n } else {\n return unstyled(message)\n }\n}\n\n/**\n * Prints a log message in the console to stdout.\n *\n * @param message - The message to print.\n */\nexport function consoleLog(message: string): void {\n process.stdout.write(`${withOrWithoutStyle(message)}\\n`)\n}\n\n/**\n * Prints a warning message in the console to stderr.\n *\n * @param message - The message to print.\n */\nexport function consoleWarn(message: string): void {\n process.stderr.write(`${withOrWithoutStyle(message)}\\n`)\n}\n\n/**\n * Logs an unformatted message at the given log level.\n * Note: By default, messages are sent through the standard error.\n *\n * @param content - The content to be output to the user.\n * @param logLevel - The log level associated with the message.\n * @param logger - The logging function to use to output to the user.\n */\nexport function output(content: OutputMessage, logLevel: LogLevel = 'info', logger: Logger = consoleWarn): void {\n if (isUnitTest()) collectLog(logLevel, content)\n const message = stringifyMessage(content)\n outputWhereAppropriate(logLevel, logger, message)\n}\n"]}
|
|
@@ -5,8 +5,8 @@ import { shopifyFetch } from '../../../public/node/http.js';
|
|
|
5
5
|
import { err, ok } from '../../../public/node/result.js';
|
|
6
6
|
import { AbortError, BugError, ExtendableError } from '../../../public/node/error.js';
|
|
7
7
|
import { setLastSeenAuthMethod, setLastSeenUserIdAfterAuth } from '../session.js';
|
|
8
|
+
import { nonRandomUUID } from '../../../public/node/crypto.js';
|
|
8
9
|
import * as jose from 'jose';
|
|
9
|
-
import { nonRandomUUID } from '@shopify/cli-kit/node/crypto';
|
|
10
10
|
export class InvalidGrantError extends ExtendableError {
|
|
11
11
|
}
|
|
12
12
|
export class InvalidRequestError extends ExtendableError {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exchange.js","sourceRoot":"","sources":["../../../../src/private/node/session/exchange.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,aAAa,EAAE,QAAQ,IAAI,mBAAmB,EAAC,MAAM,eAAe,CAAA;AAC5E,OAAO,EAAC,mBAAmB,EAAC,MAAM,aAAa,CAAA;AAE/C,OAAO,EAAC,YAAY,EAAC,MAAM,sCAAsC,CAAA;AACjE,OAAO,EAAC,YAAY,EAAC,MAAM,8BAA8B,CAAA;AACzD,OAAO,EAAC,GAAG,EAAE,EAAE,EAAS,MAAM,gCAAgC,CAAA;AAC9D,OAAO,EAAC,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAC,MAAM,+BAA+B,CAAA;AACnF,OAAO,EAAC,qBAAqB,EAAE,0BAA0B,EAAC,MAAM,eAAe,CAAA;AAC/E,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAC5B,OAAO,EAAC,aAAa,EAAC,MAAM,8BAA8B,CAAA;AAE1D,MAAM,OAAO,iBAAkB,SAAQ,eAAe;CAAG;AACzD,MAAM,OAAO,mBAAoB,SAAQ,eAAe;CAAG;AAC3D,MAAM,kBAAmB,SAAQ,UAAU;CAAG;AAU9C;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,kCAAkC,CACtD,aAA4B,EAC5B,MAAsB,EACtB,KAAc;IAEd,MAAM,KAAK,GAAG,aAAa,CAAC,WAAW,CAAA;IAEvC,MAAM,CAAC,QAAQ,EAAE,UAAU,EAAE,gBAAgB,EAAE,KAAK,EAAE,aAAa,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACvF,eAAe,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC;QACnD,eAAe,CAAC,qBAAqB,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC;QAChE,eAAe,CAAC,mBAAmB,EAAE,KAAK,EAAE,MAAM,CAAC,gBAAgB,CAAC;QACpE,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;QACjE,eAAe,CAAC,gBAAgB,EAAE,KAAK,EAAE,MAAM,CAAC,aAAa,CAAC;KAC/D,CAAC,CAAA;IAEF,OAAO;QACL,GAAG,QAAQ;QACX,GAAG,UAAU;QACb,GAAG,gBAAgB;QACnB,GAAG,KAAK;QACR,GAAG,aAAa;KACjB,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,YAA2B;IAClE,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAA;IACtC,MAAM,MAAM,GAAG;QACb,UAAU,EAAE,eAAe;QAC3B,YAAY,EAAE,YAAY,CAAC,WAAW;QACtC,aAAa,EAAE,YAAY,CAAC,YAAY;QACxC,SAAS,EAAE,QAAQ;KACpB,CAAA;IACD,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAA;IAC9C,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAC,UAAU,EAAE,CAAA;IACzE,OAAO,kBAAkB,CAAC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,CAAA;AACvD,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,8BAA8B,CAC3C,OAAY,EACZ,KAAa,EACb,MAAgB;IAEhB,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;IACpC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;QAC9D,oEAAoE;QACpE,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAE,CAAC,WAAW,CAAA;QAChD,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,CAAA;QACnC,0BAA0B,CAAC,MAAM,CAAC,CAAA;QAClC,qBAAqB,CAAC,gBAAgB,CAAC,CAAA;QACvC,OAAO,EAAC,WAAW,EAAE,MAAM,EAAC,CAAA;IAC9B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAA;QAC5F,MAAM,IAAI,UAAU,CAClB,mDAAmD,UAAU,OAAO,EACpE,8CAA8C,CAC/C,CAAA;IACH,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,KAAa;IAC5D,OAAO,8BAA8B,CAAC,UAAU,EAAE,KAAK,EAAE,mBAAmB,CAAC,UAAU,CAAC,CAAC,CAAA;AAC3F,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,2CAA2C,CAC/D,KAAa;IAEb,OAAO,8BAA8B,CAAC,gBAAgB,EAAE,KAAK,EAAE,mBAAmB,CAAC,gBAAgB,CAAC,CAAC,CAAA;AACvG,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,8CAA8C,CAClE,KAAa;IAEb,OAAO,8BAA8B,CAAC,mBAAmB,EAAE,KAAK,EAAE,mBAAmB,CAAC,mBAAmB,CAAC,CAAC,CAAA;AAC7G,CAAC;AAID;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gCAAgC,CACpD,UAAkB;IAElB,MAAM,QAAQ,GAAG,MAAM,mBAAmB,EAAE,CAAA;IAE5C,MAAM,MAAM,GAAG;QACb,UAAU,EAAE,8CAA8C;QAC1D,WAAW,EAAE,UAAU;QACvB,SAAS,EAAE,QAAQ;KACpB,CAAA;IAED,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAA;IAC9C,IAAI,WAAW,CAAC,KAAK,EAAE,EAAE,CAAC;QACxB,OAAO,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,KAA4B,CAAC,CAAA;IAC5D,CAAC;IACD,MAAM,aAAa,GAAG,kBAAkB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;IAC3D,OAAO,EAAE,CAAC,aAAa,CAAC,CAAA;AAC1B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,GAAQ,EACR,KAAa,EACb,SAAmB,EAAE,EACrB,KAAc;IAEd,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;IAChC,MAAM,QAAQ,GAAG,MAAM,mBAAmB,EAAE,CAAA;IAE5C,MAAM,MAAM,GAAG;QACb,UAAU,EAAE,iDAAiD;QAC7D,oBAAoB,EAAE,+CAA+C;QACrE,kBAAkB,EAAE,+CAA+C;QACnE,SAAS,EAAE,QAAQ;QACnB,QAAQ,EAAE,KAAK;QACf,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QACvB,aAAa,EAAE,KAAK;QACpB,GAAG,CAAC,GAAG,KAAK,OAAO,IAAI,EAAC,WAAW,EAAE,WAAW,KAAK,QAAQ,EAAE,KAAK,EAAC,CAAC;KACvE,CAAA;IAED,IAAI,UAAU,GAAG,KAAK,CAAA;IACtB,IAAI,GAAG,KAAK,OAAO,IAAI,KAAK,EAAE,CAAC;QAC7B,UAAU,GAAG,GAAG,KAAK,IAAI,KAAK,EAAE,CAAA;IAClC,CAAC;IACD,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAA;IAC9C,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAC,UAAU,EAAE,CAAA;IACzE,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAA;IAC7C,OAAO,EAAC,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAC,CAAA;AACjC,CAAC;AAUD,SAAS,wBAAwB,CAAC,EAAC,KAAK,EAAE,KAAK,EAAkC;IAC/E,MAAM,yBAAyB,GAC7B,yEAAyE,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE;QACrG,MAAM;QACN,6EAA6E;QAC7E,2FAA2F;QAC3F,uEAAuE;QACvE,MAAM;QACN,qFAAqF;QACrF,+DAA+D;QAC/D,oEAAoE;QACpE,gCAAgC,CAAA;IAElC,IAAI,KAAK,KAAK,eAAe,EAAE,CAAC;QAC9B,6FAA6F;QAC7F,oGAAoG;QACpG,OAAO,IAAI,iBAAiB,EAAE,CAAA;IAChC,CAAC;IACD,IAAI,KAAK,KAAK,iBAAiB,EAAE,CAAC;QAChC,iGAAiG;QACjG,mGAAmG;QACnG,OAAO,IAAI,mBAAmB,EAAE,CAAA;IAClC,CAAC;IACD,IAAI,KAAK,KAAK,gBAAgB,EAAE,CAAC;QAC/B,OAAO,IAAI,kBAAkB,CAAC,yBAAyB,CAAC,CAAA;IAC1D,CAAC;IACD,mEAAmE;IACnE,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,CAAA;AAC9B,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,MAE3B;IACC,MAAM,IAAI,GAAG,MAAM,YAAY,EAAE,CAAA;IACjC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,WAAW,IAAI,cAAc,CAAC,CAAA;IAClD,GAAG,CAAC,MAAM,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;IAEnE,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,EAAC,MAAM,EAAE,MAAM,EAAC,CAAC,CAAA;IAC1D,8DAA8D;IAC9D,MAAM,OAAO,GAAQ,MAAM,GAAG,CAAC,IAAI,EAAE,CAAA;IAErC,IAAI,GAAG,CAAC,EAAE;QAAE,OAAO,EAAE,CAAC,OAAO,CAAC,CAAA;IAE9B,OAAO,GAAG,CAAC,EAAC,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAC,CAAC,CAAA;AACzD,CAAC;AAED,SAAS,kBAAkB,CAAC,MAA0B,EAAE,cAAuB;IAC7E,oEAAoE;IACpE,MAAM,MAAM,GAAG,cAAc,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;IAErG,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,QAAQ,CAAC,iFAAiF,CAAC,CAAA;IACvG,CAAC;IAED,OAAO;QACL,WAAW,EAAE,MAAM,CAAC,YAAY;QAChC,YAAY,EAAE,MAAM,CAAC,aAAa;QAClC,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;QAC1D,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;QAC/B,MAAM;KACP,CAAA;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,MAA0B;IACvD,OAAO;QACL,WAAW,EAAE,MAAM,CAAC,YAAY;QAChC,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;QAC1D,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;KAChC,CAAA;AACH,CAAC","sourcesContent":["import {ApplicationToken, IdentityToken} from './schema.js'\nimport {applicationId, clientId as getIdentityClientId} from './identity.js'\nimport {tokenExchangeScopes} from './scopes.js'\nimport {API} from '../api.js'\nimport {identityFqdn} from '../../../public/node/context/fqdn.js'\nimport {shopifyFetch} from '../../../public/node/http.js'\nimport {err, ok, Result} from '../../../public/node/result.js'\nimport {AbortError, BugError, ExtendableError} from '../../../public/node/error.js'\nimport {setLastSeenAuthMethod, setLastSeenUserIdAfterAuth} from '../session.js'\nimport * as jose from 'jose'\nimport {nonRandomUUID} from '@shopify/cli-kit/node/crypto'\n\nexport class InvalidGrantError extends ExtendableError {}\nexport class InvalidRequestError extends ExtendableError {}\nclass InvalidTargetError extends AbortError {}\n\nexport interface ExchangeScopes {\n admin: string[]\n partners: string[]\n storefront: string[]\n businessPlatform: string[]\n appManagement: string[]\n}\n\n/**\n * Given an identity token, request an application token.\n * @param identityToken - access token obtained in a previous step\n * @param store - the store to use, only needed for admin API\n * @returns An array with the application access tokens.\n */\nexport async function exchangeAccessForApplicationTokens(\n identityToken: IdentityToken,\n scopes: ExchangeScopes,\n store?: string,\n): Promise<{[x: string]: ApplicationToken}> {\n const token = identityToken.accessToken\n\n const [partners, storefront, businessPlatform, admin, appManagement] = await Promise.all([\n requestAppToken('partners', token, scopes.partners),\n requestAppToken('storefront-renderer', token, scopes.storefront),\n requestAppToken('business-platform', token, scopes.businessPlatform),\n store ? requestAppToken('admin', token, scopes.admin, store) : {},\n requestAppToken('app-management', token, scopes.appManagement),\n ])\n\n return {\n ...partners,\n ...storefront,\n ...businessPlatform,\n ...admin,\n ...appManagement,\n }\n}\n\n/**\n * Given an expired access token, refresh it to get a new one.\n */\nexport async function refreshAccessToken(currentToken: IdentityToken): Promise<IdentityToken> {\n const clientId = getIdentityClientId()\n const params = {\n grant_type: 'refresh_token',\n access_token: currentToken.accessToken,\n refresh_token: currentToken.refreshToken,\n client_id: clientId,\n }\n const tokenResult = await tokenRequest(params)\n const value = tokenResult.mapError(tokenRequestErrorHandler).valueOrBug()\n return buildIdentityToken(value, currentToken.userId)\n}\n\n/**\n * Given a custom CLI token passed as ENV variable request a valid API access token\n * @param token - The CLI token passed as ENV variable `SHOPIFY_CLI_PARTNERS_TOKEN`\n * @param apiName - The API to exchange for the access token\n * @param scopes - The scopes to request with the access token\n * @returns An instance with the application access tokens.\n */\nasync function exchangeCliTokenForAccessToken(\n apiName: API,\n token: string,\n scopes: string[],\n): Promise<{accessToken: string; userId: string}> {\n const appId = applicationId(apiName)\n try {\n const newToken = await requestAppToken(apiName, token, scopes)\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const accessToken = newToken[appId]!.accessToken\n const userId = nonRandomUUID(token)\n setLastSeenUserIdAfterAuth(userId)\n setLastSeenAuthMethod('partners_token')\n return {accessToken, userId}\n } catch (error) {\n const prettyName = apiName.replace(/-/g, ' ').replace(/\\b\\w/g, (char) => char.toUpperCase())\n throw new AbortError(\n `The custom token provided can't be used for the ${prettyName} API.`,\n 'Ensure the token is correct and not expired.',\n )\n }\n}\n\n/**\n * Given a custom CLI token passed as ENV variable, request a valid Partners API token\n * This token does not accept extra scopes, just the cli one.\n * @param token - The CLI token passed as ENV variable `SHOPIFY_CLI_PARTNERS_TOKEN`\n * @returns An instance with the application access tokens.\n */\nexport async function exchangeCustomPartnerToken(token: string): Promise<{accessToken: string; userId: string}> {\n return exchangeCliTokenForAccessToken('partners', token, tokenExchangeScopes('partners'))\n}\n\n/**\n * Given a custom CLI token passed as ENV variable, request a valid App Management API token\n * @param token - The CLI token passed as ENV variable `SHOPIFY_CLI_PARTNERS_TOKEN`\n * @returns An instance with the application access tokens.\n */\nexport async function exchangeCliTokenForAppManagementAccessToken(\n token: string,\n): Promise<{accessToken: string; userId: string}> {\n return exchangeCliTokenForAccessToken('app-management', token, tokenExchangeScopes('app-management'))\n}\n\n/**\n * Given a custom CLI token passed as ENV variable, request a valid Business Platform API token\n * @param token - The CLI token passed as ENV variable `SHOPIFY_CLI_PARTNERS_TOKEN`\n * @returns An instance with the application access tokens.\n */\nexport async function exchangeCliTokenForBusinessPlatformAccessToken(\n token: string,\n): Promise<{accessToken: string; userId: string}> {\n return exchangeCliTokenForAccessToken('business-platform', token, tokenExchangeScopes('business-platform'))\n}\n\ntype IdentityDeviceError = 'authorization_pending' | 'access_denied' | 'expired_token' | 'slow_down' | 'unknown_failure'\n\n/**\n * Given a deviceCode obtained after starting a device identity flow, request an identity token.\n * @param deviceCode - The device code obtained after starting a device identity flow\n * @param scopes - The scopes to request\n * @returns An instance with the identity access tokens.\n */\nexport async function exchangeDeviceCodeForAccessToken(\n deviceCode: string,\n): Promise<Result<IdentityToken, IdentityDeviceError>> {\n const clientId = await getIdentityClientId()\n\n const params = {\n grant_type: 'urn:ietf:params:oauth:grant-type:device_code',\n device_code: deviceCode,\n client_id: clientId,\n }\n\n const tokenResult = await tokenRequest(params)\n if (tokenResult.isErr()) {\n return err(tokenResult.error.error as IdentityDeviceError)\n }\n const identityToken = buildIdentityToken(tokenResult.value)\n return ok(identityToken)\n}\n\nexport async function requestAppToken(\n api: API,\n token: string,\n scopes: string[] = [],\n store?: string,\n): Promise<{[x: string]: ApplicationToken}> {\n const appId = applicationId(api)\n const clientId = await getIdentityClientId()\n\n const params = {\n grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange',\n requested_token_type: 'urn:ietf:params:oauth:token-type:access_token',\n subject_token_type: 'urn:ietf:params:oauth:token-type:access_token',\n client_id: clientId,\n audience: appId,\n scope: scopes.join(' '),\n subject_token: token,\n ...(api === 'admin' && {destination: `https://${store}/admin`, store}),\n }\n\n let identifier = appId\n if (api === 'admin' && store) {\n identifier = `${store}-${appId}`\n }\n const tokenResult = await tokenRequest(params)\n const value = tokenResult.mapError(tokenRequestErrorHandler).valueOrBug()\n const appToken = buildApplicationToken(value)\n return {[identifier]: appToken}\n}\n\ninterface TokenRequestResult {\n access_token: string\n expires_in: number\n refresh_token: string\n scope: string\n id_token?: string\n}\n\nfunction tokenRequestErrorHandler({error, store}: {error: string; store?: string}) {\n const invalidTargetErrorMessage =\n `You are not authorized to use the CLI to develop in the provided store${store ? `: ${store}` : '.'}` +\n '\\n\\n' +\n \"You can't use Shopify CLI with development stores if you only have Partner \" +\n 'staff member access. If you want to use Shopify CLI to work on a development store, then ' +\n 'you should be the store owner or create a staff account on the store.' +\n '\\n\\n' +\n \"If you're the store owner, then you need to log in to the store directly using the \" +\n 'store URL at least once before you log in using Shopify CLI. ' +\n 'Logging in to the Shopify admin directly connects the development ' +\n 'store with your Shopify login.'\n\n if (error === 'invalid_grant') {\n // There's an scenario when Identity returns \"invalid_grant\" when trying to refresh the token\n // using a valid refresh token. When that happens, we take the user through the authentication flow.\n return new InvalidGrantError()\n }\n if (error === 'invalid_request') {\n // There's an scenario when Identity returns \"invalid_request\" when exchanging an identity token.\n // This means the token is invalid. We clear the session and throw an error to let the caller know.\n return new InvalidRequestError()\n }\n if (error === 'invalid_target') {\n return new InvalidTargetError(invalidTargetErrorMessage)\n }\n // eslint-disable-next-line @shopify/cli/no-error-factory-functions\n return new AbortError(error)\n}\n\nasync function tokenRequest(params: {\n [key: string]: string\n}): Promise<Result<TokenRequestResult, {error: string; store?: string}>> {\n const fqdn = await identityFqdn()\n const url = new URL(`https://${fqdn}/oauth/token`)\n url.search = new URLSearchParams(Object.entries(params)).toString()\n\n const res = await shopifyFetch(url.href, {method: 'POST'})\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const payload: any = await res.json()\n\n if (res.ok) return ok(payload)\n\n return err({error: payload.error, store: params.store})\n}\n\nfunction buildIdentityToken(result: TokenRequestResult, existingUserId?: string): IdentityToken {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const userId = existingUserId ?? (result.id_token ? jose.decodeJwt(result.id_token).sub! : undefined)\n\n if (!userId) {\n throw new BugError('Error setting userId for session. No id_token or pre-existing user ID provided.')\n }\n\n return {\n accessToken: result.access_token,\n refreshToken: result.refresh_token,\n expiresAt: new Date(Date.now() + result.expires_in * 1000),\n scopes: result.scope.split(' '),\n userId,\n }\n}\n\nfunction buildApplicationToken(result: TokenRequestResult): ApplicationToken {\n return {\n accessToken: result.access_token,\n expiresAt: new Date(Date.now() + result.expires_in * 1000),\n scopes: result.scope.split(' '),\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"exchange.js","sourceRoot":"","sources":["../../../../src/private/node/session/exchange.ts"],"names":[],"mappings":"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","sourcesContent":["import {ApplicationToken, IdentityToken} from './schema.js'\nimport {applicationId, clientId as getIdentityClientId} from './identity.js'\nimport {tokenExchangeScopes} from './scopes.js'\nimport {API} from '../api.js'\nimport {identityFqdn} from '../../../public/node/context/fqdn.js'\nimport {shopifyFetch} from '../../../public/node/http.js'\nimport {err, ok, Result} from '../../../public/node/result.js'\nimport {AbortError, BugError, ExtendableError} from '../../../public/node/error.js'\nimport {setLastSeenAuthMethod, setLastSeenUserIdAfterAuth} from '../session.js'\nimport {nonRandomUUID} from '../../../public/node/crypto.js'\nimport * as jose from 'jose'\n\nexport class InvalidGrantError extends ExtendableError {}\nexport class InvalidRequestError extends ExtendableError {}\nclass InvalidTargetError extends AbortError {}\n\nexport interface ExchangeScopes {\n admin: string[]\n partners: string[]\n storefront: string[]\n businessPlatform: string[]\n appManagement: string[]\n}\n\n/**\n * Given an identity token, request an application token.\n * @param identityToken - access token obtained in a previous step\n * @param store - the store to use, only needed for admin API\n * @returns An array with the application access tokens.\n */\nexport async function exchangeAccessForApplicationTokens(\n identityToken: IdentityToken,\n scopes: ExchangeScopes,\n store?: string,\n): Promise<{[x: string]: ApplicationToken}> {\n const token = identityToken.accessToken\n\n const [partners, storefront, businessPlatform, admin, appManagement] = await Promise.all([\n requestAppToken('partners', token, scopes.partners),\n requestAppToken('storefront-renderer', token, scopes.storefront),\n requestAppToken('business-platform', token, scopes.businessPlatform),\n store ? requestAppToken('admin', token, scopes.admin, store) : {},\n requestAppToken('app-management', token, scopes.appManagement),\n ])\n\n return {\n ...partners,\n ...storefront,\n ...businessPlatform,\n ...admin,\n ...appManagement,\n }\n}\n\n/**\n * Given an expired access token, refresh it to get a new one.\n */\nexport async function refreshAccessToken(currentToken: IdentityToken): Promise<IdentityToken> {\n const clientId = getIdentityClientId()\n const params = {\n grant_type: 'refresh_token',\n access_token: currentToken.accessToken,\n refresh_token: currentToken.refreshToken,\n client_id: clientId,\n }\n const tokenResult = await tokenRequest(params)\n const value = tokenResult.mapError(tokenRequestErrorHandler).valueOrBug()\n return buildIdentityToken(value, currentToken.userId)\n}\n\n/**\n * Given a custom CLI token passed as ENV variable request a valid API access token\n * @param token - The CLI token passed as ENV variable `SHOPIFY_CLI_PARTNERS_TOKEN`\n * @param apiName - The API to exchange for the access token\n * @param scopes - The scopes to request with the access token\n * @returns An instance with the application access tokens.\n */\nasync function exchangeCliTokenForAccessToken(\n apiName: API,\n token: string,\n scopes: string[],\n): Promise<{accessToken: string; userId: string}> {\n const appId = applicationId(apiName)\n try {\n const newToken = await requestAppToken(apiName, token, scopes)\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const accessToken = newToken[appId]!.accessToken\n const userId = nonRandomUUID(token)\n setLastSeenUserIdAfterAuth(userId)\n setLastSeenAuthMethod('partners_token')\n return {accessToken, userId}\n } catch (error) {\n const prettyName = apiName.replace(/-/g, ' ').replace(/\\b\\w/g, (char) => char.toUpperCase())\n throw new AbortError(\n `The custom token provided can't be used for the ${prettyName} API.`,\n 'Ensure the token is correct and not expired.',\n )\n }\n}\n\n/**\n * Given a custom CLI token passed as ENV variable, request a valid Partners API token\n * This token does not accept extra scopes, just the cli one.\n * @param token - The CLI token passed as ENV variable `SHOPIFY_CLI_PARTNERS_TOKEN`\n * @returns An instance with the application access tokens.\n */\nexport async function exchangeCustomPartnerToken(token: string): Promise<{accessToken: string; userId: string}> {\n return exchangeCliTokenForAccessToken('partners', token, tokenExchangeScopes('partners'))\n}\n\n/**\n * Given a custom CLI token passed as ENV variable, request a valid App Management API token\n * @param token - The CLI token passed as ENV variable `SHOPIFY_CLI_PARTNERS_TOKEN`\n * @returns An instance with the application access tokens.\n */\nexport async function exchangeCliTokenForAppManagementAccessToken(\n token: string,\n): Promise<{accessToken: string; userId: string}> {\n return exchangeCliTokenForAccessToken('app-management', token, tokenExchangeScopes('app-management'))\n}\n\n/**\n * Given a custom CLI token passed as ENV variable, request a valid Business Platform API token\n * @param token - The CLI token passed as ENV variable `SHOPIFY_CLI_PARTNERS_TOKEN`\n * @returns An instance with the application access tokens.\n */\nexport async function exchangeCliTokenForBusinessPlatformAccessToken(\n token: string,\n): Promise<{accessToken: string; userId: string}> {\n return exchangeCliTokenForAccessToken('business-platform', token, tokenExchangeScopes('business-platform'))\n}\n\ntype IdentityDeviceError = 'authorization_pending' | 'access_denied' | 'expired_token' | 'slow_down' | 'unknown_failure'\n\n/**\n * Given a deviceCode obtained after starting a device identity flow, request an identity token.\n * @param deviceCode - The device code obtained after starting a device identity flow\n * @param scopes - The scopes to request\n * @returns An instance with the identity access tokens.\n */\nexport async function exchangeDeviceCodeForAccessToken(\n deviceCode: string,\n): Promise<Result<IdentityToken, IdentityDeviceError>> {\n const clientId = await getIdentityClientId()\n\n const params = {\n grant_type: 'urn:ietf:params:oauth:grant-type:device_code',\n device_code: deviceCode,\n client_id: clientId,\n }\n\n const tokenResult = await tokenRequest(params)\n if (tokenResult.isErr()) {\n return err(tokenResult.error.error as IdentityDeviceError)\n }\n const identityToken = buildIdentityToken(tokenResult.value)\n return ok(identityToken)\n}\n\nexport async function requestAppToken(\n api: API,\n token: string,\n scopes: string[] = [],\n store?: string,\n): Promise<{[x: string]: ApplicationToken}> {\n const appId = applicationId(api)\n const clientId = await getIdentityClientId()\n\n const params = {\n grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange',\n requested_token_type: 'urn:ietf:params:oauth:token-type:access_token',\n subject_token_type: 'urn:ietf:params:oauth:token-type:access_token',\n client_id: clientId,\n audience: appId,\n scope: scopes.join(' '),\n subject_token: token,\n ...(api === 'admin' && {destination: `https://${store}/admin`, store}),\n }\n\n let identifier = appId\n if (api === 'admin' && store) {\n identifier = `${store}-${appId}`\n }\n const tokenResult = await tokenRequest(params)\n const value = tokenResult.mapError(tokenRequestErrorHandler).valueOrBug()\n const appToken = buildApplicationToken(value)\n return {[identifier]: appToken}\n}\n\ninterface TokenRequestResult {\n access_token: string\n expires_in: number\n refresh_token: string\n scope: string\n id_token?: string\n}\n\nfunction tokenRequestErrorHandler({error, store}: {error: string; store?: string}) {\n const invalidTargetErrorMessage =\n `You are not authorized to use the CLI to develop in the provided store${store ? `: ${store}` : '.'}` +\n '\\n\\n' +\n \"You can't use Shopify CLI with development stores if you only have Partner \" +\n 'staff member access. If you want to use Shopify CLI to work on a development store, then ' +\n 'you should be the store owner or create a staff account on the store.' +\n '\\n\\n' +\n \"If you're the store owner, then you need to log in to the store directly using the \" +\n 'store URL at least once before you log in using Shopify CLI. ' +\n 'Logging in to the Shopify admin directly connects the development ' +\n 'store with your Shopify login.'\n\n if (error === 'invalid_grant') {\n // There's an scenario when Identity returns \"invalid_grant\" when trying to refresh the token\n // using a valid refresh token. When that happens, we take the user through the authentication flow.\n return new InvalidGrantError()\n }\n if (error === 'invalid_request') {\n // There's an scenario when Identity returns \"invalid_request\" when exchanging an identity token.\n // This means the token is invalid. We clear the session and throw an error to let the caller know.\n return new InvalidRequestError()\n }\n if (error === 'invalid_target') {\n return new InvalidTargetError(invalidTargetErrorMessage)\n }\n // eslint-disable-next-line @shopify/cli/no-error-factory-functions\n return new AbortError(error)\n}\n\nasync function tokenRequest(params: {\n [key: string]: string\n}): Promise<Result<TokenRequestResult, {error: string; store?: string}>> {\n const fqdn = await identityFqdn()\n const url = new URL(`https://${fqdn}/oauth/token`)\n url.search = new URLSearchParams(Object.entries(params)).toString()\n\n const res = await shopifyFetch(url.href, {method: 'POST'})\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const payload: any = await res.json()\n\n if (res.ok) return ok(payload)\n\n return err({error: payload.error, store: params.store})\n}\n\nfunction buildIdentityToken(result: TokenRequestResult, existingUserId?: string): IdentityToken {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const userId = existingUserId ?? (result.id_token ? jose.decodeJwt(result.id_token).sub! : undefined)\n\n if (!userId) {\n throw new BugError('Error setting userId for session. No id_token or pre-existing user ID provided.')\n }\n\n return {\n accessToken: result.access_token,\n refreshToken: result.refresh_token,\n expiresAt: new Date(Date.now() + result.expires_in * 1000),\n scopes: result.scope.split(' '),\n userId,\n }\n}\n\nfunction buildApplicationToken(result: TokenRequestResult): ApplicationToken {\n return {\n accessToken: result.access_token,\n expiresAt: new Date(Date.now() + result.expires_in * 1000),\n scopes: result.scope.split(' '),\n }\n}\n"]}
|
|
@@ -48,7 +48,7 @@ function defaultApiScopes(api) {
|
|
|
48
48
|
case 'partners':
|
|
49
49
|
return ['cli'];
|
|
50
50
|
case 'business-platform':
|
|
51
|
-
return ['destinations', 'store-management'];
|
|
51
|
+
return ['destinations', 'store-management', 'on-demand-user-access'];
|
|
52
52
|
case 'app-management':
|
|
53
53
|
return ['app-management'];
|
|
54
54
|
default:
|
|
@@ -71,6 +71,8 @@ function scopeTransform(scope) {
|
|
|
71
71
|
return 'https://api.shopify.com/auth/destinations.readonly';
|
|
72
72
|
case 'store-management':
|
|
73
73
|
return 'https://api.shopify.com/auth/organization.store-management';
|
|
74
|
+
case 'on-demand-user-access':
|
|
75
|
+
return 'https://api.shopify.com/auth/organization.on-demand-user-access';
|
|
74
76
|
case 'app-management':
|
|
75
77
|
return 'https://api.shopify.com/auth/organization.apps.manage';
|
|
76
78
|
default:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scopes.js","sourceRoot":"","sources":["../../../../src/private/node/session/scopes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAM,MAAM,WAAW,CAAA;AACtC,OAAO,EAAC,QAAQ,EAAC,MAAM,+BAA+B,CAAA;AAEtD;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,cAAwB,EAAE;IACzD,IAAI,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IAC/D,MAAM,GAAG,CAAC,QAAQ,EAAE,GAAG,MAAM,EAAE,GAAG,WAAW,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;IAClE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;AACpC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,GAAQ,EAAE,cAAwB,EAAE;IAC5D,MAAM,MAAM,GAAG,CAAC,GAAG,gBAAgB,CAAC,GAAG,CAAC,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;IACjG,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;AACpC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAQ;IAC1C,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,UAAU;YACb,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAA;QAChC,KAAK,gBAAgB;YACnB,OAAO,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,CAAA;QAC3C,KAAK,mBAAmB;YACtB,OAAO,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,CAAA;QACzC;YACE,MAAM,IAAI,QAAQ,CAAC,yCAAyC,GAAG,EAAE,CAAC,CAAA;IACtE,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAQ;IAChC,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,OAAO;YACV,OAAO,CAAC,SAAS,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAA;QAC9C,KAAK,qBAAqB;YACxB,OAAO,CAAC,UAAU,CAAC,CAAA;QACrB,KAAK,UAAU;YACb,OAAO,CAAC,KAAK,CAAC,CAAA;QAChB,KAAK,mBAAmB;YACtB,OAAO,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"scopes.js","sourceRoot":"","sources":["../../../../src/private/node/session/scopes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAM,MAAM,WAAW,CAAA;AACtC,OAAO,EAAC,QAAQ,EAAC,MAAM,+BAA+B,CAAA;AAEtD;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,cAAwB,EAAE;IACzD,IAAI,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IAC/D,MAAM,GAAG,CAAC,QAAQ,EAAE,GAAG,MAAM,EAAE,GAAG,WAAW,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;IAClE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;AACpC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,GAAQ,EAAE,cAAwB,EAAE;IAC5D,MAAM,MAAM,GAAG,CAAC,GAAG,gBAAgB,CAAC,GAAG,CAAC,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;IACjG,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;AACpC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAQ;IAC1C,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,UAAU;YACb,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAA;QAChC,KAAK,gBAAgB;YACnB,OAAO,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,CAAA;QAC3C,KAAK,mBAAmB;YACtB,OAAO,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,CAAA;QACzC;YACE,MAAM,IAAI,QAAQ,CAAC,yCAAyC,GAAG,EAAE,CAAC,CAAA;IACtE,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAQ;IAChC,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,OAAO;YACV,OAAO,CAAC,SAAS,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAA;QAC9C,KAAK,qBAAqB;YACxB,OAAO,CAAC,UAAU,CAAC,CAAA;QACrB,KAAK,UAAU;YACb,OAAO,CAAC,KAAK,CAAC,CAAA;QAChB,KAAK,mBAAmB;YACtB,OAAO,CAAC,cAAc,EAAE,kBAAkB,EAAE,uBAAuB,CAAC,CAAA;QACtE,KAAK,gBAAgB;YACnB,OAAO,CAAC,gBAAgB,CAAC,CAAA;QAC3B;YACE,MAAM,IAAI,QAAQ,CAAC,gBAAgB,GAAG,EAAE,CAAC,CAAA;IAC7C,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,KAAa;IACnC,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,SAAS;YACZ,OAAO,iDAAiD,CAAA;QAC1D,KAAK,QAAQ;YACX,OAAO,gDAAgD,CAAA;QACzD,KAAK,cAAc;YACjB,OAAO,2EAA2E,CAAA;QACpF,KAAK,KAAK;YACR,OAAO,sDAAsD,CAAA;QAC/D,KAAK,UAAU;YACb,OAAO,gEAAgE,CAAA;QACzE,KAAK,cAAc;YACjB,OAAO,oDAAoD,CAAA;QAC7D,KAAK,kBAAkB;YACrB,OAAO,4DAA4D,CAAA;QACrE,KAAK,uBAAuB;YAC1B,OAAO,iEAAiE,CAAA;QAC1E,KAAK,gBAAgB;YACnB,OAAO,uDAAuD,CAAA;QAChE;YACE,OAAO,KAAK,CAAA;IAChB,CAAC;AACH,CAAC","sourcesContent":["import {allAPIs, API} from '../api.js'\nimport {BugError} from '../../../public/node/error.js'\n\n/**\n * Generate a flat array with all the default scopes for all the APIs plus\n * any custom scope defined by the user.\n * @param extraScopes - custom user-defined scopes\n * @returns Array of scopes\n */\nexport function allDefaultScopes(extraScopes: string[] = []): string[] {\n let scopes = allAPIs.map((api) => defaultApiScopes(api)).flat()\n scopes = ['openid', ...scopes, ...extraScopes].map(scopeTransform)\n return Array.from(new Set(scopes))\n}\n\n/**\n * Generate a flat array with the default scopes for the given API plus\n * any custom scope defined by the user\n * @param api - API to get the scopes for\n * @param extraScopes - custom user-defined scopes\n * @returns Array of scopes\n */\nexport function apiScopes(api: API, extraScopes: string[] = []): string[] {\n const scopes = [...defaultApiScopes(api), ...extraScopes.map(scopeTransform)].map(scopeTransform)\n return Array.from(new Set(scopes))\n}\n\n/**\n * Returns specific scopes required for token exchange with the given API.\n * @param api - API to get the scopes for\n * @returns Array of transformed scopes\n */\nexport function tokenExchangeScopes(api: API): string[] {\n switch (api) {\n case 'partners':\n return [scopeTransform('cli')]\n case 'app-management':\n return [scopeTransform('app-management')]\n case 'business-platform':\n return [scopeTransform('destinations')]\n default:\n throw new BugError(`API not supported for token exchange: ${api}`)\n }\n}\n\nfunction defaultApiScopes(api: API): string[] {\n switch (api) {\n case 'admin':\n return ['graphql', 'themes', 'collaborator']\n case 'storefront-renderer':\n return ['devtools']\n case 'partners':\n return ['cli']\n case 'business-platform':\n return ['destinations', 'store-management', 'on-demand-user-access']\n case 'app-management':\n return ['app-management']\n default:\n throw new BugError(`Unknown API: ${api}`)\n }\n}\n\nfunction scopeTransform(scope: string): string {\n switch (scope) {\n case 'graphql':\n return 'https://api.shopify.com/auth/shop.admin.graphql'\n case 'themes':\n return 'https://api.shopify.com/auth/shop.admin.themes'\n case 'collaborator':\n return 'https://api.shopify.com/auth/partners.collaborator-relationships.readonly'\n case 'cli':\n return 'https://api.shopify.com/auth/partners.app.cli.access'\n case 'devtools':\n return 'https://api.shopify.com/auth/shop.storefront-renderer.devtools'\n case 'destinations':\n return 'https://api.shopify.com/auth/destinations.readonly'\n case 'store-management':\n return 'https://api.shopify.com/auth/organization.store-management'\n case 'on-demand-user-access':\n return 'https://api.shopify.com/auth/organization.on-demand-user-access'\n case 'app-management':\n return 'https://api.shopify.com/auth/organization.apps.manage'\n default:\n return scope\n }\n}\n"]}
|
|
@@ -3,7 +3,7 @@ import { applicationId } from './identity.js';
|
|
|
3
3
|
import { validateCachedIdentityTokenStructure } from './schema.js';
|
|
4
4
|
import { sessionConstants } from '../constants.js';
|
|
5
5
|
import { firstPartyDev } from '../../../public/node/context/local.js';
|
|
6
|
-
import { outputDebug } from '
|
|
6
|
+
import { outputDebug } from '../../../public/node/output.js';
|
|
7
7
|
/**
|
|
8
8
|
* Validate if an identity token is valid for the requested scopes
|
|
9
9
|
*/
|