From f0328ba36826451295ea7683836fea8b5f2ad2f0 Mon Sep 17 00:00:00 2001 From: patzick <13100280+patzick@users.noreply.github.com> Date: Tue, 7 Jan 2025 10:20:55 +0100 Subject: [PATCH 1/6] feat(api-gen): allow multiple json overrides for schema --- packages/api-client/api-gen.config.json | 3 +- packages/api-gen/api-gen.schema.json | 28 ++++++-- packages/api-gen/src/commands/generate.ts | 2 +- packages/api-gen/src/commands/validateJson.ts | 2 +- packages/api-gen/src/jsonOverrideUtils.ts | 70 ++++++++++++++----- 5 files changed, 78 insertions(+), 27 deletions(-) diff --git a/packages/api-client/api-gen.config.json b/packages/api-client/api-gen.config.json index f42f1fd2d..681358868 100644 --- a/packages/api-client/api-gen.config.json +++ b/packages/api-client/api-gen.config.json @@ -1,4 +1,5 @@ { "$schema": "../api-gen/api-gen.schema.json", - "rules": ["COMPONENTS_API_ALIAS"] + "rules": ["COMPONENTS_API_ALIAS"], + "patches": ["./api-types/storeApiSchema.overrides.json"] } diff --git a/packages/api-gen/api-gen.schema.json b/packages/api-gen/api-gen.schema.json index f3ffc691b..ffbf6682a 100644 --- a/packages/api-gen/api-gen.schema.json +++ b/packages/api-gen/api-gen.schema.json @@ -26,14 +26,32 @@ } }, "patches": { - "type": "string", - "description": "Path to a file containing patches to apply to the schema", - "anyOf": [ + "description": "Path to a file or files containing patches to apply to the schema", + "oneOf": [ { - "format": "url" + "type": "string", + "anyOf": [ + { + "format": "url" + }, + { + "format": "file-path" + } + ] }, { - "format": "file-path" + "type": "array", + "items": { + "type": "string", + "anyOf": [ + { + "format": "url" + }, + { + "format": "file-path" + } + ] + } } ] } diff --git a/packages/api-gen/src/commands/generate.ts b/packages/api-gen/src/commands/generate.ts index a611da789..076243b63 100644 --- a/packages/api-gen/src/commands/generate.ts +++ b/packages/api-gen/src/commands/generate.ts @@ -72,7 +72,7 @@ export async function generate(args: { silent: true, // we allow to not have the config file in this command }); const jsonOverrides = await loadJsonOverrides({ - path: configJSON?.patches, + paths: configJSON?.patches, apiType: args.apiType, }); diff --git a/packages/api-gen/src/commands/validateJson.ts b/packages/api-gen/src/commands/validateJson.ts index 3b0241bd7..01d941c49 100644 --- a/packages/api-gen/src/commands/validateJson.ts +++ b/packages/api-gen/src/commands/validateJson.ts @@ -89,7 +89,7 @@ export async function validateJson(args: { const errors: string[] = []; const jsonOverrides = await loadJsonOverrides({ - path: configJSON.patches, + paths: configJSON.patches, apiType: args.apiType, }); diff --git a/packages/api-gen/src/jsonOverrideUtils.ts b/packages/api-gen/src/jsonOverrideUtils.ts index 8fff847df..fb180e49c 100644 --- a/packages/api-gen/src/jsonOverrideUtils.ts +++ b/packages/api-gen/src/jsonOverrideUtils.ts @@ -2,7 +2,7 @@ import { existsSync, readFileSync } from "node:fs"; import json5 from "json5"; import { ofetch } from "ofetch"; import c from "picocolors"; -import type { OverridesSchema } from "./patchJsonSchema"; +import { type OverridesSchema, extendedDefu } from "./patchJsonSchema"; import type { validationRules } from "./validation-rules"; export type ApiGenConfig = { @@ -44,11 +44,36 @@ function isURL(str: string) { return str.startsWith("http"); } +async function resolveSinglePath(pathToResolve: string) { + try { + if (isURL(pathToResolve)) { + const response = await ofetch(pathToResolve, { + responseType: "json", + parseResponse: json5.parse, + }); + return response; + } + + const jsonOverridesFile = await readFileSync(pathToResolve, { + encoding: "utf-8", + }); + return json5.parse(jsonOverridesFile); + } catch (error) { + console.warn( + c.yellow( + `Problem with resolving overrides "patches" at address ${pathToResolve}. Check whether you configured it properly in your ${API_GEN_CONFIG_FILENAME}\n`, + ), + error, + ); + return {}; + } +} + export async function loadJsonOverrides({ - path, + paths, apiType, }: { - path?: string; + paths?: string | string[]; apiType: string; }): Promise { const localPath = `./api-types/${apiType}ApiSchema.overrides.json`; @@ -57,30 +82,37 @@ export async function loadJsonOverrides({ ? localPath : `https://raw.githubusercontent.com/shopware/frontends/main/packages/api-client/api-types/${apiType}ApiSchema.overrides.json`; - const pathToResolve = path || fallbackPath; - console.log("Loading overrides from:", pathToResolve); + const patchesToResolve: string[] = Array.isArray(paths) + ? paths + : paths + ? [paths] + : []; - try { - if (isURL(pathToResolve)) { - const response = await ofetch(pathToResolve, { - responseType: "json", - parseResponse: json5.parse, - }); - return response; - } + if (!patchesToResolve?.length) { + patchesToResolve.push(fallbackPath); + } - const jsonOverridesFile = await readFileSync(pathToResolve, { - encoding: "utf-8", - }); - const content = json5.parse(jsonOverridesFile); - return content; + console.log("Loading overrides from:", patchesToResolve); + + try { + const results = await Promise.allSettled( + patchesToResolve.map(resolveSinglePath), + ); + // merge results from correctly settled promises + return extendedDefu( + {}, + ...results + .filter((result) => result.status === "fulfilled") + .map((result) => result.value), + ); } catch (error) { console.warn( c.yellow( - `Problem with resolving overrides "patches" at address ${pathToResolve}. Check whether you configuret it properly in your ${API_GEN_CONFIG_FILENAME}\n`, + `Problem with resolving overrides "patches". Check whether you configured it properly in your ${API_GEN_CONFIG_FILENAME}\n`, ), error, ); + return {}; } } From ad32379d1b7aef7cef28187ec730dbae38d4a741 Mon Sep 17 00:00:00 2001 From: patzick <13100280+patzick@users.noreply.github.com> Date: Wed, 15 Jan 2025 14:49:55 +0100 Subject: [PATCH 2/6] chore: finishing up --- .changeset/tidy-otters-know.md | 5 ++++ packages/api-gen/README.md | 23 ++++++++++++++++++- packages/api-gen/src/commands/generate.ts | 16 +++++++++++++ packages/api-gen/src/commands/validateJson.ts | 2 ++ packages/api-gen/src/jsonOverrideUtils.ts | 4 +++- 5 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 .changeset/tidy-otters-know.md diff --git a/.changeset/tidy-otters-know.md b/.changeset/tidy-otters-know.md new file mode 100644 index 000000000..c22f70826 --- /dev/null +++ b/.changeset/tidy-otters-know.md @@ -0,0 +1,5 @@ +--- +"@shopware/api-gen": minor +--- + +Possibility to add multiple override json patches. Now you can use our default overrides and add your own on top of it. diff --git a/packages/api-gen/README.md b/packages/api-gen/README.md index 3a133fcd6..4cdd05e7e 100644 --- a/packages/api-gen/README.md +++ b/packages/api-gen/README.md @@ -107,7 +107,18 @@ Example: ```json { - "patches": "./api-types/storeApiTypes.overrides.json" + "patches": ["./api-types/storeApiTypes.overrides.json"] +} +``` + +or you could use multiple patches and add your own overrides on top: + +```json +{ + "patches": [ + "https://raw.githubusercontent.com/shopware/frontends/refs/heads/main/packages/api-client/api-types/storeApiSchema.overrides.json", + "./api-types/myOwnPatches.overrides.json" + ] } ``` @@ -175,6 +186,11 @@ pnpx @shopware/api-gen generate --apiType=store pnpx @shopware/api-gen generate --apiType=admin ``` +flags: + +- `--debug` - display debug logs and additional information which can be helpful in case of issues +- `--logPatches` - display patched logs, useful when you want to fix schema in original file + ### `loadSchema` Load OpenAPI specification from Shopware instance and save it to JSON file. @@ -191,6 +207,11 @@ pnpx @shopware/api-gen loadSchema --apiType=store pnpx @shopware/api-gen loadSchema --apiType=admin ``` +flags: + +- `--debug` - display debug logs and additional information which can be helpful in case of issues +- `--logPatches` - display patched logs, useful when you want to fix schema in original file + Remember to add `.env` file in order to authenticate with Shopware instance. ```bash diff --git a/packages/api-gen/src/commands/generate.ts b/packages/api-gen/src/commands/generate.ts index 076243b63..ed3fd61c7 100644 --- a/packages/api-gen/src/commands/generate.ts +++ b/packages/api-gen/src/commands/generate.ts @@ -28,6 +28,7 @@ export async function generate(args: { filename?: string; apiType: "store" | "admin"; debug: boolean; + logPatches: boolean; }) { const inputFilename = args.filename ? args.filename @@ -71,10 +72,24 @@ export async function generate(args: { const configJSON = await loadApiGenConfig({ silent: true, // we allow to not have the config file in this command }); + console.error("test1"); const jsonOverrides = await loadJsonOverrides({ paths: configJSON?.patches, apiType: args.apiType, }); + console.error("test2"); + + if (args.debug) { + // save overrides to file + writeFileSync( + join( + args.cwd, + "api-types", + `${args.apiType}ApiTypes.overrides-result.json`, + ), + json5.stringify(jsonOverrides, null, 2), + ); + } const { patchedSchema, @@ -93,6 +108,7 @@ export async function generate(args: { todosToFix, outdatedPatches, alreadyApliedPatches, + displayPatchedLogs: args.logPatches, }); if (args.debug) { diff --git a/packages/api-gen/src/commands/validateJson.ts b/packages/api-gen/src/commands/validateJson.ts index 01d941c49..9d56b2e2e 100644 --- a/packages/api-gen/src/commands/validateJson.ts +++ b/packages/api-gen/src/commands/validateJson.ts @@ -47,6 +47,7 @@ export async function validateJson(args: { cwd: string; filename?: string; apiType: string; + logPatches: boolean; }) { const schemaFilenameToValidate = args.filename ? args.filename @@ -185,6 +186,7 @@ export async function validateJson(args: { errors, outdatedPatches, alreadyApliedPatches, + displayPatchedLogs: args.logPatches, }); console.log( diff --git a/packages/api-gen/src/jsonOverrideUtils.ts b/packages/api-gen/src/jsonOverrideUtils.ts index fb180e49c..443664ef9 100644 --- a/packages/api-gen/src/jsonOverrideUtils.ts +++ b/packages/api-gen/src/jsonOverrideUtils.ts @@ -121,13 +121,15 @@ export function displayPatchingSummary({ outdatedPatches, alreadyApliedPatches, errors, + displayPatchedLogs, }: { todosToFix: string[][]; outdatedPatches: string[][]; alreadyApliedPatches: number; errors?: string[]; + displayPatchedLogs?: boolean; }) { - if (!errors?.length && todosToFix.length) { + if (displayPatchedLogs && !errors?.length && todosToFix.length) { console.log(c.yellow("Warnings to fix in the schema:")); for (const todo of todosToFix) { console.log(`${c.yellow("WARNING")}: ${todo[0]}`); From ae287da206ff8abd4bfc2370a04d84540e4852a2 Mon Sep 17 00:00:00 2001 From: patzick <13100280+patzick@users.noreply.github.com> Date: Wed, 15 Jan 2025 14:56:43 +0100 Subject: [PATCH 3/6] chore: fix build --- packages/api-gen/src/cli.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/api-gen/src/cli.ts b/packages/api-gen/src/cli.ts index f6a6de9e7..bd5eaf38b 100644 --- a/packages/api-gen/src/cli.ts +++ b/packages/api-gen/src/cli.ts @@ -44,6 +44,11 @@ yargs(hideBin(process.argv)) default: false, describe: "show debug information and generate intermediate files", }) + .option("logPatches", { + type: "boolean", + default: false, + describe: "show patched logs", + }) .help(); }, async (args) => generate(args), @@ -84,6 +89,11 @@ yargs(hideBin(process.argv)) describe: "name of the schema json file. The default (based on apiType parameter) is 'storeApiSchema.json' or 'adminApiSchema.json'", }) + .option("logPatches", { + type: "boolean", + default: false, + describe: "show patched logs", + }) .help(); }, async (args) => validateJson(args), From b6bd04c10ad8eb9b4ed112e4636ac41c7a7c7b24 Mon Sep 17 00:00:00 2001 From: Patryk Tomczyk <13100280+patzick@users.noreply.github.com> Date: Thu, 16 Jan 2025 10:35:27 +0100 Subject: [PATCH 4/6] Apply suggestions from code review Co-authored-by: Maciek Kucmus --- packages/api-gen/src/commands/generate.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/api-gen/src/commands/generate.ts b/packages/api-gen/src/commands/generate.ts index ed3fd61c7..c9cd4ca70 100644 --- a/packages/api-gen/src/commands/generate.ts +++ b/packages/api-gen/src/commands/generate.ts @@ -72,12 +72,10 @@ export async function generate(args: { const configJSON = await loadApiGenConfig({ silent: true, // we allow to not have the config file in this command }); - console.error("test1"); const jsonOverrides = await loadJsonOverrides({ paths: configJSON?.patches, apiType: args.apiType, }); - console.error("test2"); if (args.debug) { // save overrides to file From 6cfd34bd8bf73a07df5c769d6d1df4bf4cd22c98 Mon Sep 17 00:00:00 2001 From: patzick <13100280+patzick@users.noreply.github.com> Date: Thu, 16 Jan 2025 10:41:45 +0100 Subject: [PATCH 5/6] chore: apply suggestions --- packages/api-gen/src/cli.ts | 5 +++++ packages/api-gen/src/commands/generate.ts | 14 +++++++++----- packages/api-gen/src/commands/validateJson.ts | 15 ++++++++++++++- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/packages/api-gen/src/cli.ts b/packages/api-gen/src/cli.ts index bd5eaf38b..2329d5b1d 100644 --- a/packages/api-gen/src/cli.ts +++ b/packages/api-gen/src/cli.ts @@ -94,6 +94,11 @@ yargs(hideBin(process.argv)) default: false, describe: "show patched logs", }) + .positional("debug", { + type: "boolean", + default: false, + describe: "show debug information and generate intermediate files", + }) .help(); }, async (args) => validateJson(args), diff --git a/packages/api-gen/src/commands/generate.ts b/packages/api-gen/src/commands/generate.ts index c9cd4ca70..875654207 100644 --- a/packages/api-gen/src/commands/generate.ts +++ b/packages/api-gen/src/commands/generate.ts @@ -79,14 +79,18 @@ export async function generate(args: { if (args.debug) { // save overrides to file + const overridesFilePath = join( + args.cwd, + "api-types", + `${args.apiType}ApiTypes.overrides-result.json`, + ); writeFileSync( - join( - args.cwd, - "api-types", - `${args.apiType}ApiTypes.overrides-result.json`, - ), + overridesFilePath, json5.stringify(jsonOverrides, null, 2), ); + console.log( + `Check the overrides result in: ${c.bold(overridesFilePath)} file.`, + ); } const { diff --git a/packages/api-gen/src/commands/validateJson.ts b/packages/api-gen/src/commands/validateJson.ts index 9d56b2e2e..aad720495 100644 --- a/packages/api-gen/src/commands/validateJson.ts +++ b/packages/api-gen/src/commands/validateJson.ts @@ -1,4 +1,4 @@ -import { readFileSync } from "node:fs"; +import { readFileSync, writeFileSync } from "node:fs"; import { join } from "node:path"; import json5 from "json5"; import type { ObjectSubtype, OpenAPI3 } from "openapi-typescript"; @@ -48,6 +48,7 @@ export async function validateJson(args: { filename?: string; apiType: string; logPatches: boolean; + debug: boolean; }) { const schemaFilenameToValidate = args.filename ? args.filename @@ -94,6 +95,18 @@ export async function validateJson(args: { apiType: args.apiType, }); + if (args.debug) { + const overridesFilePath = join( + args.cwd, + "api-types", + `${args.apiType}ApiTypes.overrides-result.json`, + ); + writeFileSync(overridesFilePath, json5.stringify(jsonOverrides, null, 2)); + console.log( + `Check the overrides result in: ${c.bold(overridesFilePath)} file.`, + ); + } + for (const [schemaName, schema] of Object.entries( fileContentAsJson.components?.schemas || {}, )) { From f640595a897e398987abd1b38cfc433bb54e8dc0 Mon Sep 17 00:00:00 2001 From: patzick <13100280+patzick@users.noreply.github.com> Date: Thu, 16 Jan 2025 10:58:20 +0100 Subject: [PATCH 6/6] chore: additional logs on debug --- packages/api-gen/src/commands/generate.ts | 9 ++++++++- packages/api-gen/src/commands/validateJson.ts | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/api-gen/src/commands/generate.ts b/packages/api-gen/src/commands/generate.ts index 875654207..2d81eb5fd 100644 --- a/packages/api-gen/src/commands/generate.ts +++ b/packages/api-gen/src/commands/generate.ts @@ -89,7 +89,7 @@ export async function generate(args: { json5.stringify(jsonOverrides, null, 2), ); console.log( - `Check the overrides result in: ${c.bold(overridesFilePath)} file.`, + `[DEBUG] Check the overrides result in: ${c.bold(overridesFilePath)} file.`, ); } @@ -127,6 +127,9 @@ export async function generate(args: { writeFileSync(patchedSchemaPath, json5.stringify(patchedSchema), { encoding: "utf-8", }); + console.log( + `[DEBUG] Check the patched schema in: ${c.bold(patchedSchemaPath)} file.`, + ); } const astSchema = await openapiTS(patchedSchema, { @@ -227,6 +230,7 @@ export async function generate(args: { writeFileSync(fullOutputFilePath, schema, { encoding: "utf-8", }); + console.log(`[DEBUG]: Debug Schema saved to ${fullOutputFilePath}`); schema = await format(schema, { // semi: false, @@ -269,6 +273,9 @@ export async function generate(args: { writeFileSync(fullOutputFilePath, schema, { encoding: "utf-8", }); + console.log( + `[DEBUG] Check the generated schema in: ${c.bold(fullOutputFilePath)} file.`, + ); } // TODO: change overrides file name to param diff --git a/packages/api-gen/src/commands/validateJson.ts b/packages/api-gen/src/commands/validateJson.ts index aad720495..0efa53a16 100644 --- a/packages/api-gen/src/commands/validateJson.ts +++ b/packages/api-gen/src/commands/validateJson.ts @@ -103,7 +103,7 @@ export async function validateJson(args: { ); writeFileSync(overridesFilePath, json5.stringify(jsonOverrides, null, 2)); console.log( - `Check the overrides result in: ${c.bold(overridesFilePath)} file.`, + `[DEBUG] Check the overrides result in: ${c.bold(overridesFilePath)} file.`, ); }