@shopify/cli-kit 3.68.0 → 3.69.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/api/graphql/admin/generated/public_api_versions.d.ts +14 -0
- package/dist/cli/api/graphql/admin/generated/public_api_versions.js +28 -0
- package/dist/cli/api/graphql/admin/generated/public_api_versions.js.map +1 -0
- package/dist/private/node/api/graphql.d.ts +1 -1
- package/dist/private/node/api/graphql.js +1 -0
- package/dist/private/node/api/graphql.js.map +1 -1
- package/dist/private/node/api/headers.js +2 -2
- package/dist/private/node/api/headers.js.map +1 -1
- package/dist/private/node/api/rest.js +3 -1
- package/dist/private/node/api/rest.js.map +1 -1
- package/dist/private/node/api.d.ts +2 -2
- package/dist/private/node/api.js +8 -6
- package/dist/private/node/api.js.map +1 -1
- package/dist/private/node/constants.d.ts +0 -1
- package/dist/private/node/constants.js +0 -1
- package/dist/private/node/constants.js.map +1 -1
- package/dist/private/node/demo-recorder.js +1 -0
- package/dist/private/node/demo-recorder.js.map +1 -1
- package/dist/private/node/session/device-authorization.js +15 -7
- package/dist/private/node/session/device-authorization.js.map +1 -1
- package/dist/private/node/session/exchange.d.ts +0 -8
- package/dist/private/node/session/exchange.js +2 -19
- package/dist/private/node/session/exchange.js.map +1 -1
- package/dist/private/node/session/validate.js +1 -0
- package/dist/private/node/session/validate.js.map +1 -1
- package/dist/private/node/session.d.ts +5 -5
- package/dist/private/node/session.js +4 -12
- package/dist/private/node/session.js.map +1 -1
- package/dist/private/node/testing/ui.js +0 -3
- package/dist/private/node/testing/ui.js.map +1 -1
- package/dist/private/node/themes/generate-theme-name.js +1 -0
- package/dist/private/node/themes/generate-theme-name.js.map +1 -1
- package/dist/private/node/ui/components/AutocompletePrompt.test.js +0 -3
- package/dist/private/node/ui/components/AutocompletePrompt.test.js.map +1 -1
- package/dist/private/node/ui/components/Banner.js +1 -0
- package/dist/private/node/ui/components/Banner.js.map +1 -1
- package/dist/private/node/ui/components/ConcurrentOutput.test.js +7 -7
- package/dist/private/node/ui/components/ConcurrentOutput.test.js.map +1 -1
- package/dist/private/node/ui/components/FatalError.js +1 -0
- package/dist/private/node/ui/components/FatalError.js.map +1 -1
- package/dist/private/node/ui/components/List.js +1 -1
- package/dist/private/node/ui/components/List.js.map +1 -1
- package/dist/private/node/ui/components/Prompts/InfoTable.js +1 -0
- package/dist/private/node/ui/components/Prompts/InfoTable.js.map +1 -1
- package/dist/private/node/ui/components/SelectInput.js +1 -1
- package/dist/private/node/ui/components/SelectInput.js.map +1 -1
- package/dist/private/node/ui/components/SelectPrompt.test.js +0 -4
- package/dist/private/node/ui/components/SelectPrompt.test.js.map +1 -1
- package/dist/private/node/ui/components/Table/Row.js.map +1 -1
- package/dist/private/node/ui/components/Tasks.js +2 -1
- package/dist/private/node/ui/components/Tasks.js.map +1 -1
- package/dist/private/node/ui/components/TextPrompt.d.ts +1 -1
- package/dist/private/node/ui/components/TextPrompt.js.map +1 -1
- package/dist/private/node/ui/components/TokenizedText.js +1 -0
- package/dist/private/node/ui/components/TokenizedText.js.map +1 -1
- package/dist/private/node/ui/hooks/use-abort-signal.js +1 -1
- package/dist/private/node/ui/hooks/use-abort-signal.js.map +1 -1
- package/dist/private/node/ui.js +3 -1
- package/dist/private/node/ui.js.map +1 -1
- package/dist/public/common/array.js +1 -0
- package/dist/public/common/array.js.map +1 -1
- package/dist/public/common/string.js +3 -0
- package/dist/public/common/string.js.map +1 -1
- package/dist/public/common/version.d.ts +1 -1
- package/dist/public/common/version.js +1 -1
- package/dist/public/common/version.js.map +1 -1
- package/dist/public/node/api/admin.d.ts +14 -1
- package/dist/public/node/api/admin.js +29 -28
- package/dist/public/node/api/admin.js.map +1 -1
- package/dist/public/node/api/app-management.d.ts +5 -3
- package/dist/public/node/api/app-management.js +16 -11
- package/dist/public/node/api/app-management.js.map +1 -1
- package/dist/public/node/api/graphql.js +13 -1
- package/dist/public/node/api/graphql.js.map +1 -1
- package/dist/public/node/api/rest-api-throttler.js +10 -3
- package/dist/public/node/api/rest-api-throttler.js.map +1 -1
- package/dist/public/node/archiver.js +6 -2
- package/dist/public/node/archiver.js.map +1 -1
- package/dist/public/node/base-command.js +1 -1
- package/dist/public/node/base-command.js.map +1 -1
- package/dist/public/node/context/local.d.ts +0 -9
- package/dist/public/node/context/local.js +0 -13
- package/dist/public/node/context/local.js.map +1 -1
- package/dist/public/node/context/spin.js +1 -1
- package/dist/public/node/context/spin.js.map +1 -1
- package/dist/public/node/custom-oclif-loader.js +5 -4
- package/dist/public/node/custom-oclif-loader.js.map +1 -1
- package/dist/public/node/dot-env.js +2 -1
- package/dist/public/node/dot-env.js.map +1 -1
- package/dist/public/node/environments.js +1 -1
- package/dist/public/node/environments.js.map +1 -1
- package/dist/public/node/error-handler.js +1 -1
- package/dist/public/node/error-handler.js.map +1 -1
- package/dist/public/node/framework.js +5 -4
- package/dist/public/node/framework.js.map +1 -1
- package/dist/public/node/fs.d.ts +2 -1
- package/dist/public/node/fs.js +2 -2
- package/dist/public/node/fs.js.map +1 -1
- package/dist/public/node/git.js +2 -0
- package/dist/public/node/git.js.map +1 -1
- package/dist/public/node/github.js +2 -0
- package/dist/public/node/github.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/hooks/postrun.js +2 -1
- package/dist/public/node/hooks/postrun.js.map +1 -1
- package/dist/public/node/hooks/prerun.js +1 -1
- package/dist/public/node/hooks/prerun.js.map +1 -1
- package/dist/public/node/http.js +2 -1
- package/dist/public/node/http.js.map +1 -1
- package/dist/public/node/json-schema.d.ts +1 -1
- package/dist/public/node/json-schema.js.map +1 -1
- package/dist/public/node/liquid.js +12 -2
- package/dist/public/node/liquid.js.map +1 -1
- package/dist/public/node/local-storage.d.ts +1 -1
- package/dist/public/node/local-storage.js.map +1 -1
- package/dist/public/node/metadata.js +1 -0
- package/dist/public/node/metadata.js.map +1 -1
- package/dist/public/node/monorail.d.ts +2 -1
- package/dist/public/node/monorail.js +1 -1
- package/dist/public/node/monorail.js.map +1 -1
- package/dist/public/node/output.js +2 -1
- package/dist/public/node/output.js.map +1 -1
- package/dist/public/node/ruby.js +1 -0
- package/dist/public/node/ruby.js.map +1 -1
- package/dist/public/node/session.d.ts +7 -6
- package/dist/public/node/session.js +2 -1
- package/dist/public/node/session.js.map +1 -1
- package/dist/public/node/system.js +1 -1
- package/dist/public/node/system.js.map +1 -1
- package/dist/public/node/themes/api.js +34 -4
- package/dist/public/node/themes/api.js.map +1 -1
- package/dist/public/node/themes/factories.js +1 -0
- package/dist/public/node/themes/factories.js.map +1 -1
- package/dist/public/node/themes/types.d.ts +2 -3
- package/dist/public/node/themes/types.js.map +1 -1
- package/dist/public/node/themes/urls.d.ts +1 -0
- package/dist/public/node/themes/urls.js +3 -0
- package/dist/public/node/themes/urls.js.map +1 -1
- package/dist/public/node/tree-kill.js +8 -4
- package/dist/public/node/tree-kill.js.map +1 -1
- package/dist/public/node/ui.js +5 -2
- package/dist/public/node/ui.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -5
- package/assets/auth-error.html +0 -23
- package/assets/empty-url.html +0 -23
- package/assets/favicon.svg +0 -26
- package/assets/missing-code.html +0 -23
- package/assets/missing-state.html +0 -23
- package/assets/style.css +0 -58
- package/assets/success.html +0 -20
- package/dist/private/node/session/authorize.d.ts +0 -5
- package/dist/private/node/session/authorize.js +0 -69
- package/dist/private/node/session/authorize.js.map +0 -1
- package/dist/private/node/session/post-auth.d.ts +0 -10
- package/dist/private/node/session/post-auth.js +0 -61
- package/dist/private/node/session/post-auth.js.map +0 -1
- package/dist/private/node/session/redirect-listener.d.ts +0 -34
- package/dist/private/node/session/redirect-listener.js +0 -105
- package/dist/private/node/session/redirect-listener.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"string.js","sourceRoot":"","sources":["../../../src/public/common/string.ts"],"names":[],"mappings":"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","sourcesContent":["import {takeRandomFromArray} from './array.js'\nimport {unstyled} from '../../public/node/output.js'\nimport {Token, TokenItem} from '../../private/node/ui/components/TokenizedText.js'\nimport {camelCase, constantCase, paramCase, snakeCase, pascalCase} from 'change-case'\n\nconst SAFE_RANDOM_BUSINESS_ADJECTIVES = [\n 'commercial',\n 'profitable',\n 'amortizable',\n 'branded',\n 'integrated',\n 'synergistic',\n 'consolidated',\n 'diversified',\n 'lean',\n 'niche',\n 'premium',\n 'luxury',\n 'scalable',\n 'optimized',\n 'empowered',\n 'international',\n 'beneficial',\n 'fruitful',\n 'extensive',\n 'lucrative',\n 'modern',\n 'stable',\n 'strategic',\n 'adaptive',\n 'efficient',\n 'growing',\n 'sustainable',\n 'innovative',\n 'regional',\n 'specialized',\n 'focused',\n 'pragmatic',\n 'ethical',\n 'flexible',\n 'competitive',\n]\n\nconst SAFE_RANDOM_CREATIVE_ADJECTIVES = [\n 'bright',\n 'impactful',\n 'stylish',\n 'colorful',\n 'modern',\n 'minimal',\n 'trendy',\n 'creative',\n 'artistic',\n 'spectacular',\n 'glamorous',\n 'luxury',\n 'retro',\n 'nostalgic',\n 'comfy',\n 'polished',\n 'fabulous',\n 'balanced',\n 'monochrome',\n 'glitched',\n 'contrasted',\n 'elegant',\n 'textured',\n 'vibrant',\n 'harmonious',\n 'versatile',\n 'eclectic',\n 'futuristic',\n 'idealistic',\n 'intricate',\n 'bohemian',\n 'abstract',\n 'meticulous',\n 'refined',\n 'flamboyant',\n]\n\nconst SAFE_RANDOM_BUSINESS_NOUNS = [\n 'account',\n 'consumer',\n 'customer',\n 'enterprise',\n 'business',\n 'venture',\n 'marketplace',\n 'revenue',\n 'vertical',\n 'portfolio',\n 'negotiation',\n 'shipping',\n 'demand',\n 'supply',\n 'growth',\n 'merchant',\n 'investment',\n 'shareholder',\n 'conversion',\n 'capital',\n 'projection',\n 'upside',\n 'trade',\n 'deal',\n 'merchandise',\n 'transaction',\n 'sale',\n 'franchise',\n 'subsidiary',\n 'logistics',\n 'infrastructure',\n 'sponsorship',\n 'partnership',\n 'tax',\n 'policy',\n 'outsource',\n 'equity',\n 'strategy',\n 'valuation',\n 'benchmark',\n 'metrics',\n 'duplication',\n]\n\nconst SAFE_RANDOM_CREATIVE_NOUNS = [\n 'vibe',\n 'style',\n 'moment',\n 'mood',\n 'flavor',\n 'look',\n 'appearance',\n 'perspective',\n 'aspect',\n 'ambience',\n 'quality',\n 'backdrop',\n 'focus',\n 'tone',\n 'inspiration',\n 'imagery',\n 'aesthetics',\n 'palette',\n 'ornamentation',\n 'contrast',\n 'colorway',\n 'visuals',\n 'typography',\n 'composition',\n 'scale',\n 'symmetry',\n 'gradients',\n 'proportions',\n 'textures',\n 'harmony',\n 'shapes',\n 'patterns',\n]\n\nexport type RandomNameFamily = 'business' | 'creative'\n\n/**\n * Generates a random name by combining an adjective and noun.\n *\n * @param family - Theme to use for the random name (business or creative).\n * @returns A random name generated by combining an adjective and noun.\n */\nexport function getRandomName(family: RandomNameFamily = 'business'): string {\n const mapping = {\n business: {\n adjectives: SAFE_RANDOM_BUSINESS_ADJECTIVES,\n nouns: SAFE_RANDOM_BUSINESS_NOUNS,\n },\n creative: {\n adjectives: SAFE_RANDOM_CREATIVE_ADJECTIVES,\n nouns: SAFE_RANDOM_CREATIVE_NOUNS,\n },\n }\n return `${takeRandomFromArray(mapping[family].adjectives)}-${takeRandomFromArray(mapping[family].nouns)}`\n}\n\n/**\n * Given a string, it returns it with the first letter capitalized.\n *\n * @param str - String to capitalize.\n * @returns String with the first letter capitalized.\n */\nexport function capitalize(str: string): string {\n return str.substring(0, 1).toUpperCase() + str.substring(1)\n}\n\n/**\n * Given a list of items, it returns a pluralized string based on the amount of items.\n *\n * @param items - List of items.\n * @param plural - Supplier used when the list of items has more than one item.\n * @param singular - Supplier used when the list of items has a single item.\n * @param none - Supplier used when the list has no items.\n * @returns The {@link TokenItem} supplied by the {@link plural}, {@link singular}, or {@link none} functions.\n */\nexport function pluralize<\n T,\n TToken extends Token = Token,\n TPluralToken extends TToken = TToken,\n TSingularToken extends TToken = TToken,\n TNoneToken extends TToken = TToken,\n>(\n items: T[],\n plural: (items: T[]) => TokenItem<TPluralToken>,\n singular: (item: T) => TokenItem<TSingularToken>,\n none?: () => TokenItem<TNoneToken>,\n): TokenItem<TPluralToken | TSingularToken | TNoneToken> | string {\n if (items.length === 1) {\n return singular(items[0]!)\n }\n\n if (items.length > 1) {\n return plural(items)\n }\n\n if (none) {\n return none()\n }\n\n return ''\n}\n\n/**\n * Try to convert a string to an int, falling back to undefined if unable to.\n *\n * @param maybeInt - String to convert to an int.\n * @returns The int if it was able to convert, otherwise undefined.\n */\nexport function tryParseInt(maybeInt: string | undefined): number | undefined {\n let asInt: number | undefined\n if (maybeInt !== undefined) {\n asInt = parseInt(maybeInt, 10)\n if (isNaN(asInt)) {\n asInt = undefined\n }\n }\n return asInt\n}\n\n/**\n * Transforms a matrix of strings into a single string with the columns aligned.\n *\n * @param lines - Array of rows, where each row is an array of strings (representing columns).\n * @returns A string with the columns aligned.\n */\nexport function linesToColumns(lines: string[][]): string {\n const widths: number[] = []\n for (let i = 0; lines[0] && i < lines[0].length; i++) {\n const columnRows = lines.map((line) => line[i]!)\n widths.push(Math.max(...columnRows.map((row) => unstyled(row).length)))\n }\n const paddedLines = lines\n .map((line) => {\n return line\n .map((col, index) => {\n return `${col}${' '.repeat(widths[index]! - unstyled(col).length)}`\n })\n .join(' ')\n .trimEnd()\n })\n .join('\\n')\n return paddedLines\n}\n\n/**\n * Given a string, it transforms it to a slug (lowercase, hyphenated, no special chars, trimmed...).\n *\n * @param str - String to slugify.\n * @returns The slugified string.\n */\nexport function slugify(str: string): string {\n return str\n .toLowerCase()\n .trim()\n .replace(/[^\\w\\s-]/g, '')\n .replace(/[\\s_-]+/g, '-')\n .replace(/^-+|-+$/g, '')\n}\n\n/**\n * Given a string, it returns it with the special regex characters escaped.\n * More info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping.\n *\n * @param str - String to escape.\n * @returns The escaped string.\n */\nexport function escapeRegExp(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\n/**\n * Transform a string to camelCase.\n *\n * @param input - String to escape.\n * @returns The escaped string.\n */\nexport function camelize(input: string): string {\n return camelCase(input)\n}\n\n/**\n * Transform a string to param-case.\n *\n * @param input - String to transform.\n * @returns The transformed string.\n */\nexport function hyphenate(input: string): string {\n return paramCase(input)\n}\n\n/**\n * Transform a string to snake_case.\n *\n * @param input - String to transform.\n * @returns The transformed string.\n */\nexport function underscore(input: string): string {\n return snakeCase(input)\n}\n\n/**\n * Transform a string to CONSTANT_CASE.\n *\n * @param input - String to transform.\n * @returns The transformed string.\n */\nexport function constantize(input: string): string {\n return constantCase(input)\n}\n\n/**\n * Given a date, return a formatted string like \"2021-01-01 12:00:00\".\n *\n * @param date - Date to format.\n * @returns The transformed string.\n */\nexport function formatDate(date: Date): string {\n const components = date.toISOString().split('T')\n const dateString = components[0] ?? date.toDateString()\n const timeString = components[1]?.split('.')[0] ?? date.toTimeString()\n return `${dateString} ${timeString}`\n}\n\n/**\n * Given a date in UTC ISO String format, return a formatted string in local time like \"2021-01-01 12:00:00\".\n *\n * @param dateString - UTC ISO Date String.\n * @returns The transformed string in local system time.\n */\nexport function formatLocalDate(dateString: string): string {\n const dateObj = new Date(dateString)\n const localDate = new Date(\n Date.UTC(\n dateObj.getFullYear(),\n dateObj.getMonth(),\n dateObj.getDate(),\n dateObj.getHours(),\n dateObj.getMinutes(),\n dateObj.getSeconds(),\n ),\n )\n return formatDate(localDate)\n}\n\n/**\n * Given a list of items, it returns a string with the items joined by commas and the last item joined by \"and\".\n * All items are wrapped in double quotes.\n * For example: [\"a\", \"b\", \"c\"] returns \"a\", \"b\" and \"c\".\n *\n * @param items - List of items.\n * @returns The joined string.\n */\nexport function joinWithAnd(items: string[]): string {\n if (items.length === 0) return ''\n if (items.length === 1) return `\"${items[0]}\"`\n\n return `${items\n .slice(0, -1)\n .map((item) => `\"${item}\"`)\n .join(', ')} and \"${items[items.length - 1]}\"`\n}\n\n/**\n * Given a string, it returns the PascalCase form of it.\n * Eg: \"pascal_case\" returns \"PascalCase\".\n *\n * @param str - String to PascalCase.\n * @returns String with all the first letter capitalized with no spaces.\n */\nexport function pascalize(str: string): string {\n return pascalCase(str)\n}\n\n/**\n * Given a string that represents a list of delimited tokens, it returns the normalized string representing the same\n * list, without empty elements, sorted, and with no duplicates.\n *\n * @param delimitedString - String to normalize.\n * @param delimiter - Delimiter used to split the string into tokens.\n * @returns String with the normalized list of tokens.\n */\nexport function normalizeDelimitedString(delimitedString?: string, delimiter = ','): string | undefined {\n if (!delimitedString) return\n\n const items = delimitedString.split(delimiter).map((value) => value.trim())\n const nonEmptyItems = items.filter((value) => value !== '')\n const sortedItems = nonEmptyItems.sort()\n const uniqueSortedItems = [...new Set(sortedItems)]\n\n return uniqueSortedItems.join(delimiter)\n}\n"]}
|
|
1
|
+
{"version":3,"file":"string.js","sourceRoot":"","sources":["../../../src/public/common/string.ts"],"names":[],"mappings":"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","sourcesContent":["import {takeRandomFromArray} from './array.js'\nimport {unstyled} from '../../public/node/output.js'\nimport {Token, TokenItem} from '../../private/node/ui/components/TokenizedText.js'\nimport {camelCase, constantCase, paramCase, snakeCase, pascalCase} from 'change-case'\n\nconst SAFE_RANDOM_BUSINESS_ADJECTIVES = [\n 'commercial',\n 'profitable',\n 'amortizable',\n 'branded',\n 'integrated',\n 'synergistic',\n 'consolidated',\n 'diversified',\n 'lean',\n 'niche',\n 'premium',\n 'luxury',\n 'scalable',\n 'optimized',\n 'empowered',\n 'international',\n 'beneficial',\n 'fruitful',\n 'extensive',\n 'lucrative',\n 'modern',\n 'stable',\n 'strategic',\n 'adaptive',\n 'efficient',\n 'growing',\n 'sustainable',\n 'innovative',\n 'regional',\n 'specialized',\n 'focused',\n 'pragmatic',\n 'ethical',\n 'flexible',\n 'competitive',\n]\n\nconst SAFE_RANDOM_CREATIVE_ADJECTIVES = [\n 'bright',\n 'impactful',\n 'stylish',\n 'colorful',\n 'modern',\n 'minimal',\n 'trendy',\n 'creative',\n 'artistic',\n 'spectacular',\n 'glamorous',\n 'luxury',\n 'retro',\n 'nostalgic',\n 'comfy',\n 'polished',\n 'fabulous',\n 'balanced',\n 'monochrome',\n 'glitched',\n 'contrasted',\n 'elegant',\n 'textured',\n 'vibrant',\n 'harmonious',\n 'versatile',\n 'eclectic',\n 'futuristic',\n 'idealistic',\n 'intricate',\n 'bohemian',\n 'abstract',\n 'meticulous',\n 'refined',\n 'flamboyant',\n]\n\nconst SAFE_RANDOM_BUSINESS_NOUNS = [\n 'account',\n 'consumer',\n 'customer',\n 'enterprise',\n 'business',\n 'venture',\n 'marketplace',\n 'revenue',\n 'vertical',\n 'portfolio',\n 'negotiation',\n 'shipping',\n 'demand',\n 'supply',\n 'growth',\n 'merchant',\n 'investment',\n 'shareholder',\n 'conversion',\n 'capital',\n 'projection',\n 'upside',\n 'trade',\n 'deal',\n 'merchandise',\n 'transaction',\n 'sale',\n 'franchise',\n 'subsidiary',\n 'logistics',\n 'infrastructure',\n 'sponsorship',\n 'partnership',\n 'tax',\n 'policy',\n 'outsource',\n 'equity',\n 'strategy',\n 'valuation',\n 'benchmark',\n 'metrics',\n 'duplication',\n]\n\nconst SAFE_RANDOM_CREATIVE_NOUNS = [\n 'vibe',\n 'style',\n 'moment',\n 'mood',\n 'flavor',\n 'look',\n 'appearance',\n 'perspective',\n 'aspect',\n 'ambience',\n 'quality',\n 'backdrop',\n 'focus',\n 'tone',\n 'inspiration',\n 'imagery',\n 'aesthetics',\n 'palette',\n 'ornamentation',\n 'contrast',\n 'colorway',\n 'visuals',\n 'typography',\n 'composition',\n 'scale',\n 'symmetry',\n 'gradients',\n 'proportions',\n 'textures',\n 'harmony',\n 'shapes',\n 'patterns',\n]\n\nexport type RandomNameFamily = 'business' | 'creative'\n\n/**\n * Generates a random name by combining an adjective and noun.\n *\n * @param family - Theme to use for the random name (business or creative).\n * @returns A random name generated by combining an adjective and noun.\n */\nexport function getRandomName(family: RandomNameFamily = 'business'): string {\n const mapping = {\n business: {\n adjectives: SAFE_RANDOM_BUSINESS_ADJECTIVES,\n nouns: SAFE_RANDOM_BUSINESS_NOUNS,\n },\n creative: {\n adjectives: SAFE_RANDOM_CREATIVE_ADJECTIVES,\n nouns: SAFE_RANDOM_CREATIVE_NOUNS,\n },\n }\n return `${takeRandomFromArray(mapping[family].adjectives)}-${takeRandomFromArray(mapping[family].nouns)}`\n}\n\n/**\n * Given a string, it returns it with the first letter capitalized.\n *\n * @param str - String to capitalize.\n * @returns String with the first letter capitalized.\n */\nexport function capitalize(str: string): string {\n return str.substring(0, 1).toUpperCase() + str.substring(1)\n}\n\n/**\n * Given a list of items, it returns a pluralized string based on the amount of items.\n *\n * @param items - List of items.\n * @param plural - Supplier used when the list of items has more than one item.\n * @param singular - Supplier used when the list of items has a single item.\n * @param none - Supplier used when the list has no items.\n * @returns The {@link TokenItem} supplied by the {@link plural}, {@link singular}, or {@link none} functions.\n */\nexport function pluralize<\n T,\n TToken extends Token = Token,\n TPluralToken extends TToken = TToken,\n TSingularToken extends TToken = TToken,\n TNoneToken extends TToken = TToken,\n>(\n items: T[],\n plural: (items: T[]) => TokenItem<TPluralToken>,\n singular: (item: T) => TokenItem<TSingularToken>,\n none?: () => TokenItem<TNoneToken>,\n): TokenItem<TPluralToken | TSingularToken | TNoneToken> | string {\n if (items.length === 1) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return singular(items[0]!)\n }\n\n if (items.length > 1) {\n return plural(items)\n }\n\n if (none) {\n return none()\n }\n\n return ''\n}\n\n/**\n * Try to convert a string to an int, falling back to undefined if unable to.\n *\n * @param maybeInt - String to convert to an int.\n * @returns The int if it was able to convert, otherwise undefined.\n */\nexport function tryParseInt(maybeInt: string | undefined): number | undefined {\n let asInt: number | undefined\n if (maybeInt !== undefined) {\n asInt = parseInt(maybeInt, 10)\n if (isNaN(asInt)) {\n asInt = undefined\n }\n }\n return asInt\n}\n\n/**\n * Transforms a matrix of strings into a single string with the columns aligned.\n *\n * @param lines - Array of rows, where each row is an array of strings (representing columns).\n * @returns A string with the columns aligned.\n */\nexport function linesToColumns(lines: string[][]): string {\n const widths: number[] = []\n for (let i = 0; lines[0] && i < lines[0].length; i++) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const columnRows = lines.map((line) => line[i]!)\n widths.push(Math.max(...columnRows.map((row) => unstyled(row).length)))\n }\n const paddedLines = lines\n .map((line) => {\n return line\n .map((col, index) => {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return `${col}${' '.repeat(widths[index]! - unstyled(col).length)}`\n })\n .join(' ')\n .trimEnd()\n })\n .join('\\n')\n return paddedLines\n}\n\n/**\n * Given a string, it transforms it to a slug (lowercase, hyphenated, no special chars, trimmed...).\n *\n * @param str - String to slugify.\n * @returns The slugified string.\n */\nexport function slugify(str: string): string {\n return str\n .toLowerCase()\n .trim()\n .replace(/[^\\w\\s-]/g, '')\n .replace(/[\\s_-]+/g, '-')\n .replace(/^-+|-+$/g, '')\n}\n\n/**\n * Given a string, it returns it with the special regex characters escaped.\n * More info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping.\n *\n * @param str - String to escape.\n * @returns The escaped string.\n */\nexport function escapeRegExp(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\n/**\n * Transform a string to camelCase.\n *\n * @param input - String to escape.\n * @returns The escaped string.\n */\nexport function camelize(input: string): string {\n return camelCase(input)\n}\n\n/**\n * Transform a string to param-case.\n *\n * @param input - String to transform.\n * @returns The transformed string.\n */\nexport function hyphenate(input: string): string {\n return paramCase(input)\n}\n\n/**\n * Transform a string to snake_case.\n *\n * @param input - String to transform.\n * @returns The transformed string.\n */\nexport function underscore(input: string): string {\n return snakeCase(input)\n}\n\n/**\n * Transform a string to CONSTANT_CASE.\n *\n * @param input - String to transform.\n * @returns The transformed string.\n */\nexport function constantize(input: string): string {\n return constantCase(input)\n}\n\n/**\n * Given a date, return a formatted string like \"2021-01-01 12:00:00\".\n *\n * @param date - Date to format.\n * @returns The transformed string.\n */\nexport function formatDate(date: Date): string {\n const components = date.toISOString().split('T')\n const dateString = components[0] ?? date.toDateString()\n const timeString = components[1]?.split('.')[0] ?? date.toTimeString()\n return `${dateString} ${timeString}`\n}\n\n/**\n * Given a date in UTC ISO String format, return a formatted string in local time like \"2021-01-01 12:00:00\".\n *\n * @param dateString - UTC ISO Date String.\n * @returns The transformed string in local system time.\n */\nexport function formatLocalDate(dateString: string): string {\n const dateObj = new Date(dateString)\n const localDate = new Date(\n Date.UTC(\n dateObj.getFullYear(),\n dateObj.getMonth(),\n dateObj.getDate(),\n dateObj.getHours(),\n dateObj.getMinutes(),\n dateObj.getSeconds(),\n ),\n )\n return formatDate(localDate)\n}\n\n/**\n * Given a list of items, it returns a string with the items joined by commas and the last item joined by \"and\".\n * All items are wrapped in double quotes.\n * For example: [\"a\", \"b\", \"c\"] returns \"a\", \"b\" and \"c\".\n *\n * @param items - List of items.\n * @returns The joined string.\n */\nexport function joinWithAnd(items: string[]): string {\n if (items.length === 0) return ''\n if (items.length === 1) return `\"${items[0]}\"`\n\n return `${items\n .slice(0, -1)\n .map((item) => `\"${item}\"`)\n .join(', ')} and \"${items[items.length - 1]}\"`\n}\n\n/**\n * Given a string, it returns the PascalCase form of it.\n * Eg: \"pascal_case\" returns \"PascalCase\".\n *\n * @param str - String to PascalCase.\n * @returns String with all the first letter capitalized with no spaces.\n */\nexport function pascalize(str: string): string {\n return pascalCase(str)\n}\n\n/**\n * Given a string that represents a list of delimited tokens, it returns the normalized string representing the same\n * list, without empty elements, sorted, and with no duplicates.\n *\n * @param delimitedString - String to normalize.\n * @param delimiter - Delimiter used to split the string into tokens.\n * @returns String with the normalized list of tokens.\n */\nexport function normalizeDelimitedString(delimitedString?: string, delimiter = ','): string | undefined {\n if (!delimitedString) return\n\n const items = delimitedString.split(delimiter).map((value) => value.trim())\n const nonEmptyItems = items.filter((value) => value !== '')\n const sortedItems = nonEmptyItems.sort()\n const uniqueSortedItems = [...new Set(sortedItems)]\n\n return uniqueSortedItems.join(delimiter)\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const CLI_KIT_VERSION = "3.
|
|
1
|
+
export declare const CLI_KIT_VERSION = "3.69.0";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const CLI_KIT_VERSION = '3.
|
|
1
|
+
export const CLI_KIT_VERSION = '3.69.0';
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/public/common/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAA","sourcesContent":["export const CLI_KIT_VERSION = '3.
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/public/common/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAA","sourcesContent":["export const CLI_KIT_VERSION = '3.69.0'\n"]}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { GraphQLVariables } from './graphql.js';
|
|
1
|
+
import { GraphQLResponseOptions, GraphQLVariables } from './graphql.js';
|
|
2
2
|
import { AdminSession } from '../session.js';
|
|
3
|
+
import { Variables } from 'graphql-request';
|
|
4
|
+
import { TypedDocumentNode } from '@graphql-typed-document-node/core';
|
|
3
5
|
/**
|
|
4
6
|
* Executes a GraphQL query against the Admin API.
|
|
5
7
|
*
|
|
@@ -9,6 +11,17 @@ import { AdminSession } from '../session.js';
|
|
|
9
11
|
* @returns The response of the query of generic type <T>.
|
|
10
12
|
*/
|
|
11
13
|
export declare function adminRequest<T>(query: string, session: AdminSession, variables?: GraphQLVariables): Promise<T>;
|
|
14
|
+
/**
|
|
15
|
+
* Executes a GraphQL query against the Admin API. Uses typed documents.
|
|
16
|
+
*
|
|
17
|
+
* @param query - GraphQL query to execute.
|
|
18
|
+
* @param session - Shopify admin session including token and Store FQDN.
|
|
19
|
+
* @param variables - GraphQL variables to pass to the query.
|
|
20
|
+
* @param version - API version.
|
|
21
|
+
* @param responseOptions - Control how API responses will be handled.
|
|
22
|
+
* @returns The response of the query of generic type <TResult>.
|
|
23
|
+
*/
|
|
24
|
+
export declare function adminRequestDoc<TResult, TVariables extends Variables>(query: TypedDocumentNode<TResult, TVariables>, session: AdminSession, variables?: TVariables, version?: string, responseOptions?: GraphQLResponseOptions<TResult>): Promise<TResult>;
|
|
12
25
|
/**
|
|
13
26
|
* GraphQL query to retrieve all supported API versions.
|
|
14
27
|
*
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { graphqlRequest } from './graphql.js';
|
|
1
|
+
import { graphqlRequest, graphqlRequestDoc } from './graphql.js';
|
|
2
2
|
import { outputContent, outputToken } from '../../../public/node/output.js';
|
|
3
3
|
import { BugError, AbortError } from '../error.js';
|
|
4
4
|
import { restRequestBody, restRequestHeaders, restRequestUrl } from '../../../private/node/api/rest.js';
|
|
5
5
|
import { fetch } from '../http.js';
|
|
6
|
-
import {
|
|
6
|
+
import { PublicApiVersions } from '../../../cli/api/graphql/admin/generated/public_api_versions.js';
|
|
7
|
+
import { ClientError } from 'graphql-request';
|
|
7
8
|
/**
|
|
8
9
|
* Executes a GraphQL query against the Admin API.
|
|
9
10
|
*
|
|
@@ -18,6 +19,29 @@ export async function adminRequest(query, session, variables) {
|
|
|
18
19
|
const url = adminUrl(session.storeFqdn, version);
|
|
19
20
|
return graphqlRequest({ query, api, url, token: session.token, variables });
|
|
20
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Executes a GraphQL query against the Admin API. Uses typed documents.
|
|
24
|
+
*
|
|
25
|
+
* @param query - GraphQL query to execute.
|
|
26
|
+
* @param session - Shopify admin session including token and Store FQDN.
|
|
27
|
+
* @param variables - GraphQL variables to pass to the query.
|
|
28
|
+
* @param version - API version.
|
|
29
|
+
* @param responseOptions - Control how API responses will be handled.
|
|
30
|
+
* @returns The response of the query of generic type <TResult>.
|
|
31
|
+
*/
|
|
32
|
+
export async function adminRequestDoc(query, session, variables, version, responseOptions) {
|
|
33
|
+
let apiVersion = version;
|
|
34
|
+
if (!version) {
|
|
35
|
+
apiVersion = await fetchLatestSupportedApiVersion(session);
|
|
36
|
+
}
|
|
37
|
+
const opts = {
|
|
38
|
+
url: adminUrl(session.storeFqdn, apiVersion),
|
|
39
|
+
api: 'Admin',
|
|
40
|
+
token: session.token,
|
|
41
|
+
};
|
|
42
|
+
const result = graphqlRequestDoc({ ...opts, query, variables, responseOptions });
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
21
45
|
/**
|
|
22
46
|
* GraphQL query to retrieve the latest supported API version.
|
|
23
47
|
*
|
|
@@ -26,6 +50,7 @@ export async function adminRequest(query, session, variables) {
|
|
|
26
50
|
*/
|
|
27
51
|
async function fetchLatestSupportedApiVersion(session) {
|
|
28
52
|
const apiVersions = await supportedApiVersions(session);
|
|
53
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
29
54
|
return apiVersions.reverse()[0];
|
|
30
55
|
}
|
|
31
56
|
/**
|
|
@@ -48,18 +73,9 @@ export async function supportedApiVersions(session) {
|
|
|
48
73
|
* @returns - An array of supported and unsupported API versions.
|
|
49
74
|
*/
|
|
50
75
|
async function fetchApiVersions(session) {
|
|
51
|
-
const url = adminUrl(session.storeFqdn, 'unstable');
|
|
52
|
-
const query = apiVersionQuery();
|
|
53
76
|
try {
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
api: 'Admin',
|
|
57
|
-
url,
|
|
58
|
-
token: session.token,
|
|
59
|
-
variables: {},
|
|
60
|
-
responseOptions: { handleErrors: false },
|
|
61
|
-
});
|
|
62
|
-
return data.publicApiVersions;
|
|
77
|
+
const response = await adminRequestDoc(PublicApiVersions, session, {}, 'unstable', { handleErrors: false });
|
|
78
|
+
return response.publicApiVersions;
|
|
63
79
|
}
|
|
64
80
|
catch (error) {
|
|
65
81
|
if (error instanceof ClientError && error.response.status === 403) {
|
|
@@ -80,21 +96,6 @@ export function adminUrl(store, version) {
|
|
|
80
96
|
const realVersion = version || 'unstable';
|
|
81
97
|
return `https://${store}/admin/api/${realVersion}/graphql.json`;
|
|
82
98
|
}
|
|
83
|
-
/**
|
|
84
|
-
* GraphQL query string to retrieve the latest supported API version.
|
|
85
|
-
*
|
|
86
|
-
* @returns - A query string.
|
|
87
|
-
*/
|
|
88
|
-
function apiVersionQuery() {
|
|
89
|
-
return gql `
|
|
90
|
-
query {
|
|
91
|
-
publicApiVersions {
|
|
92
|
-
handle
|
|
93
|
-
supported
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
`;
|
|
97
|
-
}
|
|
98
99
|
/**
|
|
99
100
|
* Executes a REST request against the Admin API.
|
|
100
101
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin.js","sourceRoot":"","sources":["../../../../src/public/node/api/admin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,
|
|
1
|
+
{"version":3,"file":"admin.js","sourceRoot":"","sources":["../../../../src/public/node/api/admin.ts"],"names":[],"mappings":"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","sourcesContent":["import {graphqlRequest, graphqlRequestDoc, GraphQLResponseOptions, GraphQLVariables} from './graphql.js'\nimport {AdminSession} from '../session.js'\nimport {outputContent, outputToken} from '../../../public/node/output.js'\nimport {BugError, AbortError} from '../error.js'\nimport {restRequestBody, restRequestHeaders, restRequestUrl} from '../../../private/node/api/rest.js'\nimport {fetch} from '../http.js'\nimport {PublicApiVersions} from '../../../cli/api/graphql/admin/generated/public_api_versions.js'\nimport {ClientError, Variables} from 'graphql-request'\nimport {TypedDocumentNode} from '@graphql-typed-document-node/core'\n\n/**\n * Executes a GraphQL query against the Admin API.\n *\n * @param query - GraphQL query to execute.\n * @param session - Shopify admin session including token and Store FQDN.\n * @param variables - GraphQL variables to pass to the query.\n * @returns The response of the query of generic type <T>.\n */\nexport async function adminRequest<T>(query: string, session: AdminSession, variables?: GraphQLVariables): Promise<T> {\n const api = 'Admin'\n const version = await fetchLatestSupportedApiVersion(session)\n const url = adminUrl(session.storeFqdn, version)\n return graphqlRequest({query, api, url, token: session.token, variables})\n}\n\n/**\n * Executes a GraphQL query against the Admin API. Uses typed documents.\n *\n * @param query - GraphQL query to execute.\n * @param session - Shopify admin session including token and Store FQDN.\n * @param variables - GraphQL variables to pass to the query.\n * @param version - API version.\n * @param responseOptions - Control how API responses will be handled.\n * @returns The response of the query of generic type <TResult>.\n */\nexport async function adminRequestDoc<TResult, TVariables extends Variables>(\n query: TypedDocumentNode<TResult, TVariables>,\n session: AdminSession,\n variables?: TVariables,\n version?: string,\n responseOptions?: GraphQLResponseOptions<TResult>,\n): Promise<TResult> {\n let apiVersion = version\n if (!version) {\n apiVersion = await fetchLatestSupportedApiVersion(session)\n }\n const opts = {\n url: adminUrl(session.storeFqdn, apiVersion),\n api: 'Admin',\n token: session.token,\n }\n const result = graphqlRequestDoc<TResult, TVariables>({...opts, query, variables, responseOptions})\n return result\n}\n\n/**\n * GraphQL query to retrieve the latest supported API version.\n *\n * @param session - Shopify admin session including token and Store FQDN.\n * @returns - The latest supported API version.\n */\nasync function fetchLatestSupportedApiVersion(session: AdminSession): Promise<string> {\n const apiVersions = await supportedApiVersions(session)\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return apiVersions.reverse()[0]!\n}\n\n/**\n * GraphQL query to retrieve all supported API versions.\n *\n * @param session - Shopify admin session including token and Store FQDN.\n * @returns - An array of supported API versions.\n */\nexport async function supportedApiVersions(session: AdminSession): Promise<string[]> {\n const apiVersions = await fetchApiVersions(session)\n return apiVersions\n .filter((item) => item.supported)\n .map((item) => item.handle)\n .sort()\n}\n\n/**\n * GraphQL query to retrieve all API versions.\n *\n * @param session - Shopify admin session including token and Store FQDN.\n * @returns - An array of supported and unsupported API versions.\n */\nasync function fetchApiVersions(session: AdminSession): Promise<ApiVersion[]> {\n try {\n const response = await adminRequestDoc(PublicApiVersions, session, {}, 'unstable', {handleErrors: false})\n return response.publicApiVersions\n } catch (error) {\n if (error instanceof ClientError && error.response.status === 403) {\n const storeName = session.storeFqdn.replace('.myshopify.com', '')\n throw new AbortError(\n outputContent`Looks like you don't have access this dev store: (${outputToken.link(\n storeName,\n `https://${session.storeFqdn}`,\n )})`,\n outputContent`If you're not the owner, create a dev store staff account for yourself`,\n )\n }\n throw new BugError(`Unknown error connecting to your store`)\n }\n}\n\n/**\n * Returns the Admin API URL for the given store and version.\n *\n * @param store - Store FQDN.\n * @param version - API version.\n * @returns - Admin API URL.\n */\nexport function adminUrl(store: string, version: string | undefined): string {\n const realVersion = version || 'unstable'\n return `https://${store}/admin/api/${realVersion}/graphql.json`\n}\n\ninterface ApiVersion {\n handle: string\n supported: boolean\n}\n\n/**\n * Executes a REST request against the Admin API.\n *\n * @param method - Request's HTTP method.\n * @param path - Path of the REST resource.\n * @param session - Shopify Admin session including token and Store FQDN.\n * @param requestBody - Request body of including REST resource specific parameters.\n * @param searchParams - Search params, appended to the URL.\n * @param apiVersion - Admin API version.\n * @returns - The {@link RestResponse}.\n */\nexport async function restRequest<T>(\n method: string,\n path: string,\n session: AdminSession,\n requestBody?: T,\n searchParams: {[name: string]: string} = {},\n apiVersion = 'unstable',\n): Promise<RestResponse> {\n const url = restRequestUrl(session, apiVersion, path, searchParams)\n const body = restRequestBody<T>(requestBody)\n\n const headers = restRequestHeaders(session)\n const response = await fetch(url, {\n headers,\n method,\n body,\n })\n\n const json = await response.json().catch(() => ({}))\n\n return {\n json,\n status: response.status,\n headers: response.headers.raw(),\n }\n}\n\n/**\n * Respose of a REST request.\n */\nexport interface RestResponse {\n /**\n * REST JSON respose.\n */\n // Using `any` to avoid introducing extra DTO layers.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n json: any\n\n /**\n * HTTP response status.\n */\n status: number\n\n /**\n * HTTP response headers.\n */\n headers: {[key: string]: string[]}\n}\n"]}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { GraphQLResponse } from './graphql.js';
|
|
2
|
+
import { TypedDocumentNode } from '@graphql-typed-document-node/core';
|
|
3
|
+
import { Variables } from 'graphql-request';
|
|
2
4
|
/**
|
|
3
|
-
* Executes an org-scoped GraphQL query against the App Management API.
|
|
5
|
+
* Executes an org-scoped GraphQL query against the App Management API. Uses typed documents.
|
|
4
6
|
*
|
|
5
7
|
* @param orgId - The organization ID.
|
|
6
8
|
* @param query - GraphQL query to execute.
|
|
@@ -8,7 +10,7 @@ import { GraphQLVariables, GraphQLResponse } from './graphql.js';
|
|
|
8
10
|
* @param variables - GraphQL variables to pass to the query.
|
|
9
11
|
* @returns The response of the query of generic type <T>.
|
|
10
12
|
*/
|
|
11
|
-
export declare function
|
|
13
|
+
export declare function appManagementRequestDoc<TResult, TVariables extends Variables>(orgId: string, query: TypedDocumentNode<TResult, TVariables>, token: string, variables?: TVariables): Promise<TResult>;
|
|
12
14
|
/**
|
|
13
15
|
* Sets the next deprecation date from [GraphQL response extensions](https://www.apollographql.com/docs/resources/graphql-glossary/#extensions)
|
|
14
16
|
* if `response.extensions.deprecations` objects contain a `supportedUntilDate` (ISO 8601-formatted string).
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { graphqlRequestDoc } from './graphql.js';
|
|
2
2
|
import { appManagementFqdn } from '../context/fqdn.js';
|
|
3
3
|
import { setNextDeprecationDate } from '../../../private/node/context/deprecations-store.js';
|
|
4
4
|
import Bottleneck from 'bottleneck';
|
|
@@ -9,8 +9,19 @@ const limiter = new Bottleneck({
|
|
|
9
9
|
minTime: 150,
|
|
10
10
|
maxConcurrent: 10,
|
|
11
11
|
});
|
|
12
|
+
async function setupRequest(orgId, token) {
|
|
13
|
+
const api = 'App Management';
|
|
14
|
+
const fqdn = await appManagementFqdn();
|
|
15
|
+
const url = `https://${fqdn}/app_management/unstable/organizations/${orgId}/graphql.json`;
|
|
16
|
+
return {
|
|
17
|
+
token,
|
|
18
|
+
api,
|
|
19
|
+
url,
|
|
20
|
+
responseOptions: { onResponse: handleDeprecations },
|
|
21
|
+
};
|
|
22
|
+
}
|
|
12
23
|
/**
|
|
13
|
-
* Executes an org-scoped GraphQL query against the App Management API.
|
|
24
|
+
* Executes an org-scoped GraphQL query against the App Management API. Uses typed documents.
|
|
14
25
|
*
|
|
15
26
|
* @param orgId - The organization ID.
|
|
16
27
|
* @param query - GraphQL query to execute.
|
|
@@ -18,17 +29,11 @@ const limiter = new Bottleneck({
|
|
|
18
29
|
* @param variables - GraphQL variables to pass to the query.
|
|
19
30
|
* @returns The response of the query of generic type <T>.
|
|
20
31
|
*/
|
|
21
|
-
export async function
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
const url = `https://${fqdn}/app_management/unstable/organizations/${orgId}/graphql.json`;
|
|
25
|
-
const result = limiter.schedule(() => graphqlRequest({
|
|
32
|
+
export async function appManagementRequestDoc(orgId, query, token, variables) {
|
|
33
|
+
const result = limiter.schedule(async () => graphqlRequestDoc({
|
|
34
|
+
...(await setupRequest(orgId, token)),
|
|
26
35
|
query,
|
|
27
|
-
api,
|
|
28
|
-
url,
|
|
29
|
-
token,
|
|
30
36
|
variables,
|
|
31
|
-
responseOptions: { onResponse: handleDeprecations },
|
|
32
37
|
}));
|
|
33
38
|
return result;
|
|
34
39
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-management.js","sourceRoot":"","sources":["../../../../src/public/node/api/app-management.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"app-management.js","sourceRoot":"","sources":["../../../../src/public/node/api/app-management.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,iBAAiB,EAAC,MAAM,cAAc,CAAA;AAC/D,OAAO,EAAC,iBAAiB,EAAC,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAC,sBAAsB,EAAC,MAAM,qDAAqD,CAAA;AAC1F,OAAO,UAAU,MAAM,YAAY,CAAA;AAInC,sEAAsE;AACtE,yEAAyE;AACzE,iDAAiD;AACjD,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC;IAC7B,OAAO,EAAE,GAAG;IACZ,aAAa,EAAE,EAAE;CAClB,CAAC,CAAA;AAEF,KAAK,UAAU,YAAY,CAAC,KAAa,EAAE,KAAa;IACtD,MAAM,GAAG,GAAG,gBAAgB,CAAA;IAC5B,MAAM,IAAI,GAAG,MAAM,iBAAiB,EAAE,CAAA;IACtC,MAAM,GAAG,GAAG,WAAW,IAAI,0CAA0C,KAAK,eAAe,CAAA;IACzF,OAAO;QACL,KAAK;QACL,GAAG;QACH,GAAG;QACH,eAAe,EAAE,EAAC,UAAU,EAAE,kBAAkB,EAAC;KAClD,CAAA;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,KAAa,EACb,KAA6C,EAC7C,KAAa,EACb,SAAsB;IAEtB,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAU,KAAK,IAAI,EAAE,CAClD,iBAAiB,CAAsB;QACrC,GAAG,CAAC,MAAM,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACrC,KAAK;QACL,SAAS;KACV,CAAC,CACH,CAAA;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AASD;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAI,QAA4B;IAChE,IAAI,CAAC,QAAQ,CAAC,UAAU;QAAE,OAAM;IAEhC,MAAM,gBAAgB,GAAW,EAAE,CAAA;IACnC,KAAK,MAAM,WAAW,IAAK,QAAQ,CAAC,UAA+B,CAAC,YAAY,EAAE;QAChF,IAAI,WAAW,CAAC,kBAAkB,EAAE;YAClC,gBAAgB,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,CAAA;SAChE;KACF;IAED,sBAAsB,CAAC,gBAAgB,CAAC,CAAA;AAC1C,CAAC","sourcesContent":["import {GraphQLResponse, graphqlRequestDoc} from './graphql.js'\nimport {appManagementFqdn} from '../context/fqdn.js'\nimport {setNextDeprecationDate} from '../../../private/node/context/deprecations-store.js'\nimport Bottleneck from 'bottleneck'\nimport {TypedDocumentNode} from '@graphql-typed-document-node/core'\nimport {Variables} from 'graphql-request'\n\n// API Rate limiter for partners API (Limit is 10 requests per second)\n// Jobs are launched every 150ms to add an extra 50ms margin per request.\n// Only 10 requests can be executed concurrently.\nconst limiter = new Bottleneck({\n minTime: 150,\n maxConcurrent: 10,\n})\n\nasync function setupRequest(orgId: string, token: string) {\n const api = 'App Management'\n const fqdn = await appManagementFqdn()\n const url = `https://${fqdn}/app_management/unstable/organizations/${orgId}/graphql.json`\n return {\n token,\n api,\n url,\n responseOptions: {onResponse: handleDeprecations},\n }\n}\n\n/**\n * Executes an org-scoped GraphQL query against the App Management API. Uses typed documents.\n *\n * @param orgId - The organization ID.\n * @param query - GraphQL query to execute.\n * @param token - Partners token.\n * @param variables - GraphQL variables to pass to the query.\n * @returns The response of the query of generic type <T>.\n */\nexport async function appManagementRequestDoc<TResult, TVariables extends Variables>(\n orgId: string,\n query: TypedDocumentNode<TResult, TVariables>,\n token: string,\n variables?: TVariables,\n): Promise<TResult> {\n const result = limiter.schedule<TResult>(async () =>\n graphqlRequestDoc<TResult, TVariables>({\n ...(await setupRequest(orgId, token)),\n query,\n variables,\n }),\n )\n\n return result\n}\ninterface Deprecation {\n supportedUntilDate?: string\n}\n\ninterface WithDeprecations {\n deprecations: Deprecation[]\n}\n\n/**\n * Sets the next deprecation date from [GraphQL response extensions](https://www.apollographql.com/docs/resources/graphql-glossary/#extensions)\n * if `response.extensions.deprecations` objects contain a `supportedUntilDate` (ISO 8601-formatted string).\n *\n * @param response - The response of the query.\n */\nexport function handleDeprecations<T>(response: GraphQLResponse<T>): void {\n if (!response.extensions) return\n\n const deprecationDates: Date[] = []\n for (const deprecation of (response.extensions as WithDeprecations).deprecations) {\n if (deprecation.supportedUntilDate) {\n deprecationDates.push(new Date(deprecation.supportedUntilDate))\n }\n }\n\n setNextDeprecationDate(deprecationDates)\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { buildHeaders, httpsAgent } from '../../../private/node/api/headers.js';
|
|
2
2
|
import { debugLogRequestInfo, errorHandler } from '../../../private/node/api/graphql.js';
|
|
3
|
-
import { runWithTimer } from '../metadata.js';
|
|
3
|
+
import { addPublicMetadata, runWithTimer } from '../metadata.js';
|
|
4
4
|
import { retryAwareRequest } from '../../../private/node/api.js';
|
|
5
5
|
import { GraphQLClient, resolveRequestDocument } from 'graphql-request';
|
|
6
6
|
/**
|
|
@@ -22,6 +22,18 @@ async function performGraphQLRequest(options) {
|
|
|
22
22
|
if (responseOptions?.onResponse) {
|
|
23
23
|
responseOptions.onResponse(response);
|
|
24
24
|
}
|
|
25
|
+
try {
|
|
26
|
+
const requestId = response.headers.get('x-request-id');
|
|
27
|
+
await addPublicMetadata(async () => {
|
|
28
|
+
return {
|
|
29
|
+
cmd_all_last_graphql_request_id: requestId ?? undefined,
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
// eslint-disable-next-line no-catch-all/no-catch-all
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// no problem if unable to get request ID.
|
|
36
|
+
}
|
|
25
37
|
return response.data;
|
|
26
38
|
});
|
|
27
39
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphql.js","sourceRoot":"","sources":["../../../../src/public/node/api/graphql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,UAAU,EAAC,MAAM,sCAAsC,CAAA;AAC7E,OAAO,EAAC,mBAAmB,EAAE,YAAY,EAAC,MAAM,sCAAsC,CAAA;AACtF,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"graphql.js","sourceRoot":"","sources":["../../../../src/public/node/api/graphql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,UAAU,EAAC,MAAM,sCAAsC,CAAA;AAC7E,OAAO,EAAC,mBAAmB,EAAE,YAAY,EAAC,MAAM,sCAAsC,CAAA;AACtF,OAAO,EAAC,iBAAiB,EAAE,YAAY,EAAC,MAAM,gBAAgB,CAAA;AAC9D,OAAO,EAAC,iBAAiB,EAAC,MAAM,8BAA8B,CAAA;AAC9D,OAAO,EAAC,aAAa,EAA+B,sBAAsB,EAAY,MAAM,iBAAiB,CAAA;AAyC7G;;;;GAIG;AACH,KAAK,UAAU,qBAAqB,CAAU,OAA8C;IAC1F,MAAM,EAAC,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,EAAE,eAAe,EAAC,GAAG,OAAO,CAAA;IAC1F,MAAM,OAAO,GAAG;QACd,GAAG,YAAY;QACf,GAAG,YAAY,CAAC,KAAK,CAAC;KACvB,CAAA;IAED,mBAAmB,CAAC,GAAG,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,CAAC,CAAA;IAC3D,MAAM,aAAa,GAAG,EAAC,KAAK,EAAE,MAAM,UAAU,EAAE,EAAE,OAAO,EAAC,CAAA;IAC1D,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,GAAG,EAAE,aAAa,CAAC,CAAA;IAEpD,OAAO,YAAY,CAAC,2BAA2B,CAAC,CAAC,KAAK,IAAI,EAAE;QAC1D,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CACtC,EAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,CAAU,aAAa,EAAE,SAAS,CAAC,EAAE,GAAG,EAAC,EAC1E,eAAe,EAAE,YAAY,KAAK,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CACxE,CAAA;QAED,IAAI,eAAe,EAAE,UAAU,EAAE;YAC/B,eAAe,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;SACrC;QAED,IAAI;YACF,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;YACtD,MAAM,iBAAiB,CAAC,KAAK,IAAI,EAAE;gBACjC,OAAO;oBACL,+BAA+B,EAAE,SAAS,IAAI,SAAS;iBACxD,CAAA;YACH,CAAC,CAAC,CAAA;YACF,qDAAqD;SACtD;QAAC,MAAM;YACN,0CAA0C;SAC3C;QAED,OAAO,QAAQ,CAAC,IAAI,CAAA;IACtB,CAAC,CAAC,CAAA;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAI,OAAiC;IACvE,OAAO,qBAAqB,CAAI;QAC9B,GAAG,OAAO;QACV,aAAa,EAAE,OAAO,CAAC,KAAe;KACvC,CAAC,CAAA;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAsD;IAEtD,OAAO,qBAAqB,CAAU;QACpC,GAAG,OAAO;QACV,aAAa,EAAE,sBAAsB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK;KAC3D,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import {buildHeaders, httpsAgent} from '../../../private/node/api/headers.js'\nimport {debugLogRequestInfo, errorHandler} from '../../../private/node/api/graphql.js'\nimport {addPublicMetadata, runWithTimer} from '../metadata.js'\nimport {retryAwareRequest} from '../../../private/node/api.js'\nimport {GraphQLClient, rawRequest, RequestDocument, resolveRequestDocument, Variables} from 'graphql-request'\nimport {TypedDocumentNode} from '@graphql-typed-document-node/core'\n\n// to replace TVariable type when there graphql query has no variables\nexport type Exact<T extends {[key: string]: unknown}> = {[K in keyof T]: T[K]}\n\nexport interface GraphQLVariables {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: any\n}\n\nexport type GraphQLResponse<T> = Awaited<ReturnType<typeof rawRequest<T>>>\n\ninterface GraphQLRequestBaseOptions<TResult> {\n api: string\n url: string\n token?: string\n addedHeaders?: {[header: string]: string}\n responseOptions?: GraphQLResponseOptions<TResult>\n}\n\ntype PerformGraphQLRequestOptions<TResult> = GraphQLRequestBaseOptions<TResult> & {\n queryAsString: string\n variables?: Variables\n}\n\nexport type GraphQLRequestOptions<T> = GraphQLRequestBaseOptions<T> & {\n query: RequestDocument\n variables?: Variables\n}\n\nexport type GraphQLRequestDocOptions<TResult, TVariables> = GraphQLRequestBaseOptions<TResult> & {\n query: TypedDocumentNode<TResult, TVariables> | TypedDocumentNode<TResult, Exact<{[key: string]: never}>>\n variables?: TVariables\n}\n\nexport interface GraphQLResponseOptions<T> {\n handleErrors?: boolean\n onResponse?: (response: GraphQLResponse<T>) => void\n}\n\n/**\n * Handles execution of a GraphQL query.\n *\n * @param options - GraphQL request options.\n */\nasync function performGraphQLRequest<TResult>(options: PerformGraphQLRequestOptions<TResult>) {\n const {token, addedHeaders, queryAsString, variables, api, url, responseOptions} = options\n const headers = {\n ...addedHeaders,\n ...buildHeaders(token),\n }\n\n debugLogRequestInfo(api, queryAsString, variables, headers)\n const clientOptions = {agent: await httpsAgent(), headers}\n const client = new GraphQLClient(url, clientOptions)\n\n return runWithTimer('cmd_all_timing_network_ms')(async () => {\n const response = await retryAwareRequest(\n {request: () => client.rawRequest<TResult>(queryAsString, variables), url},\n responseOptions?.handleErrors === false ? undefined : errorHandler(api),\n )\n\n if (responseOptions?.onResponse) {\n responseOptions.onResponse(response)\n }\n\n try {\n const requestId = response.headers.get('x-request-id')\n await addPublicMetadata(async () => {\n return {\n cmd_all_last_graphql_request_id: requestId ?? undefined,\n }\n })\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch {\n // no problem if unable to get request ID.\n }\n\n return response.data\n })\n}\n\n/**\n * Executes a GraphQL query to an endpoint.\n *\n * @param options - GraphQL request options.\n * @returns The response of the query of generic type <T>.\n */\nexport async function graphqlRequest<T>(options: GraphQLRequestOptions<T>): Promise<T> {\n return performGraphQLRequest<T>({\n ...options,\n queryAsString: options.query as string,\n })\n}\n\n/**\n * Executes a GraphQL query to an endpoint. Uses typed documents.\n *\n * @param options - GraphQL request options.\n * @returns The response of the query of generic type <TResult>.\n */\nexport async function graphqlRequestDoc<TResult, TVariables extends Variables>(\n options: GraphQLRequestDocOptions<TResult, TVariables>,\n): Promise<TResult> {\n return performGraphQLRequest<TResult>({\n ...options,\n queryAsString: resolveRequestDocument(options.query).query,\n })\n}\n"]}
|
|
@@ -27,7 +27,9 @@ export async function throttle(request) {
|
|
|
27
27
|
*/
|
|
28
28
|
const throttleByHeader = () => {
|
|
29
29
|
if (isReachingApiLimit()) {
|
|
30
|
-
setTimeout(() =>
|
|
30
|
+
setTimeout(() => {
|
|
31
|
+
throttleByParallelCounter(performRequest);
|
|
32
|
+
}, DELAY_FOR_TOO_CLOSE_TO_API_LIMIT);
|
|
31
33
|
}
|
|
32
34
|
else {
|
|
33
35
|
throttleByParallelCounter(performRequest);
|
|
@@ -44,7 +46,9 @@ export async function throttle(request) {
|
|
|
44
46
|
*/
|
|
45
47
|
const throttleByParallelCounter = (command) => {
|
|
46
48
|
if (hasTooManyRequests()) {
|
|
47
|
-
setTimeout(() =>
|
|
49
|
+
setTimeout(() => {
|
|
50
|
+
throttleByParallelCounter(throttleByHeader);
|
|
51
|
+
}, DELAY_FOR_TOO_MANY_PARALLEL_REQUESTS);
|
|
48
52
|
}
|
|
49
53
|
else {
|
|
50
54
|
command();
|
|
@@ -129,7 +133,9 @@ function extractRetryDelayMsFromResponse(response) {
|
|
|
129
133
|
export async function delayAwareRetry(response, operation) {
|
|
130
134
|
const retryDelay = extractRetryDelayMsFromResponse(response);
|
|
131
135
|
return new Promise((resolve, _reject) => {
|
|
132
|
-
setTimeout(() =>
|
|
136
|
+
setTimeout(() => {
|
|
137
|
+
resolve(operation());
|
|
138
|
+
}, retryDelay);
|
|
133
139
|
});
|
|
134
140
|
}
|
|
135
141
|
function extractApiCallLimitFromResponse(response) {
|
|
@@ -209,6 +215,7 @@ if (import.meta.vitest) {
|
|
|
209
215
|
};
|
|
210
216
|
// When
|
|
211
217
|
const callLimit = extractApiCallLimitFromResponse(response);
|
|
218
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
212
219
|
const [used, limit] = callLimit;
|
|
213
220
|
// Then
|
|
214
221
|
expect(used).toBe(10);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rest-api-throttler.js","sourceRoot":"","sources":["../../../../src/public/node/api/rest-api-throttler.ts"],"names":[],"mappings":"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","sourcesContent":["import {RestResponse} from './admin.js'\nimport {tryParseInt} from '@shopify/cli-kit/common/string'\n\nconst MAX_NUMBER_OF_PARALLEL_REQUESTS = 5\nconst MARGIN_TO_RATE_LIMIT = 5\n\nconst DELAY_FOR_TOO_MANY_PARALLEL_REQUESTS = 1000\nconst DELAY_FOR_TOO_CLOSE_TO_API_LIMIT = 4000\n\nconst THEME_CONTEXT = 'theme'\n\n/**\n * Throttles a provided action, limiting the number of globally parallel requests, or by the last seen API limit\n * headers.\n *\n * @param request - A function performing a request.\n * @returns - The result of the request, once it eventually runs.\n */\nexport async function throttle<T>(request: () => T): Promise<T> {\n return new Promise<T>((resolve, _reject) => {\n const performRequest = () => {\n throttlingState(THEME_CONTEXT).requestCounter += 1\n resolve(request())\n }\n\n /**\n * Performs the request taking into account the\n * limit of parallel requests only when the API limit has not\n * been reached.\n *\n * Otherwise, performs the request to get the updated API limit\n * headers, so throttler parameters get updates.\n */\n const throttleByHeader = () => {\n if (isReachingApiLimit()) {\n setTimeout(() => throttleByParallelCounter(performRequest), DELAY_FOR_TOO_CLOSE_TO_API_LIMIT)\n } else {\n throttleByParallelCounter(performRequest)\n }\n }\n\n /**\n * Performs the command only when the the limit\n * of parallel request has not been reached.\n *\n * Otherwise, defers the execution to the throttle by rate-limit function,\n * still respecting the limit of parallel requests.\n *\n * @param command - The action to execute.\n */\n const throttleByParallelCounter = (command: () => void) => {\n if (hasTooManyRequests()) {\n setTimeout(() => throttleByParallelCounter(throttleByHeader), DELAY_FOR_TOO_MANY_PARALLEL_REQUESTS)\n } else {\n command()\n }\n }\n\n /**\n * Start throttling by counter to get the API limit headers.\n */\n throttleByParallelCounter(throttleByHeader)\n }).finally(() => {\n throttlingState(THEME_CONTEXT).requestCounter -= 1\n })\n}\n\n/**\n * Keep track of the latest API call limit data from a response.\n *\n * @param response - The response object.\n */\nexport function updateApiCallLimitFromResponse(response: RestResponse): void {\n const callLimit = extractApiCallLimitFromResponse(response)\n\n if (!callLimit) {\n return\n }\n\n const [used, limit] = callLimit\n\n latestRequestInfo().apiCallLimit = {used, limit}\n}\n\nfunction hasTooManyRequests() {\n return throttlingState(THEME_CONTEXT).requestCounter > MAX_NUMBER_OF_PARALLEL_REQUESTS\n}\n\nfunction isReachingApiLimit() {\n const {used, limit} = latestRequestInfo().apiCallLimit\n return used >= limit - MARGIN_TO_RATE_LIMIT\n}\n\nfunction latestRequestInfo() {\n return throttlingState(THEME_CONTEXT).latestRequestInfo\n}\n\n/**\n * Even considering the Stateless modules convention,\n * tracking information about the latest request is\n * critical to optimize the request throttler efficiently.\n *\n * Thus, in this case, this module deliberately avoids\n * IO cost and uses the `_throttlingState` instance for\n * that purpose.\n *\n * A context option is used if multiple APIs are using these capabilities.\n *\n * @param context - The context which we're tracking throttle state within.\n */\nfunction throttlingState(context: string): ThrottlingState {\n const stateForContext = _throttlingState[context]\n if (stateForContext === undefined) {\n const startingState = {\n requestCounter: 0,\n latestRequestInfo: {\n apiCallLimit: {used: 0, limit: 40},\n },\n }\n _throttlingState[context] = startingState\n return startingState\n } else {\n return stateForContext\n }\n}\n\ninterface ThrottlingState {\n /**\n * Number of parallel requests.\n */\n requestCounter: number\n\n /**\n * Latest request information.\n */\n latestRequestInfo: {\n apiCallLimit: {used: number; limit: number}\n }\n}\n\nconst _throttlingState: {\n [context: string]: ThrottlingState\n} = {}\n\nfunction extractRetryDelayMsFromResponse(response: RestResponse): number {\n const retryAfterStr = header(response, 'retry-after')\n const retryAfter = tryParseInt(retryAfterStr)\n\n if (!retryAfter) {\n return 0\n }\n\n return retryAfter\n}\n\n/**\n * Retries an operation after a delay specified in the response headers.\n *\n * @param response - The response object.\n * @param operation - The operation to retry.\n * @returns - The response of the operation.\n */\nexport async function delayAwareRetry(\n response: RestResponse,\n operation: () => Promise<RestResponse>,\n): Promise<RestResponse> {\n const retryDelay = extractRetryDelayMsFromResponse(response)\n return new Promise((resolve, _reject) => {\n setTimeout(() => resolve(operation()), retryDelay)\n })\n}\n\nfunction extractApiCallLimitFromResponse(response: RestResponse): [number, number] | undefined {\n const apiCallLimit = header(response, 'x-shopify-shop-api-call-limit')\n\n const [used, limit] = apiCallLimit\n .split('/')\n .map((num) => tryParseInt(num))\n .filter(Boolean)\n\n if (!used || !limit) {\n return\n }\n\n return [used, limit]\n}\n\nfunction header(response: RestResponse, name: string): string {\n const headers = response.headers\n const header = headers[name]\n\n if (header?.length === 1) {\n return header[0] ?? ''\n }\n\n return ''\n}\n\nif (import.meta.vitest) {\n const {describe, test, expect, beforeEach} = import.meta.vitest\n let response: RestResponse\n\n beforeEach(() => {\n response = {\n json: {},\n status: 200,\n headers: {},\n }\n })\n\n describe('retryAfter', () => {\n test('when the \"retry-after\" header value is valid', async () => {\n // Given\n response.headers = {\n 'retry-after': ['2.0'],\n }\n\n // When\n const retryAfterDelay = extractRetryDelayMsFromResponse(response)\n\n // Then\n expect(retryAfterDelay).toBe(2)\n })\n\n test('when the \"retry-after\" header value is not present', async () => {\n // Given\n response.headers = {\n 'retry-after': [],\n }\n\n // When\n const retryAfterDelay = extractRetryDelayMsFromResponse(response)\n\n // Then\n expect(retryAfterDelay).toBe(0)\n })\n\n test('when the \"retry-after\" header value is valid', async () => {\n // Given\n response.headers = {\n 'retry-after': ['invalid'],\n }\n\n // When\n const retryAfterDelay = extractRetryDelayMsFromResponse(response)\n\n // Then\n expect(retryAfterDelay).toBe(0)\n })\n\n test('when the \"retry-after\" header is not present', async () => {\n // Given\n response.headers = {}\n\n // When\n const retryAfterDelay = extractRetryDelayMsFromResponse(response)\n\n // Then\n expect(retryAfterDelay).toBe(0)\n })\n })\n\n describe('apiCallLimit', () => {\n test('when the \"x-shopify-shop-api-call-limit\" header is valid', async () => {\n // Given\n response.headers = {\n 'x-shopify-shop-api-call-limit': ['10/40'],\n }\n\n // When\n const callLimit = extractApiCallLimitFromResponse(response)\n const [used, limit] = callLimit!\n\n // Then\n expect(used).toBe(10)\n expect(limit).toBe(40)\n })\n\n test('when the \"x-shopify-shop-api-call-limit\" header is invalid', async () => {\n // Given\n response.headers = {\n 'x-shopify-shop-api-call-limit': ['foo/bar'],\n }\n\n // When\n const callLimit = extractApiCallLimitFromResponse(response)\n\n // Then\n expect(callLimit).toBeUndefined()\n })\n\n test('when the \"x-shopify-shop-api-call-limit\" header is not formatted as expected', async () => {\n // Given\n response.headers = {\n 'x-shopify-shop-api-call-limit': ['/10'],\n }\n\n // When\n const callLimit = extractApiCallLimitFromResponse(response)\n\n // Then\n expect(callLimit).toBeUndefined()\n })\n })\n}\n"]}
|
|
1
|
+
{"version":3,"file":"rest-api-throttler.js","sourceRoot":"","sources":["../../../../src/public/node/api/rest-api-throttler.ts"],"names":[],"mappings":"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","sourcesContent":["import {RestResponse} from './admin.js'\nimport {tryParseInt} from '@shopify/cli-kit/common/string'\n\nconst MAX_NUMBER_OF_PARALLEL_REQUESTS = 5\nconst MARGIN_TO_RATE_LIMIT = 5\n\nconst DELAY_FOR_TOO_MANY_PARALLEL_REQUESTS = 1000\nconst DELAY_FOR_TOO_CLOSE_TO_API_LIMIT = 4000\n\nconst THEME_CONTEXT = 'theme'\n\n/**\n * Throttles a provided action, limiting the number of globally parallel requests, or by the last seen API limit\n * headers.\n *\n * @param request - A function performing a request.\n * @returns - The result of the request, once it eventually runs.\n */\nexport async function throttle<T>(request: () => T): Promise<T> {\n return new Promise<T>((resolve, _reject) => {\n const performRequest = () => {\n throttlingState(THEME_CONTEXT).requestCounter += 1\n resolve(request())\n }\n\n /**\n * Performs the request taking into account the\n * limit of parallel requests only when the API limit has not\n * been reached.\n *\n * Otherwise, performs the request to get the updated API limit\n * headers, so throttler parameters get updates.\n */\n const throttleByHeader = () => {\n if (isReachingApiLimit()) {\n setTimeout(() => {\n throttleByParallelCounter(performRequest)\n }, DELAY_FOR_TOO_CLOSE_TO_API_LIMIT)\n } else {\n throttleByParallelCounter(performRequest)\n }\n }\n\n /**\n * Performs the command only when the the limit\n * of parallel request has not been reached.\n *\n * Otherwise, defers the execution to the throttle by rate-limit function,\n * still respecting the limit of parallel requests.\n *\n * @param command - The action to execute.\n */\n const throttleByParallelCounter = (command: () => void) => {\n if (hasTooManyRequests()) {\n setTimeout(() => {\n throttleByParallelCounter(throttleByHeader)\n }, DELAY_FOR_TOO_MANY_PARALLEL_REQUESTS)\n } else {\n command()\n }\n }\n\n /**\n * Start throttling by counter to get the API limit headers.\n */\n throttleByParallelCounter(throttleByHeader)\n }).finally(() => {\n throttlingState(THEME_CONTEXT).requestCounter -= 1\n })\n}\n\n/**\n * Keep track of the latest API call limit data from a response.\n *\n * @param response - The response object.\n */\nexport function updateApiCallLimitFromResponse(response: RestResponse): void {\n const callLimit = extractApiCallLimitFromResponse(response)\n\n if (!callLimit) {\n return\n }\n\n const [used, limit] = callLimit\n\n latestRequestInfo().apiCallLimit = {used, limit}\n}\n\nfunction hasTooManyRequests() {\n return throttlingState(THEME_CONTEXT).requestCounter > MAX_NUMBER_OF_PARALLEL_REQUESTS\n}\n\nfunction isReachingApiLimit() {\n const {used, limit} = latestRequestInfo().apiCallLimit\n return used >= limit - MARGIN_TO_RATE_LIMIT\n}\n\nfunction latestRequestInfo() {\n return throttlingState(THEME_CONTEXT).latestRequestInfo\n}\n\n/**\n * Even considering the Stateless modules convention,\n * tracking information about the latest request is\n * critical to optimize the request throttler efficiently.\n *\n * Thus, in this case, this module deliberately avoids\n * IO cost and uses the `_throttlingState` instance for\n * that purpose.\n *\n * A context option is used if multiple APIs are using these capabilities.\n *\n * @param context - The context which we're tracking throttle state within.\n */\nfunction throttlingState(context: string): ThrottlingState {\n const stateForContext = _throttlingState[context]\n if (stateForContext === undefined) {\n const startingState = {\n requestCounter: 0,\n latestRequestInfo: {\n apiCallLimit: {used: 0, limit: 40},\n },\n }\n _throttlingState[context] = startingState\n return startingState\n } else {\n return stateForContext\n }\n}\n\ninterface ThrottlingState {\n /**\n * Number of parallel requests.\n */\n requestCounter: number\n\n /**\n * Latest request information.\n */\n latestRequestInfo: {\n apiCallLimit: {used: number; limit: number}\n }\n}\n\nconst _throttlingState: {\n [context: string]: ThrottlingState\n} = {}\n\nfunction extractRetryDelayMsFromResponse(response: RestResponse): number {\n const retryAfterStr = header(response, 'retry-after')\n const retryAfter = tryParseInt(retryAfterStr)\n\n if (!retryAfter) {\n return 0\n }\n\n return retryAfter\n}\n\n/**\n * Retries an operation after a delay specified in the response headers.\n *\n * @param response - The response object.\n * @param operation - The operation to retry.\n * @returns - The response of the operation.\n */\nexport async function delayAwareRetry(\n response: RestResponse,\n operation: () => Promise<RestResponse>,\n): Promise<RestResponse> {\n const retryDelay = extractRetryDelayMsFromResponse(response)\n return new Promise((resolve, _reject) => {\n setTimeout(() => {\n resolve(operation())\n }, retryDelay)\n })\n}\n\nfunction extractApiCallLimitFromResponse(response: RestResponse): [number, number] | undefined {\n const apiCallLimit = header(response, 'x-shopify-shop-api-call-limit')\n\n const [used, limit] = apiCallLimit\n .split('/')\n .map((num) => tryParseInt(num))\n .filter(Boolean)\n\n if (!used || !limit) {\n return\n }\n\n return [used, limit]\n}\n\nfunction header(response: RestResponse, name: string): string {\n const headers = response.headers\n const header = headers[name]\n\n if (header?.length === 1) {\n return header[0] ?? ''\n }\n\n return ''\n}\n\nif (import.meta.vitest) {\n const {describe, test, expect, beforeEach} = import.meta.vitest\n let response: RestResponse\n\n beforeEach(() => {\n response = {\n json: {},\n status: 200,\n headers: {},\n }\n })\n\n describe('retryAfter', () => {\n test('when the \"retry-after\" header value is valid', async () => {\n // Given\n response.headers = {\n 'retry-after': ['2.0'],\n }\n\n // When\n const retryAfterDelay = extractRetryDelayMsFromResponse(response)\n\n // Then\n expect(retryAfterDelay).toBe(2)\n })\n\n test('when the \"retry-after\" header value is not present', async () => {\n // Given\n response.headers = {\n 'retry-after': [],\n }\n\n // When\n const retryAfterDelay = extractRetryDelayMsFromResponse(response)\n\n // Then\n expect(retryAfterDelay).toBe(0)\n })\n\n test('when the \"retry-after\" header value is valid', async () => {\n // Given\n response.headers = {\n 'retry-after': ['invalid'],\n }\n\n // When\n const retryAfterDelay = extractRetryDelayMsFromResponse(response)\n\n // Then\n expect(retryAfterDelay).toBe(0)\n })\n\n test('when the \"retry-after\" header is not present', async () => {\n // Given\n response.headers = {}\n\n // When\n const retryAfterDelay = extractRetryDelayMsFromResponse(response)\n\n // Then\n expect(retryAfterDelay).toBe(0)\n })\n })\n\n describe('apiCallLimit', () => {\n test('when the \"x-shopify-shop-api-call-limit\" header is valid', async () => {\n // Given\n response.headers = {\n 'x-shopify-shop-api-call-limit': ['10/40'],\n }\n\n // When\n const callLimit = extractApiCallLimitFromResponse(response)\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const [used, limit] = callLimit!\n\n // Then\n expect(used).toBe(10)\n expect(limit).toBe(40)\n })\n\n test('when the \"x-shopify-shop-api-call-limit\" header is invalid', async () => {\n // Given\n response.headers = {\n 'x-shopify-shop-api-call-limit': ['foo/bar'],\n }\n\n // When\n const callLimit = extractApiCallLimitFromResponse(response)\n\n // Then\n expect(callLimit).toBeUndefined()\n })\n\n test('when the \"x-shopify-shop-api-call-limit\" header is not formatted as expected', async () => {\n // Given\n response.headers = {\n 'x-shopify-shop-api-call-limit': ['/10'],\n }\n\n // When\n const callLimit = extractApiCallLimitFromResponse(response)\n\n // Then\n expect(callLimit).toBeUndefined()\n })\n })\n}\n"]}
|
|
@@ -22,8 +22,12 @@ export async function zip(options) {
|
|
|
22
22
|
return new Promise((resolve, reject) => {
|
|
23
23
|
const archive = archiver('zip');
|
|
24
24
|
const output = createWriteStream(outputZipPath);
|
|
25
|
-
output.on('close', () =>
|
|
26
|
-
|
|
25
|
+
output.on('close', () => {
|
|
26
|
+
resolve();
|
|
27
|
+
});
|
|
28
|
+
archive.on('error', (error) => {
|
|
29
|
+
reject(error);
|
|
30
|
+
});
|
|
27
31
|
archive.pipe(output);
|
|
28
32
|
for (const filePath of pathsToZip) {
|
|
29
33
|
const fileRelativePath = relativePath(inputDirectory, filePath);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archiver.js","sourceRoot":"","sources":["../../../src/public/node/archiver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,WAAW,CAAA;AACtC,OAAO,EAAC,IAAI,EAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,EAAC,WAAW,EAAE,aAAa,EAAE,WAAW,EAAC,MAAM,6BAA6B,CAAA;AACnF,OAAO,QAAQ,MAAM,UAAU,CAAA;AAC/B,OAAO,EAAC,iBAAiB,EAAC,MAAM,IAAI,CAAA;AAmBpC;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,OAAmB;IAC3C,MAAM,EAAC,cAAc,EAAE,aAAa,EAAE,gBAAgB,GAAG,MAAM,EAAC,GAAG,OAAO,CAAA;IAC1E,WAAW,CAAC,aAAa,CAAA,WAAW,WAAW,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,CAAA;IAC/G,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,gBAAgB,EAAE;QAC9C,GAAG,EAAE,cAAc;QACnB,QAAQ,EAAE,IAAI;QACd,GAAG,EAAE,IAAI;QACT,mBAAmB,EAAE,KAAK;KAC3B,CAAC,CAAA;IAEF,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;QAE/B,MAAM,MAAM,GAAG,iBAAiB,CAAC,aAAa,CAAC,CAAA;QAC/C,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,
|
|
1
|
+
{"version":3,"file":"archiver.js","sourceRoot":"","sources":["../../../src/public/node/archiver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,WAAW,CAAA;AACtC,OAAO,EAAC,IAAI,EAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,EAAC,WAAW,EAAE,aAAa,EAAE,WAAW,EAAC,MAAM,6BAA6B,CAAA;AACnF,OAAO,QAAQ,MAAM,UAAU,CAAA;AAC/B,OAAO,EAAC,iBAAiB,EAAC,MAAM,IAAI,CAAA;AAmBpC;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,OAAmB;IAC3C,MAAM,EAAC,cAAc,EAAE,aAAa,EAAE,gBAAgB,GAAG,MAAM,EAAC,GAAG,OAAO,CAAA;IAC1E,WAAW,CAAC,aAAa,CAAA,WAAW,WAAW,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,CAAA;IAC/G,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,gBAAgB,EAAE;QAC9C,GAAG,EAAE,cAAc;QACnB,QAAQ,EAAE,IAAI;QACd,GAAG,EAAE,IAAI;QACT,mBAAmB,EAAE,KAAK;KAC3B,CAAC,CAAA;IAEF,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;QAE/B,MAAM,MAAM,GAAG,iBAAiB,CAAC,aAAa,CAAC,CAAA;QAC/C,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACtB,OAAO,EAAE,CAAA;QACX,CAAC,CAAC,CAAA;QACF,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAC5B,MAAM,CAAC,KAAK,CAAC,CAAA;QACf,CAAC,CAAC,CAAA;QACF,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAEpB,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE;YACjC,MAAM,gBAAgB,GAAG,YAAY,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAA;YAC/D,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAC,IAAI,EAAE,gBAAgB,EAAC,CAAC,CAAA;SACjD;QAED,mEAAmE;QACnE,OAAO,CAAC,QAAQ,EAAE,CAAA;IACpB,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import {relativePath} from './path.js'\nimport {glob} from './fs.js'\nimport {outputDebug, outputContent, outputToken} from '../../public/node/output.js'\nimport archiver from 'archiver'\nimport {createWriteStream} from 'fs'\n\ninterface ZipOptions {\n /**\n * The absolute path to the directory to be zipped.\n */\n inputDirectory: string\n\n /**\n * The absolute path to the output zip file.\n */\n outputZipPath: string\n\n /**\n * Pattern to match when adding files to zip, uses glob expressions.\n */\n matchFilePattern?: string\n}\n\n/**\n * It zips a directory and by default normalizes the paths to be forward-slash.\n * Even with forward-slash paths, zip files should still be able to be opened on\n * Windows.\n *\n * @param options - ZipOptions.\n */\nexport async function zip(options: ZipOptions): Promise<void> {\n const {inputDirectory, outputZipPath, matchFilePattern = '**/*'} = options\n outputDebug(outputContent`Zipping ${outputToken.path(inputDirectory)} into ${outputToken.path(outputZipPath)}`)\n const pathsToZip = await glob(matchFilePattern, {\n cwd: inputDirectory,\n absolute: true,\n dot: true,\n followSymbolicLinks: false,\n })\n\n return new Promise((resolve, reject) => {\n const archive = archiver('zip')\n\n const output = createWriteStream(outputZipPath)\n output.on('close', () => {\n resolve()\n })\n archive.on('error', (error) => {\n reject(error)\n })\n archive.pipe(output)\n\n for (const filePath of pathsToZip) {\n const fileRelativePath = relativePath(inputDirectory, filePath)\n archive.file(filePath, {name: fileRelativePath})\n }\n\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n archive.finalize()\n })\n}\n"]}
|
|
@@ -198,7 +198,7 @@ function argsFromEnvironment(environment, options, noDefaultsResult) {
|
|
|
198
198
|
const userSpecifiedThisFlag = noDefaultsResult.flags && Object.prototype.hasOwnProperty.call(noDefaultsResult.flags, label);
|
|
199
199
|
if (flagIsRelevantToCommand && !userSpecifiedThisFlag) {
|
|
200
200
|
if (typeof value === 'boolean') {
|
|
201
|
-
if (value
|
|
201
|
+
if (value) {
|
|
202
202
|
args.push(`--${label}`);
|
|
203
203
|
}
|
|
204
204
|
else {
|