@strapi/openapi 0.0.0-experimental.6340da17068c3bed7fb006e7bcc554c71129e282 → 0.0.0-experimental.63624e21eb5b0713345a0cf2f68f1c40eab427bc

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 (60) hide show
  1. package/dist/assemblers/document/factory.d.ts +2 -0
  2. package/dist/assemblers/document/factory.d.ts.map +1 -1
  3. package/dist/assemblers/document/factory.js +10 -0
  4. package/dist/assemblers/document/factory.js.map +1 -1
  5. package/dist/assemblers/document/factory.mjs +10 -0
  6. package/dist/assemblers/document/factory.mjs.map +1 -1
  7. package/dist/assemblers/document/path/path-item/operation/body.d.ts.map +1 -1
  8. package/dist/assemblers/document/path/path-item/operation/body.js +5 -1
  9. package/dist/assemblers/document/path/path-item/operation/body.js.map +1 -1
  10. package/dist/assemblers/document/path/path-item/operation/body.mjs +5 -1
  11. package/dist/assemblers/document/path/path-item/operation/body.mjs.map +1 -1
  12. package/dist/assemblers/document/path/path-item/operation/parameters.d.ts +6 -0
  13. package/dist/assemblers/document/path/path-item/operation/parameters.d.ts.map +1 -1
  14. package/dist/assemblers/document/path/path-item/operation/parameters.js +115 -17
  15. package/dist/assemblers/document/path/path-item/operation/parameters.js.map +1 -1
  16. package/dist/assemblers/document/path/path-item/operation/parameters.mjs +115 -17
  17. package/dist/assemblers/document/path/path-item/operation/parameters.mjs.map +1 -1
  18. package/dist/assemblers/document/path/path-item/operation/responses.d.ts.map +1 -1
  19. package/dist/assemblers/document/path/path-item/operation/responses.js +3 -1
  20. package/dist/assemblers/document/path/path-item/operation/responses.js.map +1 -1
  21. package/dist/assemblers/document/path/path-item/operation/responses.mjs +3 -1
  22. package/dist/assemblers/document/path/path-item/operation/responses.mjs.map +1 -1
  23. package/dist/assemblers/document/query-param-styles.d.ts +10 -0
  24. package/dist/assemblers/document/query-param-styles.d.ts.map +1 -0
  25. package/dist/assemblers/document/query-param-styles.js +23 -0
  26. package/dist/assemblers/document/query-param-styles.js.map +1 -0
  27. package/dist/assemblers/document/query-param-styles.mjs +19 -0
  28. package/dist/assemblers/document/query-param-styles.mjs.map +1 -0
  29. package/dist/assemblers/document/security.d.ts +8 -0
  30. package/dist/assemblers/document/security.d.ts.map +1 -0
  31. package/dist/assemblers/document/security.js +45 -0
  32. package/dist/assemblers/document/security.js.map +1 -0
  33. package/dist/assemblers/document/security.mjs +43 -0
  34. package/dist/assemblers/document/security.mjs.map +1 -0
  35. package/dist/assemblers/document/server.d.ts +13 -0
  36. package/dist/assemblers/document/server.d.ts.map +1 -0
  37. package/dist/assemblers/document/server.js +25 -0
  38. package/dist/assemblers/document/server.js.map +1 -0
  39. package/dist/assemblers/document/server.mjs +23 -0
  40. package/dist/assemblers/document/server.mjs.map +1 -0
  41. package/dist/context/types.d.ts +2 -2
  42. package/dist/context/types.d.ts.map +1 -1
  43. package/dist/post-processor/component-writer.d.ts.map +1 -1
  44. package/dist/post-processor/component-writer.js +21 -3
  45. package/dist/post-processor/component-writer.js.map +1 -1
  46. package/dist/post-processor/component-writer.mjs +22 -4
  47. package/dist/post-processor/component-writer.mjs.map +1 -1
  48. package/dist/registries/factory.d.ts +4 -1
  49. package/dist/registries/factory.d.ts.map +1 -1
  50. package/dist/registries/factory.js +3 -1
  51. package/dist/registries/factory.js.map +1 -1
  52. package/dist/registries/factory.mjs +3 -1
  53. package/dist/registries/factory.mjs.map +1 -1
  54. package/dist/utils/zod.d.ts +53 -10
  55. package/dist/utils/zod.d.ts.map +1 -1
  56. package/dist/utils/zod.js +128 -14
  57. package/dist/utils/zod.js.map +1 -1
  58. package/dist/utils/zod.mjs +126 -15
  59. package/dist/utils/zod.mjs.map +1 -1
  60. package/package.json +10 -6
