@strapi/openapi 5.52.1 → 5.52.3
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/assemblers/document/path/path-item/operation/body.d.ts.map +1 -1
- package/dist/assemblers/document/path/path-item/operation/body.js +5 -1
- package/dist/assemblers/document/path/path-item/operation/body.js.map +1 -1
- package/dist/assemblers/document/path/path-item/operation/body.mjs +5 -1
- package/dist/assemblers/document/path/path-item/operation/body.mjs.map +1 -1
- package/dist/assemblers/document/path/path-item/operation/parameters.d.ts.map +1 -1
- package/dist/assemblers/document/path/path-item/operation/parameters.js +12 -6
- package/dist/assemblers/document/path/path-item/operation/parameters.js.map +1 -1
- package/dist/assemblers/document/path/path-item/operation/parameters.mjs +12 -6
- package/dist/assemblers/document/path/path-item/operation/parameters.mjs.map +1 -1
- package/dist/assemblers/document/path/path-item/operation/responses.d.ts.map +1 -1
- package/dist/assemblers/document/path/path-item/operation/responses.js +3 -1
- package/dist/assemblers/document/path/path-item/operation/responses.js.map +1 -1
- package/dist/assemblers/document/path/path-item/operation/responses.mjs +3 -1
- package/dist/assemblers/document/path/path-item/operation/responses.mjs.map +1 -1
- package/dist/post-processor/component-writer.d.ts.map +1 -1
- package/dist/post-processor/component-writer.js +19 -8
- package/dist/post-processor/component-writer.js.map +1 -1
- package/dist/post-processor/component-writer.mjs +20 -9
- package/dist/post-processor/component-writer.mjs.map +1 -1
- package/dist/registries/factory.d.ts +4 -1
- package/dist/registries/factory.d.ts.map +1 -1
- package/dist/registries/factory.js +3 -1
- package/dist/registries/factory.js.map +1 -1
- package/dist/registries/factory.mjs +3 -1
- package/dist/registries/factory.mjs.map +1 -1
- package/dist/utils/zod.d.ts +49 -12
- package/dist/utils/zod.d.ts.map +1 -1
- package/dist/utils/zod.js +117 -14
- package/dist/utils/zod.js.map +1 -1
- package/dist/utils/zod.mjs +116 -15
- package/dist/utils/zod.mjs.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"body.d.ts","sourceRoot":"","sources":["../../../../../../src/assemblers/document/path/path-item/operation/body.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAG1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAI7C,qBAAa,aAAc,YAAW,SAAS,CAAC,SAAS;IACvD,QAAQ,CAAC,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"body.d.ts","sourceRoot":"","sources":["../../../../../../src/assemblers/document/path/path-item/operation/body.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAG1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAI7C,qBAAa,aAAc,YAAW,SAAS,CAAC,SAAS;IACvD,QAAQ,CAAC,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI;CAsB7D"}
|
|
@@ -12,9 +12,13 @@ class BodyAssembler {
|
|
|
12
12
|
return;
|
|
13
13
|
}
|
|
14
14
|
const content = {};
|
|
15
|
+
const schemaStore = context.strapi.contentAPISchemaRegistry;
|
|
16
|
+
const { extractedComponentSchemas } = context.registries;
|
|
15
17
|
for (const [media, zodSchema] of Object.entries(body)){
|
|
16
18
|
content[media] = {
|
|
17
|
-
schema: zod.zodToOpenAPI(zodSchema
|
|
19
|
+
schema: zod.zodToOpenAPI(zodSchema, schemaStore, {
|
|
20
|
+
extractedComponentSchemas
|
|
21
|
+
})
|
|
18
22
|
};
|
|
19
23
|
}
|
|
20
24
|
output.data.requestBody = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"body.js","sources":["../../../../../../src/assemblers/document/path/path-item/operation/body.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport type { OpenAPIV3_1 } from 'openapi-types';\n\nimport type { OperationContext } from '../../../../../types';\nimport type { Assembler } from '../../../..';\n\nimport { zodToOpenAPI } from '../../../../../utils';\n\nexport class BodyAssembler implements Assembler.Operation {\n assemble(context: OperationContext, route: Core.Route): void {\n const { output } = context;\n const { body } = route.request ?? {};\n\n // If no `body` property is defined, we don't need to do anything\n if (!body) {\n return;\n }\n\n const content: Record<string, OpenAPIV3_1.MediaTypeObject> = {};\n\n for (const [media, zodSchema] of Object.entries(body)) {\n content[media] = {\n schema: zodToOpenAPI(zodSchema) as any,\n };\n }\n\n output.data.requestBody = { content };\n }\n}\n"],"names":["BodyAssembler","assemble","context","route","output","body","request","content","media","zodSchema","Object","entries","schema","zodToOpenAPI","data","requestBody"],"mappings":";;;;;AAQO,MAAMA,aAAAA,CAAAA;IACXC,QAAAA,CAASC,OAAyB,EAAEC,KAAiB,EAAQ;QAC3D,MAAM,EAAEC,MAAM,EAAE,GAAGF,OAAAA;AACnB,QAAA,MAAM,EAAEG,IAAI,EAAE,GAAGF,KAAAA,CAAMG,OAAO,IAAI,EAAC;;AAGnC,QAAA,IAAI,CAACD,IAAAA,EAAM;AACT,YAAA;AACF,QAAA;AAEA,QAAA,MAAME,UAAuD,EAAC;
|
|
1
|
+
{"version":3,"file":"body.js","sources":["../../../../../../src/assemblers/document/path/path-item/operation/body.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport type { OpenAPIV3_1 } from 'openapi-types';\n\nimport type { OperationContext } from '../../../../../types';\nimport type { Assembler } from '../../../..';\n\nimport { zodToOpenAPI } from '../../../../../utils';\n\nexport class BodyAssembler implements Assembler.Operation {\n assemble(context: OperationContext, route: Core.Route): void {\n const { output } = context;\n const { body } = route.request ?? {};\n\n // If no `body` property is defined, we don't need to do anything\n if (!body) {\n return;\n }\n\n const content: Record<string, OpenAPIV3_1.MediaTypeObject> = {};\n\n const schemaStore = context.strapi.contentAPISchemaRegistry;\n const { extractedComponentSchemas } = context.registries;\n\n for (const [media, zodSchema] of Object.entries(body)) {\n content[media] = {\n schema: zodToOpenAPI(zodSchema, schemaStore, { extractedComponentSchemas }) as any,\n };\n }\n\n output.data.requestBody = { content };\n }\n}\n"],"names":["BodyAssembler","assemble","context","route","output","body","request","content","schemaStore","strapi","contentAPISchemaRegistry","extractedComponentSchemas","registries","media","zodSchema","Object","entries","schema","zodToOpenAPI","data","requestBody"],"mappings":";;;;;AAQO,MAAMA,aAAAA,CAAAA;IACXC,QAAAA,CAASC,OAAyB,EAAEC,KAAiB,EAAQ;QAC3D,MAAM,EAAEC,MAAM,EAAE,GAAGF,OAAAA;AACnB,QAAA,MAAM,EAAEG,IAAI,EAAE,GAAGF,KAAAA,CAAMG,OAAO,IAAI,EAAC;;AAGnC,QAAA,IAAI,CAACD,IAAAA,EAAM;AACT,YAAA;AACF,QAAA;AAEA,QAAA,MAAME,UAAuD,EAAC;AAE9D,QAAA,MAAMC,WAAAA,GAAcN,OAAAA,CAAQO,MAAM,CAACC,wBAAwB;AAC3D,QAAA,MAAM,EAAEC,yBAAyB,EAAE,GAAGT,QAAQU,UAAU;QAExD,KAAK,MAAM,CAACC,KAAAA,EAAOC,SAAAA,CAAU,IAAIC,MAAAA,CAAOC,OAAO,CAACX,IAAAA,CAAAA,CAAO;YACrDE,OAAO,CAACM,MAAM,GAAG;gBACfI,MAAAA,EAAQC,gBAAAA,CAAaJ,WAAWN,WAAAA,EAAa;AAAEG,oBAAAA;AAA0B,iBAAA;AAC3E,aAAA;AACF,QAAA;QAEAP,MAAAA,CAAOe,IAAI,CAACC,WAAW,GAAG;AAAEb,YAAAA;AAAQ,SAAA;AACtC,IAAA;AACF;;;;"}
|
|
@@ -10,9 +10,13 @@ class BodyAssembler {
|
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
12
|
const content = {};
|
|
13
|
+
const schemaStore = context.strapi.contentAPISchemaRegistry;
|
|
14
|
+
const { extractedComponentSchemas } = context.registries;
|
|
13
15
|
for (const [media, zodSchema] of Object.entries(body)){
|
|
14
16
|
content[media] = {
|
|
15
|
-
schema: zodToOpenAPI(zodSchema
|
|
17
|
+
schema: zodToOpenAPI(zodSchema, schemaStore, {
|
|
18
|
+
extractedComponentSchemas
|
|
19
|
+
})
|
|
16
20
|
};
|
|
17
21
|
}
|
|
18
22
|
output.data.requestBody = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"body.mjs","sources":["../../../../../../src/assemblers/document/path/path-item/operation/body.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport type { OpenAPIV3_1 } from 'openapi-types';\n\nimport type { OperationContext } from '../../../../../types';\nimport type { Assembler } from '../../../..';\n\nimport { zodToOpenAPI } from '../../../../../utils';\n\nexport class BodyAssembler implements Assembler.Operation {\n assemble(context: OperationContext, route: Core.Route): void {\n const { output } = context;\n const { body } = route.request ?? {};\n\n // If no `body` property is defined, we don't need to do anything\n if (!body) {\n return;\n }\n\n const content: Record<string, OpenAPIV3_1.MediaTypeObject> = {};\n\n for (const [media, zodSchema] of Object.entries(body)) {\n content[media] = {\n schema: zodToOpenAPI(zodSchema) as any,\n };\n }\n\n output.data.requestBody = { content };\n }\n}\n"],"names":["BodyAssembler","assemble","context","route","output","body","request","content","media","zodSchema","Object","entries","schema","zodToOpenAPI","data","requestBody"],"mappings":";;;AAQO,MAAMA,aAAAA,CAAAA;IACXC,QAAAA,CAASC,OAAyB,EAAEC,KAAiB,EAAQ;QAC3D,MAAM,EAAEC,MAAM,EAAE,GAAGF,OAAAA;AACnB,QAAA,MAAM,EAAEG,IAAI,EAAE,GAAGF,KAAAA,CAAMG,OAAO,IAAI,EAAC;;AAGnC,QAAA,IAAI,CAACD,IAAAA,EAAM;AACT,YAAA;AACF,QAAA;AAEA,QAAA,MAAME,UAAuD,EAAC;
|
|
1
|
+
{"version":3,"file":"body.mjs","sources":["../../../../../../src/assemblers/document/path/path-item/operation/body.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport type { OpenAPIV3_1 } from 'openapi-types';\n\nimport type { OperationContext } from '../../../../../types';\nimport type { Assembler } from '../../../..';\n\nimport { zodToOpenAPI } from '../../../../../utils';\n\nexport class BodyAssembler implements Assembler.Operation {\n assemble(context: OperationContext, route: Core.Route): void {\n const { output } = context;\n const { body } = route.request ?? {};\n\n // If no `body` property is defined, we don't need to do anything\n if (!body) {\n return;\n }\n\n const content: Record<string, OpenAPIV3_1.MediaTypeObject> = {};\n\n const schemaStore = context.strapi.contentAPISchemaRegistry;\n const { extractedComponentSchemas } = context.registries;\n\n for (const [media, zodSchema] of Object.entries(body)) {\n content[media] = {\n schema: zodToOpenAPI(zodSchema, schemaStore, { extractedComponentSchemas }) as any,\n };\n }\n\n output.data.requestBody = { content };\n }\n}\n"],"names":["BodyAssembler","assemble","context","route","output","body","request","content","schemaStore","strapi","contentAPISchemaRegistry","extractedComponentSchemas","registries","media","zodSchema","Object","entries","schema","zodToOpenAPI","data","requestBody"],"mappings":";;;AAQO,MAAMA,aAAAA,CAAAA;IACXC,QAAAA,CAASC,OAAyB,EAAEC,KAAiB,EAAQ;QAC3D,MAAM,EAAEC,MAAM,EAAE,GAAGF,OAAAA;AACnB,QAAA,MAAM,EAAEG,IAAI,EAAE,GAAGF,KAAAA,CAAMG,OAAO,IAAI,EAAC;;AAGnC,QAAA,IAAI,CAACD,IAAAA,EAAM;AACT,YAAA;AACF,QAAA;AAEA,QAAA,MAAME,UAAuD,EAAC;AAE9D,QAAA,MAAMC,WAAAA,GAAcN,OAAAA,CAAQO,MAAM,CAACC,wBAAwB;AAC3D,QAAA,MAAM,EAAEC,yBAAyB,EAAE,GAAGT,QAAQU,UAAU;QAExD,KAAK,MAAM,CAACC,KAAAA,EAAOC,SAAAA,CAAU,IAAIC,MAAAA,CAAOC,OAAO,CAACX,IAAAA,CAAAA,CAAO;YACrDE,OAAO,CAACM,MAAM,GAAG;gBACfI,MAAAA,EAAQC,YAAAA,CAAaJ,WAAWN,WAAAA,EAAa;AAAEG,oBAAAA;AAA0B,iBAAA;AAC3E,aAAA;AACF,QAAA;QAEAP,MAAAA,CAAOe,IAAI,CAACC,WAAW,GAAG;AAAEb,YAAAA;AAAQ,SAAA;AACtC,IAAA;AACF;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parameters.d.ts","sourceRoot":"","sources":["../../../../../../src/assemblers/document/path/path-item/operation/parameters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAY7D,qBAAa,4BAA6B,YAAW,SAAS,CAAC,SAAS;IACtE,QAAQ,CAAC,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"parameters.d.ts","sourceRoot":"","sources":["../../../../../../src/assemblers/document/path/path-item/operation/parameters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAY7D,qBAAa,4BAA6B,YAAW,SAAS,CAAC,SAAS;IACtE,QAAQ,CAAC,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI;IAiB5D,OAAO,CAAC,kBAAkB;IA0B1B,OAAO,CAAC,mBAAmB;IAyD3B;;;OAGG;IACH,OAAO,CAAC,cAAc;IA2CtB,OAAO,CAAC,wBAAwB;CAqCjC"}
|
|
@@ -8,9 +8,11 @@ const debug = debug$1.createDebugger('assembler:parameters');
|
|
|
8
8
|
class OperationParametersAssembler {
|
|
9
9
|
assemble(context, route) {
|
|
10
10
|
debug('assembling parameters for %o %o...', route.method, route.path);
|
|
11
|
-
const
|
|
11
|
+
const schemaStore = context.strapi.contentAPISchemaRegistry;
|
|
12
|
+
const { extractedComponentSchemas } = context.registries;
|
|
13
|
+
const pathParameters = this._getPathParameters(route, schemaStore, extractedComponentSchemas);
|
|
12
14
|
debug('found %o path parameters', pathParameters.length);
|
|
13
|
-
const queryParameters = this._getQueryParameters(route);
|
|
15
|
+
const queryParameters = this._getQueryParameters(route, schemaStore, extractedComponentSchemas);
|
|
14
16
|
debug('found %o query parameters', queryParameters.length);
|
|
15
17
|
const parameters = [
|
|
16
18
|
...pathParameters,
|
|
@@ -19,7 +21,7 @@ class OperationParametersAssembler {
|
|
|
19
21
|
debug('assembled %o parameters for %o %o', parameters.length, route.method, route.path);
|
|
20
22
|
context.output.data.parameters = parameters;
|
|
21
23
|
}
|
|
22
|
-
_getPathParameters(route) {
|
|
24
|
+
_getPathParameters(route, schemaStore, extractedComponentSchemas) {
|
|
23
25
|
const { params } = route.request ?? {};
|
|
24
26
|
// TODO: Allow auto inference (from path) if enabled through configuration
|
|
25
27
|
if (!params) {
|
|
@@ -28,7 +30,9 @@ class OperationParametersAssembler {
|
|
|
28
30
|
const pathParams = [];
|
|
29
31
|
for (const [name, zodSchema] of Object.entries(params)){
|
|
30
32
|
const required = !zodSchema.isOptional();
|
|
31
|
-
const schema = zod.zodToOpenAPI(zodSchema
|
|
33
|
+
const schema = zod.zodToOpenAPI(zodSchema, schemaStore, {
|
|
34
|
+
extractedComponentSchemas
|
|
35
|
+
});
|
|
32
36
|
pathParams.push({
|
|
33
37
|
name,
|
|
34
38
|
in: 'path',
|
|
@@ -38,7 +42,7 @@ class OperationParametersAssembler {
|
|
|
38
42
|
}
|
|
39
43
|
return pathParams;
|
|
40
44
|
}
|
|
41
|
-
_getQueryParameters(route) {
|
|
45
|
+
_getQueryParameters(route, schemaStore, extractedComponentSchemas) {
|
|
42
46
|
const { query } = route.request ?? {};
|
|
43
47
|
if (!query) {
|
|
44
48
|
return [];
|
|
@@ -46,7 +50,9 @@ class OperationParametersAssembler {
|
|
|
46
50
|
const queryParams = [];
|
|
47
51
|
for (const [name, zodSchema] of Object.entries(query)){
|
|
48
52
|
const required = !zodSchema.isOptional();
|
|
49
|
-
const schema = zod.zodToOpenAPI(zodSchema
|
|
53
|
+
const schema = zod.zodToOpenAPI(zodSchema, schemaStore, {
|
|
54
|
+
extractedComponentSchemas
|
|
55
|
+
});
|
|
50
56
|
const resolvedSchema = this._resolveSchema(schema);
|
|
51
57
|
if (queryParamStyles.hasExpandableObjectProperties(resolvedSchema)) {
|
|
52
58
|
for (const [propName, propSchema] of Object.entries(resolvedSchema.properties)){
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parameters.js","sources":["../../../../../../src/assemblers/document/path/path-item/operation/parameters.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport type { OpenAPIV3_1 } from 'openapi-types';\nimport type { Assembler } from '../../../..';\n\nimport type { OperationContext } from '../../../../../types';\nimport { createDebugger, zodToOpenAPI } from '../../../../../utils';\nimport {\n hasExpandableObjectProperties,\n shouldUseDeepObjectStyle,\n} from '../../../query-param-styles';\n\nconst debug = createDebugger('assembler:parameters');\n\ntype PathParameterObject = OpenAPIV3_1.ParameterObject & { in: 'path' };\ntype QueryParameterObject = OpenAPIV3_1.ParameterObject & { in: 'query' };\n\nexport class OperationParametersAssembler implements Assembler.Operation {\n assemble(context: OperationContext, route: Core.Route): void {\n debug('assembling parameters for %o %o...', route.method, route.path);\n\n const pathParameters = this._getPathParameters(route);\n debug('found %o path parameters', pathParameters.length);\n\n const queryParameters = this._getQueryParameters(route);\n debug('found %o query parameters', queryParameters.length);\n\n const parameters = [...pathParameters, ...queryParameters];\n debug('assembled %o parameters for %o %o', parameters.length, route.method, route.path);\n\n context.output.data.parameters = parameters;\n }\n\n private _getPathParameters(route: Core.Route): PathParameterObject[] {\n const { params } = route.request ?? {};\n\n // TODO: Allow auto inference (from path) if enabled through configuration\n if (!params) {\n return [];\n }\n\n const pathParams: PathParameterObject[] = [];\n\n for (const [name, zodSchema] of Object.entries(params)) {\n const required = !zodSchema.isOptional();\n const schema = zodToOpenAPI(zodSchema) as any;\n\n pathParams.push({ name, in: 'path', required, schema });\n }\n\n return pathParams;\n }\n\n private _getQueryParameters(route: Core.Route): QueryParameterObject[] {\n const { query } = route.request ?? {};\n\n if (!query) {\n return [];\n }\n\n const queryParams: QueryParameterObject[] = [];\n\n for (const [name, zodSchema] of Object.entries(query)) {\n const required = !zodSchema.isOptional();\n const schema = zodToOpenAPI(zodSchema) as any;\n\n const resolvedSchema = this._resolveSchema(schema);\n\n if (hasExpandableObjectProperties(resolvedSchema)) {\n for (const [propName, propSchema] of Object.entries(resolvedSchema.properties!)) {\n const isRequired = resolvedSchema.required?.includes(propName) ?? false;\n\n const param: QueryParameterObject = {\n name: `${name}[${propName}]`,\n in: 'query',\n required: isRequired,\n schema: propSchema as any,\n };\n\n Object.assign(param, { 'x-strapi-serialize': 'querystring' });\n queryParams.push(param);\n }\n } else if (shouldUseDeepObjectStyle(name, resolvedSchema)) {\n const param: QueryParameterObject = {\n name,\n in: 'query',\n required,\n schema: resolvedSchema as any,\n style: 'deepObject',\n explode: true,\n };\n\n Object.assign(param, { 'x-strapi-serialize': 'querystring' });\n queryParams.push(param);\n } else {\n const param: QueryParameterObject = { name, in: 'query', required, schema };\n Object.assign(param, { 'x-strapi-serialize': 'querystring' });\n queryParams.push(param);\n }\n }\n\n return queryParams;\n }\n\n /**\n * Resolve composite OpenAPI schemas (allOf/anyOf/oneOf) into a flat object shape\n * so nested Strapi query params can be emitted as bracket notation (e.g. pagination[page]).\n */\n private _resolveSchema(schema: OpenAPIV3_1.SchemaObject): OpenAPIV3_1.SchemaObject {\n if (schema.type === 'object' && schema.properties) {\n return schema;\n }\n\n if (schema.allOf && Array.isArray(schema.allOf)) {\n const mergedSchema: OpenAPIV3_1.SchemaObject = {\n type: 'object',\n properties: {},\n required: [],\n };\n\n for (const subSchema of schema.allOf) {\n if (!('$ref' in subSchema)) {\n const hasAnyOfOneOf = Boolean(subSchema.anyOf || subSchema.oneOf);\n const resolved = this._resolveSchema(subSchema);\n\n if (resolved.type === 'object' && resolved.properties) {\n Object.assign(mergedSchema.properties!, resolved.properties);\n if (resolved.required && !hasAnyOfOneOf) {\n mergedSchema.required = [\n ...(mergedSchema.required ?? []),\n ...(resolved.required as string[]),\n ];\n }\n }\n }\n }\n\n return hasExpandableObjectProperties(mergedSchema) ? mergedSchema : schema;\n }\n\n if (schema.anyOf && Array.isArray(schema.anyOf)) {\n return this._extractCommonProperties(schema.anyOf, false);\n }\n\n if (schema.oneOf && Array.isArray(schema.oneOf)) {\n return this._extractCommonProperties(schema.oneOf, false);\n }\n\n return schema;\n }\n\n private _extractCommonProperties(\n schemas: OpenAPIV3_1.SchemaObject[],\n preserveRequired = true\n ): OpenAPIV3_1.SchemaObject {\n const objectSchemas = schemas\n .filter((s): s is OpenAPIV3_1.SchemaObject => !('$ref' in s))\n .map((s) => this._resolveSchema(s))\n .filter((s) => s.type === 'object' && s.properties);\n\n if (objectSchemas.length === 0) {\n return schemas[0] as OpenAPIV3_1.SchemaObject;\n }\n\n const allProperties: Record<string, OpenAPIV3_1.SchemaObject> = {};\n let allRequired: string[] = [];\n\n for (const objSchema of objectSchemas) {\n Object.assign(allProperties, objSchema.properties);\n if (preserveRequired && objSchema.required) {\n allRequired.push(...(objSchema.required as string[]));\n }\n }\n\n if (!preserveRequired) {\n allRequired = [];\n }\n\n if (Object.keys(allProperties).length === 0) {\n return schemas[0] as OpenAPIV3_1.SchemaObject;\n }\n\n return {\n type: 'object',\n properties: allProperties,\n required: allRequired,\n };\n }\n}\n"],"names":["debug","createDebugger","OperationParametersAssembler","assemble","context","route","method","path","pathParameters","_getPathParameters","length","queryParameters","_getQueryParameters","parameters","output","data","params","request","pathParams","name","zodSchema","Object","entries","required","isOptional","schema","zodToOpenAPI","push","in","query","queryParams","resolvedSchema","_resolveSchema","hasExpandableObjectProperties","propName","propSchema","properties","isRequired","includes","param","assign","shouldUseDeepObjectStyle","style","explode","type","allOf","Array","isArray","mergedSchema","subSchema","hasAnyOfOneOf","Boolean","anyOf","oneOf","resolved","_extractCommonProperties","schemas","preserveRequired","objectSchemas","filter","s","map","allProperties","allRequired","objSchema","keys"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"parameters.js","sources":["../../../../../../src/assemblers/document/path/path-item/operation/parameters.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport type { OpenAPIV3_1 } from 'openapi-types';\nimport type { Assembler } from '../../../..';\n\nimport type { OperationContext } from '../../../../../types';\nimport { createDebugger, zodToOpenAPI } from '../../../../../utils';\nimport {\n hasExpandableObjectProperties,\n shouldUseDeepObjectStyle,\n} from '../../../query-param-styles';\n\nconst debug = createDebugger('assembler:parameters');\n\ntype PathParameterObject = OpenAPIV3_1.ParameterObject & { in: 'path' };\ntype QueryParameterObject = OpenAPIV3_1.ParameterObject & { in: 'query' };\n\nexport class OperationParametersAssembler implements Assembler.Operation {\n assemble(context: OperationContext, route: Core.Route): void {\n debug('assembling parameters for %o %o...', route.method, route.path);\n\n const schemaStore = context.strapi.contentAPISchemaRegistry;\n const { extractedComponentSchemas } = context.registries;\n const pathParameters = this._getPathParameters(route, schemaStore, extractedComponentSchemas);\n debug('found %o path parameters', pathParameters.length);\n\n const queryParameters = this._getQueryParameters(route, schemaStore, extractedComponentSchemas);\n debug('found %o query parameters', queryParameters.length);\n\n const parameters = [...pathParameters, ...queryParameters];\n debug('assembled %o parameters for %o %o', parameters.length, route.method, route.path);\n\n context.output.data.parameters = parameters;\n }\n\n private _getPathParameters(\n route: Core.Route,\n schemaStore: Core.ContentAPISchemaRegistry,\n extractedComponentSchemas: Record<string, OpenAPIV3_1.SchemaObject>\n ): PathParameterObject[] {\n const { params } = route.request ?? {};\n\n // TODO: Allow auto inference (from path) if enabled through configuration\n if (!params) {\n return [];\n }\n\n const pathParams: PathParameterObject[] = [];\n\n for (const [name, zodSchema] of Object.entries(params)) {\n const required = !zodSchema.isOptional();\n const schema = zodToOpenAPI(zodSchema, schemaStore, {\n extractedComponentSchemas,\n }) as any;\n\n pathParams.push({ name, in: 'path', required, schema });\n }\n\n return pathParams;\n }\n\n private _getQueryParameters(\n route: Core.Route,\n schemaStore: Core.ContentAPISchemaRegistry,\n extractedComponentSchemas: Record<string, OpenAPIV3_1.SchemaObject>\n ): QueryParameterObject[] {\n const { query } = route.request ?? {};\n\n if (!query) {\n return [];\n }\n\n const queryParams: QueryParameterObject[] = [];\n\n for (const [name, zodSchema] of Object.entries(query)) {\n const required = !zodSchema.isOptional();\n const schema = zodToOpenAPI(zodSchema, schemaStore, {\n extractedComponentSchemas,\n }) as any;\n\n const resolvedSchema = this._resolveSchema(schema);\n\n if (hasExpandableObjectProperties(resolvedSchema)) {\n for (const [propName, propSchema] of Object.entries(resolvedSchema.properties!)) {\n const isRequired = resolvedSchema.required?.includes(propName) ?? false;\n\n const param: QueryParameterObject = {\n name: `${name}[${propName}]`,\n in: 'query',\n required: isRequired,\n schema: propSchema as any,\n };\n\n Object.assign(param, { 'x-strapi-serialize': 'querystring' });\n queryParams.push(param);\n }\n } else if (shouldUseDeepObjectStyle(name, resolvedSchema)) {\n const param: QueryParameterObject = {\n name,\n in: 'query',\n required,\n schema: resolvedSchema as any,\n style: 'deepObject',\n explode: true,\n };\n\n Object.assign(param, { 'x-strapi-serialize': 'querystring' });\n queryParams.push(param);\n } else {\n const param: QueryParameterObject = { name, in: 'query', required, schema };\n Object.assign(param, { 'x-strapi-serialize': 'querystring' });\n queryParams.push(param);\n }\n }\n\n return queryParams;\n }\n\n /**\n * Resolve composite OpenAPI schemas (allOf/anyOf/oneOf) into a flat object shape\n * so nested Strapi query params can be emitted as bracket notation (e.g. pagination[page]).\n */\n private _resolveSchema(schema: OpenAPIV3_1.SchemaObject): OpenAPIV3_1.SchemaObject {\n if (schema.type === 'object' && schema.properties) {\n return schema;\n }\n\n if (schema.allOf && Array.isArray(schema.allOf)) {\n const mergedSchema: OpenAPIV3_1.SchemaObject = {\n type: 'object',\n properties: {},\n required: [],\n };\n\n for (const subSchema of schema.allOf) {\n if (!('$ref' in subSchema)) {\n const hasAnyOfOneOf = Boolean(subSchema.anyOf || subSchema.oneOf);\n const resolved = this._resolveSchema(subSchema);\n\n if (resolved.type === 'object' && resolved.properties) {\n Object.assign(mergedSchema.properties!, resolved.properties);\n if (resolved.required && !hasAnyOfOneOf) {\n mergedSchema.required = [\n ...(mergedSchema.required ?? []),\n ...(resolved.required as string[]),\n ];\n }\n }\n }\n }\n\n return hasExpandableObjectProperties(mergedSchema) ? mergedSchema : schema;\n }\n\n if (schema.anyOf && Array.isArray(schema.anyOf)) {\n return this._extractCommonProperties(schema.anyOf, false);\n }\n\n if (schema.oneOf && Array.isArray(schema.oneOf)) {\n return this._extractCommonProperties(schema.oneOf, false);\n }\n\n return schema;\n }\n\n private _extractCommonProperties(\n schemas: OpenAPIV3_1.SchemaObject[],\n preserveRequired = true\n ): OpenAPIV3_1.SchemaObject {\n const objectSchemas = schemas\n .filter((s): s is OpenAPIV3_1.SchemaObject => !('$ref' in s))\n .map((s) => this._resolveSchema(s))\n .filter((s) => s.type === 'object' && s.properties);\n\n if (objectSchemas.length === 0) {\n return schemas[0] as OpenAPIV3_1.SchemaObject;\n }\n\n const allProperties: Record<string, OpenAPIV3_1.SchemaObject> = {};\n let allRequired: string[] = [];\n\n for (const objSchema of objectSchemas) {\n Object.assign(allProperties, objSchema.properties);\n if (preserveRequired && objSchema.required) {\n allRequired.push(...(objSchema.required as string[]));\n }\n }\n\n if (!preserveRequired) {\n allRequired = [];\n }\n\n if (Object.keys(allProperties).length === 0) {\n return schemas[0] as OpenAPIV3_1.SchemaObject;\n }\n\n return {\n type: 'object',\n properties: allProperties,\n required: allRequired,\n };\n }\n}\n"],"names":["debug","createDebugger","OperationParametersAssembler","assemble","context","route","method","path","schemaStore","strapi","contentAPISchemaRegistry","extractedComponentSchemas","registries","pathParameters","_getPathParameters","length","queryParameters","_getQueryParameters","parameters","output","data","params","request","pathParams","name","zodSchema","Object","entries","required","isOptional","schema","zodToOpenAPI","push","in","query","queryParams","resolvedSchema","_resolveSchema","hasExpandableObjectProperties","propName","propSchema","properties","isRequired","includes","param","assign","shouldUseDeepObjectStyle","style","explode","type","allOf","Array","isArray","mergedSchema","subSchema","hasAnyOfOneOf","Boolean","anyOf","oneOf","resolved","_extractCommonProperties","schemas","preserveRequired","objectSchemas","filter","s","map","allProperties","allRequired","objSchema","keys"],"mappings":"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"}
|
|
@@ -6,9 +6,11 @@ const debug = createDebugger('assembler:parameters');
|
|
|
6
6
|
class OperationParametersAssembler {
|
|
7
7
|
assemble(context, route) {
|
|
8
8
|
debug('assembling parameters for %o %o...', route.method, route.path);
|
|
9
|
-
const
|
|
9
|
+
const schemaStore = context.strapi.contentAPISchemaRegistry;
|
|
10
|
+
const { extractedComponentSchemas } = context.registries;
|
|
11
|
+
const pathParameters = this._getPathParameters(route, schemaStore, extractedComponentSchemas);
|
|
10
12
|
debug('found %o path parameters', pathParameters.length);
|
|
11
|
-
const queryParameters = this._getQueryParameters(route);
|
|
13
|
+
const queryParameters = this._getQueryParameters(route, schemaStore, extractedComponentSchemas);
|
|
12
14
|
debug('found %o query parameters', queryParameters.length);
|
|
13
15
|
const parameters = [
|
|
14
16
|
...pathParameters,
|
|
@@ -17,7 +19,7 @@ class OperationParametersAssembler {
|
|
|
17
19
|
debug('assembled %o parameters for %o %o', parameters.length, route.method, route.path);
|
|
18
20
|
context.output.data.parameters = parameters;
|
|
19
21
|
}
|
|
20
|
-
_getPathParameters(route) {
|
|
22
|
+
_getPathParameters(route, schemaStore, extractedComponentSchemas) {
|
|
21
23
|
const { params } = route.request ?? {};
|
|
22
24
|
// TODO: Allow auto inference (from path) if enabled through configuration
|
|
23
25
|
if (!params) {
|
|
@@ -26,7 +28,9 @@ class OperationParametersAssembler {
|
|
|
26
28
|
const pathParams = [];
|
|
27
29
|
for (const [name, zodSchema] of Object.entries(params)){
|
|
28
30
|
const required = !zodSchema.isOptional();
|
|
29
|
-
const schema = zodToOpenAPI(zodSchema
|
|
31
|
+
const schema = zodToOpenAPI(zodSchema, schemaStore, {
|
|
32
|
+
extractedComponentSchemas
|
|
33
|
+
});
|
|
30
34
|
pathParams.push({
|
|
31
35
|
name,
|
|
32
36
|
in: 'path',
|
|
@@ -36,7 +40,7 @@ class OperationParametersAssembler {
|
|
|
36
40
|
}
|
|
37
41
|
return pathParams;
|
|
38
42
|
}
|
|
39
|
-
_getQueryParameters(route) {
|
|
43
|
+
_getQueryParameters(route, schemaStore, extractedComponentSchemas) {
|
|
40
44
|
const { query } = route.request ?? {};
|
|
41
45
|
if (!query) {
|
|
42
46
|
return [];
|
|
@@ -44,7 +48,9 @@ class OperationParametersAssembler {
|
|
|
44
48
|
const queryParams = [];
|
|
45
49
|
for (const [name, zodSchema] of Object.entries(query)){
|
|
46
50
|
const required = !zodSchema.isOptional();
|
|
47
|
-
const schema = zodToOpenAPI(zodSchema
|
|
51
|
+
const schema = zodToOpenAPI(zodSchema, schemaStore, {
|
|
52
|
+
extractedComponentSchemas
|
|
53
|
+
});
|
|
48
54
|
const resolvedSchema = this._resolveSchema(schema);
|
|
49
55
|
if (hasExpandableObjectProperties(resolvedSchema)) {
|
|
50
56
|
for (const [propName, propSchema] of Object.entries(resolvedSchema.properties)){
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parameters.mjs","sources":["../../../../../../src/assemblers/document/path/path-item/operation/parameters.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport type { OpenAPIV3_1 } from 'openapi-types';\nimport type { Assembler } from '../../../..';\n\nimport type { OperationContext } from '../../../../../types';\nimport { createDebugger, zodToOpenAPI } from '../../../../../utils';\nimport {\n hasExpandableObjectProperties,\n shouldUseDeepObjectStyle,\n} from '../../../query-param-styles';\n\nconst debug = createDebugger('assembler:parameters');\n\ntype PathParameterObject = OpenAPIV3_1.ParameterObject & { in: 'path' };\ntype QueryParameterObject = OpenAPIV3_1.ParameterObject & { in: 'query' };\n\nexport class OperationParametersAssembler implements Assembler.Operation {\n assemble(context: OperationContext, route: Core.Route): void {\n debug('assembling parameters for %o %o...', route.method, route.path);\n\n const pathParameters = this._getPathParameters(route);\n debug('found %o path parameters', pathParameters.length);\n\n const queryParameters = this._getQueryParameters(route);\n debug('found %o query parameters', queryParameters.length);\n\n const parameters = [...pathParameters, ...queryParameters];\n debug('assembled %o parameters for %o %o', parameters.length, route.method, route.path);\n\n context.output.data.parameters = parameters;\n }\n\n private _getPathParameters(route: Core.Route): PathParameterObject[] {\n const { params } = route.request ?? {};\n\n // TODO: Allow auto inference (from path) if enabled through configuration\n if (!params) {\n return [];\n }\n\n const pathParams: PathParameterObject[] = [];\n\n for (const [name, zodSchema] of Object.entries(params)) {\n const required = !zodSchema.isOptional();\n const schema = zodToOpenAPI(zodSchema) as any;\n\n pathParams.push({ name, in: 'path', required, schema });\n }\n\n return pathParams;\n }\n\n private _getQueryParameters(route: Core.Route): QueryParameterObject[] {\n const { query } = route.request ?? {};\n\n if (!query) {\n return [];\n }\n\n const queryParams: QueryParameterObject[] = [];\n\n for (const [name, zodSchema] of Object.entries(query)) {\n const required = !zodSchema.isOptional();\n const schema = zodToOpenAPI(zodSchema) as any;\n\n const resolvedSchema = this._resolveSchema(schema);\n\n if (hasExpandableObjectProperties(resolvedSchema)) {\n for (const [propName, propSchema] of Object.entries(resolvedSchema.properties!)) {\n const isRequired = resolvedSchema.required?.includes(propName) ?? false;\n\n const param: QueryParameterObject = {\n name: `${name}[${propName}]`,\n in: 'query',\n required: isRequired,\n schema: propSchema as any,\n };\n\n Object.assign(param, { 'x-strapi-serialize': 'querystring' });\n queryParams.push(param);\n }\n } else if (shouldUseDeepObjectStyle(name, resolvedSchema)) {\n const param: QueryParameterObject = {\n name,\n in: 'query',\n required,\n schema: resolvedSchema as any,\n style: 'deepObject',\n explode: true,\n };\n\n Object.assign(param, { 'x-strapi-serialize': 'querystring' });\n queryParams.push(param);\n } else {\n const param: QueryParameterObject = { name, in: 'query', required, schema };\n Object.assign(param, { 'x-strapi-serialize': 'querystring' });\n queryParams.push(param);\n }\n }\n\n return queryParams;\n }\n\n /**\n * Resolve composite OpenAPI schemas (allOf/anyOf/oneOf) into a flat object shape\n * so nested Strapi query params can be emitted as bracket notation (e.g. pagination[page]).\n */\n private _resolveSchema(schema: OpenAPIV3_1.SchemaObject): OpenAPIV3_1.SchemaObject {\n if (schema.type === 'object' && schema.properties) {\n return schema;\n }\n\n if (schema.allOf && Array.isArray(schema.allOf)) {\n const mergedSchema: OpenAPIV3_1.SchemaObject = {\n type: 'object',\n properties: {},\n required: [],\n };\n\n for (const subSchema of schema.allOf) {\n if (!('$ref' in subSchema)) {\n const hasAnyOfOneOf = Boolean(subSchema.anyOf || subSchema.oneOf);\n const resolved = this._resolveSchema(subSchema);\n\n if (resolved.type === 'object' && resolved.properties) {\n Object.assign(mergedSchema.properties!, resolved.properties);\n if (resolved.required && !hasAnyOfOneOf) {\n mergedSchema.required = [\n ...(mergedSchema.required ?? []),\n ...(resolved.required as string[]),\n ];\n }\n }\n }\n }\n\n return hasExpandableObjectProperties(mergedSchema) ? mergedSchema : schema;\n }\n\n if (schema.anyOf && Array.isArray(schema.anyOf)) {\n return this._extractCommonProperties(schema.anyOf, false);\n }\n\n if (schema.oneOf && Array.isArray(schema.oneOf)) {\n return this._extractCommonProperties(schema.oneOf, false);\n }\n\n return schema;\n }\n\n private _extractCommonProperties(\n schemas: OpenAPIV3_1.SchemaObject[],\n preserveRequired = true\n ): OpenAPIV3_1.SchemaObject {\n const objectSchemas = schemas\n .filter((s): s is OpenAPIV3_1.SchemaObject => !('$ref' in s))\n .map((s) => this._resolveSchema(s))\n .filter((s) => s.type === 'object' && s.properties);\n\n if (objectSchemas.length === 0) {\n return schemas[0] as OpenAPIV3_1.SchemaObject;\n }\n\n const allProperties: Record<string, OpenAPIV3_1.SchemaObject> = {};\n let allRequired: string[] = [];\n\n for (const objSchema of objectSchemas) {\n Object.assign(allProperties, objSchema.properties);\n if (preserveRequired && objSchema.required) {\n allRequired.push(...(objSchema.required as string[]));\n }\n }\n\n if (!preserveRequired) {\n allRequired = [];\n }\n\n if (Object.keys(allProperties).length === 0) {\n return schemas[0] as OpenAPIV3_1.SchemaObject;\n }\n\n return {\n type: 'object',\n properties: allProperties,\n required: allRequired,\n };\n }\n}\n"],"names":["debug","createDebugger","OperationParametersAssembler","assemble","context","route","method","path","pathParameters","_getPathParameters","length","queryParameters","_getQueryParameters","parameters","output","data","params","request","pathParams","name","zodSchema","Object","entries","required","isOptional","schema","zodToOpenAPI","push","in","query","queryParams","resolvedSchema","_resolveSchema","hasExpandableObjectProperties","propName","propSchema","properties","isRequired","includes","param","assign","shouldUseDeepObjectStyle","style","explode","type","allOf","Array","isArray","mergedSchema","subSchema","hasAnyOfOneOf","Boolean","anyOf","oneOf","resolved","_extractCommonProperties","schemas","preserveRequired","objectSchemas","filter","s","map","allProperties","allRequired","objSchema","keys"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"parameters.mjs","sources":["../../../../../../src/assemblers/document/path/path-item/operation/parameters.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport type { OpenAPIV3_1 } from 'openapi-types';\nimport type { Assembler } from '../../../..';\n\nimport type { OperationContext } from '../../../../../types';\nimport { createDebugger, zodToOpenAPI } from '../../../../../utils';\nimport {\n hasExpandableObjectProperties,\n shouldUseDeepObjectStyle,\n} from '../../../query-param-styles';\n\nconst debug = createDebugger('assembler:parameters');\n\ntype PathParameterObject = OpenAPIV3_1.ParameterObject & { in: 'path' };\ntype QueryParameterObject = OpenAPIV3_1.ParameterObject & { in: 'query' };\n\nexport class OperationParametersAssembler implements Assembler.Operation {\n assemble(context: OperationContext, route: Core.Route): void {\n debug('assembling parameters for %o %o...', route.method, route.path);\n\n const schemaStore = context.strapi.contentAPISchemaRegistry;\n const { extractedComponentSchemas } = context.registries;\n const pathParameters = this._getPathParameters(route, schemaStore, extractedComponentSchemas);\n debug('found %o path parameters', pathParameters.length);\n\n const queryParameters = this._getQueryParameters(route, schemaStore, extractedComponentSchemas);\n debug('found %o query parameters', queryParameters.length);\n\n const parameters = [...pathParameters, ...queryParameters];\n debug('assembled %o parameters for %o %o', parameters.length, route.method, route.path);\n\n context.output.data.parameters = parameters;\n }\n\n private _getPathParameters(\n route: Core.Route,\n schemaStore: Core.ContentAPISchemaRegistry,\n extractedComponentSchemas: Record<string, OpenAPIV3_1.SchemaObject>\n ): PathParameterObject[] {\n const { params } = route.request ?? {};\n\n // TODO: Allow auto inference (from path) if enabled through configuration\n if (!params) {\n return [];\n }\n\n const pathParams: PathParameterObject[] = [];\n\n for (const [name, zodSchema] of Object.entries(params)) {\n const required = !zodSchema.isOptional();\n const schema = zodToOpenAPI(zodSchema, schemaStore, {\n extractedComponentSchemas,\n }) as any;\n\n pathParams.push({ name, in: 'path', required, schema });\n }\n\n return pathParams;\n }\n\n private _getQueryParameters(\n route: Core.Route,\n schemaStore: Core.ContentAPISchemaRegistry,\n extractedComponentSchemas: Record<string, OpenAPIV3_1.SchemaObject>\n ): QueryParameterObject[] {\n const { query } = route.request ?? {};\n\n if (!query) {\n return [];\n }\n\n const queryParams: QueryParameterObject[] = [];\n\n for (const [name, zodSchema] of Object.entries(query)) {\n const required = !zodSchema.isOptional();\n const schema = zodToOpenAPI(zodSchema, schemaStore, {\n extractedComponentSchemas,\n }) as any;\n\n const resolvedSchema = this._resolveSchema(schema);\n\n if (hasExpandableObjectProperties(resolvedSchema)) {\n for (const [propName, propSchema] of Object.entries(resolvedSchema.properties!)) {\n const isRequired = resolvedSchema.required?.includes(propName) ?? false;\n\n const param: QueryParameterObject = {\n name: `${name}[${propName}]`,\n in: 'query',\n required: isRequired,\n schema: propSchema as any,\n };\n\n Object.assign(param, { 'x-strapi-serialize': 'querystring' });\n queryParams.push(param);\n }\n } else if (shouldUseDeepObjectStyle(name, resolvedSchema)) {\n const param: QueryParameterObject = {\n name,\n in: 'query',\n required,\n schema: resolvedSchema as any,\n style: 'deepObject',\n explode: true,\n };\n\n Object.assign(param, { 'x-strapi-serialize': 'querystring' });\n queryParams.push(param);\n } else {\n const param: QueryParameterObject = { name, in: 'query', required, schema };\n Object.assign(param, { 'x-strapi-serialize': 'querystring' });\n queryParams.push(param);\n }\n }\n\n return queryParams;\n }\n\n /**\n * Resolve composite OpenAPI schemas (allOf/anyOf/oneOf) into a flat object shape\n * so nested Strapi query params can be emitted as bracket notation (e.g. pagination[page]).\n */\n private _resolveSchema(schema: OpenAPIV3_1.SchemaObject): OpenAPIV3_1.SchemaObject {\n if (schema.type === 'object' && schema.properties) {\n return schema;\n }\n\n if (schema.allOf && Array.isArray(schema.allOf)) {\n const mergedSchema: OpenAPIV3_1.SchemaObject = {\n type: 'object',\n properties: {},\n required: [],\n };\n\n for (const subSchema of schema.allOf) {\n if (!('$ref' in subSchema)) {\n const hasAnyOfOneOf = Boolean(subSchema.anyOf || subSchema.oneOf);\n const resolved = this._resolveSchema(subSchema);\n\n if (resolved.type === 'object' && resolved.properties) {\n Object.assign(mergedSchema.properties!, resolved.properties);\n if (resolved.required && !hasAnyOfOneOf) {\n mergedSchema.required = [\n ...(mergedSchema.required ?? []),\n ...(resolved.required as string[]),\n ];\n }\n }\n }\n }\n\n return hasExpandableObjectProperties(mergedSchema) ? mergedSchema : schema;\n }\n\n if (schema.anyOf && Array.isArray(schema.anyOf)) {\n return this._extractCommonProperties(schema.anyOf, false);\n }\n\n if (schema.oneOf && Array.isArray(schema.oneOf)) {\n return this._extractCommonProperties(schema.oneOf, false);\n }\n\n return schema;\n }\n\n private _extractCommonProperties(\n schemas: OpenAPIV3_1.SchemaObject[],\n preserveRequired = true\n ): OpenAPIV3_1.SchemaObject {\n const objectSchemas = schemas\n .filter((s): s is OpenAPIV3_1.SchemaObject => !('$ref' in s))\n .map((s) => this._resolveSchema(s))\n .filter((s) => s.type === 'object' && s.properties);\n\n if (objectSchemas.length === 0) {\n return schemas[0] as OpenAPIV3_1.SchemaObject;\n }\n\n const allProperties: Record<string, OpenAPIV3_1.SchemaObject> = {};\n let allRequired: string[] = [];\n\n for (const objSchema of objectSchemas) {\n Object.assign(allProperties, objSchema.properties);\n if (preserveRequired && objSchema.required) {\n allRequired.push(...(objSchema.required as string[]));\n }\n }\n\n if (!preserveRequired) {\n allRequired = [];\n }\n\n if (Object.keys(allProperties).length === 0) {\n return schemas[0] as OpenAPIV3_1.SchemaObject;\n }\n\n return {\n type: 'object',\n properties: allProperties,\n required: allRequired,\n };\n }\n}\n"],"names":["debug","createDebugger","OperationParametersAssembler","assemble","context","route","method","path","schemaStore","strapi","contentAPISchemaRegistry","extractedComponentSchemas","registries","pathParameters","_getPathParameters","length","queryParameters","_getQueryParameters","parameters","output","data","params","request","pathParams","name","zodSchema","Object","entries","required","isOptional","schema","zodToOpenAPI","push","in","query","queryParams","resolvedSchema","_resolveSchema","hasExpandableObjectProperties","propName","propSchema","properties","isRequired","includes","param","assign","shouldUseDeepObjectStyle","style","explode","type","allOf","Array","isArray","mergedSchema","subSchema","hasAnyOfOneOf","Boolean","anyOf","oneOf","resolved","_extractCommonProperties","schemas","preserveRequired","objectSchemas","filter","s","map","allProperties","allRequired","objSchema","keys"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../../../../../../src/assemblers/document/path/path-item/operation/responses.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG7D,qBAAa,2BAA4B,YAAW,SAAS,CAAC,SAAS;IACrE,OAAO,KAAK,OAAO,GAQlB;IAED,QAAQ,CAAC,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../../../../../../src/assemblers/document/path/path-item/operation/responses.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG7D,qBAAa,2BAA4B,YAAW,SAAS,CAAC,SAAS;IACrE,OAAO,KAAK,OAAO,GAQlB;IAED,QAAQ,CAAC,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI;CAuB7D"}
|
|
@@ -33,7 +33,9 @@ class OperationResponsesAssembler {
|
|
|
33
33
|
responses[errorCode] = response;
|
|
34
34
|
}
|
|
35
35
|
if (route.response) {
|
|
36
|
-
const schema = zod.zodToOpenAPI(route.response
|
|
36
|
+
const schema = zod.zodToOpenAPI(route.response, context.strapi.contentAPISchemaRegistry, {
|
|
37
|
+
extractedComponentSchemas: context.registries.extractedComponentSchemas
|
|
38
|
+
});
|
|
37
39
|
responses[200] = {
|
|
38
40
|
description: 'OK',
|
|
39
41
|
content: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"responses.js","sources":["../../../../../../src/assemblers/document/path/path-item/operation/responses.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport type { OpenAPIV3_1 } from 'openapi-types';\nimport type { Assembler } from '../../../..';\nimport type { OperationContext } from '../../../../../types';\nimport { zodToOpenAPI } from '../../../../../utils';\n\nexport class OperationResponsesAssembler implements Assembler.Operation {\n private get _errors() {\n return {\n 400: { description: 'Bad request' },\n 401: { description: 'Unauthorized' },\n 403: { description: 'Forbidden' },\n 404: { description: 'Not found' },\n 500: { description: 'Internal server error' },\n };\n }\n\n assemble(context: OperationContext, route: Core.Route): void {\n const { output } = context;\n\n const responses = { ...output.data.responses } satisfies OpenAPIV3_1.ResponsesObject;\n\n // Register common error responses first to allow manual overrides\n for (const [errorCode, response] of Object.entries(this._errors)) {\n responses[errorCode] = response;\n }\n\n if (route.response) {\n const schema = zodToOpenAPI(route.response);\n\n responses[200] = {\n description: 'OK',\n content: { 'application/json': { schema } },\n };\n }\n\n output.data.responses = responses;\n }\n}\n"],"names":["OperationResponsesAssembler","_errors","description","assemble","context","route","output","responses","data","errorCode","response","Object","entries","schema","zodToOpenAPI","content"],"mappings":";;;;;AAMO,MAAMA,2BAAAA,CAAAA;AACX,IAAA,IAAYC,OAAAA,GAAU;QACpB,OAAO;YACL,GAAA,EAAK;gBAAEC,WAAAA,EAAa;AAAc,aAAA;YAClC,GAAA,EAAK;gBAAEA,WAAAA,EAAa;AAAe,aAAA;YACnC,GAAA,EAAK;gBAAEA,WAAAA,EAAa;AAAY,aAAA;YAChC,GAAA,EAAK;gBAAEA,WAAAA,EAAa;AAAY,aAAA;YAChC,GAAA,EAAK;gBAAEA,WAAAA,EAAa;AAAwB;AAC9C,SAAA;AACF,IAAA;IAEAC,QAAAA,CAASC,OAAyB,EAAEC,KAAiB,EAAQ;QAC3D,MAAM,EAAEC,MAAM,EAAE,GAAGF,OAAAA;AAEnB,QAAA,MAAMG,SAAAA,GAAY;YAAE,GAAGD,MAAAA,CAAOE,IAAI,CAACD;AAAU,SAAA;;QAG7C,KAAK,MAAM,CAACE,SAAAA,EAAWC,QAAAA,CAAS,IAAIC,MAAAA,CAAOC,OAAO,CAAC,IAAI,CAACX,OAAO,CAAA,CAAG;YAChEM,SAAS,CAACE,UAAU,GAAGC,QAAAA;AACzB,QAAA;QAEA,IAAIL,KAAAA,CAAMK,QAAQ,EAAE;YAClB,MAAMG,MAAAA,GAASC,
|
|
1
|
+
{"version":3,"file":"responses.js","sources":["../../../../../../src/assemblers/document/path/path-item/operation/responses.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport type { OpenAPIV3_1 } from 'openapi-types';\nimport type { Assembler } from '../../../..';\nimport type { OperationContext } from '../../../../../types';\nimport { zodToOpenAPI } from '../../../../../utils';\n\nexport class OperationResponsesAssembler implements Assembler.Operation {\n private get _errors() {\n return {\n 400: { description: 'Bad request' },\n 401: { description: 'Unauthorized' },\n 403: { description: 'Forbidden' },\n 404: { description: 'Not found' },\n 500: { description: 'Internal server error' },\n };\n }\n\n assemble(context: OperationContext, route: Core.Route): void {\n const { output } = context;\n\n const responses = { ...output.data.responses } satisfies OpenAPIV3_1.ResponsesObject;\n\n // Register common error responses first to allow manual overrides\n for (const [errorCode, response] of Object.entries(this._errors)) {\n responses[errorCode] = response;\n }\n\n if (route.response) {\n const schema = zodToOpenAPI(route.response, context.strapi.contentAPISchemaRegistry, {\n extractedComponentSchemas: context.registries.extractedComponentSchemas,\n });\n\n responses[200] = {\n description: 'OK',\n content: { 'application/json': { schema } },\n };\n }\n\n output.data.responses = responses;\n }\n}\n"],"names":["OperationResponsesAssembler","_errors","description","assemble","context","route","output","responses","data","errorCode","response","Object","entries","schema","zodToOpenAPI","strapi","contentAPISchemaRegistry","extractedComponentSchemas","registries","content"],"mappings":";;;;;AAMO,MAAMA,2BAAAA,CAAAA;AACX,IAAA,IAAYC,OAAAA,GAAU;QACpB,OAAO;YACL,GAAA,EAAK;gBAAEC,WAAAA,EAAa;AAAc,aAAA;YAClC,GAAA,EAAK;gBAAEA,WAAAA,EAAa;AAAe,aAAA;YACnC,GAAA,EAAK;gBAAEA,WAAAA,EAAa;AAAY,aAAA;YAChC,GAAA,EAAK;gBAAEA,WAAAA,EAAa;AAAY,aAAA;YAChC,GAAA,EAAK;gBAAEA,WAAAA,EAAa;AAAwB;AAC9C,SAAA;AACF,IAAA;IAEAC,QAAAA,CAASC,OAAyB,EAAEC,KAAiB,EAAQ;QAC3D,MAAM,EAAEC,MAAM,EAAE,GAAGF,OAAAA;AAEnB,QAAA,MAAMG,SAAAA,GAAY;YAAE,GAAGD,MAAAA,CAAOE,IAAI,CAACD;AAAU,SAAA;;QAG7C,KAAK,MAAM,CAACE,SAAAA,EAAWC,QAAAA,CAAS,IAAIC,MAAAA,CAAOC,OAAO,CAAC,IAAI,CAACX,OAAO,CAAA,CAAG;YAChEM,SAAS,CAACE,UAAU,GAAGC,QAAAA;AACzB,QAAA;QAEA,IAAIL,KAAAA,CAAMK,QAAQ,EAAE;YAClB,MAAMG,MAAAA,GAASC,iBAAaT,KAAAA,CAAMK,QAAQ,EAAEN,OAAAA,CAAQW,MAAM,CAACC,wBAAwB,EAAE;gBACnFC,yBAAAA,EAA2Bb,OAAAA,CAAQc,UAAU,CAACD;AAChD,aAAA,CAAA;YAEAV,SAAS,CAAC,IAAI,GAAG;gBACfL,WAAAA,EAAa,IAAA;gBACbiB,OAAAA,EAAS;oBAAE,kBAAA,EAAoB;AAAEN,wBAAAA;AAAO;AAAE;AAC5C,aAAA;AACF,QAAA;QAEAP,MAAAA,CAAOE,IAAI,CAACD,SAAS,GAAGA,SAAAA;AAC1B,IAAA;AACF;;;;"}
|
|
@@ -31,7 +31,9 @@ class OperationResponsesAssembler {
|
|
|
31
31
|
responses[errorCode] = response;
|
|
32
32
|
}
|
|
33
33
|
if (route.response) {
|
|
34
|
-
const schema = zodToOpenAPI(route.response
|
|
34
|
+
const schema = zodToOpenAPI(route.response, context.strapi.contentAPISchemaRegistry, {
|
|
35
|
+
extractedComponentSchemas: context.registries.extractedComponentSchemas
|
|
36
|
+
});
|
|
35
37
|
responses[200] = {
|
|
36
38
|
description: 'OK',
|
|
37
39
|
content: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"responses.mjs","sources":["../../../../../../src/assemblers/document/path/path-item/operation/responses.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport type { OpenAPIV3_1 } from 'openapi-types';\nimport type { Assembler } from '../../../..';\nimport type { OperationContext } from '../../../../../types';\nimport { zodToOpenAPI } from '../../../../../utils';\n\nexport class OperationResponsesAssembler implements Assembler.Operation {\n private get _errors() {\n return {\n 400: { description: 'Bad request' },\n 401: { description: 'Unauthorized' },\n 403: { description: 'Forbidden' },\n 404: { description: 'Not found' },\n 500: { description: 'Internal server error' },\n };\n }\n\n assemble(context: OperationContext, route: Core.Route): void {\n const { output } = context;\n\n const responses = { ...output.data.responses } satisfies OpenAPIV3_1.ResponsesObject;\n\n // Register common error responses first to allow manual overrides\n for (const [errorCode, response] of Object.entries(this._errors)) {\n responses[errorCode] = response;\n }\n\n if (route.response) {\n const schema = zodToOpenAPI(route.response);\n\n responses[200] = {\n description: 'OK',\n content: { 'application/json': { schema } },\n };\n }\n\n output.data.responses = responses;\n }\n}\n"],"names":["OperationResponsesAssembler","_errors","description","assemble","context","route","output","responses","data","errorCode","response","Object","entries","schema","zodToOpenAPI","content"],"mappings":";;;AAMO,MAAMA,2BAAAA,CAAAA;AACX,IAAA,IAAYC,OAAAA,GAAU;QACpB,OAAO;YACL,GAAA,EAAK;gBAAEC,WAAAA,EAAa;AAAc,aAAA;YAClC,GAAA,EAAK;gBAAEA,WAAAA,EAAa;AAAe,aAAA;YACnC,GAAA,EAAK;gBAAEA,WAAAA,EAAa;AAAY,aAAA;YAChC,GAAA,EAAK;gBAAEA,WAAAA,EAAa;AAAY,aAAA;YAChC,GAAA,EAAK;gBAAEA,WAAAA,EAAa;AAAwB;AAC9C,SAAA;AACF,IAAA;IAEAC,QAAAA,CAASC,OAAyB,EAAEC,KAAiB,EAAQ;QAC3D,MAAM,EAAEC,MAAM,EAAE,GAAGF,OAAAA;AAEnB,QAAA,MAAMG,SAAAA,GAAY;YAAE,GAAGD,MAAAA,CAAOE,IAAI,CAACD;AAAU,SAAA;;QAG7C,KAAK,MAAM,CAACE,SAAAA,EAAWC,QAAAA,CAAS,IAAIC,MAAAA,CAAOC,OAAO,CAAC,IAAI,CAACX,OAAO,CAAA,CAAG;YAChEM,SAAS,CAACE,UAAU,GAAGC,QAAAA;AACzB,QAAA;QAEA,IAAIL,KAAAA,CAAMK,QAAQ,EAAE;YAClB,MAAMG,MAAAA,GAASC,
|
|
1
|
+
{"version":3,"file":"responses.mjs","sources":["../../../../../../src/assemblers/document/path/path-item/operation/responses.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport type { OpenAPIV3_1 } from 'openapi-types';\nimport type { Assembler } from '../../../..';\nimport type { OperationContext } from '../../../../../types';\nimport { zodToOpenAPI } from '../../../../../utils';\n\nexport class OperationResponsesAssembler implements Assembler.Operation {\n private get _errors() {\n return {\n 400: { description: 'Bad request' },\n 401: { description: 'Unauthorized' },\n 403: { description: 'Forbidden' },\n 404: { description: 'Not found' },\n 500: { description: 'Internal server error' },\n };\n }\n\n assemble(context: OperationContext, route: Core.Route): void {\n const { output } = context;\n\n const responses = { ...output.data.responses } satisfies OpenAPIV3_1.ResponsesObject;\n\n // Register common error responses first to allow manual overrides\n for (const [errorCode, response] of Object.entries(this._errors)) {\n responses[errorCode] = response;\n }\n\n if (route.response) {\n const schema = zodToOpenAPI(route.response, context.strapi.contentAPISchemaRegistry, {\n extractedComponentSchemas: context.registries.extractedComponentSchemas,\n });\n\n responses[200] = {\n description: 'OK',\n content: { 'application/json': { schema } },\n };\n }\n\n output.data.responses = responses;\n }\n}\n"],"names":["OperationResponsesAssembler","_errors","description","assemble","context","route","output","responses","data","errorCode","response","Object","entries","schema","zodToOpenAPI","strapi","contentAPISchemaRegistry","extractedComponentSchemas","registries","content"],"mappings":";;;AAMO,MAAMA,2BAAAA,CAAAA;AACX,IAAA,IAAYC,OAAAA,GAAU;QACpB,OAAO;YACL,GAAA,EAAK;gBAAEC,WAAAA,EAAa;AAAc,aAAA;YAClC,GAAA,EAAK;gBAAEA,WAAAA,EAAa;AAAe,aAAA;YACnC,GAAA,EAAK;gBAAEA,WAAAA,EAAa;AAAY,aAAA;YAChC,GAAA,EAAK;gBAAEA,WAAAA,EAAa;AAAY,aAAA;YAChC,GAAA,EAAK;gBAAEA,WAAAA,EAAa;AAAwB;AAC9C,SAAA;AACF,IAAA;IAEAC,QAAAA,CAASC,OAAyB,EAAEC,KAAiB,EAAQ;QAC3D,MAAM,EAAEC,MAAM,EAAE,GAAGF,OAAAA;AAEnB,QAAA,MAAMG,SAAAA,GAAY;YAAE,GAAGD,MAAAA,CAAOE,IAAI,CAACD;AAAU,SAAA;;QAG7C,KAAK,MAAM,CAACE,SAAAA,EAAWC,QAAAA,CAAS,IAAIC,MAAAA,CAAOC,OAAO,CAAC,IAAI,CAACX,OAAO,CAAA,CAAG;YAChEM,SAAS,CAACE,UAAU,GAAGC,QAAAA;AACzB,QAAA;QAEA,IAAIL,KAAAA,CAAMK,QAAQ,EAAE;YAClB,MAAMG,MAAAA,GAASC,aAAaT,KAAAA,CAAMK,QAAQ,EAAEN,OAAAA,CAAQW,MAAM,CAACC,wBAAwB,EAAE;gBACnFC,yBAAAA,EAA2Bb,OAAAA,CAAQc,UAAU,CAACD;AAChD,aAAA,CAAA;YAEAV,SAAS,CAAC,IAAI,GAAG;gBACfL,WAAAA,EAAa,IAAA;gBACbiB,OAAAA,EAAS;oBAAE,kBAAA,EAAoB;AAAEN,wBAAAA;AAAO;AAAE;AAC5C,aAAA;AACF,QAAA;QAEAP,MAAAA,CAAOE,IAAI,CAACD,SAAS,GAAGA,SAAAA;AAC1B,IAAA;AACF;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component-writer.d.ts","sourceRoot":"","sources":["../../src/post-processor/component-writer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"component-writer.d.ts","sourceRoot":"","sources":["../../src/post-processor/component-writer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAMhD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAM7C,qBAAa,gBAAiB,YAAW,aAAa;IACpD,WAAW,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;CA2B5C"}
|
|
@@ -23,21 +23,32 @@ function _interopNamespace(e) {
|
|
|
23
23
|
|
|
24
24
|
var z__namespace = /*#__PURE__*/_interopNamespace(z);
|
|
25
25
|
|
|
26
|
+
const isPlainObject = (value)=>{
|
|
27
|
+
return typeof value === 'object' && value !== null && Array.isArray(value) === false;
|
|
28
|
+
};
|
|
26
29
|
class ComponentsWriter {
|
|
27
30
|
postProcess(context) {
|
|
28
|
-
const { output } = context;
|
|
29
|
-
const
|
|
31
|
+
const { output, strapi } = context;
|
|
32
|
+
const registry = z__namespace.registry();
|
|
33
|
+
for (const [id, schema] of strapi.contentAPISchemaRegistry.entries()){
|
|
34
|
+
registry.add(schema, {
|
|
35
|
+
id
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
const { schemas } = z__namespace.toJSONSchema(registry, {
|
|
39
|
+
...zod.OPENAPI_SCHEMA_CONVERSION_OPTIONS,
|
|
30
40
|
uri: zod.toComponentsPath
|
|
31
41
|
});
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
zod.stripJsonSchemaId(schema);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
42
|
+
const converted = isPlainObject(schemas) ? schemas : {};
|
|
43
|
+
zod.liftZodSharedDefinitions(converted);
|
|
37
44
|
const existingComponents = output.data.components ?? {};
|
|
45
|
+
const extracted = context.registries.extractedComponentSchemas;
|
|
38
46
|
output.data.components = {
|
|
39
47
|
...existingComponents,
|
|
40
|
-
schemas
|
|
48
|
+
schemas: {
|
|
49
|
+
...extracted,
|
|
50
|
+
...converted
|
|
51
|
+
}
|
|
41
52
|
};
|
|
42
53
|
}
|
|
43
54
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component-writer.js","sources":["../../src/post-processor/component-writer.ts"],"sourcesContent":["import { OpenAPIV3_1 } from 'openapi-types';\nimport * as z from 'zod/v4';\nimport type { DocumentContext } from '../types';\nimport {
|
|
1
|
+
{"version":3,"file":"component-writer.js","sources":["../../src/post-processor/component-writer.ts"],"sourcesContent":["import { OpenAPIV3_1 } from 'openapi-types';\nimport * as z from 'zod/v4';\nimport type { DocumentContext } from '../types';\nimport {\n OPENAPI_SCHEMA_CONVERSION_OPTIONS,\n liftZodSharedDefinitions,\n toComponentsPath,\n} from '../utils/zod';\nimport type { PostProcessor } from './types';\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n return typeof value === 'object' && value !== null && Array.isArray(value) === false;\n};\n\nexport class ComponentsWriter implements PostProcessor {\n postProcess(context: DocumentContext): void {\n const { output, strapi } = context;\n const registry = z.registry<{ id: string }>();\n\n for (const [id, schema] of strapi.contentAPISchemaRegistry.entries()) {\n registry.add(schema, { id });\n }\n\n const { schemas } = z.toJSONSchema(registry, {\n ...OPENAPI_SCHEMA_CONVERSION_OPTIONS,\n uri: toComponentsPath,\n });\n\n const converted: Record<string, unknown> = isPlainObject(schemas) ? schemas : {};\n liftZodSharedDefinitions(converted);\n\n const existingComponents = output.data.components ?? {};\n const extracted = context.registries.extractedComponentSchemas;\n\n output.data.components = {\n ...existingComponents,\n schemas: {\n ...extracted,\n ...(converted as Record<string, OpenAPIV3_1.SchemaObject>),\n },\n };\n }\n}\n"],"names":["isPlainObject","value","Array","isArray","ComponentsWriter","postProcess","context","output","strapi","registry","z","id","schema","contentAPISchemaRegistry","entries","add","schemas","toJSONSchema","OPENAPI_SCHEMA_CONVERSION_OPTIONS","uri","toComponentsPath","converted","liftZodSharedDefinitions","existingComponents","data","components","extracted","registries","extractedComponentSchemas"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAUA,MAAMA,gBAAgB,CAACC,KAAAA,GAAAA;IACrB,OAAO,OAAOA,UAAU,QAAA,IAAYA,KAAAA,KAAU,QAAQC,KAAAA,CAAMC,OAAO,CAACF,KAAAA,CAAAA,KAAW,KAAA;AACjF,CAAA;AAEO,MAAMG,gBAAAA,CAAAA;AACXC,IAAAA,WAAAA,CAAYC,OAAwB,EAAQ;AAC1C,QAAA,MAAM,EAAEC,MAAM,EAAEC,MAAM,EAAE,GAAGF,OAAAA;QAC3B,MAAMG,QAAAA,GAAWC,aAAED,QAAQ,EAAA;QAE3B,KAAK,MAAM,CAACE,EAAAA,EAAIC,MAAAA,CAAO,IAAIJ,MAAAA,CAAOK,wBAAwB,CAACC,OAAO,EAAA,CAAI;YACpEL,QAAAA,CAASM,GAAG,CAACH,MAAAA,EAAQ;AAAED,gBAAAA;AAAG,aAAA,CAAA;AAC5B,QAAA;AAEA,QAAA,MAAM,EAAEK,OAAO,EAAE,GAAGN,YAAAA,CAAEO,YAAY,CAACR,QAAAA,EAAU;AAC3C,YAAA,GAAGS,qCAAiC;YACpCC,GAAAA,EAAKC;AACP,SAAA,CAAA;AAEA,QAAA,MAAMC,SAAAA,GAAqCrB,aAAAA,CAAcgB,OAAAA,CAAAA,GAAWA,OAAAA,GAAU,EAAC;QAC/EM,4BAAAA,CAAyBD,SAAAA,CAAAA;AAEzB,QAAA,MAAME,qBAAqBhB,MAAAA,CAAOiB,IAAI,CAACC,UAAU,IAAI,EAAC;AACtD,QAAA,MAAMC,SAAAA,GAAYpB,OAAAA,CAAQqB,UAAU,CAACC,yBAAyB;QAE9DrB,MAAAA,CAAOiB,IAAI,CAACC,UAAU,GAAG;AACvB,YAAA,GAAGF,kBAAkB;YACrBP,OAAAA,EAAS;AACP,gBAAA,GAAGU,SAAS;AACZ,gBAAA,GAAIL;AACN;AACF,SAAA;AACF,IAAA;AACF;;;;"}
|
|
@@ -1,21 +1,32 @@
|
|
|
1
1
|
import * as z from 'zod/v4';
|
|
2
|
-
import { toComponentsPath,
|
|
2
|
+
import { toComponentsPath, OPENAPI_SCHEMA_CONVERSION_OPTIONS, liftZodSharedDefinitions } from '../utils/zod.mjs';
|
|
3
3
|
|
|
4
|
+
const isPlainObject = (value)=>{
|
|
5
|
+
return typeof value === 'object' && value !== null && Array.isArray(value) === false;
|
|
6
|
+
};
|
|
4
7
|
class ComponentsWriter {
|
|
5
8
|
postProcess(context) {
|
|
6
|
-
const { output } = context;
|
|
7
|
-
const
|
|
9
|
+
const { output, strapi } = context;
|
|
10
|
+
const registry = z.registry();
|
|
11
|
+
for (const [id, schema] of strapi.contentAPISchemaRegistry.entries()){
|
|
12
|
+
registry.add(schema, {
|
|
13
|
+
id
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
const { schemas } = z.toJSONSchema(registry, {
|
|
17
|
+
...OPENAPI_SCHEMA_CONVERSION_OPTIONS,
|
|
8
18
|
uri: toComponentsPath
|
|
9
19
|
});
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
stripJsonSchemaId(schema);
|
|
13
|
-
}
|
|
14
|
-
}
|
|
20
|
+
const converted = isPlainObject(schemas) ? schemas : {};
|
|
21
|
+
liftZodSharedDefinitions(converted);
|
|
15
22
|
const existingComponents = output.data.components ?? {};
|
|
23
|
+
const extracted = context.registries.extractedComponentSchemas;
|
|
16
24
|
output.data.components = {
|
|
17
25
|
...existingComponents,
|
|
18
|
-
schemas
|
|
26
|
+
schemas: {
|
|
27
|
+
...extracted,
|
|
28
|
+
...converted
|
|
29
|
+
}
|
|
19
30
|
};
|
|
20
31
|
}
|
|
21
32
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component-writer.mjs","sources":["../../src/post-processor/component-writer.ts"],"sourcesContent":["import { OpenAPIV3_1 } from 'openapi-types';\nimport * as z from 'zod/v4';\nimport type { DocumentContext } from '../types';\nimport {
|
|
1
|
+
{"version":3,"file":"component-writer.mjs","sources":["../../src/post-processor/component-writer.ts"],"sourcesContent":["import { OpenAPIV3_1 } from 'openapi-types';\nimport * as z from 'zod/v4';\nimport type { DocumentContext } from '../types';\nimport {\n OPENAPI_SCHEMA_CONVERSION_OPTIONS,\n liftZodSharedDefinitions,\n toComponentsPath,\n} from '../utils/zod';\nimport type { PostProcessor } from './types';\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n return typeof value === 'object' && value !== null && Array.isArray(value) === false;\n};\n\nexport class ComponentsWriter implements PostProcessor {\n postProcess(context: DocumentContext): void {\n const { output, strapi } = context;\n const registry = z.registry<{ id: string }>();\n\n for (const [id, schema] of strapi.contentAPISchemaRegistry.entries()) {\n registry.add(schema, { id });\n }\n\n const { schemas } = z.toJSONSchema(registry, {\n ...OPENAPI_SCHEMA_CONVERSION_OPTIONS,\n uri: toComponentsPath,\n });\n\n const converted: Record<string, unknown> = isPlainObject(schemas) ? schemas : {};\n liftZodSharedDefinitions(converted);\n\n const existingComponents = output.data.components ?? {};\n const extracted = context.registries.extractedComponentSchemas;\n\n output.data.components = {\n ...existingComponents,\n schemas: {\n ...extracted,\n ...(converted as Record<string, OpenAPIV3_1.SchemaObject>),\n },\n };\n }\n}\n"],"names":["isPlainObject","value","Array","isArray","ComponentsWriter","postProcess","context","output","strapi","registry","z","id","schema","contentAPISchemaRegistry","entries","add","schemas","toJSONSchema","OPENAPI_SCHEMA_CONVERSION_OPTIONS","uri","toComponentsPath","converted","liftZodSharedDefinitions","existingComponents","data","components","extracted","registries","extractedComponentSchemas"],"mappings":";;;AAUA,MAAMA,gBAAgB,CAACC,KAAAA,GAAAA;IACrB,OAAO,OAAOA,UAAU,QAAA,IAAYA,KAAAA,KAAU,QAAQC,KAAAA,CAAMC,OAAO,CAACF,KAAAA,CAAAA,KAAW,KAAA;AACjF,CAAA;AAEO,MAAMG,gBAAAA,CAAAA;AACXC,IAAAA,WAAAA,CAAYC,OAAwB,EAAQ;AAC1C,QAAA,MAAM,EAAEC,MAAM,EAAEC,MAAM,EAAE,GAAGF,OAAAA;QAC3B,MAAMG,QAAAA,GAAWC,EAAED,QAAQ,EAAA;QAE3B,KAAK,MAAM,CAACE,EAAAA,EAAIC,MAAAA,CAAO,IAAIJ,MAAAA,CAAOK,wBAAwB,CAACC,OAAO,EAAA,CAAI;YACpEL,QAAAA,CAASM,GAAG,CAACH,MAAAA,EAAQ;AAAED,gBAAAA;AAAG,aAAA,CAAA;AAC5B,QAAA;AAEA,QAAA,MAAM,EAAEK,OAAO,EAAE,GAAGN,CAAAA,CAAEO,YAAY,CAACR,QAAAA,EAAU;AAC3C,YAAA,GAAGS,iCAAiC;YACpCC,GAAAA,EAAKC;AACP,SAAA,CAAA;AAEA,QAAA,MAAMC,SAAAA,GAAqCrB,aAAAA,CAAcgB,OAAAA,CAAAA,GAAWA,OAAAA,GAAU,EAAC;QAC/EM,wBAAAA,CAAyBD,SAAAA,CAAAA;AAEzB,QAAA,MAAME,qBAAqBhB,MAAAA,CAAOiB,IAAI,CAACC,UAAU,IAAI,EAAC;AACtD,QAAA,MAAMC,SAAAA,GAAYpB,OAAAA,CAAQqB,UAAU,CAACC,yBAAyB;QAE9DrB,MAAAA,CAAOiB,IAAI,CAACC,UAAU,GAAG;AACvB,YAAA,GAAGF,kBAAkB;YACrBP,OAAAA,EAAS;AACP,gBAAA,GAAGU,SAAS;AACZ,gBAAA,GAAIL;AACN;AACF,SAAA;AACF,IAAA;AACF;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/registries/factory.ts"],"names":[],"mappings":"AAAA,qBAAa,iBAAiB;IAC5B,SAAS;
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/registries/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,qBAAa,iBAAiB;IAC5B,SAAS,IAAI;QACX,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC;KACrE;CAKF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.js","sources":["../../src/registries/factory.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"factory.js","sources":["../../src/registries/factory.ts"],"sourcesContent":["import type { OpenAPIV3_1 } from 'openapi-types';\n\nexport class RegistriesFactory {\n createAll(): {\n extractedComponentSchemas: Record<string, OpenAPIV3_1.SchemaObject>;\n } {\n return {\n extractedComponentSchemas: {},\n };\n }\n}\n"],"names":["RegistriesFactory","createAll","extractedComponentSchemas"],"mappings":";;AAEO,MAAMA,iBAAAA,CAAAA;IACXC,SAAAA,GAEE;QACA,OAAO;AACLC,YAAAA,yBAAAA,EAA2B;AAC7B,SAAA;AACF,IAAA;AACF;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.mjs","sources":["../../src/registries/factory.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"factory.mjs","sources":["../../src/registries/factory.ts"],"sourcesContent":["import type { OpenAPIV3_1 } from 'openapi-types';\n\nexport class RegistriesFactory {\n createAll(): {\n extractedComponentSchemas: Record<string, OpenAPIV3_1.SchemaObject>;\n } {\n return {\n extractedComponentSchemas: {},\n };\n }\n}\n"],"names":["RegistriesFactory","createAll","extractedComponentSchemas"],"mappings":"AAEO,MAAMA,iBAAAA,CAAAA;IACXC,SAAAA,GAEE;QACA,OAAO;AACLC,YAAAA,yBAAAA,EAA2B;AAC7B,SAAA;AACF,IAAA;AACF;;;;"}
|
package/dist/utils/zod.d.ts
CHANGED
|
@@ -1,20 +1,64 @@
|
|
|
1
1
|
import * as z from 'zod/v4';
|
|
2
|
+
import type { Core } from '@strapi/types';
|
|
2
3
|
import type { OpenAPIV3_1 } from 'openapi-types';
|
|
3
4
|
/**
|
|
4
|
-
*
|
|
5
|
+
* OpenAPI 3.1 uses the JSON Schema 2020-12 dialect. Zod 4.4.3 has no `openapi-3.1`
|
|
6
|
+
* target, so `draft-2020-12` preserves valid 3.1 schemas. Explicit output mode preserves
|
|
7
|
+
* the conversion direction used before these defaults were pinned.
|
|
8
|
+
*/
|
|
9
|
+
export declare const OPENAPI_SCHEMA_CONVERSION_OPTIONS: {
|
|
10
|
+
readonly target: "draft-2020-12";
|
|
11
|
+
readonly io: "output";
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Zod 4.4.3 embeds `$id` in registry `toJSONSchema` output when `uri` is configured.
|
|
5
15
|
* Strip it so OpenAPI documents stay stable — inline schemas use random UUIDs
|
|
6
|
-
* as registry
|
|
16
|
+
* as registry IDs.
|
|
7
17
|
*/
|
|
8
18
|
export declare const stripJsonSchemaId: <T extends object>(schema: T) => T;
|
|
19
|
+
/**
|
|
20
|
+
* Generates a path string for referencing a component schema by its identifier.
|
|
21
|
+
*
|
|
22
|
+
* @param id - The identifier of the component schema.
|
|
23
|
+
* @returns The constructed path string for the specified component schema.
|
|
24
|
+
*/
|
|
25
|
+
export declare const toComponentsPath: (id: string) => string;
|
|
26
|
+
/**
|
|
27
|
+
* Moves Zod's sibling `__shared` bucket into named component schemas and rewrites
|
|
28
|
+
* `$ref`s that targeted that bucket.
|
|
29
|
+
*
|
|
30
|
+
* Zod 4.4.3 emits `#/components/schemas/__shared#/$defs/<id>` when an identified
|
|
31
|
+
* nested schema is not in the conversion registry. Those definitions must become
|
|
32
|
+
* first-class `components.schemas` entries; `__shared` is never written out.
|
|
33
|
+
*
|
|
34
|
+
* @returns Named schemas lifted from `__shared` (after `$id` stripping). Route
|
|
35
|
+
* conversion copies these into the shared harvest bag so ComponentsWriter can
|
|
36
|
+
* merge them into the document.
|
|
37
|
+
*/
|
|
38
|
+
export declare const liftZodSharedDefinitions: (schemas: Record<string, unknown>) => Record<string, OpenAPIV3_1.SchemaObject>;
|
|
39
|
+
export type ZodToOpenAPIOptions = {
|
|
40
|
+
/**
|
|
41
|
+
* Shared harvest bag filled with named schemas lifted from Zod's `__shared`
|
|
42
|
+
* bucket. Assemblers pass `context.registries.extractedComponentSchemas` so
|
|
43
|
+
* ComponentsWriter can merge them into `components.schemas`.
|
|
44
|
+
*/
|
|
45
|
+
extractedComponentSchemas?: Record<string, OpenAPIV3_1.SchemaObject>;
|
|
46
|
+
};
|
|
9
47
|
/**
|
|
10
48
|
* Converts a Zod schema to an OpenAPI Schema Object.
|
|
11
49
|
*
|
|
12
50
|
* @description
|
|
13
51
|
* Takes a Zod schema and converts it into an OpenAPI Schema Object (v3.1).
|
|
14
52
|
* It uses a local registry to handle the conversion process and generates the appropriate
|
|
15
|
-
* OpenAPI components.
|
|
53
|
+
* OpenAPI components. Identified nested schemas that Zod would otherwise park in
|
|
54
|
+
* `__shared` are rewritten to `#/components/schemas/<id>` and copied into
|
|
55
|
+
* `options.extractedComponentSchemas` when that bag is provided.
|
|
16
56
|
*
|
|
17
57
|
* @param zodSchema - The Zod schema to convert to OpenAPI format. Can be any valid Zod schema.
|
|
58
|
+
* @param schemaStore - The application-owned content-API schema store to copy named
|
|
59
|
+
* component definitions from. Conversion uses a local registry and does not read a
|
|
60
|
+
* live Zod registry from the store.
|
|
61
|
+
* @param options - Optional harvest bag shared across assemblers and ComponentsWriter.
|
|
18
62
|
*
|
|
19
63
|
* @returns An OpenAPI Schema Object representing the input Zod schema structure.
|
|
20
64
|
* If the conversion cannot be completed, returns undefined.
|
|
@@ -31,15 +75,8 @@ export declare const stripJsonSchemaId: <T extends object>(schema: T) => T;
|
|
|
31
75
|
* });
|
|
32
76
|
*
|
|
33
77
|
* // Convert to OpenAPI schema
|
|
34
|
-
* const openAPISchema = zodToOpenAPI(userSchema);
|
|
78
|
+
* const openAPISchema = zodToOpenAPI(userSchema, strapi.contentAPISchemaRegistry);
|
|
35
79
|
* ```
|
|
36
80
|
*/
|
|
37
|
-
export declare const zodToOpenAPI: (zodSchema: z.ZodType) => OpenAPIV3_1.SchemaObject | OpenAPIV3_1.ReferenceObject;
|
|
38
|
-
/**
|
|
39
|
-
* Generates a path string for referencing a component schema by its identifier.
|
|
40
|
-
*
|
|
41
|
-
* @param id - The identifier of the component schema.
|
|
42
|
-
* @returns The constructed path string for the specified component schema.
|
|
43
|
-
*/
|
|
44
|
-
export declare const toComponentsPath: (id: string) => string;
|
|
81
|
+
export declare const zodToOpenAPI: (zodSchema: z.ZodType, schemaStore: Core.ContentAPISchemaRegistry, options?: ZodToOpenAPIOptions) => OpenAPIV3_1.SchemaObject | OpenAPIV3_1.ReferenceObject;
|
|
45
82
|
//# sourceMappingURL=zod.d.ts.map
|
package/dist/utils/zod.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zod.d.ts","sourceRoot":"","sources":["../../src/utils/zod.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAE5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,MAAM,EAAE,QAAQ,CAAC,KAAG,CAK/D,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"zod.d.ts","sourceRoot":"","sources":["../../src/utils/zod.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAE5B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD;;;;GAIG;AACH,eAAO,MAAM,iCAAiC;;;CAG+B,CAAC;AAc9E;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,MAAM,EAAE,QAAQ,CAAC,KAAG,CAK/D,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAAI,IAAI,MAAM,WAAiC,CAAC;AA4C7E;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB,GACnC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC/B,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,YAAY,CAoCzC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;;OAIG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC;CACtE,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,YAAY,GACvB,WAAW,CAAC,CAAC,OAAO,EACpB,aAAa,IAAI,CAAC,wBAAwB,EAC1C,UAAU,mBAAmB,KAC5B,WAAW,CAAC,YAAY,GAAG,WAAW,CAAC,eA+BzC,CAAC"}
|
package/dist/utils/zod.js
CHANGED
|
@@ -24,24 +24,126 @@ function _interopNamespace(e) {
|
|
|
24
24
|
var z__namespace = /*#__PURE__*/_interopNamespace(z);
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
27
|
+
* OpenAPI 3.1 uses the JSON Schema 2020-12 dialect. Zod 4.4.3 has no `openapi-3.1`
|
|
28
|
+
* target, so `draft-2020-12` preserves valid 3.1 schemas. Explicit output mode preserves
|
|
29
|
+
* the conversion direction used before these defaults were pinned.
|
|
30
|
+
*/ const OPENAPI_SCHEMA_CONVERSION_OPTIONS = {
|
|
31
|
+
target: 'draft-2020-12',
|
|
32
|
+
io: 'output'
|
|
33
|
+
};
|
|
34
|
+
const ZOD_SHARED_BUCKET = '__shared';
|
|
35
|
+
/**
|
|
36
|
+
* Zod 4.4.3 emits `#/components/schemas/__shared#/$defs/<id>` (and close variants)
|
|
37
|
+
* when an identified nested schema is missing from the conversion registry.
|
|
38
|
+
*/ const ZOD_SHARED_REF_RE = /^#\/components\/schemas\/__shared#?\/(?:\$defs|definitions)\/(.+)$/;
|
|
39
|
+
const isPlainObject = (value)=>{
|
|
40
|
+
return typeof value === 'object' && value !== null && Array.isArray(value) === false;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Zod 4.4.3 embeds `$id` in registry `toJSONSchema` output when `uri` is configured.
|
|
28
44
|
* Strip it so OpenAPI documents stay stable — inline schemas use random UUIDs
|
|
29
|
-
* as registry
|
|
45
|
+
* as registry IDs.
|
|
30
46
|
*/ const stripJsonSchemaId = (schema)=>{
|
|
31
47
|
if ('$id' in schema) {
|
|
32
48
|
delete schema.$id;
|
|
33
49
|
}
|
|
34
50
|
return schema;
|
|
35
51
|
};
|
|
52
|
+
/**
|
|
53
|
+
* Generates a path string for referencing a component schema by its identifier.
|
|
54
|
+
*
|
|
55
|
+
* @param id - The identifier of the component schema.
|
|
56
|
+
* @returns The constructed path string for the specified component schema.
|
|
57
|
+
*/ const toComponentsPath = (id)=>`#/components/schemas/${id}`;
|
|
58
|
+
const rewriteZodSharedRef = (ref)=>{
|
|
59
|
+
const match = ZOD_SHARED_REF_RE.exec(ref);
|
|
60
|
+
const id = match?.[1];
|
|
61
|
+
if (id === undefined || id.length === 0) {
|
|
62
|
+
return ref;
|
|
63
|
+
}
|
|
64
|
+
return toComponentsPath(id);
|
|
65
|
+
};
|
|
66
|
+
const rewriteZodSharedRefs = (value, seen = new WeakSet())=>{
|
|
67
|
+
if (Array.isArray(value)) {
|
|
68
|
+
if (seen.has(value)) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
seen.add(value);
|
|
72
|
+
for (const item of value){
|
|
73
|
+
rewriteZodSharedRefs(item, seen);
|
|
74
|
+
}
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (isPlainObject(value) === false) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (seen.has(value)) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
seen.add(value);
|
|
84
|
+
const ref = value.$ref;
|
|
85
|
+
if (typeof ref === 'string') {
|
|
86
|
+
value.$ref = rewriteZodSharedRef(ref);
|
|
87
|
+
}
|
|
88
|
+
for (const nested of Object.values(value)){
|
|
89
|
+
rewriteZodSharedRefs(nested, seen);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Moves Zod's sibling `__shared` bucket into named component schemas and rewrites
|
|
94
|
+
* `$ref`s that targeted that bucket.
|
|
95
|
+
*
|
|
96
|
+
* Zod 4.4.3 emits `#/components/schemas/__shared#/$defs/<id>` when an identified
|
|
97
|
+
* nested schema is not in the conversion registry. Those definitions must become
|
|
98
|
+
* first-class `components.schemas` entries; `__shared` is never written out.
|
|
99
|
+
*
|
|
100
|
+
* @returns Named schemas lifted from `__shared` (after `$id` stripping). Route
|
|
101
|
+
* conversion copies these into the shared harvest bag so ComponentsWriter can
|
|
102
|
+
* merge them into the document.
|
|
103
|
+
*/ const liftZodSharedDefinitions = (schemas)=>{
|
|
104
|
+
const harvested = {};
|
|
105
|
+
const shared = schemas[ZOD_SHARED_BUCKET];
|
|
106
|
+
if (isPlainObject(shared)) {
|
|
107
|
+
const defs = shared.$defs ?? shared.definitions;
|
|
108
|
+
if (isPlainObject(defs)) {
|
|
109
|
+
for (const [id, def] of Object.entries(defs)){
|
|
110
|
+
if (isPlainObject(def) === false) {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
const cleaned = stripJsonSchemaId(def);
|
|
114
|
+
harvested[id] = cleaned;
|
|
115
|
+
if (schemas[id] === undefined) {
|
|
116
|
+
schemas[id] = cleaned;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
delete schemas[ZOD_SHARED_BUCKET];
|
|
121
|
+
}
|
|
122
|
+
const seen = new WeakSet();
|
|
123
|
+
rewriteZodSharedRefs(schemas, seen);
|
|
124
|
+
rewriteZodSharedRefs(harvested, seen);
|
|
125
|
+
for (const schema of Object.values(schemas)){
|
|
126
|
+
if (isPlainObject(schema)) {
|
|
127
|
+
stripJsonSchemaId(schema);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return harvested;
|
|
131
|
+
};
|
|
36
132
|
/**
|
|
37
133
|
* Converts a Zod schema to an OpenAPI Schema Object.
|
|
38
134
|
*
|
|
39
135
|
* @description
|
|
40
136
|
* Takes a Zod schema and converts it into an OpenAPI Schema Object (v3.1).
|
|
41
137
|
* It uses a local registry to handle the conversion process and generates the appropriate
|
|
42
|
-
* OpenAPI components.
|
|
138
|
+
* OpenAPI components. Identified nested schemas that Zod would otherwise park in
|
|
139
|
+
* `__shared` are rewritten to `#/components/schemas/<id>` and copied into
|
|
140
|
+
* `options.extractedComponentSchemas` when that bag is provided.
|
|
43
141
|
*
|
|
44
142
|
* @param zodSchema - The Zod schema to convert to OpenAPI format. Can be any valid Zod schema.
|
|
143
|
+
* @param schemaStore - The application-owned content-API schema store to copy named
|
|
144
|
+
* component definitions from. Conversion uses a local registry and does not read a
|
|
145
|
+
* live Zod registry from the store.
|
|
146
|
+
* @param options - Optional harvest bag shared across assemblers and ComponentsWriter.
|
|
45
147
|
*
|
|
46
148
|
* @returns An OpenAPI Schema Object representing the input Zod schema structure.
|
|
47
149
|
* If the conversion cannot be completed, returns undefined.
|
|
@@ -58,9 +160,9 @@ var z__namespace = /*#__PURE__*/_interopNamespace(z);
|
|
|
58
160
|
* });
|
|
59
161
|
*
|
|
60
162
|
* // Convert to OpenAPI schema
|
|
61
|
-
* const openAPISchema = zodToOpenAPI(userSchema);
|
|
163
|
+
* const openAPISchema = zodToOpenAPI(userSchema, strapi.contentAPISchemaRegistry);
|
|
62
164
|
* ```
|
|
63
|
-
*/ const zodToOpenAPI = (zodSchema)=>{
|
|
165
|
+
*/ const zodToOpenAPI = (zodSchema, schemaStore, options)=>{
|
|
64
166
|
try {
|
|
65
167
|
const id = node_crypto.randomUUID();
|
|
66
168
|
const registry = z__namespace.registry();
|
|
@@ -68,30 +170,31 @@ var z__namespace = /*#__PURE__*/_interopNamespace(z);
|
|
|
68
170
|
registry.add(zodSchema, {
|
|
69
171
|
id
|
|
70
172
|
});
|
|
71
|
-
// Copy
|
|
72
|
-
//
|
|
73
|
-
for (const [key, value] of
|
|
173
|
+
// Copy Strapi-owned definitions into the local registry so references resolve without
|
|
174
|
+
// generating "__shared" definitions.
|
|
175
|
+
for (const [key, value] of schemaStore.entries()){
|
|
74
176
|
registry.add(value, {
|
|
75
177
|
id: key
|
|
76
178
|
});
|
|
77
179
|
}
|
|
78
180
|
// Generate the schemas and only return the one we want, transform the URI path to be OpenAPI compliant
|
|
79
181
|
const { schemas } = z__namespace.toJSONSchema(registry, {
|
|
182
|
+
...OPENAPI_SCHEMA_CONVERSION_OPTIONS,
|
|
80
183
|
uri: toComponentsPath
|
|
81
184
|
});
|
|
185
|
+
const harvested = isPlainObject(schemas) ? liftZodSharedDefinitions(schemas) : {};
|
|
186
|
+
if (options?.extractedComponentSchemas !== undefined) {
|
|
187
|
+
Object.assign(options.extractedComponentSchemas, harvested);
|
|
188
|
+
}
|
|
82
189
|
// TODO: make sure it's compliant
|
|
83
190
|
return stripJsonSchemaId(schemas[id]);
|
|
84
191
|
} catch {
|
|
85
192
|
throw new Error("Couldn't transform the zod schema into an OpenAPI schema");
|
|
86
193
|
}
|
|
87
194
|
};
|
|
88
|
-
/**
|
|
89
|
-
* Generates a path string for referencing a component schema by its identifier.
|
|
90
|
-
*
|
|
91
|
-
* @param id - The identifier of the component schema.
|
|
92
|
-
* @returns The constructed path string for the specified component schema.
|
|
93
|
-
*/ const toComponentsPath = (id)=>`#/components/schemas/${id}`;
|
|
94
195
|
|
|
196
|
+
exports.OPENAPI_SCHEMA_CONVERSION_OPTIONS = OPENAPI_SCHEMA_CONVERSION_OPTIONS;
|
|
197
|
+
exports.liftZodSharedDefinitions = liftZodSharedDefinitions;
|
|
95
198
|
exports.stripJsonSchemaId = stripJsonSchemaId;
|
|
96
199
|
exports.toComponentsPath = toComponentsPath;
|
|
97
200
|
exports.zodToOpenAPI = zodToOpenAPI;
|
package/dist/utils/zod.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zod.js","sources":["../../src/utils/zod.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport * as z from 'zod/v4';\n\nimport type { OpenAPIV3_1 } from 'openapi-types';\n\n/**\n * Zod ≥3.25.76 embeds `$id` in `toJSONSchema` output (set after `override`).\n * Strip it so OpenAPI documents stay stable — inline schemas use random UUIDs\n * as registry ids — and match the pre-3.25.76 shape.\n */\nexport const stripJsonSchemaId = <T extends object>(schema: T): T => {\n if ('$id' in schema) {\n delete (schema as { $id?: string }).$id;\n }\n return schema;\n};\n\n/**\n * Converts a Zod schema to an OpenAPI Schema Object.\n *\n * @description\n * Takes a Zod schema and converts it into an OpenAPI Schema Object (v3.1).\n * It uses a local registry to handle the conversion process and generates the appropriate\n * OpenAPI components.\n *\n * @param zodSchema - The Zod schema to convert to OpenAPI format. Can be any valid Zod schema.\n *\n * @returns An OpenAPI Schema Object representing the input Zod schema structure.\n * If the conversion cannot be completed, returns undefined.\n *\n * @example\n * ```typescript\n * import * as z from 'zod/v4';\n *\n * // Create a Zod schema\n * const userSchema = z.object({\n * id: z.number(),\n * name: z.string(),\n * email: z.string().email()\n * });\n *\n * // Convert to OpenAPI schema\n * const openAPISchema = zodToOpenAPI(userSchema);\n * ```\n */\nexport const zodToOpenAPI = (\n zodSchema: z.ZodType\n): OpenAPIV3_1.SchemaObject | OpenAPIV3_1.ReferenceObject => {\n try {\n const id = randomUUID();\n const registry = z.registry<{ id: string }>();\n\n // Add the schema to the local registry with a custom, unique ID\n registry.add(zodSchema, { id });\n\n // Copy the global registry definitions into the local registry to make sure references are resolved\n // This prevent \"__shared\" definitions from being created\n for (const [key, value] of z.globalRegistry._idmap) {\n registry.add(value, { id: key });\n }\n\n // Generate the schemas and only return the one we want, transform the URI path to be OpenAPI compliant\n const { schemas } = z.toJSONSchema(registry, { uri: toComponentsPath });\n\n // TODO: make sure it's compliant\n return stripJsonSchemaId(schemas[id] as OpenAPIV3_1.SchemaObject);\n } catch {\n throw new Error(\"Couldn't transform the zod schema into an OpenAPI schema\");\n }\n};\n\n/**\n * Generates a path string for referencing a component schema by its identifier.\n *\n * @param id - The identifier of the component schema.\n * @returns The constructed path string for the specified component schema.\n */\nexport const toComponentsPath = (id: string) => `#/components/schemas/${id}`;\n"],"names":["stripJsonSchemaId","schema","$id","zodToOpenAPI","zodSchema","id","randomUUID","registry","z","add","key","value","globalRegistry","_idmap","schemas","toJSONSchema","uri","toComponentsPath","Error"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAKA;;;;IAKO,MAAMA,iBAAAA,GAAoB,CAAmBC,MAAAA,GAAAA;AAClD,IAAA,IAAI,SAASA,MAAAA,EAAQ;QACnB,OAAQA,OAA4BC,GAAG;AACzC,IAAA;IACA,OAAOD,MAAAA;AACT;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;IA4BO,MAAME,YAAAA,GAAe,CAC1BC,SAAAA,GAAAA;IAEA,IAAI;AACF,QAAA,MAAMC,EAAAA,GAAKC,sBAAAA,EAAAA;QACX,MAAMC,QAAAA,GAAWC,aAAED,QAAQ,EAAA;;QAG3BA,QAAAA,CAASE,GAAG,CAACL,SAAAA,EAAW;AAAEC,YAAAA;AAAG,SAAA,CAAA;;;QAI7B,KAAK,MAAM,CAACK,GAAAA,EAAKC,KAAAA,CAAM,IAAIH,YAAAA,CAAEI,cAAc,CAACC,MAAM,CAAE;YAClDN,QAAAA,CAASE,GAAG,CAACE,KAAAA,EAAO;gBAAEN,EAAAA,EAAIK;AAAI,aAAA,CAAA;AAChC,QAAA;;AAGA,QAAA,MAAM,EAAEI,OAAO,EAAE,GAAGN,YAAAA,CAAEO,YAAY,CAACR,QAAAA,EAAU;YAAES,GAAAA,EAAKC;AAAiB,SAAA,CAAA;;QAGrE,OAAOjB,iBAAAA,CAAkBc,OAAO,CAACT,EAAAA,CAAG,CAAA;AACtC,IAAA,CAAA,CAAE,OAAM;AACN,QAAA,MAAM,IAAIa,KAAAA,CAAM,0DAAA,CAAA;AAClB,IAAA;AACF;AAEA;;;;;UAMaD,gBAAAA,GAAmB,CAACZ,KAAe,CAAC,qBAAqB,EAAEA,EAAAA,CAAAA;;;;;;"}
|
|
1
|
+
{"version":3,"file":"zod.js","sources":["../../src/utils/zod.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport * as z from 'zod/v4';\n\nimport type { Core } from '@strapi/types';\nimport type { OpenAPIV3_1 } from 'openapi-types';\n\n/**\n * OpenAPI 3.1 uses the JSON Schema 2020-12 dialect. Zod 4.4.3 has no `openapi-3.1`\n * target, so `draft-2020-12` preserves valid 3.1 schemas. Explicit output mode preserves\n * the conversion direction used before these defaults were pinned.\n */\nexport const OPENAPI_SCHEMA_CONVERSION_OPTIONS = {\n target: 'draft-2020-12',\n io: 'output',\n} as const satisfies Pick<z.core.RegistryToJSONSchemaParams, 'target' | 'io'>;\n\nconst ZOD_SHARED_BUCKET = '__shared';\n\n/**\n * Zod 4.4.3 emits `#/components/schemas/__shared#/$defs/<id>` (and close variants)\n * when an identified nested schema is missing from the conversion registry.\n */\nconst ZOD_SHARED_REF_RE = /^#\\/components\\/schemas\\/__shared#?\\/(?:\\$defs|definitions)\\/(.+)$/;\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n return typeof value === 'object' && value !== null && Array.isArray(value) === false;\n};\n\n/**\n * Zod 4.4.3 embeds `$id` in registry `toJSONSchema` output when `uri` is configured.\n * Strip it so OpenAPI documents stay stable — inline schemas use random UUIDs\n * as registry IDs.\n */\nexport const stripJsonSchemaId = <T extends object>(schema: T): T => {\n if ('$id' in schema) {\n delete (schema as { $id?: string }).$id;\n }\n return schema;\n};\n\n/**\n * Generates a path string for referencing a component schema by its identifier.\n *\n * @param id - The identifier of the component schema.\n * @returns The constructed path string for the specified component schema.\n */\nexport const toComponentsPath = (id: string) => `#/components/schemas/${id}`;\n\nconst rewriteZodSharedRef = (ref: string): string => {\n const match = ZOD_SHARED_REF_RE.exec(ref);\n const id = match?.[1];\n\n if (id === undefined || id.length === 0) {\n return ref;\n }\n\n return toComponentsPath(id);\n};\n\nconst rewriteZodSharedRefs = (value: unknown, seen: WeakSet<object> = new WeakSet()): void => {\n if (Array.isArray(value)) {\n if (seen.has(value)) {\n return;\n }\n seen.add(value);\n for (const item of value) {\n rewriteZodSharedRefs(item, seen);\n }\n return;\n }\n\n if (isPlainObject(value) === false) {\n return;\n }\n\n if (seen.has(value)) {\n return;\n }\n seen.add(value);\n\n const ref = value.$ref;\n if (typeof ref === 'string') {\n value.$ref = rewriteZodSharedRef(ref);\n }\n\n for (const nested of Object.values(value)) {\n rewriteZodSharedRefs(nested, seen);\n }\n};\n\n/**\n * Moves Zod's sibling `__shared` bucket into named component schemas and rewrites\n * `$ref`s that targeted that bucket.\n *\n * Zod 4.4.3 emits `#/components/schemas/__shared#/$defs/<id>` when an identified\n * nested schema is not in the conversion registry. Those definitions must become\n * first-class `components.schemas` entries; `__shared` is never written out.\n *\n * @returns Named schemas lifted from `__shared` (after `$id` stripping). Route\n * conversion copies these into the shared harvest bag so ComponentsWriter can\n * merge them into the document.\n */\nexport const liftZodSharedDefinitions = (\n schemas: Record<string, unknown>\n): Record<string, OpenAPIV3_1.SchemaObject> => {\n const harvested: Record<string, OpenAPIV3_1.SchemaObject> = {};\n const shared = schemas[ZOD_SHARED_BUCKET];\n\n if (isPlainObject(shared)) {\n const defs = shared.$defs ?? shared.definitions;\n\n if (isPlainObject(defs)) {\n for (const [id, def] of Object.entries(defs)) {\n if (isPlainObject(def) === false) {\n continue;\n }\n\n const cleaned = stripJsonSchemaId(def) as OpenAPIV3_1.SchemaObject;\n harvested[id] = cleaned;\n\n if (schemas[id] === undefined) {\n schemas[id] = cleaned;\n }\n }\n }\n\n delete schemas[ZOD_SHARED_BUCKET];\n }\n\n const seen = new WeakSet<object>();\n rewriteZodSharedRefs(schemas, seen);\n rewriteZodSharedRefs(harvested, seen);\n\n for (const schema of Object.values(schemas)) {\n if (isPlainObject(schema)) {\n stripJsonSchemaId(schema);\n }\n }\n\n return harvested;\n};\n\nexport type ZodToOpenAPIOptions = {\n /**\n * Shared harvest bag filled with named schemas lifted from Zod's `__shared`\n * bucket. Assemblers pass `context.registries.extractedComponentSchemas` so\n * ComponentsWriter can merge them into `components.schemas`.\n */\n extractedComponentSchemas?: Record<string, OpenAPIV3_1.SchemaObject>;\n};\n\n/**\n * Converts a Zod schema to an OpenAPI Schema Object.\n *\n * @description\n * Takes a Zod schema and converts it into an OpenAPI Schema Object (v3.1).\n * It uses a local registry to handle the conversion process and generates the appropriate\n * OpenAPI components. Identified nested schemas that Zod would otherwise park in\n * `__shared` are rewritten to `#/components/schemas/<id>` and copied into\n * `options.extractedComponentSchemas` when that bag is provided.\n *\n * @param zodSchema - The Zod schema to convert to OpenAPI format. Can be any valid Zod schema.\n * @param schemaStore - The application-owned content-API schema store to copy named\n * component definitions from. Conversion uses a local registry and does not read a\n * live Zod registry from the store.\n * @param options - Optional harvest bag shared across assemblers and ComponentsWriter.\n *\n * @returns An OpenAPI Schema Object representing the input Zod schema structure.\n * If the conversion cannot be completed, returns undefined.\n *\n * @example\n * ```typescript\n * import * as z from 'zod/v4';\n *\n * // Create a Zod schema\n * const userSchema = z.object({\n * id: z.number(),\n * name: z.string(),\n * email: z.string().email()\n * });\n *\n * // Convert to OpenAPI schema\n * const openAPISchema = zodToOpenAPI(userSchema, strapi.contentAPISchemaRegistry);\n * ```\n */\nexport const zodToOpenAPI = (\n zodSchema: z.ZodType,\n schemaStore: Core.ContentAPISchemaRegistry,\n options?: ZodToOpenAPIOptions\n): OpenAPIV3_1.SchemaObject | OpenAPIV3_1.ReferenceObject => {\n try {\n const id = randomUUID();\n const registry = z.registry<{ id: string }>();\n\n // Add the schema to the local registry with a custom, unique ID\n registry.add(zodSchema, { id });\n\n // Copy Strapi-owned definitions into the local registry so references resolve without\n // generating \"__shared\" definitions.\n for (const [key, value] of schemaStore.entries()) {\n registry.add(value, { id: key });\n }\n\n // Generate the schemas and only return the one we want, transform the URI path to be OpenAPI compliant\n const { schemas } = z.toJSONSchema(registry, {\n ...OPENAPI_SCHEMA_CONVERSION_OPTIONS,\n uri: toComponentsPath,\n });\n\n const harvested = isPlainObject(schemas) ? liftZodSharedDefinitions(schemas) : {};\n\n if (options?.extractedComponentSchemas !== undefined) {\n Object.assign(options.extractedComponentSchemas, harvested);\n }\n\n // TODO: make sure it's compliant\n return stripJsonSchemaId(schemas[id] as OpenAPIV3_1.SchemaObject);\n } catch {\n throw new Error(\"Couldn't transform the zod schema into an OpenAPI schema\");\n }\n};\n"],"names":["OPENAPI_SCHEMA_CONVERSION_OPTIONS","target","io","ZOD_SHARED_BUCKET","ZOD_SHARED_REF_RE","isPlainObject","value","Array","isArray","stripJsonSchemaId","schema","$id","toComponentsPath","id","rewriteZodSharedRef","ref","match","exec","undefined","length","rewriteZodSharedRefs","seen","WeakSet","has","add","item","$ref","nested","Object","values","liftZodSharedDefinitions","schemas","harvested","shared","defs","$defs","definitions","def","entries","cleaned","zodToOpenAPI","zodSchema","schemaStore","options","randomUUID","registry","z","key","toJSONSchema","uri","extractedComponentSchemas","assign","Error"],"mappings":"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"}
|
package/dist/utils/zod.mjs
CHANGED
|
@@ -2,24 +2,126 @@ import { randomUUID } from 'node:crypto';
|
|
|
2
2
|
import * as z from 'zod/v4';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* OpenAPI 3.1 uses the JSON Schema 2020-12 dialect. Zod 4.4.3 has no `openapi-3.1`
|
|
6
|
+
* target, so `draft-2020-12` preserves valid 3.1 schemas. Explicit output mode preserves
|
|
7
|
+
* the conversion direction used before these defaults were pinned.
|
|
8
|
+
*/ const OPENAPI_SCHEMA_CONVERSION_OPTIONS = {
|
|
9
|
+
target: 'draft-2020-12',
|
|
10
|
+
io: 'output'
|
|
11
|
+
};
|
|
12
|
+
const ZOD_SHARED_BUCKET = '__shared';
|
|
13
|
+
/**
|
|
14
|
+
* Zod 4.4.3 emits `#/components/schemas/__shared#/$defs/<id>` (and close variants)
|
|
15
|
+
* when an identified nested schema is missing from the conversion registry.
|
|
16
|
+
*/ const ZOD_SHARED_REF_RE = /^#\/components\/schemas\/__shared#?\/(?:\$defs|definitions)\/(.+)$/;
|
|
17
|
+
const isPlainObject = (value)=>{
|
|
18
|
+
return typeof value === 'object' && value !== null && Array.isArray(value) === false;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Zod 4.4.3 embeds `$id` in registry `toJSONSchema` output when `uri` is configured.
|
|
6
22
|
* Strip it so OpenAPI documents stay stable — inline schemas use random UUIDs
|
|
7
|
-
* as registry
|
|
23
|
+
* as registry IDs.
|
|
8
24
|
*/ const stripJsonSchemaId = (schema)=>{
|
|
9
25
|
if ('$id' in schema) {
|
|
10
26
|
delete schema.$id;
|
|
11
27
|
}
|
|
12
28
|
return schema;
|
|
13
29
|
};
|
|
30
|
+
/**
|
|
31
|
+
* Generates a path string for referencing a component schema by its identifier.
|
|
32
|
+
*
|
|
33
|
+
* @param id - The identifier of the component schema.
|
|
34
|
+
* @returns The constructed path string for the specified component schema.
|
|
35
|
+
*/ const toComponentsPath = (id)=>`#/components/schemas/${id}`;
|
|
36
|
+
const rewriteZodSharedRef = (ref)=>{
|
|
37
|
+
const match = ZOD_SHARED_REF_RE.exec(ref);
|
|
38
|
+
const id = match?.[1];
|
|
39
|
+
if (id === undefined || id.length === 0) {
|
|
40
|
+
return ref;
|
|
41
|
+
}
|
|
42
|
+
return toComponentsPath(id);
|
|
43
|
+
};
|
|
44
|
+
const rewriteZodSharedRefs = (value, seen = new WeakSet())=>{
|
|
45
|
+
if (Array.isArray(value)) {
|
|
46
|
+
if (seen.has(value)) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
seen.add(value);
|
|
50
|
+
for (const item of value){
|
|
51
|
+
rewriteZodSharedRefs(item, seen);
|
|
52
|
+
}
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (isPlainObject(value) === false) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (seen.has(value)) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
seen.add(value);
|
|
62
|
+
const ref = value.$ref;
|
|
63
|
+
if (typeof ref === 'string') {
|
|
64
|
+
value.$ref = rewriteZodSharedRef(ref);
|
|
65
|
+
}
|
|
66
|
+
for (const nested of Object.values(value)){
|
|
67
|
+
rewriteZodSharedRefs(nested, seen);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Moves Zod's sibling `__shared` bucket into named component schemas and rewrites
|
|
72
|
+
* `$ref`s that targeted that bucket.
|
|
73
|
+
*
|
|
74
|
+
* Zod 4.4.3 emits `#/components/schemas/__shared#/$defs/<id>` when an identified
|
|
75
|
+
* nested schema is not in the conversion registry. Those definitions must become
|
|
76
|
+
* first-class `components.schemas` entries; `__shared` is never written out.
|
|
77
|
+
*
|
|
78
|
+
* @returns Named schemas lifted from `__shared` (after `$id` stripping). Route
|
|
79
|
+
* conversion copies these into the shared harvest bag so ComponentsWriter can
|
|
80
|
+
* merge them into the document.
|
|
81
|
+
*/ const liftZodSharedDefinitions = (schemas)=>{
|
|
82
|
+
const harvested = {};
|
|
83
|
+
const shared = schemas[ZOD_SHARED_BUCKET];
|
|
84
|
+
if (isPlainObject(shared)) {
|
|
85
|
+
const defs = shared.$defs ?? shared.definitions;
|
|
86
|
+
if (isPlainObject(defs)) {
|
|
87
|
+
for (const [id, def] of Object.entries(defs)){
|
|
88
|
+
if (isPlainObject(def) === false) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const cleaned = stripJsonSchemaId(def);
|
|
92
|
+
harvested[id] = cleaned;
|
|
93
|
+
if (schemas[id] === undefined) {
|
|
94
|
+
schemas[id] = cleaned;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
delete schemas[ZOD_SHARED_BUCKET];
|
|
99
|
+
}
|
|
100
|
+
const seen = new WeakSet();
|
|
101
|
+
rewriteZodSharedRefs(schemas, seen);
|
|
102
|
+
rewriteZodSharedRefs(harvested, seen);
|
|
103
|
+
for (const schema of Object.values(schemas)){
|
|
104
|
+
if (isPlainObject(schema)) {
|
|
105
|
+
stripJsonSchemaId(schema);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return harvested;
|
|
109
|
+
};
|
|
14
110
|
/**
|
|
15
111
|
* Converts a Zod schema to an OpenAPI Schema Object.
|
|
16
112
|
*
|
|
17
113
|
* @description
|
|
18
114
|
* Takes a Zod schema and converts it into an OpenAPI Schema Object (v3.1).
|
|
19
115
|
* It uses a local registry to handle the conversion process and generates the appropriate
|
|
20
|
-
* OpenAPI components.
|
|
116
|
+
* OpenAPI components. Identified nested schemas that Zod would otherwise park in
|
|
117
|
+
* `__shared` are rewritten to `#/components/schemas/<id>` and copied into
|
|
118
|
+
* `options.extractedComponentSchemas` when that bag is provided.
|
|
21
119
|
*
|
|
22
120
|
* @param zodSchema - The Zod schema to convert to OpenAPI format. Can be any valid Zod schema.
|
|
121
|
+
* @param schemaStore - The application-owned content-API schema store to copy named
|
|
122
|
+
* component definitions from. Conversion uses a local registry and does not read a
|
|
123
|
+
* live Zod registry from the store.
|
|
124
|
+
* @param options - Optional harvest bag shared across assemblers and ComponentsWriter.
|
|
23
125
|
*
|
|
24
126
|
* @returns An OpenAPI Schema Object representing the input Zod schema structure.
|
|
25
127
|
* If the conversion cannot be completed, returns undefined.
|
|
@@ -36,9 +138,9 @@ import * as z from 'zod/v4';
|
|
|
36
138
|
* });
|
|
37
139
|
*
|
|
38
140
|
* // Convert to OpenAPI schema
|
|
39
|
-
* const openAPISchema = zodToOpenAPI(userSchema);
|
|
141
|
+
* const openAPISchema = zodToOpenAPI(userSchema, strapi.contentAPISchemaRegistry);
|
|
40
142
|
* ```
|
|
41
|
-
*/ const zodToOpenAPI = (zodSchema)=>{
|
|
143
|
+
*/ const zodToOpenAPI = (zodSchema, schemaStore, options)=>{
|
|
42
144
|
try {
|
|
43
145
|
const id = randomUUID();
|
|
44
146
|
const registry = z.registry();
|
|
@@ -46,29 +148,28 @@ import * as z from 'zod/v4';
|
|
|
46
148
|
registry.add(zodSchema, {
|
|
47
149
|
id
|
|
48
150
|
});
|
|
49
|
-
// Copy
|
|
50
|
-
//
|
|
51
|
-
for (const [key, value] of
|
|
151
|
+
// Copy Strapi-owned definitions into the local registry so references resolve without
|
|
152
|
+
// generating "__shared" definitions.
|
|
153
|
+
for (const [key, value] of schemaStore.entries()){
|
|
52
154
|
registry.add(value, {
|
|
53
155
|
id: key
|
|
54
156
|
});
|
|
55
157
|
}
|
|
56
158
|
// Generate the schemas and only return the one we want, transform the URI path to be OpenAPI compliant
|
|
57
159
|
const { schemas } = z.toJSONSchema(registry, {
|
|
160
|
+
...OPENAPI_SCHEMA_CONVERSION_OPTIONS,
|
|
58
161
|
uri: toComponentsPath
|
|
59
162
|
});
|
|
163
|
+
const harvested = isPlainObject(schemas) ? liftZodSharedDefinitions(schemas) : {};
|
|
164
|
+
if (options?.extractedComponentSchemas !== undefined) {
|
|
165
|
+
Object.assign(options.extractedComponentSchemas, harvested);
|
|
166
|
+
}
|
|
60
167
|
// TODO: make sure it's compliant
|
|
61
168
|
return stripJsonSchemaId(schemas[id]);
|
|
62
169
|
} catch {
|
|
63
170
|
throw new Error("Couldn't transform the zod schema into an OpenAPI schema");
|
|
64
171
|
}
|
|
65
172
|
};
|
|
66
|
-
/**
|
|
67
|
-
* Generates a path string for referencing a component schema by its identifier.
|
|
68
|
-
*
|
|
69
|
-
* @param id - The identifier of the component schema.
|
|
70
|
-
* @returns The constructed path string for the specified component schema.
|
|
71
|
-
*/ const toComponentsPath = (id)=>`#/components/schemas/${id}`;
|
|
72
173
|
|
|
73
|
-
export { stripJsonSchemaId, toComponentsPath, zodToOpenAPI };
|
|
174
|
+
export { OPENAPI_SCHEMA_CONVERSION_OPTIONS, liftZodSharedDefinitions, stripJsonSchemaId, toComponentsPath, zodToOpenAPI };
|
|
74
175
|
//# sourceMappingURL=zod.mjs.map
|
package/dist/utils/zod.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zod.mjs","sources":["../../src/utils/zod.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport * as z from 'zod/v4';\n\nimport type { OpenAPIV3_1 } from 'openapi-types';\n\n/**\n * Zod ≥3.25.76 embeds `$id` in `toJSONSchema` output (set after `override`).\n * Strip it so OpenAPI documents stay stable — inline schemas use random UUIDs\n * as registry ids — and match the pre-3.25.76 shape.\n */\nexport const stripJsonSchemaId = <T extends object>(schema: T): T => {\n if ('$id' in schema) {\n delete (schema as { $id?: string }).$id;\n }\n return schema;\n};\n\n/**\n * Converts a Zod schema to an OpenAPI Schema Object.\n *\n * @description\n * Takes a Zod schema and converts it into an OpenAPI Schema Object (v3.1).\n * It uses a local registry to handle the conversion process and generates the appropriate\n * OpenAPI components.\n *\n * @param zodSchema - The Zod schema to convert to OpenAPI format. Can be any valid Zod schema.\n *\n * @returns An OpenAPI Schema Object representing the input Zod schema structure.\n * If the conversion cannot be completed, returns undefined.\n *\n * @example\n * ```typescript\n * import * as z from 'zod/v4';\n *\n * // Create a Zod schema\n * const userSchema = z.object({\n * id: z.number(),\n * name: z.string(),\n * email: z.string().email()\n * });\n *\n * // Convert to OpenAPI schema\n * const openAPISchema = zodToOpenAPI(userSchema);\n * ```\n */\nexport const zodToOpenAPI = (\n zodSchema: z.ZodType\n): OpenAPIV3_1.SchemaObject | OpenAPIV3_1.ReferenceObject => {\n try {\n const id = randomUUID();\n const registry = z.registry<{ id: string }>();\n\n // Add the schema to the local registry with a custom, unique ID\n registry.add(zodSchema, { id });\n\n // Copy the global registry definitions into the local registry to make sure references are resolved\n // This prevent \"__shared\" definitions from being created\n for (const [key, value] of z.globalRegistry._idmap) {\n registry.add(value, { id: key });\n }\n\n // Generate the schemas and only return the one we want, transform the URI path to be OpenAPI compliant\n const { schemas } = z.toJSONSchema(registry, { uri: toComponentsPath });\n\n // TODO: make sure it's compliant\n return stripJsonSchemaId(schemas[id] as OpenAPIV3_1.SchemaObject);\n } catch {\n throw new Error(\"Couldn't transform the zod schema into an OpenAPI schema\");\n }\n};\n\n/**\n * Generates a path string for referencing a component schema by its identifier.\n *\n * @param id - The identifier of the component schema.\n * @returns The constructed path string for the specified component schema.\n */\nexport const toComponentsPath = (id: string) => `#/components/schemas/${id}`;\n"],"names":["stripJsonSchemaId","schema","$id","zodToOpenAPI","zodSchema","id","randomUUID","registry","z","add","key","value","globalRegistry","_idmap","schemas","toJSONSchema","uri","toComponentsPath","Error"],"mappings":";;;AAKA;;;;IAKO,MAAMA,iBAAAA,GAAoB,CAAmBC,MAAAA,GAAAA;AAClD,IAAA,IAAI,SAASA,MAAAA,EAAQ;QACnB,OAAQA,OAA4BC,GAAG;AACzC,IAAA;IACA,OAAOD,MAAAA;AACT;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;IA4BO,MAAME,YAAAA,GAAe,CAC1BC,SAAAA,GAAAA;IAEA,IAAI;AACF,QAAA,MAAMC,EAAAA,GAAKC,UAAAA,EAAAA;QACX,MAAMC,QAAAA,GAAWC,EAAED,QAAQ,EAAA;;QAG3BA,QAAAA,CAASE,GAAG,CAACL,SAAAA,EAAW;AAAEC,YAAAA;AAAG,SAAA,CAAA;;;QAI7B,KAAK,MAAM,CAACK,GAAAA,EAAKC,KAAAA,CAAM,IAAIH,CAAAA,CAAEI,cAAc,CAACC,MAAM,CAAE;YAClDN,QAAAA,CAASE,GAAG,CAACE,KAAAA,EAAO;gBAAEN,EAAAA,EAAIK;AAAI,aAAA,CAAA;AAChC,QAAA;;AAGA,QAAA,MAAM,EAAEI,OAAO,EAAE,GAAGN,CAAAA,CAAEO,YAAY,CAACR,QAAAA,EAAU;YAAES,GAAAA,EAAKC;AAAiB,SAAA,CAAA;;QAGrE,OAAOjB,iBAAAA,CAAkBc,OAAO,CAACT,EAAAA,CAAG,CAAA;AACtC,IAAA,CAAA,CAAE,OAAM;AACN,QAAA,MAAM,IAAIa,KAAAA,CAAM,0DAAA,CAAA;AAClB,IAAA;AACF;AAEA;;;;;UAMaD,gBAAAA,GAAmB,CAACZ,KAAe,CAAC,qBAAqB,EAAEA,EAAAA,CAAAA;;;;"}
|
|
1
|
+
{"version":3,"file":"zod.mjs","sources":["../../src/utils/zod.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport * as z from 'zod/v4';\n\nimport type { Core } from '@strapi/types';\nimport type { OpenAPIV3_1 } from 'openapi-types';\n\n/**\n * OpenAPI 3.1 uses the JSON Schema 2020-12 dialect. Zod 4.4.3 has no `openapi-3.1`\n * target, so `draft-2020-12` preserves valid 3.1 schemas. Explicit output mode preserves\n * the conversion direction used before these defaults were pinned.\n */\nexport const OPENAPI_SCHEMA_CONVERSION_OPTIONS = {\n target: 'draft-2020-12',\n io: 'output',\n} as const satisfies Pick<z.core.RegistryToJSONSchemaParams, 'target' | 'io'>;\n\nconst ZOD_SHARED_BUCKET = '__shared';\n\n/**\n * Zod 4.4.3 emits `#/components/schemas/__shared#/$defs/<id>` (and close variants)\n * when an identified nested schema is missing from the conversion registry.\n */\nconst ZOD_SHARED_REF_RE = /^#\\/components\\/schemas\\/__shared#?\\/(?:\\$defs|definitions)\\/(.+)$/;\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n return typeof value === 'object' && value !== null && Array.isArray(value) === false;\n};\n\n/**\n * Zod 4.4.3 embeds `$id` in registry `toJSONSchema` output when `uri` is configured.\n * Strip it so OpenAPI documents stay stable — inline schemas use random UUIDs\n * as registry IDs.\n */\nexport const stripJsonSchemaId = <T extends object>(schema: T): T => {\n if ('$id' in schema) {\n delete (schema as { $id?: string }).$id;\n }\n return schema;\n};\n\n/**\n * Generates a path string for referencing a component schema by its identifier.\n *\n * @param id - The identifier of the component schema.\n * @returns The constructed path string for the specified component schema.\n */\nexport const toComponentsPath = (id: string) => `#/components/schemas/${id}`;\n\nconst rewriteZodSharedRef = (ref: string): string => {\n const match = ZOD_SHARED_REF_RE.exec(ref);\n const id = match?.[1];\n\n if (id === undefined || id.length === 0) {\n return ref;\n }\n\n return toComponentsPath(id);\n};\n\nconst rewriteZodSharedRefs = (value: unknown, seen: WeakSet<object> = new WeakSet()): void => {\n if (Array.isArray(value)) {\n if (seen.has(value)) {\n return;\n }\n seen.add(value);\n for (const item of value) {\n rewriteZodSharedRefs(item, seen);\n }\n return;\n }\n\n if (isPlainObject(value) === false) {\n return;\n }\n\n if (seen.has(value)) {\n return;\n }\n seen.add(value);\n\n const ref = value.$ref;\n if (typeof ref === 'string') {\n value.$ref = rewriteZodSharedRef(ref);\n }\n\n for (const nested of Object.values(value)) {\n rewriteZodSharedRefs(nested, seen);\n }\n};\n\n/**\n * Moves Zod's sibling `__shared` bucket into named component schemas and rewrites\n * `$ref`s that targeted that bucket.\n *\n * Zod 4.4.3 emits `#/components/schemas/__shared#/$defs/<id>` when an identified\n * nested schema is not in the conversion registry. Those definitions must become\n * first-class `components.schemas` entries; `__shared` is never written out.\n *\n * @returns Named schemas lifted from `__shared` (after `$id` stripping). Route\n * conversion copies these into the shared harvest bag so ComponentsWriter can\n * merge them into the document.\n */\nexport const liftZodSharedDefinitions = (\n schemas: Record<string, unknown>\n): Record<string, OpenAPIV3_1.SchemaObject> => {\n const harvested: Record<string, OpenAPIV3_1.SchemaObject> = {};\n const shared = schemas[ZOD_SHARED_BUCKET];\n\n if (isPlainObject(shared)) {\n const defs = shared.$defs ?? shared.definitions;\n\n if (isPlainObject(defs)) {\n for (const [id, def] of Object.entries(defs)) {\n if (isPlainObject(def) === false) {\n continue;\n }\n\n const cleaned = stripJsonSchemaId(def) as OpenAPIV3_1.SchemaObject;\n harvested[id] = cleaned;\n\n if (schemas[id] === undefined) {\n schemas[id] = cleaned;\n }\n }\n }\n\n delete schemas[ZOD_SHARED_BUCKET];\n }\n\n const seen = new WeakSet<object>();\n rewriteZodSharedRefs(schemas, seen);\n rewriteZodSharedRefs(harvested, seen);\n\n for (const schema of Object.values(schemas)) {\n if (isPlainObject(schema)) {\n stripJsonSchemaId(schema);\n }\n }\n\n return harvested;\n};\n\nexport type ZodToOpenAPIOptions = {\n /**\n * Shared harvest bag filled with named schemas lifted from Zod's `__shared`\n * bucket. Assemblers pass `context.registries.extractedComponentSchemas` so\n * ComponentsWriter can merge them into `components.schemas`.\n */\n extractedComponentSchemas?: Record<string, OpenAPIV3_1.SchemaObject>;\n};\n\n/**\n * Converts a Zod schema to an OpenAPI Schema Object.\n *\n * @description\n * Takes a Zod schema and converts it into an OpenAPI Schema Object (v3.1).\n * It uses a local registry to handle the conversion process and generates the appropriate\n * OpenAPI components. Identified nested schemas that Zod would otherwise park in\n * `__shared` are rewritten to `#/components/schemas/<id>` and copied into\n * `options.extractedComponentSchemas` when that bag is provided.\n *\n * @param zodSchema - The Zod schema to convert to OpenAPI format. Can be any valid Zod schema.\n * @param schemaStore - The application-owned content-API schema store to copy named\n * component definitions from. Conversion uses a local registry and does not read a\n * live Zod registry from the store.\n * @param options - Optional harvest bag shared across assemblers and ComponentsWriter.\n *\n * @returns An OpenAPI Schema Object representing the input Zod schema structure.\n * If the conversion cannot be completed, returns undefined.\n *\n * @example\n * ```typescript\n * import * as z from 'zod/v4';\n *\n * // Create a Zod schema\n * const userSchema = z.object({\n * id: z.number(),\n * name: z.string(),\n * email: z.string().email()\n * });\n *\n * // Convert to OpenAPI schema\n * const openAPISchema = zodToOpenAPI(userSchema, strapi.contentAPISchemaRegistry);\n * ```\n */\nexport const zodToOpenAPI = (\n zodSchema: z.ZodType,\n schemaStore: Core.ContentAPISchemaRegistry,\n options?: ZodToOpenAPIOptions\n): OpenAPIV3_1.SchemaObject | OpenAPIV3_1.ReferenceObject => {\n try {\n const id = randomUUID();\n const registry = z.registry<{ id: string }>();\n\n // Add the schema to the local registry with a custom, unique ID\n registry.add(zodSchema, { id });\n\n // Copy Strapi-owned definitions into the local registry so references resolve without\n // generating \"__shared\" definitions.\n for (const [key, value] of schemaStore.entries()) {\n registry.add(value, { id: key });\n }\n\n // Generate the schemas and only return the one we want, transform the URI path to be OpenAPI compliant\n const { schemas } = z.toJSONSchema(registry, {\n ...OPENAPI_SCHEMA_CONVERSION_OPTIONS,\n uri: toComponentsPath,\n });\n\n const harvested = isPlainObject(schemas) ? liftZodSharedDefinitions(schemas) : {};\n\n if (options?.extractedComponentSchemas !== undefined) {\n Object.assign(options.extractedComponentSchemas, harvested);\n }\n\n // TODO: make sure it's compliant\n return stripJsonSchemaId(schemas[id] as OpenAPIV3_1.SchemaObject);\n } catch {\n throw new Error(\"Couldn't transform the zod schema into an OpenAPI schema\");\n }\n};\n"],"names":["OPENAPI_SCHEMA_CONVERSION_OPTIONS","target","io","ZOD_SHARED_BUCKET","ZOD_SHARED_REF_RE","isPlainObject","value","Array","isArray","stripJsonSchemaId","schema","$id","toComponentsPath","id","rewriteZodSharedRef","ref","match","exec","undefined","length","rewriteZodSharedRefs","seen","WeakSet","has","add","item","$ref","nested","Object","values","liftZodSharedDefinitions","schemas","harvested","shared","defs","$defs","definitions","def","entries","cleaned","zodToOpenAPI","zodSchema","schemaStore","options","randomUUID","registry","z","key","toJSONSchema","uri","extractedComponentSchemas","assign","Error"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@strapi/openapi",
|
|
3
|
-
"version": "5.52.
|
|
3
|
+
"version": "5.52.3",
|
|
4
4
|
"description": "A tool set to help generate and validate API documentation for Strapi projects",
|
|
5
5
|
"homepage": "https://strapi.io",
|
|
6
6
|
"bugs": {
|
|
@@ -60,10 +60,10 @@
|
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"debug": "4.3.4",
|
|
62
62
|
"openapi-types": "12.1.3",
|
|
63
|
-
"zod": "
|
|
63
|
+
"zod": "4.4.3"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
|
-
"@strapi/types": "5.52.
|
|
66
|
+
"@strapi/types": "5.52.3",
|
|
67
67
|
"@types/debug": "^4",
|
|
68
68
|
"@types/jest": "29.5.2",
|
|
69
69
|
"@types/node": "20.19.41",
|