@shopify/cli-kit 3.58.2 → 3.59.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/assets/cli-ruby/Gemfile +0 -2
- package/assets/cli-ruby/lib/project_types/theme/cli.rb +0 -2
- package/assets/cli-ruby/lib/shopify_cli/constants.rb +6 -0
- package/assets/cli-ruby/lib/shopify_cli/environment.rb +7 -0
- package/assets/cli-ruby/lib/shopify_cli/theme/dev_server/proxy.rb +6 -1
- package/assets/cli-ruby/lib/shopify_cli/theme/repl/api.rb +1 -1
- package/assets/cli-ruby/lib/shopify_cli/theme/theme_access_api.rb +3 -3
- package/assets/cli-ruby/shopify-cli.gemspec +0 -8
- package/dist/private/common/ts/overloaded-parameters.d.ts +0 -1
- package/dist/private/common/ts/overloaded-parameters.js.map +1 -1
- package/dist/private/node/analytics.d.ts +1 -0
- package/dist/private/node/analytics.js +2 -0
- package/dist/private/node/analytics.js.map +1 -1
- package/dist/private/node/api/graphql.d.ts +1 -1
- package/dist/private/node/api/graphql.js.map +1 -1
- package/dist/private/node/api/headers.js +1 -1
- package/dist/private/node/api/headers.js.map +1 -1
- package/dist/private/node/api/rest.d.ts +2 -1
- package/dist/private/node/api/rest.js +4 -2
- package/dist/private/node/api/rest.js.map +1 -1
- package/dist/private/node/constants.d.ts +2 -3
- package/dist/private/node/constants.js +2 -3
- package/dist/private/node/constants.js.map +1 -1
- package/dist/private/node/session/authorize.js +1 -1
- package/dist/private/node/session/authorize.js.map +1 -1
- package/dist/private/node/session/device-authorization.js +1 -1
- package/dist/private/node/session/device-authorization.js.map +1 -1
- package/dist/private/node/session/exchange.d.ts +2 -1
- package/dist/private/node/session/exchange.js.map +1 -1
- package/dist/private/node/session/post-auth.d.ts +0 -3
- package/dist/private/node/session/post-auth.js +1 -2
- package/dist/private/node/session/post-auth.js.map +1 -1
- package/dist/private/node/session/store.d.ts +0 -4
- package/dist/private/node/session/store.js +0 -4
- package/dist/private/node/session/store.js.map +1 -1
- package/dist/private/node/ui/components/AutocompletePrompt.js +1 -1
- package/dist/private/node/ui/components/AutocompletePrompt.js.map +1 -1
- package/dist/private/node/ui/components/AutocompletePrompt.test.js.map +1 -1
- package/dist/private/node/ui/components/ConcurrentOutput.d.ts +0 -3
- package/dist/private/node/ui/components/ConcurrentOutput.js.map +1 -1
- package/dist/private/node/ui/components/FatalError.d.ts +1 -1
- package/dist/private/node/ui/components/FatalError.js.map +1 -1
- package/dist/private/node/ui/components/Prompts/PromptLayout.d.ts +1 -1
- package/dist/private/node/ui/components/Prompts/PromptLayout.js.map +1 -1
- package/dist/private/node/ui/components/Scrollbar.d.ts +1 -1
- package/dist/private/node/ui/components/Scrollbar.js.map +1 -1
- package/dist/private/node/ui/components/SelectPrompt.test.js +0 -2
- package/dist/private/node/ui/components/SelectPrompt.test.js.map +1 -1
- package/dist/private/node/ui/hooks/use-select-state.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/business-platform.d.ts +1 -1
- package/dist/public/node/api/business-platform.js +1 -1
- package/dist/public/node/api/business-platform.js.map +1 -1
- package/dist/public/node/cli.d.ts +1 -1
- package/dist/public/node/cli.js +5 -6
- package/dist/public/node/cli.js.map +1 -1
- package/dist/public/node/custom-oclif-loader.js +23 -0
- package/dist/public/node/custom-oclif-loader.js.map +1 -1
- package/dist/public/node/is-global.d.ts +31 -0
- package/dist/public/node/is-global.js +69 -0
- package/dist/public/node/is-global.js.map +1 -1
- package/dist/public/node/monorail.d.ts +2 -1
- package/dist/public/node/monorail.js +15 -2
- package/dist/public/node/monorail.js.map +1 -1
- package/dist/public/node/tcp.d.ts +8 -1
- package/dist/public/node/tcp.js +8 -2
- package/dist/public/node/tcp.js.map +1 -1
- package/dist/public/node/themes/utils.d.ts +1 -0
- package/dist/public/node/themes/utils.js +9 -0
- package/dist/public/node/themes/utils.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -12
- package/assets/cli-ruby/lib/project_types/theme/commands/check.rb +0 -38
- package/assets/cli-ruby/lib/project_types/theme/commands/language_server.rb +0 -18
- package/dist/private/common/lodash.d.ts +0 -47
- package/dist/private/common/lodash.js +0 -2
- package/dist/private/common/lodash.js.map +0 -1
- package/dist/private/node/ui/components/FullScreen.d.ts +0 -8
- package/dist/private/node/ui/components/FullScreen.js +0 -33
- package/dist/private/node/ui/components/FullScreen.js.map +0 -1
package/assets/cli-ruby/Gemfile
CHANGED
|
@@ -12,13 +12,11 @@ module Theme
|
|
|
12
12
|
subcommand :Pull, "pull", Project.project_filepath("commands/pull")
|
|
13
13
|
subcommand :Push, "push", Project.project_filepath("commands/push")
|
|
14
14
|
subcommand :Delete, "delete", Project.project_filepath("commands/delete")
|
|
15
|
-
subcommand :Check, "check", Project.project_filepath("commands/check")
|
|
16
15
|
subcommand :Publish, "publish", Project.project_filepath("commands/publish")
|
|
17
16
|
subcommand :Package, "package", Project.project_filepath("commands/package")
|
|
18
17
|
subcommand :Open, "open", Project.project_filepath("commands/open")
|
|
19
18
|
subcommand :List, "list", Project.project_filepath("commands/list")
|
|
20
19
|
subcommand :Share, "share", Project.project_filepath("commands/share")
|
|
21
|
-
subcommand :LanguageServer, "language-server", Project.project_filepath("commands/language_server")
|
|
22
20
|
subcommand :Console, "console", Project.project_filepath("commands/console")
|
|
23
21
|
subcommand :Token, "token", Project.project_filepath("commands/token")
|
|
24
22
|
end
|
|
@@ -34,6 +34,7 @@ module ShopifyCLI
|
|
|
34
34
|
RUN_AS_SUBPROCESS = "SHOPIFY_CLI_RUN_AS_SUBPROCESS"
|
|
35
35
|
RUBY_BIN = "SHOPIFY_CLI_RUBY_BIN"
|
|
36
36
|
UNIFIED_DEPLOYMENT = "SHOPIFY_CLI_UNIFIED_DEPLOYMENT"
|
|
37
|
+
THEME_KIT_ACCESS_DOMAIN = "SHOPIFY_CLI_THEME_KIT_ACCESS_DOMAIN"
|
|
37
38
|
|
|
38
39
|
# When true the CLI points to a local instance of
|
|
39
40
|
# the partners dashboard and identity.
|
|
@@ -67,6 +68,11 @@ module ShopifyCLI
|
|
|
67
68
|
STORE = "SHOPIFY_SHOP"
|
|
68
69
|
end
|
|
69
70
|
|
|
71
|
+
module ThemeKitAccess
|
|
72
|
+
# override with SHOPIFY_CLI_THEME_KIT_ACCESS_DOMAIN
|
|
73
|
+
BASE_URL = "theme-kit-access.shopifyapps.com"
|
|
74
|
+
end
|
|
75
|
+
|
|
70
76
|
module SupportedVersions
|
|
71
77
|
module Ruby
|
|
72
78
|
FROM = "2.7.5"
|
|
@@ -206,5 +206,12 @@ module ShopifyCLI
|
|
|
206
206
|
env_variables: env_variables
|
|
207
207
|
)
|
|
208
208
|
end
|
|
209
|
+
|
|
210
|
+
def self.theme_kit_access_domain(env_variables: ENV)
|
|
211
|
+
return env_variables[Constants::EnvironmentVariables::THEME_KIT_ACCESS_DOMAIN] if env_variables.key?(
|
|
212
|
+
Constants::EnvironmentVariables::THEME_KIT_ACCESS_DOMAIN
|
|
213
|
+
)
|
|
214
|
+
Constants::ThemeKitAccess::BASE_URL
|
|
215
|
+
end
|
|
209
216
|
end
|
|
210
217
|
end
|
|
@@ -106,6 +106,11 @@ module ShopifyCLI
|
|
|
106
106
|
private
|
|
107
107
|
|
|
108
108
|
def clean_sfr_cache(env, query, headers)
|
|
109
|
+
if env["PATH_INFO"].start_with?("/password")
|
|
110
|
+
@cache_cleaned = false
|
|
111
|
+
return
|
|
112
|
+
end
|
|
113
|
+
|
|
109
114
|
return if @cache_cleaned
|
|
110
115
|
|
|
111
116
|
@cache_cleaned = true
|
|
@@ -249,7 +254,7 @@ module ShopifyCLI
|
|
|
249
254
|
"X-Shopify-Access-Token" => Environment.admin_auth_token,
|
|
250
255
|
"X-Shopify-Shop" => shop,
|
|
251
256
|
})
|
|
252
|
-
uri = URI.join("https://#{
|
|
257
|
+
uri = URI.join("https://#{ShopifyCLI::Constants::ThemeKitAccess::BASE_URL}", "cli/sfr#{path}")
|
|
253
258
|
end
|
|
254
259
|
|
|
255
260
|
uri.query = URI.encode_www_form(query + [[:_fd, 0], [:pb, 0]])
|
|
@@ -92,7 +92,7 @@ module ShopifyCLI
|
|
|
92
92
|
return @api_uri if @api_uri
|
|
93
93
|
|
|
94
94
|
uri_address = if Environment.theme_access_password?
|
|
95
|
-
"https://#{
|
|
95
|
+
"https://#{ShopifyCLI::Constants::ThemeKitAccess::BASE_URL}/cli/sfr#{url}"
|
|
96
96
|
else
|
|
97
97
|
"https://#{shop}#{url}"
|
|
98
98
|
end
|
|
@@ -9,8 +9,6 @@ module ShopifyCLI
|
|
|
9
9
|
# generated from Shopify Theme Access app to access the Shopify Admin API (for theme operations)
|
|
10
10
|
#
|
|
11
11
|
class ThemeAccessAPI < API
|
|
12
|
-
BASE_URL = "theme-kit-access.shopifyapps.com"
|
|
13
|
-
|
|
14
12
|
class << self
|
|
15
13
|
##
|
|
16
14
|
# #### Parameters
|
|
@@ -57,8 +55,10 @@ module ShopifyCLI
|
|
|
57
55
|
private
|
|
58
56
|
|
|
59
57
|
def build_url(api_version, path, query = nil)
|
|
58
|
+
domain = Environment.theme_kit_access_domain
|
|
59
|
+
|
|
60
60
|
URI::HTTPS.build(
|
|
61
|
-
host:
|
|
61
|
+
host: domain,
|
|
62
62
|
path: "/cli/admin/api/#{api_version}/#{path}",
|
|
63
63
|
query: query
|
|
64
64
|
).to_s
|
|
@@ -42,13 +42,5 @@ Gem::Specification.new do |spec|
|
|
|
42
42
|
spec.add_dependency("bugsnag", "~> 6.22")
|
|
43
43
|
spec.add_dependency("listen", "~> 3.7.0")
|
|
44
44
|
|
|
45
|
-
# We prefer being more strict here with the version range to have a more deterministic build.
|
|
46
|
-
# The added benefit is that, if the user upgrades the CLI, and we have "~> 1.10.1" version range,
|
|
47
|
-
# they will get a theme-check update.
|
|
48
|
-
# Whereas if we were to have "~> 1.9", that version would still be satisfied and thus not upgraded.
|
|
49
|
-
# Both shopify-cli and theme-check gems are owned and developed by Shopify.
|
|
50
|
-
# These gems are currently being actively developed and it's easiest to update them together.
|
|
51
|
-
spec.add_dependency("theme-check", "~> 1.14.0")
|
|
52
|
-
|
|
53
45
|
spec.extensions = ["ext/shopify-extensions/extconf.rb"]
|
|
54
46
|
end
|
|
@@ -2,5 +2,4 @@ type OverloadProps<TOverload> = Pick<TOverload, keyof TOverload>;
|
|
|
2
2
|
type OverloadUnionRecursive<TOverload, TPartialOverload = unknown> = TOverload extends (...args: infer TArgs) => infer TReturn ? TPartialOverload extends TOverload ? never : OverloadUnionRecursive<TPartialOverload & TOverload, TPartialOverload & ((...args: TArgs) => TReturn) & OverloadProps<TOverload>> | ((...args: TArgs) => TReturn) : never;
|
|
3
3
|
type OverloadUnion<TOverload extends (...args: any[]) => any> = Exclude<OverloadUnionRecursive<(() => never) & TOverload>, TOverload extends () => never ? never : () => never>;
|
|
4
4
|
export type OverloadParameters<T extends (...args: any[]) => any> = Parameters<OverloadUnion<T>>;
|
|
5
|
-
export type OverloadReturnType<T extends (...args: any[]) => any> = ReturnType<OverloadUnion<T>>;
|
|
6
5
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overloaded-parameters.js","sourceRoot":"","sources":["../../../../src/private/common/ts/overloaded-parameters.ts"],"names":[],"mappings":"","sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\ntype OverloadProps<TOverload> = Pick<TOverload, keyof TOverload>\n\n// Prevent infinite recursion by stopping recursion when TPartialOverload\n// has accumulated all of the TOverload signatures.\ntype OverloadUnionRecursive<TOverload, TPartialOverload = unknown> = TOverload extends (\n ...args: infer TArgs\n) => infer TReturn\n ? TPartialOverload extends TOverload\n ? never\n :\n | OverloadUnionRecursive<\n TPartialOverload & TOverload,\n TPartialOverload & ((...args: TArgs) => TReturn) & OverloadProps<TOverload>\n >\n | ((...args: TArgs) => TReturn)\n : never\n\n// The \"() => never\" signature must be hoisted to the \"front\" of the\n// intersection, for two reasons: a) because recursion stops when it is\n// encountered, and b) it seems to prevent the collapse of subsequent\n// \"compatible\" signatures (eg. \"() => void\" into \"(a?: 1) => void\"),\n// which gives a direct conversion to a union.\ntype OverloadUnion<TOverload extends (...args: any[]) => any> = Exclude<\n OverloadUnionRecursive<(() => never) & TOverload>,\n TOverload extends () => never ? never : () => never\n>\n\n// Inferring a union of parameter tuples or return types is now possible.\nexport type OverloadParameters<T extends (...args: any[]) => any> = Parameters<OverloadUnion<T>>\
|
|
1
|
+
{"version":3,"file":"overloaded-parameters.js","sourceRoot":"","sources":["../../../../src/private/common/ts/overloaded-parameters.ts"],"names":[],"mappings":"","sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\ntype OverloadProps<TOverload> = Pick<TOverload, keyof TOverload>\n\n// Prevent infinite recursion by stopping recursion when TPartialOverload\n// has accumulated all of the TOverload signatures.\ntype OverloadUnionRecursive<TOverload, TPartialOverload = unknown> = TOverload extends (\n ...args: infer TArgs\n) => infer TReturn\n ? TPartialOverload extends TOverload\n ? never\n :\n | OverloadUnionRecursive<\n TPartialOverload & TOverload,\n TPartialOverload & ((...args: TArgs) => TReturn) & OverloadProps<TOverload>\n >\n | ((...args: TArgs) => TReturn)\n : never\n\n// The \"() => never\" signature must be hoisted to the \"front\" of the\n// intersection, for two reasons: a) because recursion stops when it is\n// encountered, and b) it seems to prevent the collapse of subsequent\n// \"compatible\" signatures (eg. \"() => void\" into \"(a?: 1) => void\"),\n// which gives a direct conversion to a union.\ntype OverloadUnion<TOverload extends (...args: any[]) => any> = Exclude<\n OverloadUnionRecursive<(() => never) & TOverload>,\n TOverload extends () => never ? never : () => never\n>\n\n// Inferring a union of parameter tuples or return types is now possible.\nexport type OverloadParameters<T extends (...args: any[]) => any> = Parameters<OverloadUnion<T>>\n"]}
|
|
@@ -19,6 +19,7 @@ interface EnvironmentData {
|
|
|
19
19
|
env_device_id: string;
|
|
20
20
|
env_cloud: string;
|
|
21
21
|
env_package_manager: string;
|
|
22
|
+
env_is_global: boolean;
|
|
22
23
|
}
|
|
23
24
|
export declare function getEnvironmentData(config: Interfaces.Config): Promise<EnvironmentData>;
|
|
24
25
|
export declare function getSensitiveEnvironmentData(config: Interfaces.Config): Promise<{
|
|
@@ -4,6 +4,7 @@ import * as metadata from '../../public/node/metadata.js';
|
|
|
4
4
|
import { platformAndArch } from '../../public/node/os.js';
|
|
5
5
|
import { ciPlatform, cloudEnvironment, macAddress } from '@shopify/cli-kit/node/context/local';
|
|
6
6
|
import { cwd } from '@shopify/cli-kit/node/path';
|
|
7
|
+
import { currentProcessIsGlobal } from '@shopify/cli-kit/node/is-global';
|
|
7
8
|
export async function startAnalytics({ commandContent, args, currentTime = new Date().getTime(), commandClass, }) {
|
|
8
9
|
let startCommand = commandContent.command;
|
|
9
10
|
if (commandClass && Object.prototype.hasOwnProperty.call(commandClass, 'analyticsNameOverride')) {
|
|
@@ -40,6 +41,7 @@ export async function getEnvironmentData(config) {
|
|
|
40
41
|
env_device_id: hashString(await macAddress()),
|
|
41
42
|
env_cloud: cloudEnvironment().platform,
|
|
42
43
|
env_package_manager: await getPackageManager(cwd()),
|
|
44
|
+
env_is_global: currentProcessIsGlobal(),
|
|
43
45
|
};
|
|
44
46
|
}
|
|
45
47
|
export async function getSensitiveEnvironmentData(config) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../../src/private/node/analytics.ts"],"names":[],"mappings":"AAAA,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;AAEvD,OAAO,EAAC,UAAU,EAAE,gBAAgB,EAAE,UAAU,EAAC,MAAM,qCAAqC,CAAA;AAC5F,OAAO,EAAC,GAAG,EAAC,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../../src/private/node/analytics.ts"],"names":[],"mappings":"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","sourcesContent":["import {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 {Command, Interfaces} from '@oclif/core'\nimport {ciPlatform, cloudEnvironment, macAddress} from '@shopify/cli-kit/node/context/local'\nimport {cwd} from '@shopify/cli-kit/node/path'\nimport {currentProcessIsGlobal} from '@shopify/cli-kit/node/is-global'\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 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: commandClass?.plugin?.name,\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}\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 }\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"]}
|
|
@@ -2,4 +2,4 @@ import { RequestDocument, Variables } from 'graphql-request';
|
|
|
2
2
|
export declare function debugLogRequestInfo(api: string, query: RequestDocument, variables?: Variables, headers?: {
|
|
3
3
|
[key: string]: string;
|
|
4
4
|
}): void;
|
|
5
|
-
export declare function errorHandler
|
|
5
|
+
export declare function errorHandler(api: string): (error: unknown, requestId?: string) => Error | unknown;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphql.js","sourceRoot":"","sources":["../../../../src/private/node/api/graphql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kBAAkB,EAAE,sBAAsB,EAAC,MAAM,cAAc,CAAA;AACvE,OAAO,EAAC,gBAAgB,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAC,MAAM,gCAAgC,CAAA;AACxG,OAAO,EAAC,UAAU,EAAC,MAAM,+BAA+B,CAAA;AACxD,OAAO,EAAC,WAAW,EAA6B,MAAM,iBAAiB,CAAA;AAEvE,MAAM,UAAU,mBAAmB,CACjC,GAAW,EACX,KAAsB,EACtB,SAAqB,EACrB,UAAmC,EAAE;IAErC,WAAW,CAAC,aAAa,CAAA,WAAW,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;IACvD,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;EAC1C,SAAS,CAAC,CAAC,CAAC,sBAAsB,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;;EAEvE,sBAAsB,CAAC,OAAO,CAAC;CAChC,CAAC,CAAA;AACF,CAAC;AAED,SAAS,iBAAiB,CAAC,SAAoB;IAC7C,MAAM,MAAM,GAAc,EAAC,GAAG,SAAS,EAAC,CAAA;IACxC,IAAI,QAAQ,IAAI,MAAM,EAAE;QACtB,MAAM,CAAC,MAAM,GAAG,OAAO,CAAA;KACxB;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;AACxC,CAAC;AAED,MAAM,UAAU,YAAY,
|
|
1
|
+
{"version":3,"file":"graphql.js","sourceRoot":"","sources":["../../../../src/private/node/api/graphql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kBAAkB,EAAE,sBAAsB,EAAC,MAAM,cAAc,CAAA;AACvE,OAAO,EAAC,gBAAgB,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAC,MAAM,gCAAgC,CAAA;AACxG,OAAO,EAAC,UAAU,EAAC,MAAM,+BAA+B,CAAA;AACxD,OAAO,EAAC,WAAW,EAA6B,MAAM,iBAAiB,CAAA;AAEvE,MAAM,UAAU,mBAAmB,CACjC,GAAW,EACX,KAAsB,EACtB,SAAqB,EACrB,UAAmC,EAAE;IAErC,WAAW,CAAC,aAAa,CAAA,WAAW,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;IACvD,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;EAC1C,SAAS,CAAC,CAAC,CAAC,sBAAsB,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;;EAEvE,sBAAsB,CAAC,OAAO,CAAC;CAChC,CAAC,CAAA;AACF,CAAC;AAED,SAAS,iBAAiB,CAAC,SAAoB;IAC7C,MAAM,MAAM,GAAc,EAAC,GAAG,SAAS,EAAC,CAAA;IACxC,IAAI,QAAQ,IAAI,MAAM,EAAE;QACtB,MAAM,CAAC,MAAM,GAAG,OAAO,CAAA;KACxB;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;AACxC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,OAAO,CAAC,KAAc,EAAE,SAAkB,EAAE,EAAE;QAC5C,IAAI,KAAK,YAAY,WAAW,EAAE;YAChC,MAAM,EAAC,MAAM,EAAC,GAAG,KAAK,CAAC,QAAQ,CAAA;YAC/B,IAAI,YAAY,GAAG,gBAAgB,CAAC,aAAa,CAAA;MACjD,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,6CAClB,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,oBAAoB,MAAM,MAClD;;EAEJ,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;OAClC,CAAC,CAAA;YACF,IAAI,SAAS,EAAE;gBACb,YAAY,IAAI;cACV,SAAS;CACtB,CAAA;aACM;YACD,IAAI,WAAkB,CAAA;YACtB,IAAI,MAAM,GAAG,GAAG,EAAE;gBAChB,WAAW,GAAG,IAAI,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;aAClF;iBAAM;gBACL,WAAW,GAAG,IAAI,UAAU,CAAC,YAAY,CAAC,CAAA;aAC3C;YACD,WAAW,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAA;YAC/B,OAAO,WAAW,CAAA;SACnB;aAAM;YACL,OAAO,KAAK,CAAA;SACb;IACH,CAAC,CAAA;AACH,CAAC","sourcesContent":["import {GraphQLClientError, sanitizedHeadersOutput} from './headers.js'\nimport {stringifyMessage, outputContent, outputToken, outputDebug} from '../../../public/node/output.js'\nimport {AbortError} from '../../../public/node/error.js'\nimport {ClientError, RequestDocument, Variables} from 'graphql-request'\n\nexport function debugLogRequestInfo(\n api: string,\n query: RequestDocument,\n variables?: Variables,\n headers: {[key: string]: string} = {},\n) {\n outputDebug(outputContent`Sending ${outputToken.json(api)} GraphQL request:\n ${outputToken.raw(query.toString().trim())}\n${variables ? `\\nWith variables:\\n${sanitizeVariables(variables)}\\n` : ''}\nWith request headers:\n${sanitizedHeadersOutput(headers)}\n`)\n}\n\nfunction sanitizeVariables(variables: Variables): string {\n const result: Variables = {...variables}\n if ('apiKey' in result) {\n result.apiKey = '*****'\n }\n return JSON.stringify(result, null, 2)\n}\n\nexport function errorHandler(api: string): (error: unknown, requestId?: string) => Error | unknown {\n return (error: unknown, requestId?: string) => {\n if (error instanceof ClientError) {\n const {status} = error.response\n let errorMessage = stringifyMessage(outputContent`\nThe ${outputToken.raw(api)} GraphQL API responded unsuccessfully with${\n status === 200 ? '' : ` the HTTP status ${status} and`\n } errors:\n\n${outputToken.json(error.response.errors)}\n `)\n if (requestId) {\n errorMessage += `\nRequest ID: ${requestId}\n`\n }\n let mappedError: Error\n if (status < 500) {\n mappedError = new GraphQLClientError(errorMessage, status, error.response.errors)\n } else {\n mappedError = new AbortError(errorMessage)\n }\n mappedError.stack = error.stack\n return mappedError\n } else {\n return error\n }\n }\n}\n"]}
|
|
@@ -46,7 +46,7 @@ export function buildHeaders(token) {
|
|
|
46
46
|
...(firstPartyDev() && { 'X-Shopify-Cli-Employee': '1' }),
|
|
47
47
|
};
|
|
48
48
|
if (token) {
|
|
49
|
-
const authString = token.match(/^shp(at|ua)/) ? token : `Bearer ${token}`;
|
|
49
|
+
const authString = token.match(/^shp(at|ua|ca)/) ? token : `Bearer ${token}`;
|
|
50
50
|
// eslint-disable-next-line dot-notation
|
|
51
51
|
headers['authorization'] = authString;
|
|
52
52
|
headers['X-Shopify-Access-Token'] = authString;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"headers.js","sourceRoot":"","sources":["../../../../src/private/node/api/headers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,mCAAmC,CAAA;AACjE,OAAO,EAAC,aAAa,EAAC,MAAM,uCAAuC,CAAA;AACnE,OAAO,EAAC,WAAW,EAAE,kBAAkB,EAAC,MAAM,uBAAuB,CAAA;AACrE,OAAO,EAAC,eAAe,EAAC,MAAM,+BAA+B,CAAA;AAC7D,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,MAAM,OAAO,kBAAmB,SAAQ,eAAe;IAErD,YAAmB,OAAe,EAAE,UAAkB;QACpD,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;IAC9B,CAAC;CACF;AACD,MAAM,OAAO,kBAAmB,SAAQ,kBAAkB;IAIxD,8DAA8D;IAC9D,YAAmB,OAAe,EAAE,UAAkB,EAAE,MAAc;QACpE,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;QAC1B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAgC;IACrE,MAAM,SAAS,GAA4B,EAAE,CAAA;IAC7C,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,eAAe,EAAE,eAAe,CAAC,CAAA;IAC5D,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;QACtC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,SAAS,EAAE;YAC1F,SAAS,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAE,CAAA;SACrC;IACH,CAAC,CAAC,CAAA;IACF,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;SAC1B,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QACd,OAAO,MAAM,MAAM,KAAK,SAAS,CAAC,MAAM,CAAC,EAAE,CAAA;IAC7C,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAA;AACf,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,MAAM,SAAS,GAAG,kBAAkB,eAAe,EAAE,CAAA;IAErD,MAAM,OAAO,GAA+B;QAC1C,YAAY,EAAE,SAAS;QACvB,YAAY,EAAE,YAAY;QAC1B,0DAA0D;QAC1D,oBAAoB,EAAE,OAAO,CAAC,QAAQ;QACtC,cAAc,EAAE,kBAAkB;QAClC,GAAG,CAAC,aAAa,EAAE,IAAI,EAAC,wBAAwB,EAAE,GAAG,EAAC,CAAC;KACxD,CAAA;IACD,IAAI,KAAK,EAAE;QACT,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"headers.js","sourceRoot":"","sources":["../../../../src/private/node/api/headers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,mCAAmC,CAAA;AACjE,OAAO,EAAC,aAAa,EAAC,MAAM,uCAAuC,CAAA;AACnE,OAAO,EAAC,WAAW,EAAE,kBAAkB,EAAC,MAAM,uBAAuB,CAAA;AACrE,OAAO,EAAC,eAAe,EAAC,MAAM,+BAA+B,CAAA;AAC7D,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,MAAM,OAAO,kBAAmB,SAAQ,eAAe;IAErD,YAAmB,OAAe,EAAE,UAAkB;QACpD,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;IAC9B,CAAC;CACF;AACD,MAAM,OAAO,kBAAmB,SAAQ,kBAAkB;IAIxD,8DAA8D;IAC9D,YAAmB,OAAe,EAAE,UAAkB,EAAE,MAAc;QACpE,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;QAC1B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAgC;IACrE,MAAM,SAAS,GAA4B,EAAE,CAAA;IAC7C,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,eAAe,EAAE,eAAe,CAAC,CAAA;IAC5D,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;QACtC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,SAAS,EAAE;YAC1F,SAAS,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAE,CAAA;SACrC;IACH,CAAC,CAAC,CAAA;IACF,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;SAC1B,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QACd,OAAO,MAAM,MAAM,KAAK,SAAS,CAAC,MAAM,CAAC,EAAE,CAAA;IAC7C,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAA;AACf,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,MAAM,SAAS,GAAG,kBAAkB,eAAe,EAAE,CAAA;IAErD,MAAM,OAAO,GAA+B;QAC1C,YAAY,EAAE,SAAS;QACvB,YAAY,EAAE,YAAY;QAC1B,0DAA0D;QAC1D,oBAAoB,EAAE,OAAO,CAAC,QAAQ;QACtC,cAAc,EAAE,kBAAkB;QAClC,GAAG,CAAC,aAAa,EAAE,IAAI,EAAC,wBAAwB,EAAE,GAAG,EAAC,CAAC;KACxD,CAAA;IACD,IAAI,KAAK,EAAE;QACT,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,KAAK,EAAE,CAAA;QAC5E,wCAAwC;QACxC,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,CAAA;QACrC,OAAO,CAAC,wBAAwB,CAAC,GAAG,UAAU,CAAA;KAC/C;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC;QACrB,kBAAkB,EAAE,MAAM,gCAAgC,EAAE;QAC5D,SAAS,EAAE,IAAI;KAChB,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,KAAK,UAAU,gCAAgC;IAC7C,OAAO,CAAC,MAAM,kBAAkB,EAAE,CAAC,KAAK,WAAW,CAAC,IAAI,CAAA;AAC1D,CAAC","sourcesContent":["import {CLI_KIT_VERSION} from '../../../public/common/version.js'\nimport {firstPartyDev} from '../../../public/node/context/local.js'\nimport {Environment, serviceEnvironment} from '../context/service.js'\nimport {ExtendableError} from '../../../public/node/error.js'\nimport https from 'https'\n\nexport class RequestClientError extends ExtendableError {\n statusCode: number\n public constructor(message: string, statusCode: number) {\n super(message)\n this.statusCode = statusCode\n }\n}\nexport class GraphQLClientError extends RequestClientError {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n errors?: any[]\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public constructor(message: string, statusCode: number, errors?: any[]) {\n super(message, statusCode)\n this.errors = errors\n }\n}\n\n/**\n * Removes the sensitive data from the headers and outputs them as a string.\n * @param headers - HTTP headers.\n * @returns A sanitized version of the headers as a string.\n */\nexport function sanitizedHeadersOutput(headers: {[key: string]: string}): string {\n const sanitized: {[key: string]: string} = {}\n const keywords = ['token', 'authorization', 'subject_token']\n Object.keys(headers).forEach((header) => {\n if (keywords.find((keyword) => header.toLocaleLowerCase().includes(keyword)) === undefined) {\n sanitized[header] = headers[header]!\n }\n })\n return Object.keys(sanitized)\n .map((header) => {\n return ` - ${header}: ${sanitized[header]}`\n })\n .join('\\n')\n}\n\nexport function buildHeaders(token?: string): {[key: string]: string} {\n const userAgent = `Shopify CLI; v=${CLI_KIT_VERSION}`\n\n const headers: {[header: string]: string} = {\n 'User-Agent': userAgent,\n 'Keep-Alive': 'timeout=30',\n // 'Sec-CH-UA': secCHUA, This header requires the Git sha.\n 'Sec-CH-UA-PLATFORM': process.platform,\n 'Content-Type': 'application/json',\n ...(firstPartyDev() && {'X-Shopify-Cli-Employee': '1'}),\n }\n if (token) {\n const authString = token.match(/^shp(at|ua|ca)/) ? token : `Bearer ${token}`\n // eslint-disable-next-line dot-notation\n headers['authorization'] = authString\n headers['X-Shopify-Access-Token'] = authString\n }\n\n return headers\n}\n\n/**\n * This utility function returns the https.Agent to use for a given service. The agent\n * includes the right configuration based on the service's environment. For example,\n * if the service is running in a Spin environment, the attribute \"rejectUnauthorized\" is\n * set to false\n */\nexport async function httpsAgent(): Promise<https.Agent> {\n return new https.Agent({\n rejectUnauthorized: await shouldRejectUnauthorizedRequests(),\n keepAlive: true,\n })\n}\n\n/**\n * Spin stores the CA certificate in the keychain and it should be used when sending HTTP\n * requests to Spin instances. However, Node doesn't read certificates from the Keychain\n * by default, which leads to Shopifolks running into issues that they workaround by setting the\n * NODE_TLS_REJECT_UNAUTHORIZED=0 environment variable, which applies to all the HTTP\n * requests sent from the CLI (context: https://github.com/nodejs/node/issues/39657)\n * This utility function allows controlling the behavior in a per-service level by returning\n * the value of for the \"rejectUnauthorized\" attribute that's used in the https agent.\n *\n * @returns A promise that resolves with a boolean indicating whether\n * unauthorized requests should be rejected or not.\n */\nasync function shouldRejectUnauthorizedRequests(): Promise<boolean> {\n return (await serviceEnvironment()) !== Environment.Spin\n}\n"]}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
1
2
|
import { AdminSession } from '@shopify/cli-kit/node/session';
|
|
2
3
|
export declare function restRequestBody<T>(requestBody?: T): string | undefined;
|
|
3
4
|
export declare function restRequestUrl(session: AdminSession, apiVersion: string, path: string, searchParams?: {
|
|
4
5
|
[name: string]: string;
|
|
5
|
-
}): string;
|
|
6
|
+
}, env?: NodeJS.ProcessEnv): string;
|
|
6
7
|
export declare function restRequestHeaders(session: AdminSession): {
|
|
7
8
|
[key: string]: string;
|
|
8
9
|
};
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { buildHeaders } from './headers.js';
|
|
2
|
+
import { defaultThemeKitAccessDomain, environmentVariables } from '../constants.js';
|
|
2
3
|
export function restRequestBody(requestBody) {
|
|
3
4
|
if (!requestBody) {
|
|
4
5
|
return;
|
|
5
6
|
}
|
|
6
7
|
return JSON.stringify(requestBody);
|
|
7
8
|
}
|
|
8
|
-
export function restRequestUrl(session, apiVersion, path, searchParams = {}) {
|
|
9
|
+
export function restRequestUrl(session, apiVersion, path, searchParams = {}, env = process.env) {
|
|
10
|
+
const themeKitAccessDomain = env[environmentVariables.themeKitAccessDomain] || defaultThemeKitAccessDomain;
|
|
9
11
|
const url = new URL(isThemeAccessSession(session)
|
|
10
|
-
? `https
|
|
12
|
+
? `https://${themeKitAccessDomain}/cli/admin/api/${apiVersion}${path}.json`
|
|
11
13
|
: `https://${session.storeFqdn}/admin/api/${apiVersion}${path}.json`);
|
|
12
14
|
Object.entries(searchParams).forEach(([name, value]) => url.searchParams.set(name, value));
|
|
13
15
|
return url.toString();
|
|
@@ -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;
|
|
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,2BAA2B,EAAE,oBAAoB,EAAC,MAAM,iBAAiB,CAAA;AAGjF,MAAM,UAAU,eAAe,CAAI,WAAe;IAChD,IAAI,CAAC,WAAW,EAAE;QAChB,OAAM;KACP;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAA;AACpC,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,OAAqB,EACrB,UAAkB,EAClB,IAAY,EACZ,eAAyC,EAAE,EAC3C,GAAG,GAAG,OAAO,CAAC,GAAG;IAEjB,MAAM,oBAAoB,GAAG,GAAG,CAAC,oBAAoB,CAAC,oBAAoB,CAAC,IAAI,2BAA2B,CAAA;IAC1G,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,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAA;IAE1F,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;QACjC,OAAO,CAAC,gBAAgB,CAAC,GAAG,KAAK,CAAA;QACjC,OAAO,CAAC,wBAAwB,CAAC,GAAG,KAAK,CAAA;KAC1C;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,SAAS,oBAAoB,CAAC,OAAqB;IACjD,OAAO,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;AAC5C,CAAC","sourcesContent":["import {buildHeaders} from './headers.js'\nimport {defaultThemeKitAccessDomain, environmentVariables} from '../constants.js'\nimport {AdminSession} from '@shopify/cli-kit/node/session'\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 env = process.env,\n) {\n const themeKitAccessDomain = env[environmentVariables.themeKitAccessDomain] || defaultThemeKitAccessDomain\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]) => url.searchParams.set(name, value))\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\nfunction isThemeAccessSession(session: AdminSession) {\n return session.token.startsWith('shptka_')\n}\n"]}
|
|
@@ -28,7 +28,9 @@ export declare const environmentVariables: {
|
|
|
28
28
|
identityToken: string;
|
|
29
29
|
refreshToken: string;
|
|
30
30
|
otelURL: string;
|
|
31
|
+
themeKitAccessDomain: string;
|
|
31
32
|
};
|
|
33
|
+
export declare const defaultThemeKitAccessDomain = "theme-kit-access.shopifyapps.com";
|
|
32
34
|
export declare const systemEnvironmentVariables: {
|
|
33
35
|
backendPort: string;
|
|
34
36
|
};
|
|
@@ -46,9 +48,6 @@ export declare const pathConstants: {
|
|
|
46
48
|
};
|
|
47
49
|
};
|
|
48
50
|
};
|
|
49
|
-
export declare const keychainConstants: {
|
|
50
|
-
service: string;
|
|
51
|
-
};
|
|
52
51
|
export declare const sessionConstants: {
|
|
53
52
|
expirationTimeMarginInMinutes: number;
|
|
54
53
|
};
|
|
@@ -37,7 +37,9 @@ export const environmentVariables = {
|
|
|
37
37
|
identityToken: 'SHOPIFY_CLI_IDENTITY_TOKEN',
|
|
38
38
|
refreshToken: 'SHOPIFY_CLI_REFRESH_TOKEN',
|
|
39
39
|
otelURL: 'SHOPIFY_CLI_OTEL_EXPORTER_OTLP_ENDPOINT',
|
|
40
|
+
themeKitAccessDomain: 'SHOPIFY_CLI_THEME_KIT_ACCESS_DOMAIN',
|
|
40
41
|
};
|
|
42
|
+
export const defaultThemeKitAccessDomain = 'theme-kit-access.shopifyapps.com';
|
|
41
43
|
export const systemEnvironmentVariables = {
|
|
42
44
|
backendPort: 'BACKEND_PORT',
|
|
43
45
|
};
|
|
@@ -61,9 +63,6 @@ export const pathConstants = {
|
|
|
61
63
|
},
|
|
62
64
|
},
|
|
63
65
|
};
|
|
64
|
-
export const keychainConstants = {
|
|
65
|
-
service: 'shopify-cli',
|
|
66
|
-
};
|
|
67
66
|
export const sessionConstants = {
|
|
68
67
|
expirationTimeMarginInMinutes: 4,
|
|
69
68
|
};
|
|
@@ -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,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,eAAe,EAAE,+BAA+B;IAChD,eAAe,EAAE,+BAA+B;IAChD,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;
|
|
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,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,eAAe,EAAE,+BAA+B;IAChD,eAAe,EAAE,+BAA+B;IAChD,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;CAC5D,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","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 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 noThemeBundling: 'SHOPIFY_CLI_NO_THEME_BUNDLING',\n bundledThemeCLI: 'SHOPIFY_CLI_BUNDLED_THEME_CLI',\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}\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"]}
|
|
@@ -27,7 +27,7 @@ export async function authorize(scopes, state = randomHex(30)) {
|
|
|
27
27
|
code_challenge_method: 'S256',
|
|
28
28
|
code_challenge: codeChallenge,
|
|
29
29
|
};
|
|
30
|
-
outputInfo('\nTo run this command, log in to Shopify
|
|
30
|
+
outputInfo('\nTo run this command, log in to Shopify.');
|
|
31
31
|
outputInfo('👉 Press any key to open the login page on your browser');
|
|
32
32
|
await keypress();
|
|
33
33
|
url = `${url}?${new URLSearchParams(params).toString()}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorize.js","sourceRoot":"","sources":["../../../../src/private/node/session/authorize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,eAAe,CAAA;AACtC,OAAO,EAAC,cAAc,EAAC,MAAM,wBAAwB,CAAA;AACrD,OAAO,EAAC,eAAe,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAC,MAAM,gCAAgC,CAAA;AAC9F,OAAO,EAAC,OAAO,EAAC,MAAM,gCAAgC,CAAA;AACtD,OAAO,EAAC,UAAU,EAAE,eAAe,EAAC,MAAM,+BAA+B,CAAA;AACzE,OAAO,EAAC,YAAY,EAAC,MAAM,sCAAsC,CAAA;AACjE,OAAO,EAAC,QAAQ,EAAE,wBAAwB,EAAC,MAAM,4BAA4B,CAAA;AAC7E,OAAO,EAAC,UAAU,EAAC,MAAM,gCAAgC,CAAA;AACzD,OAAO,EAAC,YAAY,EAAC,MAAM,kCAAkC,CAAA;AAC7D,OAAO,EAAC,SAAS,IAAI,eAAe,EAAC,MAAM,iBAAiB,CAAA;AAC5D,OAAO,WAAW,MAAM,cAAc,CAAA;AAOtC,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAAgB,EAAE,QAAgB,SAAS,CAAC,EAAE,CAAC;IAC7E,MAAM,IAAI,GAAG,IAAI,CAAA;IACjB,MAAM,IAAI,GAAG,WAAW,CAAA;IACxB,MAAM,WAAW,GAAG,UAAU,IAAI,IAAI,IAAI,EAAE,CAAA;IAC5C,MAAM,IAAI,GAAG,MAAM,YAAY,EAAE,CAAA;IACjC,MAAM,gBAAgB,GAAG,QAAQ,EAAE,CAAA;IAEnC,MAAM,mCAAmC,CAAC,IAAI,CAAC,CAAA;IAE/C,IAAI,GAAG,GAAG,UAAU,IAAI,kBAAkB,CAAA;IAE1C,MAAM,EAAC,YAAY,EAAE,aAAa,EAAC,GAAG,2BAA2B,EAAE,CAAA;IAEnE,MAAM,MAAM,GAAG;QACb,SAAS,EAAE,gBAAgB;QAC3B,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QACvB,YAAY,EAAE,WAAW;QACzB,KAAK;QACL,aAAa,EAAE,MAAM;QACrB,qBAAqB,EAAE,MAAM;QAC7B,cAAc,EAAE,aAAa;KAC9B,CAAA;IAED,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"authorize.js","sourceRoot":"","sources":["../../../../src/private/node/session/authorize.ts"],"names":[],"mappings":"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","sourcesContent":["import {clientId} from './identity.js'\nimport {listenRedirect} from './redirect-listener.js'\nimport {base64URLEncode, randomBytes, randomHex, sha256} from '../../../public/node/crypto.js'\nimport {openURL} from '../../../public/node/system.js'\nimport {AbortError, CancelExecution} from '../../../public/node/error.js'\nimport {identityFqdn} from '../../../public/node/context/fqdn.js'\nimport {keypress, renderConfirmationPrompt} from '../../../public/node/ui.js'\nimport {outputInfo} from '../../../public/node/output.js'\nimport {runWithTimer} from '../../../public/node/metadata.js'\nimport {checkPort as isPortAvailable} from 'get-port-please'\nimport findProcess from 'find-process'\n\nexport interface CodeAuthResult {\n code: string\n codeVerifier: string\n}\n\nexport async function authorize(scopes: string[], state: string = randomHex(30)): Promise<CodeAuthResult> {\n const port = 3456\n const host = '127.0.0.1'\n const redirectUri = `http://${host}:${port}`\n const fqdn = await identityFqdn()\n const identityClientId = clientId()\n\n await validateRedirectionPortAvailability(port)\n\n let url = `http://${fqdn}/oauth/authorize`\n\n const {codeVerifier, codeChallenge} = generateRandomChallengePair()\n\n const params = {\n client_id: identityClientId,\n scope: scopes.join(' '),\n redirect_uri: redirectUri,\n state,\n response_type: 'code',\n code_challenge_method: 'S256',\n code_challenge: codeChallenge,\n }\n\n outputInfo('\\nTo run this command, log in to Shopify.')\n outputInfo('👉 Press any key to open the login page on your browser')\n await keypress()\n\n url = `${url}?${new URLSearchParams(params).toString()}`\n await openURL(url)\n\n return runWithTimer('cmd_all_timing_prompts_ms')(async () => {\n const result = await listenRedirect(host, port, url)\n\n if (result.state !== state) {\n throw new AbortError(\n \"The state received from the authentication doesn't match the one that initiated the authentication process.\",\n )\n }\n\n return {code: result.code, codeVerifier}\n })\n}\n\nfunction generateRandomChallengePair() {\n const codeVerifier = base64URLEncode(randomBytes(32))\n const codeChallenge = base64URLEncode(sha256(codeVerifier))\n return {codeVerifier, codeChallenge}\n}\n\nasync function validateRedirectionPortAvailability(port: number) {\n const {killPortProcess} = await import('kill-port-process')\n\n if (await isPortAvailable(port)) {\n return\n }\n\n if (await terminateBlockingPortProcessPrompt(port, 'Authentication')) {\n await killPortProcess(port)\n } else {\n throw new CancelExecution()\n }\n}\n\nasync function terminateBlockingPortProcessPrompt(port: number, stepDescription: string): Promise<boolean> {\n const processInfo = await findProcess('port', port)\n const formattedProcessName =\n processInfo && processInfo.length > 0 && processInfo[0]?.name ? ` (${processInfo[0].name})` : ''\n\n return renderConfirmationPrompt({\n message: `${stepDescription} requires a port ${port} that's unavailable because it's running another process${formattedProcessName}. Terminate that process?`,\n confirmationMessage: 'Yes, terminate process in order to log in now',\n cancellationMessage: `No, cancel command and try later`,\n })\n}\n"]}
|
|
@@ -30,7 +30,7 @@ export async function requestDeviceAuthorization(scopes) {
|
|
|
30
30
|
if (!jsonResult.device_code || !jsonResult.verification_uri_complete) {
|
|
31
31
|
throw new BugError('Failed to start authorization process');
|
|
32
32
|
}
|
|
33
|
-
outputInfo('\nTo run this command, log in to Shopify
|
|
33
|
+
outputInfo('\nTo run this command, log in to Shopify.');
|
|
34
34
|
outputInfo(outputContent `User verification code: ${jsonResult.user_code}`);
|
|
35
35
|
outputInfo(outputContent `👉 Open this link to start the auth process: ${outputToken.green(jsonResult.verification_uri_complete)}`);
|
|
36
36
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"device-authorization.js","sourceRoot":"","sources":["../../../../src/private/node/session/device-authorization.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,eAAe,CAAA;AACtC,OAAO,EAAC,gCAAgC,EAAC,MAAM,eAAe,CAAA;AAE9D,OAAO,EAAC,YAAY,EAAC,MAAM,sCAAsC,CAAA;AACjE,OAAO,EAAC,YAAY,EAAC,MAAM,8BAA8B,CAAA;AACzD,OAAO,EAAC,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAC,MAAM,gCAAgC,CAAA;AAClG,OAAO,EAAC,QAAQ,EAAC,MAAM,+BAA+B,CAAA;AAWtD;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,MAAgB;IAC/D,MAAM,IAAI,GAAG,MAAM,YAAY,EAAE,CAAA;IACjC,MAAM,gBAAgB,GAAG,MAAM,QAAQ,EAAE,CAAA;IACzC,MAAM,WAAW,GAAG,EAAC,SAAS,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAC,CAAA;IAC1E,MAAM,GAAG,GAAG,WAAW,IAAI,6BAA6B,CAAA;IAExD,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE;QACvC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAC,cAAc,EAAE,mCAAmC,EAAC;QAC9D,IAAI,EAAE,sBAAsB,CAAC,WAAW,CAAC;KAC1C,CAAC,CAAA;IAEF,8DAA8D;IAC9D,MAAM,UAAU,GAAQ,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;IAE7C,WAAW,CAAC,aAAa,CAAA,uCAAuC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;IAC/F,IAAI,CAAC,UAAU,CAAC,WAAW,IAAI,CAAC,UAAU,CAAC,yBAAyB,EAAE;QACpE,MAAM,IAAI,QAAQ,CAAC,uCAAuC,CAAC,CAAA;KAC5D;IAED,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"device-authorization.js","sourceRoot":"","sources":["../../../../src/private/node/session/device-authorization.ts"],"names":[],"mappings":"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","sourcesContent":["import {clientId} from './identity.js'\nimport {exchangeDeviceCodeForAccessToken} from './exchange.js'\nimport {IdentityToken} from './schema.js'\nimport {identityFqdn} from '../../../public/node/context/fqdn.js'\nimport {shopifyFetch} from '../../../public/node/http.js'\nimport {outputContent, outputDebug, outputInfo, outputToken} from '../../../public/node/output.js'\nimport {BugError} from '../../../public/node/error.js'\n\nexport interface DeviceAuthorizationResponse {\n deviceCode: string\n userCode: string\n verificationUri: string\n expiresIn: number\n verificationUriComplete?: string\n interval?: number\n}\n\n/**\n * Initiate a device authorization flow.\n * This will return a DeviceAuthorizationResponse containing the URL where user\n * should go to authorize the device without the need of a callback to the CLI.\n *\n * Also returns a `deviceCode` used for polling the token endpoint in the next step.\n *\n * @param scopes - The scopes to request\n * @returns An object with the device authorization response.\n */\nexport async function requestDeviceAuthorization(scopes: string[]): Promise<DeviceAuthorizationResponse> {\n const fqdn = await identityFqdn()\n const identityClientId = await clientId()\n const queryParams = {client_id: identityClientId, scope: scopes.join(' ')}\n const url = `https://${fqdn}/oauth/device_authorization`\n\n const response = await shopifyFetch(url, {\n method: 'POST',\n headers: {'Content-type': 'application/x-www-form-urlencoded'},\n body: convertRequestToParams(queryParams),\n })\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const jsonResult: any = await response.json()\n\n outputDebug(outputContent`Received device authorization code: ${outputToken.json(jsonResult)}`)\n if (!jsonResult.device_code || !jsonResult.verification_uri_complete) {\n throw new BugError('Failed to start authorization process')\n }\n\n outputInfo('\\nTo run this command, log in to Shopify.')\n outputInfo(outputContent`User verification code: ${jsonResult.user_code}`)\n outputInfo(\n outputContent`👉 Open this link to start the auth process: ${outputToken.green(\n jsonResult.verification_uri_complete,\n )}`,\n )\n\n return {\n deviceCode: jsonResult.device_code,\n userCode: jsonResult.user_code,\n verificationUri: jsonResult.verification_uri,\n expiresIn: jsonResult.expires_in,\n verificationUriComplete: jsonResult.verification_uri_complete,\n interval: jsonResult.interval,\n }\n}\n\n/**\n * Poll the Oauth token endpoint with the device code obtained from a DeviceAuthorizationResponse.\n * The endpoint will return `authorization_pending` until the user completes the auth flow in the browser.\n * Once the user completes the auth flow, the endpoint will return the identity token.\n *\n * Timeout for the polling is defined by the server and is around 600 seconds.\n *\n * @param code - The device code obtained after starting a device identity flow\n * @param interval - The interval to poll the token endpoint\n * @returns The identity token\n */\nexport async function pollForDeviceAuthorization(code: string, interval = 5): Promise<IdentityToken> {\n let currentIntervalInSeconds = interval\n\n return new Promise<IdentityToken>((resolve, reject) => {\n const onPoll = async () => {\n const result = await exchangeDeviceCodeForAccessToken(code)\n if (!result.isErr()) return resolve(result.value)\n\n const error = result.error ?? 'unknown_failure'\n\n outputDebug(outputContent`Polling for device authorization... status: ${error}`)\n switch (error) {\n case 'authorization_pending':\n return startPolling()\n case 'slow_down':\n currentIntervalInSeconds += 5\n return startPolling()\n case 'access_denied':\n case 'expired_token':\n case 'unknown_failure':\n return reject(result)\n }\n }\n\n const startPolling = () => {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n setTimeout(onPoll, currentIntervalInSeconds * 1000)\n }\n\n startPolling()\n })\n}\n\nfunction convertRequestToParams(queryParams: {client_id: string; scope: string}): string {\n return Object.entries(queryParams)\n .map(([key, value]) => value && `${key}=${value}`)\n .filter((hasValue) => Boolean(hasValue))\n .join('&')\n}\n"]}
|
|
@@ -39,7 +39,7 @@ export declare function refreshAccessToken(currentToken: IdentityToken): Promise
|
|
|
39
39
|
* @returns An instance with the application access tokens.
|
|
40
40
|
*/
|
|
41
41
|
export declare function exchangeCustomPartnerToken(token: string): Promise<ApplicationToken>;
|
|
42
|
-
|
|
42
|
+
type IdentityDeviceError = 'authorization_pending' | 'access_denied' | 'expired_token' | 'slow_down' | 'unknown_failure';
|
|
43
43
|
/**
|
|
44
44
|
* Given a deviceCode obtained after starting a device identity flow, request an identity token.
|
|
45
45
|
* @param deviceCode - The device code obtained after starting a device identity flow
|
|
@@ -47,3 +47,4 @@ export type IdentityDeviceError = 'authorization_pending' | 'access_denied' | 'e
|
|
|
47
47
|
* @returns An instance with the identity access tokens.
|
|
48
48
|
*/
|
|
49
49
|
export declare function exchangeDeviceCodeForAccessToken(deviceCode: string): Promise<Result<IdentityToken, IdentityDeviceError>>;
|
|
50
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
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 {CodeAuthResult} from './authorize.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, ExtendableError} from '../../../public/node/error.js'\n\nexport class InvalidGrantError extends ExtendableError {}\nexport class InvalidRequestError extends ExtendableError {}\n\nexport interface ExchangeScopes {\n admin: string[]\n partners: string[]\n storefront: string[]\n businessPlatform: string[]\n}\n/**\n * Given a valid authorization code, request an identity access token.\n * This token can then be used to get API specific tokens.\n * @param codeData - code and codeVerifier from the authorize endpoint\n * @returns An instance with the identity access tokens.\n */\nexport async function exchangeCodeForAccessToken(codeData: CodeAuthResult): Promise<IdentityToken> {\n const clientId = await getIdentityClientId()\n const params = {\n grant_type: 'authorization_code',\n code: codeData.code,\n redirect_uri: 'http://127.0.0.1:3456',\n client_id: clientId,\n code_verifier: codeData.codeVerifier,\n }\n\n const tokenResult = await tokenRequest(params)\n const value = tokenResult.mapError(tokenRequestErrorHandler).valueOrBug()\n return buildIdentityToken(value)\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] = 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 ])\n\n return {\n ...partners,\n ...storefront,\n ...businessPlatform,\n ...admin,\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)\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\n * @returns An instance with the application access tokens.\n */\nexport async function exchangeCustomPartnerToken(token: string): Promise<ApplicationToken> {\n const appId = applicationId('partners')\n try {\n const newToken = await requestAppToken('partners', token, ['https://api.shopify.com/auth/partners.app.cli.access'])\n return newToken[appId]!\n } catch (error) {\n throw new AbortError('The custom token provided is invalid.', 'Ensure the token is correct and not expired.')\n }\n}\n\nexport type IdentityDeviceError =\n | 'authorization_pending'\n | 'access_denied'\n | 'expired_token'\n | 'slow_down'\n | '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 as IdentityDeviceError)\n }\n const identityToken = buildIdentityToken(tokenResult.value)\n return ok(identityToken)\n}\n\nasync 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`}),\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 = await 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}\n\nfunction tokenRequestErrorHandler(error: string) {\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 // eslint-disable-next-line @shopify/cli/no-error-factory-functions\n return new AbortError(error)\n}\n\nasync function tokenRequest(params: {[key: string]: string}): Promise<Result<TokenRequestResult, 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 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 return err(payload.error)\n}\n\nfunction buildIdentityToken(result: TokenRequestResult): IdentityToken {\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 }\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 {CodeAuthResult} from './authorize.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, ExtendableError} from '../../../public/node/error.js'\n\nexport class InvalidGrantError extends ExtendableError {}\nexport class InvalidRequestError extends ExtendableError {}\n\nexport interface ExchangeScopes {\n admin: string[]\n partners: string[]\n storefront: string[]\n businessPlatform: string[]\n}\n/**\n * Given a valid authorization code, request an identity access token.\n * This token can then be used to get API specific tokens.\n * @param codeData - code and codeVerifier from the authorize endpoint\n * @returns An instance with the identity access tokens.\n */\nexport async function exchangeCodeForAccessToken(codeData: CodeAuthResult): Promise<IdentityToken> {\n const clientId = await getIdentityClientId()\n const params = {\n grant_type: 'authorization_code',\n code: codeData.code,\n redirect_uri: 'http://127.0.0.1:3456',\n client_id: clientId,\n code_verifier: codeData.codeVerifier,\n }\n\n const tokenResult = await tokenRequest(params)\n const value = tokenResult.mapError(tokenRequestErrorHandler).valueOrBug()\n return buildIdentityToken(value)\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] = 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 ])\n\n return {\n ...partners,\n ...storefront,\n ...businessPlatform,\n ...admin,\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)\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\n * @returns An instance with the application access tokens.\n */\nexport async function exchangeCustomPartnerToken(token: string): Promise<ApplicationToken> {\n const appId = applicationId('partners')\n try {\n const newToken = await requestAppToken('partners', token, ['https://api.shopify.com/auth/partners.app.cli.access'])\n return newToken[appId]!\n } catch (error) {\n throw new AbortError('The custom token provided is invalid.', 'Ensure the token is correct and not expired.')\n }\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 as IdentityDeviceError)\n }\n const identityToken = buildIdentityToken(tokenResult.value)\n return ok(identityToken)\n}\n\nasync 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`}),\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 = await 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}\n\nfunction tokenRequestErrorHandler(error: string) {\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 // eslint-disable-next-line @shopify/cli/no-error-factory-functions\n return new AbortError(error)\n}\n\nasync function tokenRequest(params: {[key: string]: string}): Promise<Result<TokenRequestResult, 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 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 return err(payload.error)\n}\n\nfunction buildIdentityToken(result: TokenRequestResult): IdentityToken {\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 }\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,4 +1,3 @@
|
|
|
1
|
-
import { BugError } from '../../../public/node/error.js';
|
|
2
1
|
export declare const getEmptyUrlHTML: () => Promise<string>;
|
|
3
2
|
export declare const getAuthErrorHTML: () => Promise<string>;
|
|
4
3
|
export declare const getMissingCodeHTML: () => Promise<string>;
|
|
@@ -7,7 +6,5 @@ export declare const getSuccessHTML: () => Promise<string>;
|
|
|
7
6
|
export declare const getStylesheet: () => Promise<string>;
|
|
8
7
|
export declare const getFavicon: () => Promise<string>;
|
|
9
8
|
export declare const EmptyUrlString = "We received the authentication redirect but the URL is empty.";
|
|
10
|
-
export declare const AuthErrorString = "There was an issue while trying to authenticate.";
|
|
11
9
|
export declare const MissingCodeString = "The authentication can't continue because the redirect doesn't include the code.";
|
|
12
10
|
export declare const MissingStateString = "The authentication can't continue because the redirect doesn't include the state.";
|
|
13
|
-
export declare const RedirectPageAssetNotFoundError: () => BugError;
|
|
@@ -55,8 +55,7 @@ export const getFavicon = async () => {
|
|
|
55
55
|
return readFile(filePath);
|
|
56
56
|
};
|
|
57
57
|
export const EmptyUrlString = 'We received the authentication redirect but the URL is empty.';
|
|
58
|
-
export const AuthErrorString = 'There was an issue while trying to authenticate.';
|
|
59
58
|
export const MissingCodeString = "The authentication can't continue because the redirect doesn't include the code.";
|
|
60
59
|
export const MissingStateString = "The authentication can't continue because the redirect doesn't include the state.";
|
|
61
|
-
|
|
60
|
+
const RedirectPageAssetNotFoundError = () => new BugError(`Redirect page asset not found`);
|
|
62
61
|
//# sourceMappingURL=post-auth.js.map
|