@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.
Files changed (33) hide show
  1. package/dist/assemblers/document/path/path-item/operation/body.d.ts.map +1 -1
  2. package/dist/assemblers/document/path/path-item/operation/body.js +5 -1
  3. package/dist/assemblers/document/path/path-item/operation/body.js.map +1 -1
  4. package/dist/assemblers/document/path/path-item/operation/body.mjs +5 -1
  5. package/dist/assemblers/document/path/path-item/operation/body.mjs.map +1 -1
  6. package/dist/assemblers/document/path/path-item/operation/parameters.d.ts.map +1 -1
  7. package/dist/assemblers/document/path/path-item/operation/parameters.js +12 -6
  8. package/dist/assemblers/document/path/path-item/operation/parameters.js.map +1 -1
  9. package/dist/assemblers/document/path/path-item/operation/parameters.mjs +12 -6
  10. package/dist/assemblers/document/path/path-item/operation/parameters.mjs.map +1 -1
  11. package/dist/assemblers/document/path/path-item/operation/responses.d.ts.map +1 -1
  12. package/dist/assemblers/document/path/path-item/operation/responses.js +3 -1
  13. package/dist/assemblers/document/path/path-item/operation/responses.js.map +1 -1
  14. package/dist/assemblers/document/path/path-item/operation/responses.mjs +3 -1
  15. package/dist/assemblers/document/path/path-item/operation/responses.mjs.map +1 -1
  16. package/dist/post-processor/component-writer.d.ts.map +1 -1
  17. package/dist/post-processor/component-writer.js +19 -8
  18. package/dist/post-processor/component-writer.js.map +1 -1
  19. package/dist/post-processor/component-writer.mjs +20 -9
  20. package/dist/post-processor/component-writer.mjs.map +1 -1
  21. package/dist/registries/factory.d.ts +4 -1
  22. package/dist/registries/factory.d.ts.map +1 -1
  23. package/dist/registries/factory.js +3 -1
  24. package/dist/registries/factory.js.map +1 -1
  25. package/dist/registries/factory.mjs +3 -1
  26. package/dist/registries/factory.mjs.map +1 -1
  27. package/dist/utils/zod.d.ts +49 -12
  28. package/dist/utils/zod.d.ts.map +1 -1
  29. package/dist/utils/zod.js +117 -14
  30. package/dist/utils/zod.js.map +1 -1
  31. package/dist/utils/zod.mjs +116 -15
  32. package/dist/utils/zod.mjs.map +1 -1
  33. 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;CAmB7D"}
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;QAE9D,KAAK,MAAM,CAACC,KAAAA,EAAOC,SAAAA,CAAU,IAAIC,MAAAA,CAAOC,OAAO,CAACN,IAAAA,CAAAA,CAAO;YACrDE,OAAO,CAACC,MAAM,GAAG;AACfI,gBAAAA,MAAAA,EAAQC,gBAAAA,CAAaJ,SAAAA;AACvB,aAAA;AACF,QAAA;QAEAL,MAAAA,CAAOU,IAAI,CAACC,WAAW,GAAG;AAAER,YAAAA;AAAQ,SAAA;AACtC,IAAA;AACF;;;;"}
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;QAE9D,KAAK,MAAM,CAACC,KAAAA,EAAOC,SAAAA,CAAU,IAAIC,MAAAA,CAAOC,OAAO,CAACN,IAAAA,CAAAA,CAAO;YACrDE,OAAO,CAACC,MAAM,GAAG;AACfI,gBAAAA,MAAAA,EAAQC,YAAAA,CAAaJ,SAAAA;AACvB,aAAA;AACF,QAAA;QAEAL,MAAAA,CAAOU,IAAI,CAACC,WAAW,GAAG;AAAER,YAAAA;AAAQ,SAAA;AACtC,IAAA;AACF;;;;"}
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;IAe5D,OAAO,CAAC,kBAAkB;IAoB1B,OAAO,CAAC,mBAAmB;IAmD3B;;;OAGG;IACH,OAAO,CAAC,cAAc;IA2CtB,OAAO,CAAC,wBAAwB;CAqCjC"}
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 pathParameters = this._getPathParameters(route);
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 pathParameters = this._getPathParameters(route);
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;CAqB7D"}
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,gBAAAA,CAAaT,KAAAA,CAAMK,QAAQ,CAAA;YAE1CH,SAAS,CAAC,IAAI,GAAG;gBACfL,WAAAA,EAAa,IAAA;gBACba,OAAAA,EAAS;oBAAE,kBAAA,EAAoB;AAAEF,wBAAAA;AAAO;AAAE;AAC5C,aAAA;AACF,QAAA;QAEAP,MAAAA,CAAOE,IAAI,CAACD,SAAS,GAAGA,SAAAA;AAC1B,IAAA;AACF;;;;"}
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,YAAAA,CAAaT,KAAAA,CAAMK,QAAQ,CAAA;YAE1CH,SAAS,CAAC,IAAI,GAAG;gBACfL,WAAAA,EAAa,IAAA;gBACba,OAAAA,EAAS;oBAAE,kBAAA,EAAoB;AAAEF,wBAAAA;AAAO;AAAE;AAC5C,aAAA;AACF,QAAA;QAEAP,MAAAA,CAAOE,IAAI,CAACD,SAAS,GAAGA,SAAAA;AAC1B,IAAA;AACF;;;;"}
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;AAEhD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,qBAAa,gBAAiB,YAAW,aAAa;IACpD,WAAW,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;CAoB5C"}
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 { schemas } = z__namespace.toJSONSchema(z__namespace.globalRegistry, {
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
- for (const schema of Object.values(schemas ?? {})){
33
- if (schema && typeof schema === 'object') {
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 { stripJsonSchemaId, toComponentsPath } from '../utils/zod';\nimport type { PostProcessor } from './types';\n\nexport class ComponentsWriter implements PostProcessor {\n postProcess(context: DocumentContext): void {\n const { output } = context;\n\n const { schemas } = z.toJSONSchema(z.globalRegistry, {\n uri: toComponentsPath,\n }) as OpenAPIV3_1.ComponentsObject;\n\n for (const schema of Object.values(schemas ?? {})) {\n if (schema && typeof schema === 'object') {\n stripJsonSchemaId(schema);\n }\n }\n\n const existingComponents = output.data.components ?? {};\n\n output.data.components = {\n ...existingComponents,\n schemas,\n };\n }\n}\n"],"names":["ComponentsWriter","postProcess","context","output","schemas","z","toJSONSchema","globalRegistry","uri","toComponentsPath","schema","Object","values","stripJsonSchemaId","existingComponents","data","components"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAMO,MAAMA,gBAAAA,CAAAA;AACXC,IAAAA,WAAAA,CAAYC,OAAwB,EAAQ;QAC1C,MAAM,EAAEC,MAAM,EAAE,GAAGD,OAAAA;QAEnB,MAAM,EAAEE,OAAO,EAAE,GAAGC,aAAEC,YAAY,CAACD,YAAAA,CAAEE,cAAc,EAAE;YACnDC,GAAAA,EAAKC;AACP,SAAA,CAAA;AAEA,QAAA,KAAK,MAAMC,MAAAA,IAAUC,MAAAA,CAAOC,MAAM,CAACR,OAAAA,IAAW,EAAC,CAAA,CAAI;YACjD,IAAIM,MAAAA,IAAU,OAAOA,MAAAA,KAAW,QAAA,EAAU;gBACxCG,qBAAAA,CAAkBH,MAAAA,CAAAA;AACpB,YAAA;AACF,QAAA;AAEA,QAAA,MAAMI,qBAAqBX,MAAAA,CAAOY,IAAI,CAACC,UAAU,IAAI,EAAC;QAEtDb,MAAAA,CAAOY,IAAI,CAACC,UAAU,GAAG;AACvB,YAAA,GAAGF,kBAAkB;AACrBV,YAAAA;AACF,SAAA;AACF,IAAA;AACF;;;;"}
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, stripJsonSchemaId } from '../utils/zod.mjs';
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 { schemas } = z.toJSONSchema(z.globalRegistry, {
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
- for (const schema of Object.values(schemas ?? {})){
11
- if (schema && typeof schema === 'object') {
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 { stripJsonSchemaId, toComponentsPath } from '../utils/zod';\nimport type { PostProcessor } from './types';\n\nexport class ComponentsWriter implements PostProcessor {\n postProcess(context: DocumentContext): void {\n const { output } = context;\n\n const { schemas } = z.toJSONSchema(z.globalRegistry, {\n uri: toComponentsPath,\n }) as OpenAPIV3_1.ComponentsObject;\n\n for (const schema of Object.values(schemas ?? {})) {\n if (schema && typeof schema === 'object') {\n stripJsonSchemaId(schema);\n }\n }\n\n const existingComponents = output.data.components ?? {};\n\n output.data.components = {\n ...existingComponents,\n schemas,\n };\n }\n}\n"],"names":["ComponentsWriter","postProcess","context","output","schemas","z","toJSONSchema","globalRegistry","uri","toComponentsPath","schema","Object","values","stripJsonSchemaId","existingComponents","data","components"],"mappings":";;;AAMO,MAAMA,gBAAAA,CAAAA;AACXC,IAAAA,WAAAA,CAAYC,OAAwB,EAAQ;QAC1C,MAAM,EAAEC,MAAM,EAAE,GAAGD,OAAAA;QAEnB,MAAM,EAAEE,OAAO,EAAE,GAAGC,EAAEC,YAAY,CAACD,CAAAA,CAAEE,cAAc,EAAE;YACnDC,GAAAA,EAAKC;AACP,SAAA,CAAA;AAEA,QAAA,KAAK,MAAMC,MAAAA,IAAUC,MAAAA,CAAOC,MAAM,CAACR,OAAAA,IAAW,EAAC,CAAA,CAAI;YACjD,IAAIM,MAAAA,IAAU,OAAOA,MAAAA,KAAW,QAAA,EAAU;gBACxCG,iBAAAA,CAAkBH,MAAAA,CAAAA;AACpB,YAAA;AACF,QAAA;AAEA,QAAA,MAAMI,qBAAqBX,MAAAA,CAAOY,IAAI,CAACC,UAAU,IAAI,EAAC;QAEtDb,MAAAA,CAAOY,IAAI,CAACC,UAAU,GAAG;AACvB,YAAA,GAAGF,kBAAkB;AACrBV,YAAAA;AACF,SAAA;AACF,IAAA;AACF;;;;"}
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,4 +1,7 @@
1
+ import type { OpenAPIV3_1 } from 'openapi-types';
1
2
  export declare class RegistriesFactory {
2
- createAll(): {};
3
+ createAll(): {
4
+ extractedComponentSchemas: Record<string, OpenAPIV3_1.SchemaObject>;
5
+ };
3
6
  }
4
7
  //# sourceMappingURL=factory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/registries/factory.ts"],"names":[],"mappings":"AAAA,qBAAa,iBAAiB;IAC5B,SAAS;CAGV"}
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"}
@@ -2,7 +2,9 @@
2
2
 
3
3
  class RegistriesFactory {
4
4
  createAll() {
5
- return {};
5
+ return {
6
+ extractedComponentSchemas: {}
7
+ };
6
8
  }
7
9
  }
8
10
 
@@ -1 +1 @@
1
- {"version":3,"file":"factory.js","sources":["../../src/registries/factory.ts"],"sourcesContent":["export class RegistriesFactory {\n createAll() {\n return {};\n }\n}\n"],"names":["RegistriesFactory","createAll"],"mappings":";;AAAO,MAAMA,iBAAAA,CAAAA;IACXC,SAAAA,GAAY;AACV,QAAA,OAAO,EAAC;AACV,IAAA;AACF;;;;"}
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,6 +1,8 @@
1
1
  class RegistriesFactory {
2
2
  createAll() {
3
- return {};
3
+ return {
4
+ extractedComponentSchemas: {}
5
+ };
4
6
  }
5
7
  }
6
8
 
@@ -1 +1 @@
1
- {"version":3,"file":"factory.mjs","sources":["../../src/registries/factory.ts"],"sourcesContent":["export class RegistriesFactory {\n createAll() {\n return {};\n }\n}\n"],"names":["RegistriesFactory","createAll"],"mappings":"AAAO,MAAMA,iBAAAA,CAAAA;IACXC,SAAAA,GAAY;AACV,QAAA,OAAO,EAAC;AACV,IAAA;AACF;;;;"}
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;;;;"}
@@ -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
- * Zod 3.25.76 embeds `$id` in `toJSONSchema` output (set after `override`).
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 ids — and match the pre-3.25.76 shape.
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
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,YAAY,GACvB,WAAW,CAAC,CAAC,OAAO,KACnB,WAAW,CAAC,YAAY,GAAG,WAAW,CAAC,eAsBzC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAAI,IAAI,MAAM,WAAiC,CAAC"}
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
- * Zod 3.25.76 embeds `$id` in `toJSONSchema` output (set after `override`).
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 ids — and match the pre-3.25.76 shape.
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 the global registry definitions into the local registry to make sure references are resolved
72
- // This prevent "__shared" definitions from being created
73
- for (const [key, value] of z__namespace.globalRegistry._idmap){
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;
@@ -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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"}
@@ -2,24 +2,126 @@ import { randomUUID } from 'node:crypto';
2
2
  import * as z from 'zod/v4';
3
3
 
4
4
  /**
5
- * Zod 3.25.76 embeds `$id` in `toJSONSchema` output (set after `override`).
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 ids — and match the pre-3.25.76 shape.
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 the global registry definitions into the local registry to make sure references are resolved
50
- // This prevent "__shared" definitions from being created
51
- for (const [key, value] of z.globalRegistry._idmap){
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
@@ -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.1",
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": "3.25.76"
63
+ "zod": "4.4.3"
64
64
  },
65
65
  "devDependencies": {
66
- "@strapi/types": "5.52.1",
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",