@@ -1,14 +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';
4
+ /**
5
+ * OpenAPI 3.1 uses the JSON Schema 2020-12 dialect. Zod 4.4.3 has no `openapi-3.1`
6
+ * target, so `draft-2020-12` preserves valid 3.1 schemas. Explicit output mode preserves
7
+ * the conversion direction used before these defaults were pinned.
8
+ */
9
+ export declare const OPENAPI_SCHEMA_CONVERSION_OPTIONS: {
10
+ readonly target: "draft-2020-12";
11
+ readonly io: "output";
12
+ };
13
+ /**
14
+ * Zod 4.4.3 embeds `$id` in registry `toJSONSchema` output when `uri` is configured.
15
+ * Strip it so OpenAPI documents stay stable — inline schemas use random UUIDs
16
+ * as registry IDs.
17
+ */
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
+ };
3
47
  /**
4
48
  * Converts a Zod schema to an OpenAPI Schema Object.
5
49
  *
6
50
  * @description
7
51
  * Takes a Zod schema and converts it into an OpenAPI Schema Object (v3.1).
8
52
  * It uses a local registry to handle the conversion process and generates the appropriate
9
- * 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.
10
56
  *
11
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.
12
62
  *
13
63
  * @returns An OpenAPI Schema Object representing the input Zod schema structure.
14
64
  * If the conversion cannot be completed, returns undefined.
@@ -25,15 +75,8 @@ import type { OpenAPIV3_1 } from 'openapi-types';
25
75
  * });
26
76
  *
27
77
  * // Convert to OpenAPI schema
28
- * const openAPISchema = zodToOpenAPI(userSchema);
78
+ * const openAPISchema = zodToOpenAPI(userSchema, strapi.contentAPISchemaRegistry);
29
79
  * ```
30
80
  */
31
- export declare const zodToOpenAPI: (zodSchema: z.ZodType) => OpenAPIV3_1.SchemaObject | OpenAPIV3_1.ReferenceObject;
32
- /**
33
- * Generates a path string for referencing a component schema by its identifier.
34
- *
35
- * @param id - The identifier of the component schema.
36
- * @returns The constructed path string for the specified component schema.
37
- */
38
- 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;
39
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;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,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
@@ -23,15 +23,127 @@ function _interopNamespace(e) {
23
23
 
24
24
  var z__namespace = /*#__PURE__*/_interopNamespace(z);
25
25
 
26
+ /**
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.
44
+ * Strip it so OpenAPI documents stay stable — inline schemas use random UUIDs
45
+ * as registry IDs.
46
+ */ const stripJsonSchemaId = (schema)=>{
47
+ if ('$id' in schema) {
48
+ delete schema.$id;
49
+ }
50
+ return schema;
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
+ };
26
132
  /**
27
133
  * Converts a Zod schema to an OpenAPI Schema Object.
28
134
  *
29
135
  * @description
30
136
  * Takes a Zod schema and converts it into an OpenAPI Schema Object (v3.1).
31
137
  * It uses a local registry to handle the conversion process and generates the appropriate
32
- * 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.
33
141
  *
34
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.
35
147
  *
36
148
  * @returns An OpenAPI Schema Object representing the input Zod schema structure.
37
149
  * If the conversion cannot be completed, returns undefined.
@@ -48,9 +160,9 @@ var z__namespace = /*#__PURE__*/_interopNamespace(z);
48
160
  * });
49
161
  *
50
162
  * // Convert to OpenAPI schema
