@shopify/cli-kit 3.74.1 → 3.75.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/api/graphql/admin/generated/theme_files_delete.d.ts +19 -0
- package/dist/cli/api/graphql/admin/generated/theme_files_delete.js +80 -0
- package/dist/cli/api/graphql/admin/generated/theme_files_delete.js.map +1 -0
- package/dist/private/node/constants.d.ts +1 -0
- package/dist/private/node/constants.js +1 -0
- package/dist/private/node/constants.js.map +1 -1
- package/dist/private/node/context/utilities.d.ts +1 -1
- package/dist/private/node/context/utilities.js.map +1 -1
- package/dist/private/node/session/validate.js +4 -7
- package/dist/private/node/session/validate.js.map +1 -1
- package/dist/private/node/ui/components/Tasks.d.ts +2 -1
- package/dist/private/node/ui/components/Tasks.js +8 -3
- package/dist/private/node/ui/components/Tasks.js.map +1 -1
- package/dist/private/node/ui/components/Tasks.test.js +62 -1
- package/dist/private/node/ui/components/Tasks.test.js.map +1 -1
- package/dist/private/node/ui/components/TextAnimation.d.ts +2 -1
- package/dist/private/node/ui/components/TextAnimation.js +12 -3
- package/dist/private/node/ui/components/TextAnimation.js.map +1 -1
- package/dist/public/common/string.js +0 -1
- 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/context/fqdn.js +5 -1
- package/dist/public/node/context/fqdn.js.map +1 -1
- package/dist/public/node/context/local.d.ts +12 -1
- package/dist/public/node/context/local.js +17 -5
- package/dist/public/node/context/local.js.map +1 -1
- package/dist/public/node/environment.d.ts +6 -0
- package/dist/public/node/environment.js +8 -0
- package/dist/public/node/environment.js.map +1 -1
- package/dist/public/node/git.d.ts +10 -0
- package/dist/public/node/git.js +36 -2
- package/dist/public/node/git.js.map +1 -1
- package/dist/public/node/json-schema.d.ts +3 -1
- package/dist/public/node/json-schema.js +30 -12
- package/dist/public/node/json-schema.js.map +1 -1
- package/dist/public/node/session.d.ts +6 -4
- package/dist/public/node/session.js +13 -9
- package/dist/public/node/session.js.map +1 -1
- package/dist/public/node/themes/api.d.ts +1 -1
- package/dist/public/node/themes/api.js +37 -5
- package/dist/public/node/themes/api.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -6
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { randomUUID } from './crypto.js';
|
|
1
2
|
import { getPathValue } from '../common/object.js';
|
|
2
3
|
import { capitalize } from '../common/string.js';
|
|
3
4
|
import { Ajv } from 'ajv';
|
|
4
5
|
import $RefParser from '@apidevtools/json-schema-ref-parser';
|
|
6
|
+
import cloneDeep from 'lodash/cloneDeep.js';
|
|
5
7
|
/**
|
|
6
8
|
* Normalises a JSON Schema by standardising it's internal implementation.
|
|
7
9
|
*
|
|
@@ -16,6 +18,23 @@ export async function normaliseJsonSchema(schema) {
|
|
|
16
18
|
await $RefParser.dereference(parsedSchema, { resolve: { external: false } });
|
|
17
19
|
return parsedSchema;
|
|
18
20
|
}
|
|
21
|
+
function createAjvValidator(handleInvalidAdditionalProperties, schema) {
|
|
22
|
+
// allowUnionTypes: Allows types like `type: ["string", "number"]`
|
|
23
|
+
// removeAdditional: Removes extraneous properties from the subject if `additionalProperties: false` is specified
|
|
24
|
+
let removeAdditional;
|
|
25
|
+
switch (handleInvalidAdditionalProperties) {
|
|
26
|
+
case 'strip':
|
|
27
|
+
removeAdditional = true;
|
|
28
|
+
break;
|
|
29
|
+
case 'fail':
|
|
30
|
+
removeAdditional = undefined;
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
const ajv = new Ajv({ allowUnionTypes: true, removeAdditional });
|
|
34
|
+
ajv.addKeyword('x-taplo');
|
|
35
|
+
const validator = ajv.compile(schema);
|
|
36
|
+
return validator;
|
|
37
|
+
}
|
|
19
38
|
const validatorsCache = new Map();
|
|
20
39
|
/**
|
|
21
40
|
* Given a subject object and a JSON schema contract, validate the subject against the contract.
|
|
@@ -24,19 +43,20 @@ const validatorsCache = new Map();
|
|
|
24
43
|
*
|
|
25
44
|
* @param subject - The object to validate.
|
|
26
45
|
* @param schema - The JSON schema to validate against.
|
|
46
|
+
* @param handleInvalidAdditionalProperties - Whether to strip or fail on invalid additional properties.
|
|
27
47
|
* @param identifier - The identifier of the schema being validated, used to cache the validator.
|
|
28
48
|
* @returns The result of the validation. If the state is 'error', the errors will be in a zod-like format.
|
|
29
49
|
*/
|
|
30
|
-
export function jsonSchemaValidate(subject, schema, identifier) {
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
const validator = validatorsCache.get(
|
|
34
|
-
validatorsCache.set(
|
|
35
|
-
validator(
|
|
50
|
+
export function jsonSchemaValidate(subject, schema, handleInvalidAdditionalProperties, identifier) {
|
|
51
|
+
const subjectToModify = cloneDeep(subject);
|
|
52
|
+
const cacheKey = identifier ?? randomUUID();
|
|
53
|
+
const validator = validatorsCache.get(cacheKey) ?? createAjvValidator(handleInvalidAdditionalProperties, schema);
|
|
54
|
+
validatorsCache.set(cacheKey, validator);
|
|
55
|
+
validator(subjectToModify);
|
|
36
56
|
// Errors from the contract are post-processed to be more zod-like and to deal with unions better
|
|
37
57
|
let jsonSchemaErrors;
|
|
38
58
|
if (validator.errors && validator.errors.length > 0) {
|
|
39
|
-
jsonSchemaErrors = convertJsonSchemaErrors(validator.errors,
|
|
59
|
+
jsonSchemaErrors = convertJsonSchemaErrors(validator.errors, subjectToModify, schema);
|
|
40
60
|
return {
|
|
41
61
|
state: 'error',
|
|
42
62
|
data: undefined,
|
|
@@ -46,7 +66,7 @@ export function jsonSchemaValidate(subject, schema, identifier) {
|
|
|
46
66
|
}
|
|
47
67
|
return {
|
|
48
68
|
state: 'ok',
|
|
49
|
-
data:
|
|
69
|
+
data: subjectToModify,
|
|
50
70
|
errors: undefined,
|
|
51
71
|
rawErrors: undefined,
|
|
52
72
|
};
|
|
@@ -137,8 +157,6 @@ function convertJsonSchemaErrors(rawErrors, subject, schema) {
|
|
|
137
157
|
* @returns A simplified list of errors.
|
|
138
158
|
*/
|
|
139
159
|
function simplifyUnionErrors(rawErrors, subject, schema) {
|
|
140
|
-
const ajv = new Ajv({ allowUnionTypes: true });
|
|
141
|
-
ajv.addKeyword('x-taplo');
|
|
142
160
|
let errors = rawErrors;
|
|
143
161
|
const resolvedUnionErrors = new Set();
|
|
144
162
|
while (true) {
|
|
@@ -159,7 +177,7 @@ function simplifyUnionErrors(rawErrors, subject, schema) {
|
|
|
159
177
|
// we know that none of the union schemas are correct, but for each of them we can measure how wrong they are
|
|
160
178
|
const correctValuesAndErrors = unionSchemas
|
|
161
179
|
.map((candidateSchemaFromUnion) => {
|
|
162
|
-
const candidateSchemaValidator =
|
|
180
|
+
const candidateSchemaValidator = createAjvValidator('fail', candidateSchemaFromUnion);
|
|
163
181
|
candidateSchemaValidator(subjectValue);
|
|
164
182
|
let score = 0;
|
|
165
183
|
if (candidateSchemaFromUnion.type === 'object') {
|
|
@@ -168,7 +186,7 @@ function simplifyUnionErrors(rawErrors, subject, schema) {
|
|
|
168
186
|
score = candidatesObjectProperties.reduce((acc, propertyName) => {
|
|
169
187
|
const subSchema = candidateSchemaFromUnion.properties[propertyName];
|
|
170
188
|
const subjectValueSlice = getPathValue(subjectValue, propertyName);
|
|
171
|
-
const subValidator =
|
|
189
|
+
const subValidator = createAjvValidator('fail', subSchema);
|
|
172
190
|
if (subValidator(subjectValueSlice)) {
|
|
173
191
|
return acc + 1;
|
|
174
192
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-schema.js","sourceRoot":"","sources":["../../../src/public/node/json-schema.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-non-null-assertion */\nimport {ParseConfigurationResult} from './schema.js'\nimport {getPathValue} from '../common/object.js'\nimport {capitalize} from '../common/string.js'\nimport {Ajv, ErrorObject, SchemaObject, ValidateFunction} from 'ajv'\nimport $RefParser from '@apidevtools/json-schema-ref-parser'\n\ntype AjvError = ErrorObject<string, {[key: string]: unknown}>\n\n/**\n * Normalises a JSON Schema by standardising it's internal implementation.\n *\n * We prefer to not use $ref elements in our schemas, so we inline them; it's easier then to process errors.\n *\n * @param schema - The JSON schema (as a string) to normalise.\n * @returns The normalised JSON schema.\n */\nexport async function normaliseJsonSchema(schema: string): Promise<SchemaObject> {\n // we want to modify the schema, removing any $ref elements and inlining with their source\n const parsedSchema = JSON.parse(schema)\n await $RefParser.dereference(parsedSchema, {resolve: {external: false}})\n return parsedSchema\n}\n\nconst validatorsCache = new Map<string, ValidateFunction>()\n\n/**\n * Given a subject object and a JSON schema contract, validate the subject against the contract.\n *\n * Errors are returned in a zod-like format, and processed to better handle unions.\n *\n * @param subject - The object to validate.\n * @param schema - The JSON schema to validate against.\n * @param identifier - The identifier of the schema being validated, used to cache the validator.\n * @returns The result of the validation. If the state is 'error', the errors will be in a zod-like format.\n */\nexport function jsonSchemaValidate(\n subject: object,\n schema: SchemaObject,\n identifier: string,\n): ParseConfigurationResult<unknown> & {rawErrors?: AjvError[]} {\n const ajv = new Ajv({allowUnionTypes: true})\n\n ajv.addKeyword('x-taplo')\n\n const validator = validatorsCache.get(identifier) ?? ajv.compile(schema)\n validatorsCache.set(identifier, validator)\n\n validator(subject)\n\n // Errors from the contract are post-processed to be more zod-like and to deal with unions better\n let jsonSchemaErrors\n if (validator.errors && validator.errors.length > 0) {\n jsonSchemaErrors = convertJsonSchemaErrors(validator.errors, subject, schema)\n return {\n state: 'error',\n data: undefined,\n errors: jsonSchemaErrors,\n rawErrors: validator.errors,\n }\n }\n return {\n state: 'ok',\n data: subject,\n errors: undefined,\n rawErrors: undefined,\n }\n}\n\n/**\n * Converts errors from Ajv into a zod-like format.\n *\n * @param rawErrors - JSON Schema errors taken directly from Ajv.\n * @param subject - The object being validated.\n * @param schema - The JSON schema to validated against.\n * @returns The errors in a zod-like format.\n */\nfunction convertJsonSchemaErrors(rawErrors: AjvError[], subject: object, schema: SchemaObject) {\n // This reduces the number of errors by simplifying errors coming from different branches of a union\n const errors = simplifyUnionErrors(rawErrors, subject, schema)\n\n // Now we can remap errors to be more zod-like\n return errors.map((error) => {\n const path: string[] = error.instancePath.split('/').slice(1)\n if (error.params.missingProperty) {\n const missingProperty = error.params.missingProperty as string\n return {path: [...path, missingProperty], message: 'Required'}\n }\n\n if (error.params.type) {\n const expectedType = error.params.type as string\n const actualType = getPathValue(subject, path.join('.'))\n return {path, message: `Expected ${expectedType}, received ${typeof actualType}`}\n }\n\n if (error.keyword === 'anyOf' || error.keyword === 'oneOf') {\n return {path, message: 'Invalid input'}\n }\n\n if (error.params.allowedValues) {\n const allowedValues = error.params.allowedValues as string[]\n const actualValue = getPathValue(subject, path.join('.'))\n return {\n path,\n message: `Invalid enum value. Expected ${allowedValues\n .map((value) => JSON.stringify(value))\n .join(' | ')}, received ${JSON.stringify(actualValue)}`.replace(/\"/g, \"'\"),\n }\n }\n\n if (error.params.comparison) {\n const comparison = error.params.comparison as string\n const limit = error.params.limit\n const actualValue = getPathValue(subject, path.join('.'))\n\n let comparisonText = comparison\n switch (comparison) {\n case '<=':\n comparisonText = 'less than or equal to'\n break\n case '<':\n comparisonText = 'less than'\n break\n case '>=':\n comparisonText = 'greater than or equal to'\n break\n case '>':\n comparisonText = 'greater than'\n break\n }\n\n return {\n path,\n message: capitalize(`${typeof actualValue} must be ${comparisonText} ${limit}`),\n }\n }\n\n return {\n path,\n message: error.message,\n }\n })\n}\n\n/**\n * If a JSON schema specifies a union (anyOf, oneOf), and the subject doesn't meet any of the 'candidates' for the\n * union, then the error list received ends up being quite long: you get an error for the union property itself, and\n * then additional errors for each of the candidate branches.\n *\n * This function simplifies the error collection. By default it strips anything other than the union error itself.\n *\n * In some cases, it can be possible to identify what the intended branch of the union was -- for instance, maybe there\n * is a discriminating field like `type` that is unique between the branches. We inspect each candidate branch and if\n * one branch is less wrong than the others -- e.g. It had a valid `type`, but problems elsewhere -- then we keep the\n * errors for that branch.\n *\n * This is complex but in practise gives much more actionable errors.\n *\n * @param rawErrors - JSON Schema errors taken directly from Ajv.\n * @param subject - The object being validated.\n * @param schema - The JSON schema to validated against.\n * @returns A simplified list of errors.\n */\nfunction simplifyUnionErrors(rawErrors: AjvError[], subject: object, schema: SchemaObject): AjvError[] {\n const ajv = new Ajv({allowUnionTypes: true})\n ajv.addKeyword('x-taplo')\n let errors = rawErrors\n\n const resolvedUnionErrors = new Set()\n while (true) {\n const unionError = errors.filter(\n (error) =>\n (error.keyword === 'oneOf' || error.keyword === 'anyOf') && !resolvedUnionErrors.has(error.instancePath),\n )[0]\n if (unionError === undefined) {\n break\n }\n // split errors into those sharing an instance path and those not\n const unrelatedErrors = errors.filter((error) => !error.instancePath.startsWith(unionError.instancePath))\n\n // we start by assuming only the union error itself is useful, and not the errors from the candidate schemas\n let simplifiedUnionRelatedErrors: AjvError[] = [unionError]\n\n // get the schema list from where the union issue occured\n const dottedSchemaPath = unionError.schemaPath.replace('#/', '').replace(/\\//g, '.')\n const unionSchemas = getPathValue<SchemaObject[]>(schema, dottedSchemaPath)\n // and the slice of the subject that caused the issue\n const subjectValue = getPathValue(subject, unionError.instancePath.split('/').slice(1).join('.'))\n\n if (unionSchemas !== undefined && subjectValue !== undefined) {\n // we know that none of the union schemas are correct, but for each of them we can measure how wrong they are\n const correctValuesAndErrors = unionSchemas\n .map((candidateSchemaFromUnion: SchemaObject) => {\n const candidateSchemaValidator = ajv.compile(candidateSchemaFromUnion)\n candidateSchemaValidator(subjectValue)\n\n let score = 0\n if (candidateSchemaFromUnion.type === 'object') {\n // provided the schema is an object, we can measure how many properties are good\n const candidatesObjectProperties = Object.keys(candidateSchemaFromUnion.properties)\n score = candidatesObjectProperties.reduce((acc, propertyName) => {\n const subSchema = candidateSchemaFromUnion.properties[propertyName] as SchemaObject\n const subjectValueSlice = getPathValue(subjectValue, propertyName)\n\n const subValidator = ajv.compile(subSchema)\n if (subValidator(subjectValueSlice)) {\n return acc + 1\n }\n return acc\n }, score)\n }\n\n return [score, candidateSchemaValidator.errors!] as const\n })\n .sort(([scoreA], [scoreB]) => scoreA - scoreB)\n\n if (correctValuesAndErrors.length >= 2) {\n const [bestScore, bestErrors] = correctValuesAndErrors[correctValuesAndErrors.length - 1]!\n const [penultimateScore] = correctValuesAndErrors[correctValuesAndErrors.length - 2]!\n\n if (bestScore !== penultimateScore) {\n // If there's a winner, show the errors for the best schema as they'll likely be actionable.\n // We got these through a nested schema, so we need to adjust the instance path\n simplifiedUnionRelatedErrors = [\n unionError,\n ...bestErrors.map((bestError) => ({\n ...bestError,\n instancePath: unionError.instancePath + bestError.instancePath,\n })),\n ]\n }\n }\n }\n errors = [...unrelatedErrors, ...simplifiedUnionRelatedErrors]\n\n resolvedUnionErrors.add(unionError.instancePath)\n }\n return errors\n}\n"]}
|
|
1
|
+
{"version":3,"file":"json-schema.js","sourceRoot":"","sources":["../../../src/public/node/json-schema.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-non-null-assertion */\nimport {ParseConfigurationResult} from './schema.js'\nimport {randomUUID} from './crypto.js'\nimport {getPathValue} from '../common/object.js'\nimport {capitalize} from '../common/string.js'\nimport {Ajv, ErrorObject, SchemaObject, ValidateFunction} from 'ajv'\nimport $RefParser from '@apidevtools/json-schema-ref-parser'\nimport cloneDeep from 'lodash/cloneDeep.js'\n\nexport type HandleInvalidAdditionalProperties = 'strip' | 'fail'\n\ntype AjvError = ErrorObject<string, {[key: string]: unknown}>\n\n/**\n * Normalises a JSON Schema by standardising it's internal implementation.\n *\n * We prefer to not use $ref elements in our schemas, so we inline them; it's easier then to process errors.\n *\n * @param schema - The JSON schema (as a string) to normalise.\n * @returns The normalised JSON schema.\n */\nexport async function normaliseJsonSchema(schema: string): Promise<SchemaObject> {\n // we want to modify the schema, removing any $ref elements and inlining with their source\n const parsedSchema = JSON.parse(schema)\n await $RefParser.dereference(parsedSchema, {resolve: {external: false}})\n return parsedSchema\n}\n\nfunction createAjvValidator(\n handleInvalidAdditionalProperties: HandleInvalidAdditionalProperties,\n schema: SchemaObject,\n) {\n // allowUnionTypes: Allows types like `type: [\"string\", \"number\"]`\n // removeAdditional: Removes extraneous properties from the subject if `additionalProperties: false` is specified\n let removeAdditional\n switch (handleInvalidAdditionalProperties) {\n case 'strip':\n removeAdditional = true\n break\n case 'fail':\n removeAdditional = undefined\n break\n }\n const ajv = new Ajv({allowUnionTypes: true, removeAdditional})\n ajv.addKeyword('x-taplo')\n\n const validator = ajv.compile(schema)\n\n return validator\n}\n\nconst validatorsCache = new Map<string, ValidateFunction>()\n\n/**\n * Given a subject object and a JSON schema contract, validate the subject against the contract.\n *\n * Errors are returned in a zod-like format, and processed to better handle unions.\n *\n * @param subject - The object to validate.\n * @param schema - The JSON schema to validate against.\n * @param handleInvalidAdditionalProperties - Whether to strip or fail on invalid additional properties.\n * @param identifier - The identifier of the schema being validated, used to cache the validator.\n * @returns The result of the validation. If the state is 'error', the errors will be in a zod-like format.\n */\nexport function jsonSchemaValidate(\n subject: object,\n schema: SchemaObject,\n handleInvalidAdditionalProperties: HandleInvalidAdditionalProperties,\n identifier?: string,\n): ParseConfigurationResult<unknown> & {rawErrors?: AjvError[]} {\n const subjectToModify = cloneDeep(subject)\n\n const cacheKey = identifier ?? randomUUID()\n\n const validator = validatorsCache.get(cacheKey) ?? createAjvValidator(handleInvalidAdditionalProperties, schema)\n validatorsCache.set(cacheKey, validator)\n\n validator(subjectToModify)\n\n // Errors from the contract are post-processed to be more zod-like and to deal with unions better\n let jsonSchemaErrors\n if (validator.errors && validator.errors.length > 0) {\n jsonSchemaErrors = convertJsonSchemaErrors(validator.errors, subjectToModify, schema)\n return {\n state: 'error',\n data: undefined,\n errors: jsonSchemaErrors,\n rawErrors: validator.errors,\n }\n }\n return {\n state: 'ok',\n data: subjectToModify,\n errors: undefined,\n rawErrors: undefined,\n }\n}\n\n/**\n * Converts errors from Ajv into a zod-like format.\n *\n * @param rawErrors - JSON Schema errors taken directly from Ajv.\n * @param subject - The object being validated.\n * @param schema - The JSON schema to validated against.\n * @returns The errors in a zod-like format.\n */\nfunction convertJsonSchemaErrors(rawErrors: AjvError[], subject: object, schema: SchemaObject) {\n // This reduces the number of errors by simplifying errors coming from different branches of a union\n const errors = simplifyUnionErrors(rawErrors, subject, schema)\n\n // Now we can remap errors to be more zod-like\n return errors.map((error) => {\n const path: string[] = error.instancePath.split('/').slice(1)\n if (error.params.missingProperty) {\n const missingProperty = error.params.missingProperty as string\n return {path: [...path, missingProperty], message: 'Required'}\n }\n\n if (error.params.type) {\n const expectedType = error.params.type as string\n const actualType = getPathValue(subject, path.join('.'))\n return {path, message: `Expected ${expectedType}, received ${typeof actualType}`}\n }\n\n if (error.keyword === 'anyOf' || error.keyword === 'oneOf') {\n return {path, message: 'Invalid input'}\n }\n\n if (error.params.allowedValues) {\n const allowedValues = error.params.allowedValues as string[]\n const actualValue = getPathValue(subject, path.join('.'))\n return {\n path,\n message: `Invalid enum value. Expected ${allowedValues\n .map((value) => JSON.stringify(value))\n .join(' | ')}, received ${JSON.stringify(actualValue)}`.replace(/\"/g, \"'\"),\n }\n }\n\n if (error.params.comparison) {\n const comparison = error.params.comparison as string\n const limit = error.params.limit\n const actualValue = getPathValue(subject, path.join('.'))\n\n let comparisonText = comparison\n switch (comparison) {\n case '<=':\n comparisonText = 'less than or equal to'\n break\n case '<':\n comparisonText = 'less than'\n break\n case '>=':\n comparisonText = 'greater than or equal to'\n break\n case '>':\n comparisonText = 'greater than'\n break\n }\n\n return {\n path,\n message: capitalize(`${typeof actualValue} must be ${comparisonText} ${limit}`),\n }\n }\n\n return {\n path,\n message: error.message,\n }\n })\n}\n\n/**\n * If a JSON schema specifies a union (anyOf, oneOf), and the subject doesn't meet any of the 'candidates' for the\n * union, then the error list received ends up being quite long: you get an error for the union property itself, and\n * then additional errors for each of the candidate branches.\n *\n * This function simplifies the error collection. By default it strips anything other than the union error itself.\n *\n * In some cases, it can be possible to identify what the intended branch of the union was -- for instance, maybe there\n * is a discriminating field like `type` that is unique between the branches. We inspect each candidate branch and if\n * one branch is less wrong than the others -- e.g. It had a valid `type`, but problems elsewhere -- then we keep the\n * errors for that branch.\n *\n * This is complex but in practise gives much more actionable errors.\n *\n * @param rawErrors - JSON Schema errors taken directly from Ajv.\n * @param subject - The object being validated.\n * @param schema - The JSON schema to validated against.\n * @returns A simplified list of errors.\n */\nfunction simplifyUnionErrors(rawErrors: AjvError[], subject: object, schema: SchemaObject): AjvError[] {\n let errors = rawErrors\n\n const resolvedUnionErrors = new Set()\n while (true) {\n const unionError = errors.filter(\n (error) =>\n (error.keyword === 'oneOf' || error.keyword === 'anyOf') && !resolvedUnionErrors.has(error.instancePath),\n )[0]\n if (unionError === undefined) {\n break\n }\n // split errors into those sharing an instance path and those not\n const unrelatedErrors = errors.filter((error) => !error.instancePath.startsWith(unionError.instancePath))\n\n // we start by assuming only the union error itself is useful, and not the errors from the candidate schemas\n let simplifiedUnionRelatedErrors: AjvError[] = [unionError]\n\n // get the schema list from where the union issue occured\n const dottedSchemaPath = unionError.schemaPath.replace('#/', '').replace(/\\//g, '.')\n const unionSchemas = getPathValue<SchemaObject[]>(schema, dottedSchemaPath)\n // and the slice of the subject that caused the issue\n const subjectValue = getPathValue(subject, unionError.instancePath.split('/').slice(1).join('.'))\n\n if (unionSchemas !== undefined && subjectValue !== undefined) {\n // we know that none of the union schemas are correct, but for each of them we can measure how wrong they are\n const correctValuesAndErrors = unionSchemas\n .map((candidateSchemaFromUnion: SchemaObject) => {\n const candidateSchemaValidator = createAjvValidator('fail', candidateSchemaFromUnion)\n candidateSchemaValidator(subjectValue)\n\n let score = 0\n if (candidateSchemaFromUnion.type === 'object') {\n // provided the schema is an object, we can measure how many properties are good\n const candidatesObjectProperties = Object.keys(candidateSchemaFromUnion.properties)\n score = candidatesObjectProperties.reduce((acc, propertyName) => {\n const subSchema = candidateSchemaFromUnion.properties[propertyName] as SchemaObject\n const subjectValueSlice = getPathValue(subjectValue, propertyName)\n\n const subValidator = createAjvValidator('fail', subSchema)\n if (subValidator(subjectValueSlice)) {\n return acc + 1\n }\n return acc\n }, score)\n }\n\n return [score, candidateSchemaValidator.errors!] as const\n })\n .sort(([scoreA], [scoreB]) => scoreA - scoreB)\n\n if (correctValuesAndErrors.length >= 2) {\n const [bestScore, bestErrors] = correctValuesAndErrors[correctValuesAndErrors.length - 1]!\n const [penultimateScore] = correctValuesAndErrors[correctValuesAndErrors.length - 2]!\n\n if (bestScore !== penultimateScore) {\n // If there's a winner, show the errors for the best schema as they'll likely be actionable.\n // We got these through a nested schema, so we need to adjust the instance path\n simplifiedUnionRelatedErrors = [\n unionError,\n ...bestErrors.map((bestError) => ({\n ...bestError,\n instancePath: unionError.instancePath + bestError.instancePath,\n })),\n ]\n }\n }\n }\n errors = [...unrelatedErrors, ...simplifiedUnionRelatedErrors]\n\n resolvedUnionErrors.add(unionError.instancePath)\n }\n return errors\n}\n"]}
|
|
@@ -26,14 +26,16 @@ export declare function ensureAuthenticatedPartners(scopes?: PartnersAPIScope[],
|
|
|
26
26
|
/**
|
|
27
27
|
* Ensure that we have a valid session to access the App Management API.
|
|
28
28
|
*
|
|
29
|
-
* @param scopes - Optional array of extra scopes to authenticate with.
|
|
30
|
-
* @param env - Optional environment variables to use.
|
|
31
29
|
* @param options - Optional extra options to use.
|
|
30
|
+
* @param appManagementScopes - Optional array of extra scopes to authenticate with.
|
|
31
|
+
* @param businessPlatformScopes - Optional array of extra scopes to authenticate with.
|
|
32
|
+
* @param env - Optional environment variables to use.
|
|
32
33
|
* @returns The access token for the App Management API.
|
|
33
34
|
*/
|
|
34
|
-
export declare function
|
|
35
|
-
|
|
35
|
+
export declare function ensureAuthenticatedAppManagementAndBusinessPlatform(options?: EnsureAuthenticatedAdditionalOptions, appManagementScopes?: AppManagementAPIScope[], businessPlatformScopes?: BusinessPlatformScope[], env?: NodeJS.ProcessEnv): Promise<{
|
|
36
|
+
appManagementToken: string;
|
|
36
37
|
userId: string;
|
|
38
|
+
businessPlatformToken: string;
|
|
37
39
|
}>;
|
|
38
40
|
/**
|
|
39
41
|
* Ensure that we have a valid session to access the Storefront API.
|
|
@@ -35,21 +35,25 @@ ${outputToken.json(scopes)}
|
|
|
35
35
|
/**
|
|
36
36
|
* Ensure that we have a valid session to access the App Management API.
|
|
37
37
|
*
|
|
38
|
-
* @param scopes - Optional array of extra scopes to authenticate with.
|
|
39
|
-
* @param env - Optional environment variables to use.
|
|
40
38
|
* @param options - Optional extra options to use.
|
|
39
|
+
* @param appManagementScopes - Optional array of extra scopes to authenticate with.
|
|
40
|
+
* @param businessPlatformScopes - Optional array of extra scopes to authenticate with.
|
|
41
|
+
* @param env - Optional environment variables to use.
|
|
41
42
|
* @returns The access token for the App Management API.
|
|
42
43
|
*/
|
|
43
|
-
export async function
|
|
44
|
+
export async function ensureAuthenticatedAppManagementAndBusinessPlatform(options = {}, appManagementScopes = [], businessPlatformScopes = [], env = process.env) {
|
|
44
45
|
outputDebug(outputContent `Ensuring that the user is authenticated with the App Management API with the following scopes:
|
|
45
|
-
${outputToken.json(
|
|
46
|
+
${outputToken.json(appManagementScopes)}
|
|
46
47
|
`);
|
|
47
|
-
const tokens = await ensureAuthenticated({ appManagementApi: { scopes } }, env, options);
|
|
48
|
-
if (!tokens) {
|
|
49
|
-
throw new BugError('No App Management token found after ensuring authenticated');
|
|
48
|
+
const tokens = await ensureAuthenticated({ appManagementApi: { scopes: appManagementScopes }, businessPlatformApi: { scopes: businessPlatformScopes } }, env, options);
|
|
49
|
+
if (!tokens.appManagement || !tokens.businessPlatform) {
|
|
50
|
+
throw new BugError('No App Management or Business Platform token found after ensuring authenticated');
|
|
50
51
|
}
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
return {
|
|
53
|
+
appManagementToken: tokens.appManagement,
|
|
54
|
+
userId: tokens.userId,
|
|
55
|
+
businessPlatformToken: tokens.businessPlatform,
|
|
56
|
+
};
|
|
53
57
|
}
|
|
54
58
|
/**
|
|
55
59
|
* Ensure that we have a valid session to access the Storefront API.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/public/node/session.ts"],"names":[],"mappings":"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","sourcesContent":["import {normalizeStoreFqdn} from './context/fqdn.js'\nimport {BugError} from './error.js'\nimport {getPartnersToken} from './environment.js'\nimport {nonRandomUUID} from './crypto.js'\nimport * as secureStore from '../../private/node/session/store.js'\nimport {exchangeCustomPartnerToken} from '../../private/node/session/exchange.js'\nimport {outputContent, outputToken, outputDebug} from '../../public/node/output.js'\nimport {\n AdminAPIScope,\n AppManagementAPIScope,\n BusinessPlatformScope,\n PartnersAPIScope,\n StorefrontRendererScope,\n ensureAuthenticated,\n setLastSeenAuthMethod,\n setLastSeenUserIdAfterAuth,\n} from '../../private/node/session.js'\nimport {isThemeAccessSession} from '../../private/node/api/rest.js'\n\n/**\n * Session Object to access the Admin API, includes the token and the store FQDN.\n */\nexport interface AdminSession {\n token: string\n storeFqdn: string\n}\n\ninterface EnsureAuthenticatedAdditionalOptions {\n noPrompt?: boolean\n}\n\n/**\n * Ensure that we have a valid session to access the Partners API.\n * If SHOPIFY_CLI_PARTNERS_TOKEN exists, that token will be used to obtain a valid Partners Token\n * If SHOPIFY_CLI_PARTNERS_TOKEN exists, scopes will be ignored.\n *\n * @param scopes - Optional array of extra scopes to authenticate with.\n * @param env - Optional environment variables to use.\n * @param options - Optional extra options to use.\n * @returns The access token for the Partners API.\n */\nexport async function ensureAuthenticatedPartners(\n scopes: PartnersAPIScope[] = [],\n env = process.env,\n options: EnsureAuthenticatedAdditionalOptions = {},\n): Promise<{token: string; userId: string}> {\n outputDebug(outputContent`Ensuring that the user is authenticated with the Partners API with the following scopes:\n${outputToken.json(scopes)}\n`)\n const envToken = getPartnersToken()\n if (envToken) {\n const result = await exchangeCustomPartnerToken(envToken)\n return {token: result.accessToken, userId: result.userId}\n }\n const tokens = await ensureAuthenticated({partnersApi: {scopes}}, env, options)\n if (!tokens.partners) {\n throw new BugError('No partners token found after ensuring authenticated')\n }\n return {token: tokens.partners, userId: tokens.userId}\n}\n\n/**\n * Ensure that we have a valid session to access the App Management API.\n *\n * @param scopes - Optional array of extra scopes to authenticate with.\n * @param env - Optional environment variables to use.\n * @param options - Optional extra options to use.\n * @returns The access token for the App Management API.\n */\nexport async function ensureAuthenticatedAppManagement(\n scopes: AppManagementAPIScope[] = [],\n env = process.env,\n options: EnsureAuthenticatedAdditionalOptions = {},\n): Promise<{token: string; userId: string}> {\n outputDebug(outputContent`Ensuring that the user is authenticated with the App Management API with the following scopes:\n${outputToken.json(scopes)}\n`)\n const tokens = await ensureAuthenticated({appManagementApi: {scopes}}, env, options)\n if (!tokens) {\n throw new BugError('No App Management token found after ensuring authenticated')\n }\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return {token: tokens.appManagement!, userId: tokens.userId}\n}\n\n/**\n * Ensure that we have a valid session to access the Storefront API.\n *\n * @param scopes - Optional array of extra scopes to authenticate with.\n * @param password - Optional password to use.\n * @param forceRefresh - Optional flag to force a refresh of the token.\n * @returns The access token for the Storefront API.\n */\nexport async function ensureAuthenticatedStorefront(\n scopes: StorefrontRendererScope[] = [],\n password: string | undefined = undefined,\n forceRefresh = false,\n): Promise<string> {\n if (password) {\n const session = {token: password, storeFqdn: ''}\n const authMethod = isThemeAccessSession(session) ? 'theme_access_token' : 'custom_app_token'\n setLastSeenAuthMethod(authMethod)\n setLastSeenUserIdAfterAuth(nonRandomUUID(password))\n return password\n }\n\n outputDebug(outputContent`Ensuring that the user is authenticated with the Storefront API with the following scopes:\n${outputToken.json(scopes)}\n`)\n const tokens = await ensureAuthenticated({storefrontRendererApi: {scopes}}, process.env, {forceRefresh})\n if (!tokens.storefront) {\n throw new BugError('No storefront token found after ensuring authenticated')\n }\n return tokens.storefront\n}\n\n/**\n * Ensure that we have a valid Admin session for the given store.\n *\n * @param store - Store fqdn to request auth for.\n * @param scopes - Optional array of extra scopes to authenticate with.\n * @param forceRefresh - Optional flag to force a refresh of the token.\n * @param options - Optional extra options to use.\n * @returns The access token for the Admin API.\n */\nexport async function ensureAuthenticatedAdmin(\n store: string,\n scopes: AdminAPIScope[] = [],\n forceRefresh = false,\n options: EnsureAuthenticatedAdditionalOptions = {},\n): Promise<AdminSession> {\n outputDebug(outputContent`Ensuring that the user is authenticated with the Admin API with the following scopes for the store ${outputToken.raw(\n store,\n )}:\n${outputToken.json(scopes)}\n`)\n const tokens = await ensureAuthenticated({adminApi: {scopes, storeFqdn: store}}, process.env, {\n forceRefresh,\n ...options,\n })\n if (!tokens.admin) {\n throw new BugError('No admin token found after ensuring authenticated')\n }\n return tokens.admin\n}\n\n/**\n * Ensure that we have a valid session to access the Theme API.\n * If a password is provided, that token will be used against Theme Access API.\n * Otherwise, it will ensure that the user is authenticated with the Admin API.\n *\n * @param store - Store fqdn to request auth for.\n * @param password - Password generated from Theme Access app.\n * @param scopes - Optional array of extra scopes to authenticate with.\n * @param forceRefresh - Optional flag to force a refresh of the token.\n * @returns The access token and store.\n */\nexport async function ensureAuthenticatedThemes(\n store: string,\n password: string | undefined,\n scopes: AdminAPIScope[] = [],\n forceRefresh = false,\n): Promise<AdminSession> {\n outputDebug(outputContent`Ensuring that the user is authenticated with the Theme API with the following scopes:\n${outputToken.json(scopes)}\n`)\n if (password) {\n const session = {token: password, storeFqdn: await normalizeStoreFqdn(store)}\n const authMethod = isThemeAccessSession(session) ? 'theme_access_token' : 'custom_app_token'\n setLastSeenAuthMethod(authMethod)\n setLastSeenUserIdAfterAuth(nonRandomUUID(password))\n return session\n }\n return ensureAuthenticatedAdmin(store, scopes, forceRefresh)\n}\n\n/**\n * Ensure that we have a valid session to access the Business Platform API.\n *\n * @param scopes - Optional array of extra scopes to authenticate with.\n * @returns The access token for the Business Platform API.\n */\nexport async function ensureAuthenticatedBusinessPlatform(scopes: BusinessPlatformScope[] = []): Promise<string> {\n outputDebug(outputContent`Ensuring that the user is authenticated with the Business Platform API with the following scopes:\n${outputToken.json(scopes)}\n`)\n const tokens = await ensureAuthenticated({businessPlatformApi: {scopes}}, process.env)\n if (!tokens.businessPlatform) {\n throw new BugError('No business-platform token found after ensuring authenticated')\n }\n return tokens.businessPlatform\n}\n\n/**\n * Logout from Shopify.\n *\n * @returns A promise that resolves when the logout is complete.\n */\nexport function logout(): Promise<void> {\n return secureStore.remove()\n}\n"]}
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/public/node/session.ts"],"names":[],"mappings":"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","sourcesContent":["import {normalizeStoreFqdn} from './context/fqdn.js'\nimport {BugError} from './error.js'\nimport {getPartnersToken} from './environment.js'\nimport {nonRandomUUID} from './crypto.js'\nimport * as secureStore from '../../private/node/session/store.js'\nimport {exchangeCustomPartnerToken} from '../../private/node/session/exchange.js'\nimport {outputContent, outputToken, outputDebug} from '../../public/node/output.js'\nimport {\n AdminAPIScope,\n AppManagementAPIScope,\n BusinessPlatformScope,\n PartnersAPIScope,\n StorefrontRendererScope,\n ensureAuthenticated,\n setLastSeenAuthMethod,\n setLastSeenUserIdAfterAuth,\n} from '../../private/node/session.js'\nimport {isThemeAccessSession} from '../../private/node/api/rest.js'\n\n/**\n * Session Object to access the Admin API, includes the token and the store FQDN.\n */\nexport interface AdminSession {\n token: string\n storeFqdn: string\n}\n\ninterface EnsureAuthenticatedAdditionalOptions {\n noPrompt?: boolean\n}\n\n/**\n * Ensure that we have a valid session to access the Partners API.\n * If SHOPIFY_CLI_PARTNERS_TOKEN exists, that token will be used to obtain a valid Partners Token\n * If SHOPIFY_CLI_PARTNERS_TOKEN exists, scopes will be ignored.\n *\n * @param scopes - Optional array of extra scopes to authenticate with.\n * @param env - Optional environment variables to use.\n * @param options - Optional extra options to use.\n * @returns The access token for the Partners API.\n */\nexport async function ensureAuthenticatedPartners(\n scopes: PartnersAPIScope[] = [],\n env = process.env,\n options: EnsureAuthenticatedAdditionalOptions = {},\n): Promise<{token: string; userId: string}> {\n outputDebug(outputContent`Ensuring that the user is authenticated with the Partners API with the following scopes:\n${outputToken.json(scopes)}\n`)\n const envToken = getPartnersToken()\n if (envToken) {\n const result = await exchangeCustomPartnerToken(envToken)\n return {token: result.accessToken, userId: result.userId}\n }\n const tokens = await ensureAuthenticated({partnersApi: {scopes}}, env, options)\n if (!tokens.partners) {\n throw new BugError('No partners token found after ensuring authenticated')\n }\n return {token: tokens.partners, userId: tokens.userId}\n}\n\n/**\n * Ensure that we have a valid session to access the App Management API.\n *\n * @param options - Optional extra options to use.\n * @param appManagementScopes - Optional array of extra scopes to authenticate with.\n * @param businessPlatformScopes - Optional array of extra scopes to authenticate with.\n * @param env - Optional environment variables to use.\n * @returns The access token for the App Management API.\n */\nexport async function ensureAuthenticatedAppManagementAndBusinessPlatform(\n options: EnsureAuthenticatedAdditionalOptions = {},\n appManagementScopes: AppManagementAPIScope[] = [],\n businessPlatformScopes: BusinessPlatformScope[] = [],\n env = process.env,\n): Promise<{appManagementToken: string; userId: string; businessPlatformToken: string}> {\n outputDebug(outputContent`Ensuring that the user is authenticated with the App Management API with the following scopes:\n${outputToken.json(appManagementScopes)}\n`)\n const tokens = await ensureAuthenticated(\n {appManagementApi: {scopes: appManagementScopes}, businessPlatformApi: {scopes: businessPlatformScopes}},\n env,\n options,\n )\n if (!tokens.appManagement || !tokens.businessPlatform) {\n throw new BugError('No App Management or Business Platform token found after ensuring authenticated')\n }\n\n return {\n appManagementToken: tokens.appManagement,\n userId: tokens.userId,\n businessPlatformToken: tokens.businessPlatform,\n }\n}\n\n/**\n * Ensure that we have a valid session to access the Storefront API.\n *\n * @param scopes - Optional array of extra scopes to authenticate with.\n * @param password - Optional password to use.\n * @param forceRefresh - Optional flag to force a refresh of the token.\n * @returns The access token for the Storefront API.\n */\nexport async function ensureAuthenticatedStorefront(\n scopes: StorefrontRendererScope[] = [],\n password: string | undefined = undefined,\n forceRefresh = false,\n): Promise<string> {\n if (password) {\n const session = {token: password, storeFqdn: ''}\n const authMethod = isThemeAccessSession(session) ? 'theme_access_token' : 'custom_app_token'\n setLastSeenAuthMethod(authMethod)\n setLastSeenUserIdAfterAuth(nonRandomUUID(password))\n return password\n }\n\n outputDebug(outputContent`Ensuring that the user is authenticated with the Storefront API with the following scopes:\n${outputToken.json(scopes)}\n`)\n const tokens = await ensureAuthenticated({storefrontRendererApi: {scopes}}, process.env, {forceRefresh})\n if (!tokens.storefront) {\n throw new BugError('No storefront token found after ensuring authenticated')\n }\n return tokens.storefront\n}\n\n/**\n * Ensure that we have a valid Admin session for the given store.\n *\n * @param store - Store fqdn to request auth for.\n * @param scopes - Optional array of extra scopes to authenticate with.\n * @param forceRefresh - Optional flag to force a refresh of the token.\n * @param options - Optional extra options to use.\n * @returns The access token for the Admin API.\n */\nexport async function ensureAuthenticatedAdmin(\n store: string,\n scopes: AdminAPIScope[] = [],\n forceRefresh = false,\n options: EnsureAuthenticatedAdditionalOptions = {},\n): Promise<AdminSession> {\n outputDebug(outputContent`Ensuring that the user is authenticated with the Admin API with the following scopes for the store ${outputToken.raw(\n store,\n )}:\n${outputToken.json(scopes)}\n`)\n const tokens = await ensureAuthenticated({adminApi: {scopes, storeFqdn: store}}, process.env, {\n forceRefresh,\n ...options,\n })\n if (!tokens.admin) {\n throw new BugError('No admin token found after ensuring authenticated')\n }\n return tokens.admin\n}\n\n/**\n * Ensure that we have a valid session to access the Theme API.\n * If a password is provided, that token will be used against Theme Access API.\n * Otherwise, it will ensure that the user is authenticated with the Admin API.\n *\n * @param store - Store fqdn to request auth for.\n * @param password - Password generated from Theme Access app.\n * @param scopes - Optional array of extra scopes to authenticate with.\n * @param forceRefresh - Optional flag to force a refresh of the token.\n * @returns The access token and store.\n */\nexport async function ensureAuthenticatedThemes(\n store: string,\n password: string | undefined,\n scopes: AdminAPIScope[] = [],\n forceRefresh = false,\n): Promise<AdminSession> {\n outputDebug(outputContent`Ensuring that the user is authenticated with the Theme API with the following scopes:\n${outputToken.json(scopes)}\n`)\n if (password) {\n const session = {token: password, storeFqdn: await normalizeStoreFqdn(store)}\n const authMethod = isThemeAccessSession(session) ? 'theme_access_token' : 'custom_app_token'\n setLastSeenAuthMethod(authMethod)\n setLastSeenUserIdAfterAuth(nonRandomUUID(password))\n return session\n }\n return ensureAuthenticatedAdmin(store, scopes, forceRefresh)\n}\n\n/**\n * Ensure that we have a valid session to access the Business Platform API.\n *\n * @param scopes - Optional array of extra scopes to authenticate with.\n * @returns The access token for the Business Platform API.\n */\nexport async function ensureAuthenticatedBusinessPlatform(scopes: BusinessPlatformScope[] = []): Promise<string> {\n outputDebug(outputContent`Ensuring that the user is authenticated with the Business Platform API with the following scopes:\n${outputToken.json(scopes)}\n`)\n const tokens = await ensureAuthenticated({businessPlatformApi: {scopes}}, process.env)\n if (!tokens.businessPlatform) {\n throw new BugError('No business-platform token found after ensuring authenticated')\n }\n return tokens.businessPlatform\n}\n\n/**\n * Logout from Shopify.\n *\n * @returns A promise that resolves when the logout is complete.\n */\nexport function logout(): Promise<void> {\n return secureStore.remove()\n}\n"]}
|
|
@@ -7,7 +7,7 @@ export declare function fetchTheme(id: number, session: AdminSession): Promise<T
|
|
|
7
7
|
export declare function fetchThemes(session: AdminSession): Promise<Theme[]>;
|
|
8
8
|
export declare function createTheme(params: ThemeParams, session: AdminSession): Promise<Theme | undefined>;
|
|
9
9
|
export declare function fetchThemeAssets(id: number, filenames: Key[], session: AdminSession): Promise<ThemeAsset[]>;
|
|
10
|
-
export declare function
|
|
10
|
+
export declare function deleteThemeAssets(id: number, filenames: Key[], session: AdminSession): Promise<Result[]>;
|
|
11
11
|
export declare function bulkUploadThemeAssets(id: number, assets: AssetParams[], session: AdminSession): Promise<Result[]>;
|
|
12
12
|
export declare function fetchChecksums(id: number, session: AdminSession): Promise<Checksum[]>;
|
|
13
13
|
export declare function themeUpdate(id: number, params: ThemeParams, session: AdminSession): Promise<Theme | undefined>;
|
|
@@ -7,6 +7,7 @@ import { ThemePublish } from '../../../cli/api/graphql/admin/generated/theme_pub
|
|
|
7
7
|
import { GetThemeFileBodies } from '../../../cli/api/graphql/admin/generated/get_theme_file_bodies.js';
|
|
8
8
|
import { GetThemeFileChecksums } from '../../../cli/api/graphql/admin/generated/get_theme_file_checksums.js';
|
|
9
9
|
import { ThemeFilesUpsert, } from '../../../cli/api/graphql/admin/generated/theme_files_upsert.js';
|
|
10
|
+
import { ThemeFilesDelete } from '../../../cli/api/graphql/admin/generated/theme_files_delete.js';
|
|
10
11
|
import { MetafieldDefinitionsByOwnerType } from '../../../cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.js';
|
|
11
12
|
import { GetThemes } from '../../../cli/api/graphql/admin/generated/get_themes.js';
|
|
12
13
|
import { GetTheme } from '../../../cli/api/graphql/admin/generated/get_theme.js';
|
|
@@ -114,11 +115,42 @@ export async function fetchThemeAssets(id, filenames, session) {
|
|
|
114
115
|
after = pageInfo.endCursor;
|
|
115
116
|
}
|
|
116
117
|
}
|
|
117
|
-
export async function
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
118
|
+
export async function deleteThemeAssets(id, filenames, session) {
|
|
119
|
+
const batchSize = 50;
|
|
120
|
+
const results = [];
|
|
121
|
+
for (let i = 0; i < filenames.length; i += batchSize) {
|
|
122
|
+
const batch = filenames.slice(i, i + batchSize);
|
|
123
|
+
// eslint-disable-next-line no-await-in-loop
|
|
124
|
+
const { themeFilesDelete } = await adminRequestDoc(ThemeFilesDelete, session, {
|
|
125
|
+
themeId: composeThemeGid(id),
|
|
126
|
+
files: batch,
|
|
127
|
+
});
|
|
128
|
+
if (!themeFilesDelete) {
|
|
129
|
+
unexpectedGraphQLError('Failed to delete theme assets');
|
|
130
|
+
}
|
|
131
|
+
const { deletedThemeFiles, userErrors } = themeFilesDelete;
|
|
132
|
+
if (deletedThemeFiles) {
|
|
133
|
+
deletedThemeFiles.forEach((file) => {
|
|
134
|
+
results.push({ key: file.filename, success: true, operation: Operation.Delete });
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
if (userErrors.length > 0) {
|
|
138
|
+
userErrors.forEach((error) => {
|
|
139
|
+
if (error.filename) {
|
|
140
|
+
results.push({
|
|
141
|
+
key: error.filename,
|
|
142
|
+
success: false,
|
|
143
|
+
operation: Operation.Delete,
|
|
144
|
+
errors: { asset: [error.message] },
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
unexpectedGraphQLError(`Failed to delete theme assets: ${error.message}`);
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return results;
|
|
122
154
|
}
|
|
123
155
|
export async function bulkUploadThemeAssets(id, assets, session) {
|
|
124
156
|
const results = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../../src/public/node/themes/api.ts"],"names":[],"mappings":"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","sourcesContent":["import {storeAdminUrl} from './urls.js'\nimport {composeThemeGid, parseGid} from './utils.js'\nimport * as throttler from '../api/rest-api-throttler.js'\nimport {ThemeUpdate} from '../../../cli/api/graphql/admin/generated/theme_update.js'\nimport {ThemeDelete} from '../../../cli/api/graphql/admin/generated/theme_delete.js'\nimport {ThemePublish} from '../../../cli/api/graphql/admin/generated/theme_publish.js'\nimport {GetThemeFileBodies} from '../../../cli/api/graphql/admin/generated/get_theme_file_bodies.js'\nimport {GetThemeFileChecksums} from '../../../cli/api/graphql/admin/generated/get_theme_file_checksums.js'\nimport {\n ThemeFilesUpsert,\n ThemeFilesUpsertMutation,\n} from '../../../cli/api/graphql/admin/generated/theme_files_upsert.js'\nimport {\n OnlineStoreThemeFileBodyInputType,\n OnlineStoreThemeFilesUpsertFileInput,\n MetafieldOwnerType,\n} from '../../../cli/api/graphql/admin/generated/types.js'\nimport {MetafieldDefinitionsByOwnerType} from '../../../cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.js'\nimport {GetThemes} from '../../../cli/api/graphql/admin/generated/get_themes.js'\nimport {GetTheme} from '../../../cli/api/graphql/admin/generated/get_theme.js'\nimport {OnlineStorePasswordProtection} from '../../../cli/api/graphql/admin/generated/online_store_password_protection.js'\nimport {restRequest, RestResponse, adminRequestDoc} from '@shopify/cli-kit/node/api/admin'\nimport {AdminSession} from '@shopify/cli-kit/node/session'\nimport {AbortError} from '@shopify/cli-kit/node/error'\nimport {buildTheme} from '@shopify/cli-kit/node/themes/factories'\nimport {Result, Checksum, Key, Theme, ThemeAsset, Operation} from '@shopify/cli-kit/node/themes/types'\nimport {outputDebug} from '@shopify/cli-kit/node/output'\nimport {sleep} from '@shopify/cli-kit/node/system'\n\nexport type ThemeParams = Partial<Pick<Theme, 'name' | 'role' | 'processing' | 'src'>>\nexport type AssetParams = Pick<ThemeAsset, 'key'> & Partial<Pick<ThemeAsset, 'value' | 'attachment'>>\n\nexport async function fetchTheme(id: number, session: AdminSession): Promise<Theme | undefined> {\n const gid = composeThemeGid(id)\n\n try {\n const {theme} = await adminRequestDoc(GetTheme, session, {id: gid}, undefined, {\n handleErrors: false,\n })\n\n if (theme) {\n return buildTheme({\n id: parseGid(theme.id),\n processing: theme.processing,\n role: theme.role.toLowerCase(),\n name: theme.name,\n })\n }\n\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (_error) {\n /**\n * Consumers of this and other theme APIs in this file expect either a theme\n * or `undefined`.\n *\n * Error handlers should not inspect GraphQL error messages directly, as\n * they are internationalized.\n */\n outputDebug(`Error fetching theme with ID: ${id}`)\n }\n}\n\nexport async function fetchThemes(session: AdminSession): Promise<Theme[]> {\n const themes: Theme[] = []\n let after: string | null = null\n\n while (true) {\n // eslint-disable-next-line no-await-in-loop\n const response = await adminRequestDoc(GetThemes, session, {after})\n if (!response.themes) {\n unexpectedGraphQLError('Failed to fetch themes')\n }\n const {nodes, pageInfo} = response.themes\n nodes.forEach((theme) => {\n const t = buildTheme({\n id: parseGid(theme.id),\n processing: theme.processing,\n role: theme.role.toLowerCase(),\n name: theme.name,\n })\n if (t) {\n themes.push(t)\n }\n })\n if (!pageInfo.hasNextPage) {\n return themes\n }\n\n after = pageInfo.endCursor as string\n }\n}\n\nexport async function createTheme(params: ThemeParams, session: AdminSession): Promise<Theme | undefined> {\n const response = await request('POST', '/themes', session, {theme: {...params}})\n\n if (!params.src) {\n const minimumThemeAssets = [\n {key: 'config/settings_schema.json', value: '[]'},\n {key: 'layout/password.liquid', value: '{{ content_for_header }}{{ content_for_layout }}'},\n {key: 'layout/theme.liquid', value: '{{ content_for_header }}{{ content_for_layout }}'},\n ]\n\n await bulkUploadThemeAssets(response.json.theme.id, minimumThemeAssets, session)\n }\n\n return buildTheme({...response.json.theme, createdAtRuntime: true})\n}\n\nexport async function fetchThemeAssets(id: number, filenames: Key[], session: AdminSession): Promise<ThemeAsset[]> {\n const assets: ThemeAsset[] = []\n let after: string | null = null\n\n while (true) {\n // eslint-disable-next-line no-await-in-loop\n const response = await adminRequestDoc(GetThemeFileBodies, session, {\n id: themeGid(id),\n filenames,\n after,\n })\n\n if (!response.theme?.files?.nodes || !response.theme?.files?.pageInfo) {\n const userErrors = response.theme?.files?.userErrors.map((error) => error.filename).join(', ')\n unexpectedGraphQLError(`Error fetching assets: ${userErrors}`)\n }\n\n const {nodes, pageInfo} = response.theme.files\n\n assets.push(\n // eslint-disable-next-line no-await-in-loop\n ...(await Promise.all(\n nodes.map(async (file) => {\n const content = await parseThemeFileContent(file.body)\n return {\n key: file.filename,\n checksum: file.checksumMd5 as string,\n value: content,\n }\n }),\n )),\n )\n\n if (!pageInfo.hasNextPage) {\n return assets\n }\n\n after = pageInfo.endCursor as string\n }\n}\n\nexport async function deleteThemeAsset(id: number, key: Key, session: AdminSession): Promise<boolean> {\n const response = await request('DELETE', `/themes/${id}/assets`, session, undefined, {\n 'asset[key]': key,\n })\n return response.status === 200\n}\n\nexport async function bulkUploadThemeAssets(\n id: number,\n assets: AssetParams[],\n session: AdminSession,\n): Promise<Result[]> {\n const results: Result[] = []\n for (let i = 0; i < assets.length; i += 50) {\n const chunk = assets.slice(i, i + 50)\n const files = prepareFilesForUpload(chunk)\n // eslint-disable-next-line no-await-in-loop\n const uploadResults = await uploadFiles(id, files, session)\n results.push(...processUploadResults(uploadResults))\n }\n return results\n}\n\nfunction prepareFilesForUpload(assets: AssetParams[]): OnlineStoreThemeFilesUpsertFileInput[] {\n return assets.map((asset) => {\n if (asset.attachment) {\n return {\n filename: asset.key,\n body: {\n type: 'BASE64' as const,\n value: asset.attachment,\n },\n }\n } else {\n return {\n filename: asset.key,\n body: {\n type: 'TEXT' as const,\n value: asset.value ?? '',\n },\n }\n }\n })\n}\n\nasync function uploadFiles(\n themeId: number,\n files: {filename: string; body: {type: OnlineStoreThemeFileBodyInputType; value: string}}[],\n session: AdminSession,\n): Promise<ThemeFilesUpsertMutation> {\n return adminRequestDoc(ThemeFilesUpsert, session, {themeId: themeGid(themeId), files})\n}\n\nfunction processUploadResults(uploadResults: ThemeFilesUpsertMutation): Result[] {\n const {themeFilesUpsert} = uploadResults\n\n if (!themeFilesUpsert) {\n unexpectedGraphQLError('Failed to upload theme files')\n }\n\n const {upsertedThemeFiles, userErrors} = themeFilesUpsert\n\n const results: Result[] = []\n\n upsertedThemeFiles?.forEach((file) => {\n results.push({\n key: file.filename,\n success: true,\n operation: Operation.Upload,\n })\n })\n\n userErrors.forEach((error) => {\n if (!error.filename) {\n unexpectedGraphQLError(`Error uploading theme files: ${error.message}`)\n }\n results.push({\n key: error.filename,\n success: false,\n operation: Operation.Upload,\n errors: {asset: [error.message]},\n })\n })\n\n return results\n}\n\nexport async function fetchChecksums(id: number, session: AdminSession): Promise<Checksum[]> {\n const checksums: Checksum[] = []\n let after: string | null = null\n\n while (true) {\n // eslint-disable-next-line no-await-in-loop\n const response = await adminRequestDoc(GetThemeFileChecksums, session, {id: themeGid(id), after})\n\n if (!response?.theme?.files?.nodes || !response?.theme?.files?.pageInfo) {\n const userErrors = response.theme?.files?.userErrors.map((error) => error.filename).join(', ')\n throw new AbortError(`Failed to fetch checksums for: ${userErrors}`)\n }\n\n const {nodes, pageInfo} = response.theme.files\n\n checksums.push(\n ...nodes.map((file) => ({\n key: file.filename,\n checksum: file.checksumMd5 as string,\n })),\n )\n\n if (!pageInfo.hasNextPage) {\n return checksums\n }\n\n after = pageInfo.endCursor as string\n }\n}\n\nexport async function themeUpdate(id: number, params: ThemeParams, session: AdminSession): Promise<Theme | undefined> {\n const name = params.name\n const input: {[key: string]: string} = {}\n if (name) {\n input.name = name\n }\n\n const {themeUpdate} = await adminRequestDoc(ThemeUpdate, session, {id: composeThemeGid(id), input})\n if (!themeUpdate) {\n // An unexpected error occurred during the GraphQL request execution\n unexpectedGraphQLError('Failed to update theme')\n }\n\n const {theme, userErrors} = themeUpdate\n if (userErrors.length) {\n const userErrors = themeUpdate.userErrors.map((error) => error.message).join(', ')\n throw new AbortError(userErrors)\n }\n\n if (!theme) {\n // An unexpected error if neither theme nor userErrors are returned\n unexpectedGraphQLError('Failed to update theme')\n }\n\n return buildTheme({\n id: parseGid(theme.id),\n name: theme.name,\n role: theme.role.toLowerCase(),\n })\n}\n\nexport async function themePublish(id: number, session: AdminSession): Promise<Theme | undefined> {\n const {themePublish} = await adminRequestDoc(ThemePublish, session, {id: composeThemeGid(id)})\n if (!themePublish) {\n // An unexpected error occurred during the GraphQL request execution\n unexpectedGraphQLError('Failed to update theme')\n }\n\n const {theme, userErrors} = themePublish\n if (userErrors.length) {\n const userErrors = themePublish.userErrors.map((error) => error.message).join(', ')\n throw new AbortError(userErrors)\n }\n\n if (!theme) {\n // An unexpected error if neither theme nor userErrors are returned\n unexpectedGraphQLError('Failed to update theme')\n }\n\n return buildTheme({\n id: parseGid(theme.id),\n name: theme.name,\n role: theme.role.toLowerCase(),\n })\n}\n\nexport async function themeDelete(id: number, session: AdminSession): Promise<boolean | undefined> {\n const {themeDelete} = await adminRequestDoc(ThemeDelete, session, {id: composeThemeGid(id)})\n if (!themeDelete) {\n // An unexpected error occurred during the GraphQL request execution\n unexpectedGraphQLError('Failed to update theme')\n }\n\n const {deletedThemeId, userErrors} = themeDelete\n if (userErrors.length) {\n const userErrors = themeDelete.userErrors.map((error) => error.message).join(', ')\n throw new AbortError(userErrors)\n }\n\n if (!deletedThemeId) {\n // An unexpected error if neither theme nor userErrors are returned\n unexpectedGraphQLError('Failed to update theme')\n }\n\n return true\n}\n\nexport async function metafieldDefinitionsByOwnerType(type: MetafieldOwnerType, session: AdminSession) {\n const {metafieldDefinitions} = await adminRequestDoc(MetafieldDefinitionsByOwnerType, session, {\n ownerType: type,\n })\n\n return metafieldDefinitions.nodes.map((definition) => ({\n key: definition.key,\n namespace: definition.namespace,\n name: definition.name,\n description: definition.description,\n type: {\n name: definition.type.name,\n category: definition.type.category,\n },\n }))\n}\n\nexport async function passwordProtected(session: AdminSession): Promise<boolean> {\n const {onlineStore} = await adminRequestDoc(OnlineStorePasswordProtection, session)\n if (!onlineStore) {\n unexpectedGraphQLError(\"Unable to get details about the storefront's password protection\")\n }\n\n const {passwordProtection} = onlineStore\n\n return passwordProtection.enabled\n}\n\nasync function request<T>(\n method: string,\n path: string,\n session: AdminSession,\n params?: T,\n searchParams: {[name: string]: string} = {},\n retries = 1,\n): Promise<RestResponse> {\n const response = await throttler.throttle(() => restRequest(method, path, session, params, searchParams))\n\n const status = response.status\n\n throttler.updateApiCallLimitFromResponse(response)\n\n switch (true) {\n case status >= 200 && status <= 399:\n // Returns the successful reponse\n return response\n case status === 404:\n // Defer the decision when a resource is not found\n return response\n case status === 429:\n // Retry following the \"retry-after\" header\n return throttler.delayAwareRetry(response, () => request(method, path, session, params, searchParams))\n case status === 403:\n return handleForbiddenError(response, session)\n case status === 401:\n /**\n * We need to resolve the call to the refresh function at runtime to\n * avoid a circular reference.\n *\n * This won't be necessary when https://github.com/Shopify/cli/issues/4769\n * gets resolved, and this condition must be removed then.\n */\n if ('refresh' in session) {\n const refresh = session.refresh as () => Promise<void>\n await refresh()\n }\n\n // Retry 401 errors to be resilient to authentication errors.\n return handleRetriableError({\n path,\n retries,\n retry: () => {\n return request(method, path, session, params, searchParams, retries + 1)\n },\n fail: () => {\n throw new AbortError(`[${status}] API request unauthorized error`)\n },\n })\n case status === 422:\n throw new AbortError(`[${status}] API request unprocessable content: ${errors(response)}`)\n case status >= 400 && status <= 499:\n throw new AbortError(`[${status}] API request client error`)\n case status >= 500 && status <= 599:\n // Retry 500-family of errors as that may solve the issue (especially in 503 errors)\n return handleRetriableError({\n path,\n retries,\n retry: () => {\n return request(method, path, session, params, searchParams, retries + 1)\n },\n fail: () => {\n throw new AbortError(`[${status}] API request server error`)\n },\n })\n default:\n throw new AbortError(`[${status}] API request unexpected error`)\n }\n}\n\nfunction handleForbiddenError(response: RestResponse, session: AdminSession): never {\n const store = session.storeFqdn\n const adminUrl = storeAdminUrl(session)\n const error = errorMessage(response)\n\n if (error.match(/Cannot delete generated asset/) !== null) {\n throw new AbortError(error)\n }\n\n throw new AbortError(\n `You are not authorized to edit themes on \"${store}\".`,\n \"You can't use Shopify CLI with development stores if you only have Partner staff \" +\n 'member access. If you want to use Shopify CLI to work on a development store, then ' +\n 'you should be the store owner or create a staff account on the store.' +\n '\\n\\n' +\n \"If you're the store owner, then you need to log in to the store directly using the \" +\n `store URL at least once (for example, using \"${adminUrl}\") before you log in using ` +\n 'Shopify CLI. Logging in to the Shopify admin directly connects the development ' +\n 'store with your Shopify login.',\n )\n}\n\nfunction errors(response: RestResponse) {\n return JSON.stringify(response.json?.errors)\n}\n\nfunction errorMessage(response: RestResponse): string {\n const message = response.json?.message\n\n if (typeof message === 'string') {\n return message\n }\n\n return ''\n}\n\nfunction unexpectedGraphQLError(message: string): never {\n throw new AbortError(message)\n}\n\ninterface RetriableErrorOptions {\n path: string\n retries: number\n retry: () => Promise<RestResponse>\n fail: () => never\n}\n\nasync function handleRetriableError({path, retries, retry, fail}: RetriableErrorOptions): Promise<RestResponse> {\n if (retries >= 3) {\n fail()\n }\n\n outputDebug(`[${retries}] Retrying '${path}' request...`)\n\n await sleep(0.2)\n return retry()\n}\n\nfunction themeGid(id: number): string {\n return `gid://shopify/OnlineStoreTheme/${id}`\n}\n\ntype OnlineStoreThemeFileBody =\n | {__typename: 'OnlineStoreThemeFileBodyBase64'; contentBase64: string}\n | {__typename: 'OnlineStoreThemeFileBodyText'; content: string}\n | {__typename: 'OnlineStoreThemeFileBodyUrl'; url: string}\n\nasync function parseThemeFileContent(body: OnlineStoreThemeFileBody): Promise<string> {\n switch (body.__typename) {\n case 'OnlineStoreThemeFileBodyText':\n return body.content\n case 'OnlineStoreThemeFileBodyBase64':\n return Buffer.from(body.contentBase64, 'base64').toString()\n case 'OnlineStoreThemeFileBodyUrl':\n try {\n const response = await fetch(body.url)\n return await response.text()\n } catch (error) {\n // Raise error if we can't download the file\n throw new AbortError(`Error downloading content from URL: ${body.url}`)\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../../src/public/node/themes/api.ts"],"names":[],"mappings":"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","sourcesContent":["import {storeAdminUrl} from './urls.js'\nimport {composeThemeGid, parseGid} from './utils.js'\nimport * as throttler from '../api/rest-api-throttler.js'\nimport {ThemeUpdate} from '../../../cli/api/graphql/admin/generated/theme_update.js'\nimport {ThemeDelete} from '../../../cli/api/graphql/admin/generated/theme_delete.js'\nimport {ThemePublish} from '../../../cli/api/graphql/admin/generated/theme_publish.js'\nimport {GetThemeFileBodies} from '../../../cli/api/graphql/admin/generated/get_theme_file_bodies.js'\nimport {GetThemeFileChecksums} from '../../../cli/api/graphql/admin/generated/get_theme_file_checksums.js'\nimport {\n ThemeFilesUpsert,\n ThemeFilesUpsertMutation,\n} from '../../../cli/api/graphql/admin/generated/theme_files_upsert.js'\nimport {ThemeFilesDelete} from '../../../cli/api/graphql/admin/generated/theme_files_delete.js'\nimport {\n OnlineStoreThemeFileBodyInputType,\n OnlineStoreThemeFilesUpsertFileInput,\n MetafieldOwnerType,\n} from '../../../cli/api/graphql/admin/generated/types.js'\nimport {MetafieldDefinitionsByOwnerType} from '../../../cli/api/graphql/admin/generated/metafield_definitions_by_owner_type.js'\nimport {GetThemes} from '../../../cli/api/graphql/admin/generated/get_themes.js'\nimport {GetTheme} from '../../../cli/api/graphql/admin/generated/get_theme.js'\nimport {OnlineStorePasswordProtection} from '../../../cli/api/graphql/admin/generated/online_store_password_protection.js'\nimport {restRequest, RestResponse, adminRequestDoc} from '@shopify/cli-kit/node/api/admin'\nimport {AdminSession} from '@shopify/cli-kit/node/session'\nimport {AbortError} from '@shopify/cli-kit/node/error'\nimport {buildTheme} from '@shopify/cli-kit/node/themes/factories'\nimport {Result, Checksum, Key, Theme, ThemeAsset, Operation} from '@shopify/cli-kit/node/themes/types'\nimport {outputDebug} from '@shopify/cli-kit/node/output'\nimport {sleep} from '@shopify/cli-kit/node/system'\n\nexport type ThemeParams = Partial<Pick<Theme, 'name' | 'role' | 'processing' | 'src'>>\nexport type AssetParams = Pick<ThemeAsset, 'key'> & Partial<Pick<ThemeAsset, 'value' | 'attachment'>>\n\nexport async function fetchTheme(id: number, session: AdminSession): Promise<Theme | undefined> {\n const gid = composeThemeGid(id)\n\n try {\n const {theme} = await adminRequestDoc(GetTheme, session, {id: gid}, undefined, {\n handleErrors: false,\n })\n\n if (theme) {\n return buildTheme({\n id: parseGid(theme.id),\n processing: theme.processing,\n role: theme.role.toLowerCase(),\n name: theme.name,\n })\n }\n\n // eslint-disable-next-line no-catch-all/no-catch-all\n } catch (_error) {\n /**\n * Consumers of this and other theme APIs in this file expect either a theme\n * or `undefined`.\n *\n * Error handlers should not inspect GraphQL error messages directly, as\n * they are internationalized.\n */\n outputDebug(`Error fetching theme with ID: ${id}`)\n }\n}\n\nexport async function fetchThemes(session: AdminSession): Promise<Theme[]> {\n const themes: Theme[] = []\n let after: string | null = null\n\n while (true) {\n // eslint-disable-next-line no-await-in-loop\n const response = await adminRequestDoc(GetThemes, session, {after})\n if (!response.themes) {\n unexpectedGraphQLError('Failed to fetch themes')\n }\n const {nodes, pageInfo} = response.themes\n nodes.forEach((theme) => {\n const t = buildTheme({\n id: parseGid(theme.id),\n processing: theme.processing,\n role: theme.role.toLowerCase(),\n name: theme.name,\n })\n if (t) {\n themes.push(t)\n }\n })\n if (!pageInfo.hasNextPage) {\n return themes\n }\n\n after = pageInfo.endCursor as string\n }\n}\n\nexport async function createTheme(params: ThemeParams, session: AdminSession): Promise<Theme | undefined> {\n const response = await request('POST', '/themes', session, {theme: {...params}})\n\n if (!params.src) {\n const minimumThemeAssets = [\n {key: 'config/settings_schema.json', value: '[]'},\n {key: 'layout/password.liquid', value: '{{ content_for_header }}{{ content_for_layout }}'},\n {key: 'layout/theme.liquid', value: '{{ content_for_header }}{{ content_for_layout }}'},\n ]\n\n await bulkUploadThemeAssets(response.json.theme.id, minimumThemeAssets, session)\n }\n\n return buildTheme({...response.json.theme, createdAtRuntime: true})\n}\n\nexport async function fetchThemeAssets(id: number, filenames: Key[], session: AdminSession): Promise<ThemeAsset[]> {\n const assets: ThemeAsset[] = []\n let after: string | null = null\n\n while (true) {\n // eslint-disable-next-line no-await-in-loop\n const response = await adminRequestDoc(GetThemeFileBodies, session, {\n id: themeGid(id),\n filenames,\n after,\n })\n\n if (!response.theme?.files?.nodes || !response.theme?.files?.pageInfo) {\n const userErrors = response.theme?.files?.userErrors.map((error) => error.filename).join(', ')\n unexpectedGraphQLError(`Error fetching assets: ${userErrors}`)\n }\n\n const {nodes, pageInfo} = response.theme.files\n\n assets.push(\n // eslint-disable-next-line no-await-in-loop\n ...(await Promise.all(\n nodes.map(async (file) => {\n const content = await parseThemeFileContent(file.body)\n return {\n key: file.filename,\n checksum: file.checksumMd5 as string,\n value: content,\n }\n }),\n )),\n )\n\n if (!pageInfo.hasNextPage) {\n return assets\n }\n\n after = pageInfo.endCursor as string\n }\n}\n\nexport async function deleteThemeAssets(id: number, filenames: Key[], session: AdminSession): Promise<Result[]> {\n const batchSize = 50\n const results: Result[] = []\n\n for (let i = 0; i < filenames.length; i += batchSize) {\n const batch = filenames.slice(i, i + batchSize)\n // eslint-disable-next-line no-await-in-loop\n const {themeFilesDelete} = await adminRequestDoc(ThemeFilesDelete, session, {\n themeId: composeThemeGid(id),\n files: batch,\n })\n\n if (!themeFilesDelete) {\n unexpectedGraphQLError('Failed to delete theme assets')\n }\n\n const {deletedThemeFiles, userErrors} = themeFilesDelete\n\n if (deletedThemeFiles) {\n deletedThemeFiles.forEach((file) => {\n results.push({key: file.filename, success: true, operation: Operation.Delete})\n })\n }\n\n if (userErrors.length > 0) {\n userErrors.forEach((error) => {\n if (error.filename) {\n results.push({\n key: error.filename,\n success: false,\n operation: Operation.Delete,\n errors: {asset: [error.message]},\n })\n } else {\n unexpectedGraphQLError(`Failed to delete theme assets: ${error.message}`)\n }\n })\n }\n }\n\n return results\n}\n\nexport async function bulkUploadThemeAssets(\n id: number,\n assets: AssetParams[],\n session: AdminSession,\n): Promise<Result[]> {\n const results: Result[] = []\n for (let i = 0; i < assets.length; i += 50) {\n const chunk = assets.slice(i, i + 50)\n const files = prepareFilesForUpload(chunk)\n // eslint-disable-next-line no-await-in-loop\n const uploadResults = await uploadFiles(id, files, session)\n results.push(...processUploadResults(uploadResults))\n }\n return results\n}\n\nfunction prepareFilesForUpload(assets: AssetParams[]): OnlineStoreThemeFilesUpsertFileInput[] {\n return assets.map((asset) => {\n if (asset.attachment) {\n return {\n filename: asset.key,\n body: {\n type: 'BASE64' as const,\n value: asset.attachment,\n },\n }\n } else {\n return {\n filename: asset.key,\n body: {\n type: 'TEXT' as const,\n value: asset.value ?? '',\n },\n }\n }\n })\n}\n\nasync function uploadFiles(\n themeId: number,\n files: {filename: string; body: {type: OnlineStoreThemeFileBodyInputType; value: string}}[],\n session: AdminSession,\n): Promise<ThemeFilesUpsertMutation> {\n return adminRequestDoc(ThemeFilesUpsert, session, {themeId: themeGid(themeId), files})\n}\n\nfunction processUploadResults(uploadResults: ThemeFilesUpsertMutation): Result[] {\n const {themeFilesUpsert} = uploadResults\n\n if (!themeFilesUpsert) {\n unexpectedGraphQLError('Failed to upload theme files')\n }\n\n const {upsertedThemeFiles, userErrors} = themeFilesUpsert\n\n const results: Result[] = []\n\n upsertedThemeFiles?.forEach((file) => {\n results.push({\n key: file.filename,\n success: true,\n operation: Operation.Upload,\n })\n })\n\n userErrors.forEach((error) => {\n if (!error.filename) {\n unexpectedGraphQLError(`Error uploading theme files: ${error.message}`)\n }\n results.push({\n key: error.filename,\n success: false,\n operation: Operation.Upload,\n errors: {asset: [error.message]},\n })\n })\n\n return results\n}\n\nexport async function fetchChecksums(id: number, session: AdminSession): Promise<Checksum[]> {\n const checksums: Checksum[] = []\n let after: string | null = null\n\n while (true) {\n // eslint-disable-next-line no-await-in-loop\n const response = await adminRequestDoc(GetThemeFileChecksums, session, {id: themeGid(id), after})\n\n if (!response?.theme?.files?.nodes || !response?.theme?.files?.pageInfo) {\n const userErrors = response.theme?.files?.userErrors.map((error) => error.filename).join(', ')\n throw new AbortError(`Failed to fetch checksums for: ${userErrors}`)\n }\n\n const {nodes, pageInfo} = response.theme.files\n\n checksums.push(\n ...nodes.map((file) => ({\n key: file.filename,\n checksum: file.checksumMd5 as string,\n })),\n )\n\n if (!pageInfo.hasNextPage) {\n return checksums\n }\n\n after = pageInfo.endCursor as string\n }\n}\n\nexport async function themeUpdate(id: number, params: ThemeParams, session: AdminSession): Promise<Theme | undefined> {\n const name = params.name\n const input: {[key: string]: string} = {}\n if (name) {\n input.name = name\n }\n\n const {themeUpdate} = await adminRequestDoc(ThemeUpdate, session, {id: composeThemeGid(id), input})\n if (!themeUpdate) {\n // An unexpected error occurred during the GraphQL request execution\n unexpectedGraphQLError('Failed to update theme')\n }\n\n const {theme, userErrors} = themeUpdate\n if (userErrors.length) {\n const userErrors = themeUpdate.userErrors.map((error) => error.message).join(', ')\n throw new AbortError(userErrors)\n }\n\n if (!theme) {\n // An unexpected error if neither theme nor userErrors are returned\n unexpectedGraphQLError('Failed to update theme')\n }\n\n return buildTheme({\n id: parseGid(theme.id),\n name: theme.name,\n role: theme.role.toLowerCase(),\n })\n}\n\nexport async function themePublish(id: number, session: AdminSession): Promise<Theme | undefined> {\n const {themePublish} = await adminRequestDoc(ThemePublish, session, {id: composeThemeGid(id)})\n if (!themePublish) {\n // An unexpected error occurred during the GraphQL request execution\n unexpectedGraphQLError('Failed to update theme')\n }\n\n const {theme, userErrors} = themePublish\n if (userErrors.length) {\n const userErrors = themePublish.userErrors.map((error) => error.message).join(', ')\n throw new AbortError(userErrors)\n }\n\n if (!theme) {\n // An unexpected error if neither theme nor userErrors are returned\n unexpectedGraphQLError('Failed to update theme')\n }\n\n return buildTheme({\n id: parseGid(theme.id),\n name: theme.name,\n role: theme.role.toLowerCase(),\n })\n}\n\nexport async function themeDelete(id: number, session: AdminSession): Promise<boolean | undefined> {\n const {themeDelete} = await adminRequestDoc(ThemeDelete, session, {id: composeThemeGid(id)})\n if (!themeDelete) {\n // An unexpected error occurred during the GraphQL request execution\n unexpectedGraphQLError('Failed to update theme')\n }\n\n const {deletedThemeId, userErrors} = themeDelete\n if (userErrors.length) {\n const userErrors = themeDelete.userErrors.map((error) => error.message).join(', ')\n throw new AbortError(userErrors)\n }\n\n if (!deletedThemeId) {\n // An unexpected error if neither theme nor userErrors are returned\n unexpectedGraphQLError('Failed to update theme')\n }\n\n return true\n}\n\nexport async function metafieldDefinitionsByOwnerType(type: MetafieldOwnerType, session: AdminSession) {\n const {metafieldDefinitions} = await adminRequestDoc(MetafieldDefinitionsByOwnerType, session, {\n ownerType: type,\n })\n\n return metafieldDefinitions.nodes.map((definition) => ({\n key: definition.key,\n namespace: definition.namespace,\n name: definition.name,\n description: definition.description,\n type: {\n name: definition.type.name,\n category: definition.type.category,\n },\n }))\n}\n\nexport async function passwordProtected(session: AdminSession): Promise<boolean> {\n const {onlineStore} = await adminRequestDoc(OnlineStorePasswordProtection, session)\n if (!onlineStore) {\n unexpectedGraphQLError(\"Unable to get details about the storefront's password protection\")\n }\n\n const {passwordProtection} = onlineStore\n\n return passwordProtection.enabled\n}\n\nasync function request<T>(\n method: string,\n path: string,\n session: AdminSession,\n params?: T,\n searchParams: {[name: string]: string} = {},\n retries = 1,\n): Promise<RestResponse> {\n const response = await throttler.throttle(() => restRequest(method, path, session, params, searchParams))\n\n const status = response.status\n\n throttler.updateApiCallLimitFromResponse(response)\n\n switch (true) {\n case status >= 200 && status <= 399:\n // Returns the successful reponse\n return response\n case status === 404:\n // Defer the decision when a resource is not found\n return response\n case status === 429:\n // Retry following the \"retry-after\" header\n return throttler.delayAwareRetry(response, () => request(method, path, session, params, searchParams))\n case status === 403:\n return handleForbiddenError(response, session)\n case status === 401:\n /**\n * We need to resolve the call to the refresh function at runtime to\n * avoid a circular reference.\n *\n * This won't be necessary when https://github.com/Shopify/cli/issues/4769\n * gets resolved, and this condition must be removed then.\n */\n if ('refresh' in session) {\n const refresh = session.refresh as () => Promise<void>\n await refresh()\n }\n\n // Retry 401 errors to be resilient to authentication errors.\n return handleRetriableError({\n path,\n retries,\n retry: () => {\n return request(method, path, session, params, searchParams, retries + 1)\n },\n fail: () => {\n throw new AbortError(`[${status}] API request unauthorized error`)\n },\n })\n case status === 422:\n throw new AbortError(`[${status}] API request unprocessable content: ${errors(response)}`)\n case status >= 400 && status <= 499:\n throw new AbortError(`[${status}] API request client error`)\n case status >= 500 && status <= 599:\n // Retry 500-family of errors as that may solve the issue (especially in 503 errors)\n return handleRetriableError({\n path,\n retries,\n retry: () => {\n return request(method, path, session, params, searchParams, retries + 1)\n },\n fail: () => {\n throw new AbortError(`[${status}] API request server error`)\n },\n })\n default:\n throw new AbortError(`[${status}] API request unexpected error`)\n }\n}\n\nfunction handleForbiddenError(response: RestResponse, session: AdminSession): never {\n const store = session.storeFqdn\n const adminUrl = storeAdminUrl(session)\n const error = errorMessage(response)\n\n if (error.match(/Cannot delete generated asset/) !== null) {\n throw new AbortError(error)\n }\n\n throw new AbortError(\n `You are not authorized to edit themes on \"${store}\".`,\n \"You can't use Shopify CLI with development stores if you only have Partner staff \" +\n 'member access. If you want to use Shopify CLI to work on a development store, then ' +\n 'you should be the store owner or create a staff account on the store.' +\n '\\n\\n' +\n \"If you're the store owner, then you need to log in to the store directly using the \" +\n `store URL at least once (for example, using \"${adminUrl}\") before you log in using ` +\n 'Shopify CLI. Logging in to the Shopify admin directly connects the development ' +\n 'store with your Shopify login.',\n )\n}\n\nfunction errors(response: RestResponse) {\n return JSON.stringify(response.json?.errors)\n}\n\nfunction errorMessage(response: RestResponse): string {\n const message = response.json?.message\n\n if (typeof message === 'string') {\n return message\n }\n\n return ''\n}\n\nfunction unexpectedGraphQLError(message: string): never {\n throw new AbortError(message)\n}\n\ninterface RetriableErrorOptions {\n path: string\n retries: number\n retry: () => Promise<RestResponse>\n fail: () => never\n}\n\nasync function handleRetriableError({path, retries, retry, fail}: RetriableErrorOptions): Promise<RestResponse> {\n if (retries >= 3) {\n fail()\n }\n\n outputDebug(`[${retries}] Retrying '${path}' request...`)\n\n await sleep(0.2)\n return retry()\n}\n\nfunction themeGid(id: number): string {\n return `gid://shopify/OnlineStoreTheme/${id}`\n}\n\ntype OnlineStoreThemeFileBody =\n | {__typename: 'OnlineStoreThemeFileBodyBase64'; contentBase64: string}\n | {__typename: 'OnlineStoreThemeFileBodyText'; content: string}\n | {__typename: 'OnlineStoreThemeFileBodyUrl'; url: string}\n\nasync function parseThemeFileContent(body: OnlineStoreThemeFileBody): Promise<string> {\n switch (body.__typename) {\n case 'OnlineStoreThemeFileBodyText':\n return body.content\n case 'OnlineStoreThemeFileBodyBase64':\n return Buffer.from(body.contentBase64, 'base64').toString()\n case 'OnlineStoreThemeFileBodyUrl':\n try {\n const response = await fetch(body.url)\n return await response.text()\n } catch (error) {\n // Raise error if we can't download the file\n throw new AbortError(`Error downloading content from URL: ${body.url}`)\n }\n }\n}\n"]}
|