51
- * const openAPISchema = zodToOpenAPI(userSchema);
163
+ * const openAPISchema = zodToOpenAPI(userSchema, strapi.contentAPISchemaRegistry);
52
164
  * ```
53
- */ const zodToOpenAPI = (zodSchema)=>{
165
+ */ const zodToOpenAPI = (zodSchema, schemaStore, options)=>{
54
166
  try {
55
167
  const id = node_crypto.randomUUID();
56
168
  const registry = z__namespace.registry();
@@ -58,30 +170,32 @@ var z__namespace = /*#__PURE__*/_interopNamespace(z);
58
170
  registry.add(zodSchema, {
59
171
  id
60
172
  });
61
- // Copy the global registry definitions into the local registry to make sure references are resolved
62
- // This prevent "__shared" definitions from being created
63
- 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()){
64
176
  registry.add(value, {
65
177
  id: key
66
178
  });
67
179
  }
68
180
  // Generate the schemas and only return the one we want, transform the URI path to be OpenAPI compliant
69
181
  const { schemas } = z__namespace.toJSONSchema(registry, {
182
+ ...OPENAPI_SCHEMA_CONVERSION_OPTIONS,
70
183
  uri: toComponentsPath
71
184
  });
185
+ const harvested = isPlainObject(schemas) ? liftZodSharedDefinitions(schemas) : {};
186
+ if (options?.extractedComponentSchemas !== undefined) {
187
+ Object.assign(options.extractedComponentSchemas, harvested);
188
+ }
72
189
  // TODO: make sure it's compliant
73
- return schemas[id];
74
- } catch (e) {
190
+ return stripJsonSchemaId(schemas[id]);
191
+ } catch {
75
192
  throw new Error("Couldn't transform the zod schema into an OpenAPI schema");
76
193
  }
77
194
  };
78
- /**
79
- * Generates a path string for referencing a component schema by its identifier.
80
- *
81
- * @param id - The identifier of the component schema.
82
- * @returns The constructed path string for the specified component schema.
83
- */ const toComponentsPath = (id)=>`#/components/schemas/${id}`;
84
195
 
196
+ exports.OPENAPI_SCHEMA_CONVERSION_OPTIONS = OPENAPI_SCHEMA_CONVERSION_OPTIONS;
197
+ exports.liftZodSharedDefinitions = liftZodSharedDefinitions;
198
+ exports.stripJsonSchemaId = stripJsonSchemaId;
85
199
  exports.toComponentsPath = toComponentsPath;
86
200
  exports.zodToOpenAPI = zodToOpenAPI;
87
201
  //# sourceMappingURL=zod.js.map
@@ -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 * 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 */\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 schemas[id] as OpenAPIV3_1.SchemaObject;\n } catch (e) {\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":["zodToOpenAPI","zodSchema","id","randomUUID","registry","z","add","key","value","globalRegistry","_idmap","schemas","toJSONSchema","uri","toComponentsPath","e","Error"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;IA6BO,MAAMA,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,OAAOH,OAAO,CAACT,EAAAA,CAAG;AACpB,IAAA,CAAA,CAAE,OAAOa,CAAAA,EAAG;AACV,QAAA,MAAM,IAAIC,KAAAA,CAAM,0DAAA,CAAA;AAClB,IAAA;AACF;AAEA;;;;;UAMaF,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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"}
@@ -1,15 +1,127 @@
1
1
  import { randomUUID } from 'node:crypto';
2
2
  import * as z from 'zod/v4';
3
3
 
4
+ /**
5
+ * OpenAPI 3.1 uses the JSON Schema 2020-12 dialect. Zod 4.4.3 has no `openapi-3.1`
6
+ * target, so `draft-2020-12` preserves valid 3.1 schemas. Explicit output mode preserves
7
+ * the conversion direction used before these defaults were pinned.
8
+ */ 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.
22
+ * Strip it so OpenAPI documents stay stable — inline schemas use random UUIDs
23
+ * as registry IDs.
24
+ */ const stripJsonSchemaId = (schema)=>{
25
+ if ('$id' in schema) {
26
+ delete schema.$id;
27
+ }
28
+ return schema;
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
+ };
4
110
  /**
5
111
  * Converts a Zod schema to an OpenAPI Schema Object.
6
112
  *
7
113
  * @description
8
114
  * Takes a Zod schema and converts it into an OpenAPI Schema Object (v3.1).
9
115
  * It uses a local registry to handle the conversion process and generates the appropriate
10
- * 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.
11
119
  *
12
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.
13
125
  *
14
126
  * @returns An OpenAPI Schema Object representing the input Zod schema structure.
15
127
  * If the conversion cannot be completed, returns undefined.
@@ -26,9 +138,9 @@ import * as z from 'zod/v4';
26
138
  * });
27
139
  *
28
140
  * // Convert to OpenAPI schema
29
- * const openAPISchema = zodToOpenAPI(userSchema);
141
+ * const openAPISchema = zodToOpenAPI(userSchema, strapi.contentAPISchemaRegistry);
30
142
  * ```
31
- */ const zodToOpenAPI = (zodSchema)=>{
143
+ */ const zodToOpenAPI = (zodSchema, schemaStore, options)=>{
32
144
  try {
33
145
  const id = randomUUID();
34
146
  const registry = z.registry();
@@ -36,29 +148,28 @@ import * as z from 'zod/v4';
36
148
  registry.add(zodSchema, {
37
149
  id
38
150
  });
39
- // Copy the global registry definitions into the local registry to make sure references are resolved
40
- // This prevent "__shared" definitions from being created
41
- 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()){
42
154
  registry.add(value, {
43
155
  id: key
44
156
  });
45
157
  }
46
158
  // Generate the schemas and only return the one we want, transform the URI path to be OpenAPI compliant
47
159
  const { schemas } = z.toJSONSchema(registry, {
160
+ ...OPENAPI_SCHEMA_CONVERSION_OPTIONS,
48
161
  uri: toComponentsPath
49
162
  });
163
+ const harvested = isPlainObject(schemas) ? liftZodSharedDefinitions(schemas) : {};
164
+ if (options?.extractedComponentSchemas !== undefined) {
165
+ Object.assign(options.extractedComponentSchemas, harvested);
166
+ }
50
167
  // TODO: make sure it's compliant
51
- return schemas[id];
52
- } catch (e) {
168
+ return stripJsonSchemaId(schemas[id]);
169
+ } catch {
53
170
  throw new Error("Couldn't transform the zod schema into an OpenAPI schema");
54
171
  }
55
172
  };
56
- /**
57
- * Generates a path string for referencing a component schema by its identifier.
58
- *
59
- * @param id - The identifier of the component schema.
60
- * @returns The constructed path string for the specified component schema.
61
- */ const toComponentsPath = (id)=>`#/components/schemas/${id}`;
62
173
 
63
- export { toComponentsPath, zodToOpenAPI };
174
+ export { OPENAPI_SCHEMA_CONVERSION_OPTIONS, liftZodSharedDefinitions, stripJsonSchemaId, toComponentsPath, zodToOpenAPI };
64
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 * 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 */\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 schemas[id] as OpenAPIV3_1.SchemaObject;\n } catch (e) {\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":["zodToOpenAPI","zodSchema","id","randomUUID","registry","z","add","key","value","globalRegistry","_idmap","schemas","toJSONSchema","uri","toComponentsPath","e","Error"],"mappings":";;;AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;IA6BO,MAAMA,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,OAAOH,OAAO,CAACT,EAAAA,CAAG;AACpB,IAAA,CAAA,CAAE,OAAOa,CAAAA,EAAG;AACV,QAAA,MAAM,IAAIC,KAAAA,CAAM,0DAAA,CAAA;AAClB,IAAA;AACF;AAEA;;;;;UAMaF,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": "0.0.0-experimental.6340da17068c3bed7fb006e7bcc554c71129e282",
3
+ "version": "0.0.0-experimental.63624e21eb5b0713345a0cf2f68f1c40eab427bc",
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": {
@@ -47,22 +47,26 @@
47
47
  "build:types": "run -T tsc -p tsconfig.build.json --emitDeclarationOnly",
48
48
  "watch": "run -T rollup -c -w",
49
49
  "clean": "run -T rimraf ./dist",
50
- "lint": "run -T eslint .",
50
+ "lint": "run -T eslint . --max-warnings=0",
51
51
  "prepublishOnly": "yarn clean && yarn build",
52
+ "test:ts": "run -T tsc -p tsconfig.json",
52
53
  "test:unit": "run -T jest",
53
54
  "test:unit:watch": "run -T jest --watch"
54
55
  },
55
56
  "engines": {
56
- "node": ">=20.19.0 <=26.x.x",
57
+ "node": ">=20.0.0 <=26.x.x",
57
58
  "npm": ">=6.0.0"
58
59
  },
59
60
  "dependencies": {
60
61
  "debug": "4.3.4",
61
62
  "openapi-types": "12.1.3",
62
- "zod": "3.25.67"
63
+ "zod": "4.4.3"
63
64
  },
64
65
  "devDependencies": {
65
- "@strapi/types": "0.0.0-experimental.6340da17068c3bed7fb006e7bcc554c71129e282",
66
- "@types/debug": "^4"
66
+ "@strapi/types": "0.0.0-experimental.63624e21eb5b0713345a0cf2f68f1c40eab427bc",
67
+ "@types/debug": "^4",
68
+ "@types/jest": "29.5.2",
69
+ "@types/node": "20.19.41",
70
+ "jest": "29.6.0"
67
71
  }
68
72
  }