zod-openapi 5.0.0-beta.0 → 5.0.0-beta.1

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.
@@ -1,1078 +1,2463 @@
1
1
  "use strict";
2
- const core = require("zod/v4/core");
3
- const v4 = require("zod/v4");
4
- const isAnyZodType = (schema) => typeof schema === "object" && schema !== null && "_zod" in schema;
5
- const unwrapZodObject = (zodType, io, path) => {
6
- const def = zodType._zod.def;
7
- switch (def.type) {
8
- case "object": {
9
- return zodType;
10
- }
11
- case "lazy": {
12
- return unwrapZodObject(def.getter(), io, path);
13
- }
14
- case "pipe": {
15
- if (io === "input") {
16
- return unwrapZodObject(def.in, io, path);
2
+ const extendZodSymbols = require("./extendZodSymbols.chunk.cjs");
3
+ const isZodType = (zodType, typeName) => {
4
+ var _a;
5
+ return ((_a = zodType == null ? void 0 : zodType._def) == null ? void 0 : _a.typeName) === typeName;
6
+ };
7
+ const isAnyZodType = (zodType) => {
8
+ var _a;
9
+ return Boolean(
10
+ (_a = zodType == null ? void 0 : zodType._def) == null ? void 0 : _a.typeName
11
+ );
12
+ };
13
+ const openApiVersions = [
14
+ "3.0.0",
15
+ "3.0.1",
16
+ "3.0.2",
17
+ "3.0.3",
18
+ "3.1.0",
19
+ "3.1.1"
20
+ ];
21
+ const satisfiesVersion = (test, against) => openApiVersions.indexOf(test) >= openApiVersions.indexOf(against);
22
+ const createDescriptionMetadata = (schema, description, state) => {
23
+ if (satisfiesVersion(state.components.openapi, "3.1.0")) {
24
+ return {
25
+ type: "ref",
26
+ schema: {
27
+ $ref: schema.schema.$ref,
28
+ description
29
+ },
30
+ zodType: schema.zodType,
31
+ effects: schema.effects,
32
+ schemaObject: schema.schemaObject
33
+ };
34
+ }
35
+ return {
36
+ type: "schema",
37
+ schema: {
38
+ description,
39
+ allOf: [schema.schema]
40
+ },
41
+ effects: schema.effects
42
+ };
43
+ };
44
+ const isValueEqual = (value, previous) => {
45
+ if (typeof value !== typeof previous) {
46
+ return false;
47
+ }
48
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
49
+ return value === previous;
50
+ }
51
+ if (Array.isArray(value) && Array.isArray(previous)) {
52
+ const sorted = [...value].sort();
53
+ const previousSorted = [...previous].sort();
54
+ return sorted.every((v, i) => isValueEqual(v, previousSorted[i]));
55
+ }
56
+ if (value === null || previous === null) {
57
+ return value === previous;
58
+ }
59
+ if (typeof value === "object" && typeof previous === "object") {
60
+ const keys = Object.keys(value);
61
+ return keys.every(
62
+ (key) => isValueEqual(
63
+ value[key],
64
+ previous[key]
65
+ )
66
+ );
67
+ }
68
+ return value === previous;
69
+ };
70
+ const enhanceWithMetadata = (schema, metadata, state, previous) => {
71
+ const values = Object.entries(metadata).reduce(
72
+ (acc, [key, value]) => {
73
+ if (value === void 0) {
74
+ return acc;
17
75
  }
18
- return unwrapZodObject(def.out, io, path);
76
+ acc[key] = value;
77
+ return acc;
78
+ },
79
+ {}
80
+ );
81
+ const length = Object.values(values).length;
82
+ if (schema.type === "ref") {
83
+ if (length === 0) {
84
+ return schema;
85
+ }
86
+ if (length === 1 && metadata.description) {
87
+ return createDescriptionMetadata(schema, metadata.description, state);
19
88
  }
89
+ return {
90
+ type: "schema",
91
+ schema: {
92
+ allOf: [schema.schema],
93
+ ...metadata
94
+ },
95
+ effects: schema.effects
96
+ };
20
97
  }
21
- throw new Error(
22
- `Failed to unwrap ZodObject from type: ${zodType._zod.def.type} at ${path.join(" > ")}`
98
+ if (previous && schema.schema.type !== "object") {
99
+ const diff = Object.entries({ ...schema.schema, ...values }).reduce(
100
+ (acc, [key, value]) => {
101
+ if (previous.schemaObject && isValueEqual(
102
+ previous.schemaObject[key],
103
+ value
104
+ )) {
105
+ return acc;
106
+ }
107
+ acc[key] = value;
108
+ return acc;
109
+ },
110
+ {}
111
+ );
112
+ const diffLength = Object.values(diff).length;
113
+ if (diffLength === 0) {
114
+ return {
115
+ type: "ref",
116
+ schema: {
117
+ $ref: previous.schema.$ref
118
+ },
119
+ effects: schema.effects,
120
+ schemaObject: previous.schemaObject,
121
+ zodType: previous.zodType
122
+ };
123
+ }
124
+ if (diffLength === 1 && typeof diff.description === "string") {
125
+ return createDescriptionMetadata(previous, diff.description, state);
126
+ }
127
+ return {
128
+ type: "schema",
129
+ schema: { allOf: [previous.schema], ...diff },
130
+ effects: schema.effects
131
+ };
132
+ }
133
+ return {
134
+ type: "schema",
135
+ schema: {
136
+ ...schema.schema,
137
+ ...metadata
138
+ },
139
+ effects: schema.effects
140
+ };
141
+ };
142
+ const createArraySchema = (zodArray, state) => {
143
+ var _a, _b, _c, _d;
144
+ const zodType = zodArray._def.type;
145
+ const minItems = ((_a = zodArray._def.exactLength) == null ? void 0 : _a.value) ?? ((_b = zodArray._def.minLength) == null ? void 0 : _b.value);
146
+ const maxItems = ((_c = zodArray._def.exactLength) == null ? void 0 : _c.value) ?? ((_d = zodArray._def.maxLength) == null ? void 0 : _d.value);
147
+ const items = createSchemaObject(zodType, state, ["array items"]);
148
+ return {
149
+ type: "schema",
150
+ schema: {
151
+ type: "array",
152
+ items: items.schema,
153
+ ...minItems !== void 0 && { minItems },
154
+ ...maxItems !== void 0 && { maxItems }
155
+ },
156
+ effects: items.effects
157
+ };
158
+ };
159
+ const createBigIntSchema = (_zodBigInt) => ({
160
+ type: "schema",
161
+ schema: {
162
+ type: "integer",
163
+ format: "int64"
164
+ }
165
+ });
166
+ const createBooleanSchema = (_zodBoolean) => ({
167
+ type: "schema",
168
+ schema: {
169
+ type: "boolean"
170
+ }
171
+ });
172
+ const createBrandedSchema = (zodBranded, state) => createSchemaObject(zodBranded._def.type, state, ["brand"]);
173
+ const createCatchSchema = (zodCatch, state, previous) => {
174
+ const schemaObject = createSchemaObject(zodCatch._def.innerType, state, [
175
+ "default"
176
+ ]);
177
+ const catchResult = zodCatch.safeParse(void 0);
178
+ const maybeDefaultValue = catchResult.success ? {
179
+ default: catchResult.data
180
+ } : {};
181
+ return enhanceWithMetadata(schemaObject, maybeDefaultValue, state, previous);
182
+ };
183
+ const createDateSchema = (_zodDate, state) => {
184
+ var _a;
185
+ return {
186
+ type: "schema",
187
+ schema: ((_a = state.documentOptions) == null ? void 0 : _a.defaultDateSchema) ?? {
188
+ type: "string"
189
+ }
190
+ };
191
+ };
192
+ const createDefaultSchema = (zodDefault, state, previous) => {
193
+ const schemaObject = createSchemaObject(zodDefault._def.innerType, state, [
194
+ "default"
195
+ ]);
196
+ return enhanceWithMetadata(
197
+ schemaObject,
198
+ {
199
+ default: zodDefault._def.defaultValue()
200
+ },
201
+ state,
202
+ previous
203
+ );
204
+ };
205
+ const createNativeEnumSchema = (zodEnum, state) => {
206
+ const enumValues = getValidEnumValues(zodEnum._def.values);
207
+ const { numbers, strings } = sortStringsAndNumbers(enumValues);
208
+ if (strings.length && numbers.length) {
209
+ if (satisfiesVersion(state.components.openapi, "3.1.0")) {
210
+ return {
211
+ type: "schema",
212
+ schema: {
213
+ type: ["string", "number"],
214
+ enum: [...strings, ...numbers]
215
+ }
216
+ };
217
+ }
218
+ return {
219
+ type: "schema",
220
+ schema: {
221
+ oneOf: [
222
+ { type: "string", enum: strings },
223
+ { type: "number", enum: numbers }
224
+ ]
225
+ }
226
+ };
227
+ }
228
+ if (strings.length) {
229
+ return {
230
+ type: "schema",
231
+ schema: {
232
+ type: "string",
233
+ enum: strings
234
+ }
235
+ };
236
+ }
237
+ return {
238
+ type: "schema",
239
+ schema: {
240
+ type: "number",
241
+ enum: numbers
242
+ }
243
+ };
244
+ };
245
+ const getValidEnumValues = (enumValues) => {
246
+ const keys = Object.keys(enumValues).filter(
247
+ (key) => typeof enumValues[enumValues[key]] !== "number"
23
248
  );
249
+ return keys.map((key) => enumValues[key]);
24
250
  };
25
- const isRequired = (zodType, io) => {
26
- if (io === "input") {
27
- return zodType._zod.optin === void 0;
251
+ const sortStringsAndNumbers = (values) => ({
252
+ strings: values.filter((value) => typeof value === "string"),
253
+ numbers: values.filter((value) => typeof value === "number")
254
+ });
255
+ const createTransformSchema = (zodTransform, state) => {
256
+ var _a, _b, _c, _d, _e, _f;
257
+ if (((_b = (_a = zodTransform._def.zodOpenApi) == null ? void 0 : _a.openapi) == null ? void 0 : _b.effectType) === "output") {
258
+ return {
259
+ type: "schema",
260
+ schema: createManualOutputTransformSchema(zodTransform, state)
261
+ };
262
+ }
263
+ if (((_d = (_c = zodTransform._def.zodOpenApi) == null ? void 0 : _c.openapi) == null ? void 0 : _d.effectType) === "input" || ((_f = (_e = zodTransform._def.zodOpenApi) == null ? void 0 : _e.openapi) == null ? void 0 : _f.effectType) === "same") {
264
+ return createSchemaObject(zodTransform._def.schema, state, [
265
+ "transform input"
266
+ ]);
267
+ }
268
+ if (state.type === "output") {
269
+ return {
270
+ type: "schema",
271
+ schema: createManualOutputTransformSchema(zodTransform, state)
272
+ };
28
273
  }
29
- return zodType._zod.optout === void 0;
274
+ const schema = createSchemaObject(zodTransform._def.schema, state, [
275
+ "transform input"
276
+ ]);
277
+ return {
278
+ ...schema,
279
+ effects: flattenEffects([
280
+ [
281
+ {
282
+ type: "schema",
283
+ creationType: "input",
284
+ zodType: zodTransform,
285
+ path: [...state.path]
286
+ }
287
+ ],
288
+ schema.effects
289
+ ])
290
+ };
30
291
  };
31
- const createParameter = (parameter, location, ctx, path) => {
32
- var _a, _b;
33
- const seenParameter = ctx.registry.parameters.seen.get(parameter);
34
- if (seenParameter) {
35
- return seenParameter;
36
- }
37
- const meta = v4.globalRegistry.get(parameter);
38
- const name = (location == null ? void 0 : location.name) ?? ((_a = meta == null ? void 0 : meta.param) == null ? void 0 : _a.name);
39
- const inLocation = (location == null ? void 0 : location.in) ?? ((_b = meta == null ? void 0 : meta.param) == null ? void 0 : _b.in);
40
- if (!name || !inLocation) {
292
+ const createManualOutputTransformSchema = (zodTransform, state) => {
293
+ var _a, _b, _c;
294
+ if (!((_b = (_a = zodTransform._def.zodOpenApi) == null ? void 0 : _a.openapi) == null ? void 0 : _b.type)) {
295
+ const zodType = zodTransform.constructor.name;
296
+ const schemaName = `${zodType} - ${zodTransform._def.effect.type}`;
41
297
  throw new Error(
42
- `Parameter at ${path.join(" > ")} is missing \`.meta({ param: { name, in } })\` information`
298
+ `Failed to determine a type for ${schemaName} at ${state.path.join(
299
+ " > "
300
+ )}. Please change the 'effectType' to 'same' or 'input', wrap it in a ZodPipeline or assign it a manual 'type'.`
43
301
  );
44
302
  }
45
- const computedPath = [...path, inLocation, name].join(" > ");
46
- const schemaObject = ctx.registry.schemas.setSchema(
47
- computedPath,
48
- parameter,
49
- ctx.io
303
+ return {
304
+ type: (_c = zodTransform._def.zodOpenApi) == null ? void 0 : _c.openapi.type
305
+ };
306
+ };
307
+ const getZodTypeName = (zodType) => {
308
+ if (isZodType(zodType, "ZodEffects")) {
309
+ return `${zodType._def.typeName} - ${zodType._def.effect.type}`;
310
+ }
311
+ return zodType._def.typeName;
312
+ };
313
+ const throwTransformError = (effect) => {
314
+ const typeName = getZodTypeName(effect.zodType);
315
+ const input = effect.creationType;
316
+ const opposite = input === "input" ? "output" : "input";
317
+ throw new Error(
318
+ `The ${typeName} at ${effect.path.join(
319
+ " > "
320
+ )} is used within a registered compoment schema${effect.component ? ` (${effect.component.ref})` : ""} and contains an ${input} transformation${effect.component ? ` (${getZodTypeName(
321
+ effect.component.zodType
322
+ )}) defined at ${effect.component.path.join(" > ")}` : ""} which is also used in an ${opposite} schema.
323
+
324
+ This may cause the schema to render incorrectly and is most likely a mistake. You can resolve this by:
325
+
326
+ 1. Setting an \`effectType\` on one of the transformations to \`same\` (Not applicable for ZodDefault), \`input\` or \`output\` eg. \`.openapi({type: 'same'})\`
327
+ 2. Wrapping the transformation in a ZodPipeline
328
+ 3. Assigning a manual type to the transformation eg. \`.openapi({type: 'string'})\`
329
+ 4. Removing the transformation
330
+ 5. Deregister the component containing the transformation`
50
331
  );
51
- const { id, ...rest } = (meta == null ? void 0 : meta.param) ?? {};
52
- const parameterObject = {
53
- ...rest,
54
- name,
55
- in: inLocation,
56
- schema: schemaObject
332
+ };
333
+ const resolveSingleEffect = (effect, state) => {
334
+ if (effect.type === "schema") {
335
+ return {
336
+ creationType: effect.creationType,
337
+ path: effect.path,
338
+ zodType: effect.zodType
339
+ };
340
+ }
341
+ if (effect.type === "component") {
342
+ if (state.visited.has(effect.zodType)) {
343
+ return;
344
+ }
345
+ const component = state.components.schemas.get(effect.zodType);
346
+ if ((component == null ? void 0 : component.type) !== "complete") {
347
+ throw new Error("Something went wrong, component schema is not complete");
348
+ }
349
+ if (component.resolvedEffect) {
350
+ return {
351
+ creationType: component.resolvedEffect.creationType,
352
+ path: effect.path,
353
+ zodType: effect.zodType,
354
+ component: {
355
+ ref: component.ref,
356
+ zodType: component.resolvedEffect.zodType,
357
+ path: component.resolvedEffect.path
358
+ }
359
+ };
360
+ }
361
+ if (!component.effects) {
362
+ return void 0;
363
+ }
364
+ state.visited.add(effect.zodType);
365
+ const resolved = resolveEffect(component.effects, state);
366
+ state.visited.delete(effect.zodType);
367
+ if (!resolved) {
368
+ return void 0;
369
+ }
370
+ component.resolvedEffect = resolved;
371
+ return resolved;
372
+ }
373
+ return void 0;
374
+ };
375
+ const resolveEffect = (effects, state) => {
376
+ const { input, output } = effects.reduce(
377
+ (acc, effect) => {
378
+ const resolvedSchemaEffect = resolveSingleEffect(effect, state);
379
+ if ((resolvedSchemaEffect == null ? void 0 : resolvedSchemaEffect.creationType) === "input") {
380
+ acc.input.push(resolvedSchemaEffect);
381
+ }
382
+ if ((resolvedSchemaEffect == null ? void 0 : resolvedSchemaEffect.creationType) === "output") {
383
+ acc.output.push(resolvedSchemaEffect);
384
+ }
385
+ if (resolvedSchemaEffect && acc.input.length > 1 && acc.output.length > 1) {
386
+ throwTransformError(resolvedSchemaEffect);
387
+ }
388
+ return acc;
389
+ },
390
+ { input: [], output: [] }
391
+ );
392
+ if (input.length > 0) {
393
+ return input[0];
394
+ }
395
+ if (output.length > 0) {
396
+ return output[0];
397
+ }
398
+ return void 0;
399
+ };
400
+ const verifyEffects = (effects, state) => {
401
+ const resolved = resolveEffect(effects, state);
402
+ if ((resolved == null ? void 0 : resolved.creationType) && resolved.creationType !== state.type) {
403
+ throwTransformError(resolved);
404
+ }
405
+ };
406
+ const flattenEffects = (effects) => {
407
+ const allEffects = effects.reduce((acc, effect) => {
408
+ if (effect) {
409
+ return acc.concat(effect);
410
+ }
411
+ return acc;
412
+ }, []);
413
+ return allEffects.length ? allEffects : void 0;
414
+ };
415
+ const createDiscriminatedUnionSchema = (zodDiscriminatedUnion, state) => {
416
+ const options = zodDiscriminatedUnion.options;
417
+ const schemas = options.map(
418
+ (option, index) => createSchemaObject(option, state, [`discriminated union option ${index}`])
419
+ );
420
+ const schemaObjects = schemas.map((schema) => schema.schema);
421
+ const discriminator = mapDiscriminator(
422
+ schemaObjects,
423
+ options,
424
+ zodDiscriminatedUnion.discriminator,
425
+ state
426
+ );
427
+ return {
428
+ type: "schema",
429
+ schema: {
430
+ oneOf: schemaObjects,
431
+ ...discriminator && { discriminator }
432
+ },
433
+ effects: flattenEffects(schemas.map((schema) => schema.effects))
57
434
  };
58
- if (isRequired(parameter, ctx.io)) {
59
- parameterObject.required = true;
435
+ };
436
+ const unwrapLiterals = (zodType, state) => {
437
+ if (isZodType(zodType, "ZodLiteral")) {
438
+ if (typeof zodType._def.value !== "string") {
439
+ return void 0;
440
+ }
441
+ return [zodType._def.value];
60
442
  }
61
- if (!parameterObject.description && (meta == null ? void 0 : meta.description)) {
62
- parameterObject.description = meta.description;
443
+ if (isZodType(zodType, "ZodNativeEnum")) {
444
+ const schema = createNativeEnumSchema(zodType, state);
445
+ if (schema.type === "schema" && schema.schema.type === "string") {
446
+ return schema.schema.enum;
447
+ }
63
448
  }
64
- if (id) {
65
- const ref = {
66
- $ref: `#/components/parameters/${id}`
67
- };
68
- ctx.registry.parameters.seen.set(parameter, ref);
69
- ctx.registry.parameters.ids.set(id, parameterObject);
70
- return ref;
449
+ if (isZodType(zodType, "ZodEnum")) {
450
+ return zodType._def.values;
71
451
  }
72
- ctx.registry.parameters.seen.set(parameter, parameterObject);
73
- return parameterObject;
452
+ if (isZodType(zodType, "ZodBranded")) {
453
+ return unwrapLiterals(zodType._def.type, state);
454
+ }
455
+ if (isZodType(zodType, "ZodReadonly")) {
456
+ return unwrapLiterals(zodType._def.innerType, state);
457
+ }
458
+ if (isZodType(zodType, "ZodCatch")) {
459
+ return unwrapLiterals(zodType._def.innerType, state);
460
+ }
461
+ return void 0;
74
462
  };
75
- const createManualParameters = (parameters, ctx, path) => {
76
- if (!parameters) {
463
+ const mapDiscriminator = (schemas, zodObjects, discriminator, state) => {
464
+ var _a;
465
+ if (typeof discriminator !== "string") {
77
466
  return void 0;
78
467
  }
79
- const parameterObjects = [];
80
- for (const parameter of parameters) {
81
- if (isAnyZodType(parameter)) {
82
- const seenParameter = ctx.registry.parameters.seen.get(parameter);
83
- if (seenParameter) {
84
- parameterObjects.push(seenParameter);
85
- continue;
468
+ const mapping = {};
469
+ for (const [index, zodObject] of zodObjects.entries()) {
470
+ const schema = schemas[index];
471
+ const componentSchemaRef = "$ref" in schema ? schema == null ? void 0 : schema.$ref : void 0;
472
+ if (!componentSchemaRef) {
473
+ if ((_a = state.documentOptions) == null ? void 0 : _a.enforceDiscriminatedUnionComponents) {
474
+ throw new Error(
475
+ `Discriminated Union member ${index} at ${state.path.join(" > ")} is not registered as a component`
476
+ );
86
477
  }
87
- const paramObject = createParameter(parameter, void 0, ctx, [
88
- ...path,
89
- "parameters"
90
- ]);
91
- parameterObjects.push(paramObject);
92
- continue;
478
+ return void 0;
479
+ }
480
+ const value = zodObject.shape[discriminator];
481
+ const literals = unwrapLiterals(value, state);
482
+ if (!literals) {
483
+ return void 0;
484
+ }
485
+ for (const enumValue of literals) {
486
+ mapping[enumValue] = componentSchemaRef;
93
487
  }
94
- parameterObjects.push(parameter);
95
488
  }
96
- return parameterObjects;
489
+ return {
490
+ propertyName: discriminator,
491
+ mapping
492
+ };
97
493
  };
98
- const createParameters = (requestParams, ctx, path) => {
99
- if (!requestParams) {
100
- return void 0;
494
+ const createEnumSchema = (zodEnum) => ({
495
+ type: "schema",
496
+ schema: {
497
+ type: "string",
498
+ enum: zodEnum._def.values
499
+ }
500
+ });
501
+ const createIntersectionSchema = (zodIntersection, state) => {
502
+ const schemas = flattenIntersection(zodIntersection);
503
+ const allOfs = schemas.map(
504
+ (schema, index) => createSchemaObject(schema, state, [`intersection ${index}`])
505
+ );
506
+ return {
507
+ type: "schema",
508
+ schema: {
509
+ allOf: allOfs.map((schema) => schema.schema)
510
+ },
511
+ effects: flattenEffects(allOfs.map((schema) => schema.effects))
512
+ };
513
+ };
514
+ const flattenIntersection = (zodType) => {
515
+ if (!isZodType(zodType, "ZodIntersection")) {
516
+ return [zodType];
101
517
  }
102
- const parameterObjects = [];
103
- for (const [location, schema] of Object.entries(requestParams ?? {})) {
104
- if (!schema) {
105
- continue;
106
- }
107
- const zodObject = unwrapZodObject(schema, ctx.io, path);
108
- for (const [name, zodSchema] of Object.entries(zodObject._zod.def.shape)) {
109
- const seenParameter = ctx.registry.parameters.seen.get(zodSchema);
110
- if (seenParameter) {
111
- parameterObjects.push(seenParameter);
112
- continue;
518
+ const leftSchemas = flattenIntersection(zodType._def.left);
519
+ const rightSchemas = flattenIntersection(zodType._def.right);
520
+ return [...leftSchemas, ...rightSchemas];
521
+ };
522
+ const createLazySchema = (zodLazy, state) => {
523
+ const innerSchema = zodLazy._def.getter();
524
+ return createSchemaObject(innerSchema, state, ["lazy schema"]);
525
+ };
526
+ const createNullSchema = () => ({
527
+ type: "schema",
528
+ schema: {
529
+ type: "null"
530
+ }
531
+ });
532
+ const createLiteralSchema = (zodLiteral, state) => {
533
+ if (zodLiteral.value === null) {
534
+ return createNullSchema();
535
+ }
536
+ if (satisfiesVersion(state.components.openapi, "3.1.0")) {
537
+ return {
538
+ type: "schema",
539
+ schema: {
540
+ type: typeof zodLiteral.value,
541
+ const: zodLiteral.value
113
542
  }
114
- const paramObject = createParameter(
115
- zodSchema,
116
- {
117
- in: location,
118
- name
119
- },
120
- ctx,
121
- [...path, location, name]
122
- );
123
- parameterObjects.push(paramObject);
124
- }
543
+ };
125
544
  }
126
- return parameterObjects;
545
+ return {
546
+ type: "schema",
547
+ schema: {
548
+ type: typeof zodLiteral.value,
549
+ enum: [zodLiteral.value]
550
+ }
551
+ };
127
552
  };
128
- const createMediaTypeObject = (mediaTypeObject, ctx, path) => {
129
- const computedPath = path.join(" > ");
130
- if (isAnyZodType(mediaTypeObject.schema)) {
131
- const schemaObject = ctx.registry.schemas.setSchema(
132
- computedPath,
133
- mediaTypeObject.schema,
134
- ctx.io
553
+ const createManualTypeSchema = (zodSchema, state) => {
554
+ var _a, _b, _c;
555
+ if (!((_b = (_a = zodSchema._def.zodOpenApi) == null ? void 0 : _a.openapi) == null ? void 0 : _b.type)) {
556
+ const schemaName = zodSchema.constructor.name;
557
+ throw new Error(
558
+ `Unknown schema ${schemaName} at ${state.path.join(
559
+ " > "
560
+ )}. Please assign it a manual 'type'.`
135
561
  );
562
+ }
563
+ return {
564
+ type: "schema",
565
+ schema: {
566
+ type: (_c = zodSchema._def.zodOpenApi) == null ? void 0 : _c.openapi.type
567
+ }
568
+ };
569
+ };
570
+ const createNullableSchema = (zodNullable, state) => {
571
+ const schemaObject = createSchemaObject(zodNullable.unwrap(), state, [
572
+ "nullable"
573
+ ]);
574
+ if (satisfiesVersion(state.components.openapi, "3.1.0")) {
575
+ if (schemaObject.type === "ref" || schemaObject.schema.allOf) {
576
+ return {
577
+ type: "schema",
578
+ schema: {
579
+ oneOf: mapNullOf([schemaObject.schema], state.components.openapi)
580
+ },
581
+ effects: schemaObject.effects
582
+ };
583
+ }
584
+ if (schemaObject.schema.oneOf) {
585
+ const { oneOf, ...schema3 } = schemaObject.schema;
586
+ return {
587
+ type: "schema",
588
+ schema: {
589
+ oneOf: mapNullOf(oneOf, state.components.openapi),
590
+ ...schema3
591
+ },
592
+ effects: schemaObject.effects
593
+ };
594
+ }
595
+ if (schemaObject.schema.anyOf) {
596
+ const { anyOf, ...schema3 } = schemaObject.schema;
597
+ return {
598
+ type: "schema",
599
+ schema: {
600
+ anyOf: mapNullOf(anyOf, state.components.openapi),
601
+ ...schema3
602
+ },
603
+ effects: schemaObject.effects
604
+ };
605
+ }
606
+ const { type: type2, const: schemaConst, ...schema2 } = schemaObject.schema;
607
+ if (schemaConst) {
608
+ return {
609
+ type: "schema",
610
+ schema: {
611
+ type: mapNullType(type2),
612
+ enum: [schemaConst, null],
613
+ ...schema2
614
+ },
615
+ effects: schemaObject.effects
616
+ };
617
+ }
618
+ return {
619
+ type: "schema",
620
+ schema: {
621
+ type: mapNullType(type2),
622
+ ...schema2,
623
+ // https://github.com/json-schema-org/json-schema-spec/issues/258
624
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
625
+ ...schema2.enum && { enum: [...schema2.enum, null] }
626
+ },
627
+ effects: schemaObject.effects
628
+ };
629
+ }
630
+ if (schemaObject.type === "ref") {
136
631
  return {
137
- ...mediaTypeObject,
138
- schema: schemaObject
632
+ type: "schema",
633
+ schema: {
634
+ allOf: [schemaObject.schema],
635
+ nullable: true
636
+ },
637
+ effects: schemaObject.effects
139
638
  };
140
639
  }
141
- return mediaTypeObject;
640
+ const { type, ...schema } = schemaObject.schema;
641
+ return {
642
+ type: "schema",
643
+ schema: {
644
+ ...type && { type },
645
+ nullable: true,
646
+ ...schema,
647
+ // https://github.com/OAI/OpenAPI-Specification/blob/main/proposals/2019-10-31-Clarify-Nullable.md#if-a-schema-specifies-nullable-true-and-enum-1-2-3-does-that-schema-allow-null-values-see-1900
648
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
649
+ ...schema.enum && { enum: [...schema.enum, null] }
650
+ },
651
+ effects: schemaObject.effects
652
+ };
142
653
  };
143
- const createContent = (content, ctx, path) => {
144
- const contentObject = {};
145
- for (const [mediaType, mediaTypeObject] of Object.entries(content)) {
146
- if (mediaTypeObject) {
147
- contentObject[mediaType] = createMediaTypeObject(mediaTypeObject, ctx, [
148
- ...path,
149
- mediaType
150
- ]);
654
+ const mapNullType = (type) => {
655
+ if (!type) {
656
+ return "null";
657
+ }
658
+ if (Array.isArray(type)) {
659
+ return [...type, "null"];
660
+ }
661
+ return [type, "null"];
662
+ };
663
+ const mapNullOf = (ofSchema, openapi) => {
664
+ if (satisfiesVersion(openapi, "3.1.0")) {
665
+ return [...ofSchema, { type: "null" }];
666
+ }
667
+ return [...ofSchema, { nullable: true }];
668
+ };
669
+ const createNumberSchema = (zodNumber, state) => {
670
+ const zodNumberChecks = getZodNumberChecks(zodNumber);
671
+ const minimum = mapMinimum(zodNumberChecks, state.components.openapi);
672
+ const maximum = mapMaximum(zodNumberChecks, state.components.openapi);
673
+ const multipleOf = mapMultipleOf(zodNumberChecks);
674
+ return {
675
+ type: "schema",
676
+ schema: {
677
+ type: mapNumberType(zodNumberChecks),
678
+ ...multipleOf && multipleOf,
679
+ ...minimum && minimum,
680
+ // Union types are not easy to tame
681
+ ...maximum && maximum
151
682
  }
683
+ };
684
+ };
685
+ const mapMultipleOf = (zodNumberCheck) => zodNumberCheck.multipleOf ? { multipleOf: zodNumberCheck.multipleOf.value } : void 0;
686
+ const mapMaximum = (zodNumberCheck, openapi) => {
687
+ if (!zodNumberCheck.max) {
688
+ return void 0;
689
+ }
690
+ const maximum = zodNumberCheck.max.value;
691
+ if (zodNumberCheck.max.inclusive) {
692
+ return { ...maximum !== void 0 && { maximum } };
152
693
  }
153
- return contentObject;
694
+ if (satisfiesVersion(openapi, "3.1.0")) {
695
+ return { exclusiveMaximum: maximum };
696
+ }
697
+ return { maximum, exclusiveMaximum: true };
154
698
  };
155
- const createRequestBody = (requestBody, ctx, path) => {
156
- if (!requestBody) {
699
+ const mapMinimum = (zodNumberCheck, openapi) => {
700
+ if (!zodNumberCheck.min) {
157
701
  return void 0;
158
702
  }
159
- const seenRequestBody = ctx.registry.requestBodies.seen.get(requestBody);
160
- if (seenRequestBody) {
161
- return seenRequestBody;
703
+ const minimum = zodNumberCheck.min.value;
704
+ if (zodNumberCheck.min.inclusive) {
705
+ return { ...minimum !== void 0 && { minimum } };
162
706
  }
163
- const { content, id, ...rest } = requestBody;
164
- const requestBodyObject = {
165
- ...rest,
166
- content: createContent(content, ctx, [...path, "content"])
167
- };
168
- if (id) {
169
- const ref = {
170
- $ref: `#/components/requestBodies/${id}`
171
- };
172
- ctx.registry.requestBodies.ids.set(id, requestBodyObject);
173
- ctx.registry.requestBodies.seen.set(requestBody, ref);
174
- return ref;
175
- }
176
- ctx.registry.requestBodies.seen.set(requestBody, requestBodyObject);
177
- return requestBodyObject;
178
- };
179
- const createHeader = (header, ctx, path) => {
180
- const seenHeader = ctx.registry.headers.seen.get(header);
181
- if (seenHeader) {
182
- return seenHeader;
183
- }
184
- const meta = v4.globalRegistry.get(header);
185
- const { id, ...rest } = (meta == null ? void 0 : meta.header) ?? {};
186
- const headerObject = rest;
187
- if (isRequired(header, ctx.io)) {
188
- headerObject.required = true;
189
- }
190
- if (!headerObject.description && (meta == null ? void 0 : meta.description)) {
191
- headerObject.description = meta.description;
192
- }
193
- const computedPath = path.join(" > ");
194
- headerObject.schema = ctx.registry.schemas.setSchema(
195
- computedPath,
196
- header,
197
- ctx.io
707
+ if (satisfiesVersion(openapi, "3.1.0")) {
708
+ return { exclusiveMinimum: minimum };
709
+ }
710
+ return { minimum, exclusiveMinimum: true };
711
+ };
712
+ const getZodNumberChecks = (zodNumber) => zodNumber._def.checks.reduce((acc, check) => {
713
+ acc[check.kind] = check;
714
+ return acc;
715
+ }, {});
716
+ const mapNumberType = (zodNumberChecks) => zodNumberChecks.int ? "integer" : "number";
717
+ const createOptionalSchema = (zodOptional, state) => createSchemaObject(zodOptional.unwrap(), state, ["optional"]);
718
+ const isOptionalObjectKey = (zodSchema) => isZodType(zodSchema, "ZodNever") || isZodType(zodSchema, "ZodUndefined") || isZodType(zodSchema, "ZodOptional") && isOptionalObjectKey(zodSchema.unwrap()) || isZodType(zodSchema, "ZodLiteral") && zodSchema._def.value === void 0;
719
+ const createObjectSchema = (zodObject, previous, state) => {
720
+ const extendedSchema = createExtendedSchema(
721
+ zodObject,
722
+ previous == null ? void 0 : previous.zodType,
723
+ state
198
724
  );
199
- if (id) {
200
- const ref = {
201
- $ref: `#/components/headers/${id}`
202
- };
203
- ctx.registry.headers.ids.set(id, headerObject);
204
- ctx.registry.headers.seen.set(header, ref);
205
- return ref;
725
+ if (extendedSchema) {
726
+ return extendedSchema;
206
727
  }
207
- ctx.registry.headers.seen.set(header, headerObject);
208
- return headerObject;
728
+ return createObjectSchemaFromShape(
729
+ zodObject.shape,
730
+ {
731
+ unknownKeys: zodObject._def.unknownKeys,
732
+ catchAll: zodObject._def.catchall
733
+ },
734
+ state
735
+ );
209
736
  };
210
- const createHeaders = (headers, ctx, path) => {
211
- if (!headers) {
737
+ const createExtendedSchema = (zodObject, baseZodObject, state) => {
738
+ var _a, _b, _c, _d, _e;
739
+ if (!baseZodObject) {
212
740
  return void 0;
213
741
  }
214
- if (isAnyZodType(headers)) {
215
- const zodObject = unwrapZodObject(headers, ctx.io, path);
216
- const headersObject = {};
217
- for (const [key, zodSchema] of Object.entries(zodObject._zod.def.shape)) {
218
- const header = createHeader(zodSchema, ctx, [...path, key]);
219
- headersObject[key] = header;
220
- }
221
- return headersObject;
742
+ const component = state.components.schemas.get(baseZodObject);
743
+ if (component ?? ((_b = (_a = baseZodObject._def.zodOpenApi) == null ? void 0 : _a.openapi) == null ? void 0 : _b.ref)) {
744
+ createSchemaObject(baseZodObject, state, ["extended schema"]);
222
745
  }
223
- return headers;
224
- };
225
- const isISpecificationExtension = (key) => key.startsWith("x-");
226
- const createResponse = (response, ctx, path) => {
227
- const seenResponse = ctx.registry.responses.seen.get(response);
228
- if (seenResponse) {
229
- return seenResponse;
746
+ const completeComponent = state.components.schemas.get(baseZodObject);
747
+ if (!completeComponent) {
748
+ return void 0;
230
749
  }
231
- const { content, headers, id, ...rest } = response;
232
- const responseObject = rest;
233
- if (id) {
234
- ctx.registry.responses.ids.set(id, responseObject);
750
+ const diffOpts = createDiffOpts(
751
+ {
752
+ unknownKeys: baseZodObject._def.unknownKeys,
753
+ catchAll: baseZodObject._def.catchall
754
+ },
755
+ {
756
+ unknownKeys: zodObject._def.unknownKeys,
757
+ catchAll: zodObject._def.catchall
758
+ }
759
+ );
760
+ if (!diffOpts) {
761
+ return void 0;
235
762
  }
236
- ctx.registry.responses.seen.set(response, responseObject);
237
- const maybeHeaders = createHeaders(headers, ctx, [...path, "headers"]);
238
- if (maybeHeaders) {
239
- responseObject.headers = maybeHeaders;
763
+ const diffShape = createShapeDiff(
764
+ baseZodObject._def.shape(),
765
+ zodObject._def.shape()
766
+ );
767
+ if (!diffShape) {
768
+ return void 0;
240
769
  }
241
- if (content) {
242
- responseObject.content = createContent(content, ctx, [...path, "content"]);
770
+ const extendedSchema = createObjectSchemaFromShape(
771
+ diffShape,
772
+ diffOpts,
773
+ state,
774
+ true
775
+ );
776
+ const schemaLength = Object.keys(extendedSchema.schema).length;
777
+ const effects = flattenEffects([
778
+ completeComponent.type === "complete" ? completeComponent.effects : [],
779
+ completeComponent.type === "in-progress" ? [
780
+ {
781
+ type: "component",
782
+ zodType: zodObject,
783
+ path: [...state.path]
784
+ }
785
+ ] : [],
786
+ extendedSchema.effects
787
+ ]);
788
+ if (schemaLength === 0) {
789
+ return {
790
+ type: "ref",
791
+ schema: {
792
+ $ref: createComponentSchemaRef(
793
+ completeComponent.ref,
794
+ (_c = state.documentOptions) == null ? void 0 : _c.componentRefPath
795
+ )
796
+ },
797
+ schemaObject: completeComponent.type === "complete" ? completeComponent.schemaObject : void 0,
798
+ zodType: zodObject,
799
+ effects
800
+ };
801
+ }
802
+ if (schemaLength === 1 && extendedSchema.schema.description) {
803
+ return createDescriptionMetadata(
804
+ {
805
+ schema: {
806
+ $ref: createComponentSchemaRef(
807
+ completeComponent.ref,
808
+ (_d = state.documentOptions) == null ? void 0 : _d.componentRefPath
809
+ )
810
+ },
811
+ schemaObject: completeComponent.type === "complete" ? completeComponent.schemaObject : void 0,
812
+ zodType: zodObject,
813
+ effects
814
+ },
815
+ extendedSchema.schema.description,
816
+ state
817
+ );
243
818
  }
244
- return responseObject;
819
+ return {
820
+ type: "schema",
821
+ schema: {
822
+ allOf: [
823
+ {
824
+ $ref: createComponentSchemaRef(
825
+ completeComponent.ref,
826
+ (_e = state.documentOptions) == null ? void 0 : _e.componentRefPath
827
+ )
828
+ }
829
+ ],
830
+ ...extendedSchema.schema
831
+ },
832
+ effects: flattenEffects([
833
+ completeComponent.type === "complete" ? completeComponent.effects : [],
834
+ completeComponent.type === "in-progress" ? [
835
+ {
836
+ type: "component",
837
+ zodType: zodObject,
838
+ path: [...state.path]
839
+ }
840
+ ] : [],
841
+ extendedSchema.effects
842
+ ])
843
+ };
245
844
  };
246
- const createResponses = (responses, ctx, path) => {
247
- if (!responses) {
845
+ const createDiffOpts = (baseOpts, extendedOpts) => {
846
+ if (baseOpts.unknownKeys === "strict" || !isZodType(baseOpts.catchAll, "ZodNever")) {
248
847
  return void 0;
249
848
  }
250
- const responsesObject = {};
251
- for (const [statusCode, response] of Object.entries(responses)) {
252
- if (!response) {
253
- continue;
254
- }
255
- if (isISpecificationExtension(statusCode)) {
256
- responsesObject[statusCode] = response;
849
+ return {
850
+ catchAll: extendedOpts.catchAll,
851
+ unknownKeys: extendedOpts.unknownKeys
852
+ };
853
+ };
854
+ const createShapeDiff = (baseObj, extendedObj) => {
855
+ const acc = {};
856
+ for (const [key, val] of Object.entries(extendedObj)) {
857
+ const baseValue = baseObj[key];
858
+ if (val === baseValue) {
257
859
  continue;
258
860
  }
259
- if ("$ref" in response) {
260
- responsesObject[statusCode] = response;
861
+ if (baseValue === void 0) {
862
+ acc[key] = extendedObj[key];
261
863
  continue;
262
864
  }
263
- const responseObject = createResponse(
264
- response,
265
- ctx,
266
- [...path, statusCode]
267
- );
268
- responsesObject[statusCode] = responseObject;
865
+ return null;
269
866
  }
270
- return responsesObject;
867
+ return acc;
271
868
  };
272
- const createOperation = (operationObject, registry, path) => {
273
- const {
274
- parameters,
275
- requestParams,
276
- requestBody,
277
- responses,
278
- callbacks,
279
- ...rest
280
- } = operationObject;
281
- const operation = rest;
282
- const maybeManualParameters = createManualParameters(
283
- parameters,
284
- {
285
- registry,
286
- io: "input"
287
- },
288
- [...path, "parameters"]
869
+ const mapAdditionalProperties = ({ unknownKeys, catchAll }, state) => {
870
+ if (!isZodType(catchAll, "ZodNever")) {
871
+ return createSchemaObject(catchAll, state, ["additional properties"]);
872
+ }
873
+ if (unknownKeys === "strict") {
874
+ return false;
875
+ }
876
+ if (unknownKeys === "passthrough") {
877
+ return true;
878
+ }
879
+ return void 0;
880
+ };
881
+ const createObjectSchemaFromShape = (shape, { unknownKeys, catchAll }, state, omitType) => {
882
+ const properties = mapProperties(shape, state);
883
+ const required = mapRequired(properties, shape, state);
884
+ const additionalProperties = mapAdditionalProperties(
885
+ { catchAll, unknownKeys },
886
+ state
289
887
  );
290
- const maybeRequestParams = createParameters(
291
- requestParams,
292
- {
293
- registry,
294
- io: "input"
888
+ return {
889
+ type: "schema",
890
+ schema: {
891
+ ...!omitType && { type: "object" },
892
+ ...properties && { properties: properties.properties },
893
+ ...(required == null ? void 0 : required.required.length) && { required: required.required },
894
+ ...additionalProperties !== void 0 && {
895
+ additionalProperties: typeof additionalProperties === "object" ? additionalProperties.schema : additionalProperties
896
+ }
295
897
  },
296
- [...path, "requestParams"]
297
- );
298
- if (maybeRequestParams || maybeManualParameters) {
299
- operation.parameters = [
300
- ...maybeRequestParams ?? [],
301
- ...maybeManualParameters ?? []
302
- ];
898
+ effects: flattenEffects([
899
+ ...(properties == null ? void 0 : properties.effects) ?? [],
900
+ typeof additionalProperties === "object" && (additionalProperties == null ? void 0 : additionalProperties.effects),
901
+ required == null ? void 0 : required.effects
902
+ ])
903
+ };
904
+ };
905
+ const mapRequired = (properties, shape, state) => {
906
+ if (!properties) {
907
+ return void 0;
303
908
  }
304
- const maybeRequestBody = createRequestBody(
305
- requestBody,
306
- {
307
- registry,
308
- io: "input"
909
+ const { required, effects } = Object.entries(properties.schemas).reduce(
910
+ (acc, [key, schemaOrRef]) => {
911
+ const zodSchema = shape[key];
912
+ if (!zodSchema) {
913
+ throw new Error("Property somehow doesn't exist in shape");
914
+ }
915
+ const result = zodSchema.safeParse(void 0);
916
+ if (!result.success) {
917
+ acc.required.push(key);
918
+ return acc;
919
+ }
920
+ if (result.data !== void 0) {
921
+ const baseEffect = {
922
+ zodType: zodSchema,
923
+ path: [...state.path, `property: ${key}`]
924
+ };
925
+ const effect = schemaOrRef.type === "ref" ? {
926
+ ...baseEffect,
927
+ type: "component"
928
+ } : {
929
+ ...baseEffect,
930
+ type: "schema",
931
+ creationType: state.type
932
+ };
933
+ acc.effects.push(effect);
934
+ if (state.type === "output") {
935
+ acc.required.push(key);
936
+ }
937
+ }
938
+ return acc;
309
939
  },
310
- [...path, "requestBody"]
940
+ {
941
+ required: [],
942
+ effects: []
943
+ }
311
944
  );
312
- if (maybeRequestBody) {
313
- operation.requestBody = maybeRequestBody;
945
+ return { required, effects };
946
+ };
947
+ const mapProperties = (shape, state) => {
948
+ const shapeEntries = Object.entries(shape);
949
+ if (!shapeEntries.length) {
950
+ return void 0;
314
951
  }
315
- const maybeResponses = createResponses(
316
- responses,
317
- {
318
- registry,
319
- io: "output"
952
+ return shapeEntries.reduce(
953
+ (acc, [key, zodSchema]) => {
954
+ if (isOptionalObjectKey(zodSchema)) {
955
+ return acc;
956
+ }
957
+ const schema = createSchemaObject(zodSchema, state, [`property: ${key}`]);
958
+ acc.schemas[key] = schema;
959
+ acc.properties[key] = schema.schema;
960
+ acc.effects.push(schema.effects);
961
+ return acc;
320
962
  },
321
- [...path, "responses"]
963
+ {
964
+ schemas: {},
965
+ properties: {},
966
+ effects: []
967
+ }
322
968
  );
323
- if (maybeResponses) {
324
- operation.responses = maybeResponses;
969
+ };
970
+ const createPipelineSchema = (zodPipeline, state) => {
971
+ var _a, _b, _c, _d, _e, _f;
972
+ if (((_b = (_a = zodPipeline._def.zodOpenApi) == null ? void 0 : _a.openapi) == null ? void 0 : _b.effectType) === "input" || ((_d = (_c = zodPipeline._def.zodOpenApi) == null ? void 0 : _c.openapi) == null ? void 0 : _d.effectType) === "same") {
973
+ return createSchemaObject(zodPipeline._def.in, state, ["pipeline input"]);
325
974
  }
326
- const maybeCallbacks = createCallbacks(callbacks, registry, [
327
- ...path,
328
- "callbacks"
975
+ if (((_f = (_e = zodPipeline._def.zodOpenApi) == null ? void 0 : _e.openapi) == null ? void 0 : _f.effectType) === "output") {
976
+ return createSchemaObject(zodPipeline._def.out, state, ["pipeline output"]);
977
+ }
978
+ if (state.type === "input") {
979
+ const schema2 = createSchemaObject(zodPipeline._def.in, state, [
980
+ "pipeline input"
981
+ ]);
982
+ return {
983
+ ...schema2,
984
+ effects: flattenEffects([
985
+ [
986
+ {
987
+ type: "schema",
988
+ creationType: "input",
989
+ path: [...state.path],
990
+ zodType: zodPipeline
991
+ }
992
+ ],
993
+ schema2.effects
994
+ ])
995
+ };
996
+ }
997
+ const schema = createSchemaObject(zodPipeline._def.out, state, [
998
+ "pipeline output"
999
+ ]);
1000
+ return {
1001
+ ...schema,
1002
+ effects: flattenEffects([
1003
+ [
1004
+ {
1005
+ type: "schema",
1006
+ creationType: "output",
1007
+ path: [...state.path],
1008
+ zodType: zodPipeline
1009
+ }
1010
+ ],
1011
+ schema.effects
1012
+ ])
1013
+ };
1014
+ };
1015
+ const createPreprocessSchema = (zodPreprocess, state) => createSchemaObject(zodPreprocess._def.schema, state, ["preprocess schema"]);
1016
+ const createReadonlySchema = (zodReadonly, state) => (
1017
+ // Readonly doesn't change OpenAPI schema
1018
+ createSchemaObject(zodReadonly._def.innerType, state, ["readonly"])
1019
+ );
1020
+ const createRecordSchema = (zodRecord, state) => {
1021
+ const additionalProperties = createSchemaObject(
1022
+ zodRecord.valueSchema,
1023
+ state,
1024
+ ["record value"]
1025
+ );
1026
+ const keySchema = createSchemaObject(zodRecord.keySchema, state, [
1027
+ "record key"
329
1028
  ]);
330
- if (maybeCallbacks) {
331
- operation.callbacks = maybeCallbacks;
1029
+ const maybeComponent = state.components.schemas.get(zodRecord.keySchema);
1030
+ const isComplete = maybeComponent && maybeComponent.type === "complete";
1031
+ const maybeSchema = isComplete && maybeComponent.schemaObject;
1032
+ const maybeEffects = isComplete && maybeComponent.effects || void 0;
1033
+ const renderedKeySchema = maybeSchema || keySchema.schema;
1034
+ if ("enum" in renderedKeySchema && renderedKeySchema.enum) {
1035
+ return {
1036
+ type: "schema",
1037
+ schema: {
1038
+ type: "object",
1039
+ properties: renderedKeySchema.enum.reduce((acc, key) => {
1040
+ acc[key] = additionalProperties.schema;
1041
+ return acc;
1042
+ }, {}),
1043
+ additionalProperties: false
1044
+ },
1045
+ effects: flattenEffects([
1046
+ keySchema.effects,
1047
+ additionalProperties.effects,
1048
+ maybeEffects
1049
+ ])
1050
+ };
332
1051
  }
333
- return operation;
1052
+ if (satisfiesVersion(state.components.openapi, "3.1.0") && "type" in renderedKeySchema && renderedKeySchema.type === "string" && Object.keys(renderedKeySchema).length > 1) {
1053
+ return {
1054
+ type: "schema",
1055
+ schema: {
1056
+ type: "object",
1057
+ propertyNames: keySchema.schema,
1058
+ additionalProperties: additionalProperties.schema
1059
+ },
1060
+ effects: flattenEffects([
1061
+ keySchema.effects,
1062
+ additionalProperties.effects
1063
+ ])
1064
+ };
1065
+ }
1066
+ return {
1067
+ type: "schema",
1068
+ schema: {
1069
+ type: "object",
1070
+ additionalProperties: additionalProperties.schema
1071
+ },
1072
+ effects: additionalProperties.effects
1073
+ };
334
1074
  };
335
- const createPathItem = (pathItem, registry, path) => {
336
- const pathItemObject = {};
337
- const { id, ...rest } = pathItem;
338
- for (const [key, value] of Object.entries(rest)) {
339
- if (key === "get" || key === "put" || key === "post" || key === "delete" || key === "options" || key === "head" || key === "patch" || key === "trace") {
340
- pathItemObject[key] = createOperation(
341
- value,
342
- registry,
343
- [...path, key]
344
- );
345
- continue;
346
- }
347
- if (key === "parameters") {
348
- pathItemObject[key] = createManualParameters(
349
- value,
1075
+ const createRefineSchema = (zodRefine, state) => createSchemaObject(zodRefine._def.schema, state, ["refine schema"]);
1076
+ const createSetSchema = (zodSet, state) => {
1077
+ var _a, _b;
1078
+ const schema = zodSet._def.valueType;
1079
+ const minItems = (_a = zodSet._def.minSize) == null ? void 0 : _a.value;
1080
+ const maxItems = (_b = zodSet._def.maxSize) == null ? void 0 : _b.value;
1081
+ const itemSchema = createSchemaObject(schema, state, ["set items"]);
1082
+ return {
1083
+ type: "schema",
1084
+ schema: {
1085
+ type: "array",
1086
+ items: itemSchema.schema,
1087
+ uniqueItems: true,
1088
+ ...minItems !== void 0 && { minItems },
1089
+ ...maxItems !== void 0 && { maxItems }
1090
+ },
1091
+ effects: itemSchema.effects
1092
+ };
1093
+ };
1094
+ const createStringSchema = (zodString, state) => {
1095
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1096
+ const zodStringChecks = getZodStringChecks(zodString);
1097
+ const format = mapStringFormat(zodStringChecks);
1098
+ const patterns = mapPatterns(zodStringChecks);
1099
+ const minLength = ((_b = (_a = zodStringChecks.length) == null ? void 0 : _a[0]) == null ? void 0 : _b.value) ?? ((_d = (_c = zodStringChecks.min) == null ? void 0 : _c[0]) == null ? void 0 : _d.value);
1100
+ const maxLength = ((_f = (_e = zodStringChecks.length) == null ? void 0 : _e[0]) == null ? void 0 : _f.value) ?? ((_h = (_g = zodStringChecks.max) == null ? void 0 : _g[0]) == null ? void 0 : _h.value);
1101
+ const contentEncoding = satisfiesVersion(state.components.openapi, "3.1.0") ? mapContentEncoding(zodStringChecks) : void 0;
1102
+ if (patterns.length <= 1) {
1103
+ return {
1104
+ type: "schema",
1105
+ schema: {
1106
+ type: "string",
1107
+ ...format && { format },
1108
+ ...patterns[0] && { pattern: patterns[0] },
1109
+ ...minLength !== void 0 && { minLength },
1110
+ ...maxLength !== void 0 && { maxLength },
1111
+ ...contentEncoding && { contentEncoding }
1112
+ }
1113
+ };
1114
+ }
1115
+ return {
1116
+ type: "schema",
1117
+ schema: {
1118
+ allOf: [
350
1119
  {
351
- registry,
352
- io: "input"
1120
+ type: "string",
1121
+ ...format && { format },
1122
+ ...patterns[0] && { pattern: patterns[0] },
1123
+ ...minLength !== void 0 && { minLength },
1124
+ ...maxLength !== void 0 && { maxLength },
1125
+ ...contentEncoding && { contentEncoding }
353
1126
  },
354
- [...path, key]
355
- );
356
- continue;
1127
+ ...patterns.slice(1).map(
1128
+ (pattern) => ({
1129
+ type: "string",
1130
+ pattern
1131
+ })
1132
+ )
1133
+ ]
357
1134
  }
358
- pathItemObject[key] = value;
359
- }
360
- if (id) {
361
- const ref = {
362
- $ref: `#/components/pathItems/${id}`
363
- };
364
- registry.pathItems.ids.set(id, pathItemObject);
365
- registry.pathItems.seen.set(pathItem, ref);
366
- return ref;
1135
+ };
1136
+ };
1137
+ const getZodStringChecks = (zodString) => zodString._def.checks.reduce(
1138
+ (acc, check) => {
1139
+ const mapping = acc[check.kind];
1140
+ if (mapping) {
1141
+ mapping.push(check);
1142
+ return acc;
1143
+ }
1144
+ acc[check.kind] = [check];
1145
+ return acc;
1146
+ },
1147
+ {}
1148
+ );
1149
+ const mapPatterns = (zodStringChecks) => {
1150
+ const startsWith = mapStartsWith(zodStringChecks);
1151
+ const endsWith = mapEndsWith(zodStringChecks);
1152
+ const regex = mapRegex(zodStringChecks);
1153
+ const includes = mapIncludes(zodStringChecks);
1154
+ const patterns = [
1155
+ ...regex ?? [],
1156
+ ...startsWith ? [startsWith] : [],
1157
+ ...endsWith ? [endsWith] : [],
1158
+ ...includes ?? []
1159
+ ];
1160
+ return patterns;
1161
+ };
1162
+ const mapStartsWith = (zodStringChecks) => {
1163
+ var _a, _b;
1164
+ if ((_b = (_a = zodStringChecks.startsWith) == null ? void 0 : _a[0]) == null ? void 0 : _b.value) {
1165
+ return `^${zodStringChecks.startsWith[0].value}`;
367
1166
  }
368
- return pathItemObject;
1167
+ return void 0;
369
1168
  };
370
- const createPaths = (paths, registry, path) => {
371
- if (!paths) {
372
- return void 0;
1169
+ const mapEndsWith = (zodStringChecks) => {
1170
+ var _a, _b;
1171
+ if ((_b = (_a = zodStringChecks.endsWith) == null ? void 0 : _a[0]) == null ? void 0 : _b.value) {
1172
+ return `${zodStringChecks.endsWith[0].value}$`;
373
1173
  }
374
- const pathsObject = {};
375
- for (const [singlePath, pathItemObject] of Object.entries(paths)) {
376
- if (isISpecificationExtension(singlePath)) {
377
- pathsObject[singlePath] = pathItemObject;
378
- continue;
1174
+ return void 0;
1175
+ };
1176
+ const mapRegex = (zodStringChecks) => {
1177
+ var _a;
1178
+ return (_a = zodStringChecks.regex) == null ? void 0 : _a.map((regexCheck) => regexCheck.regex.source);
1179
+ };
1180
+ const mapIncludes = (zodStringChecks) => {
1181
+ var _a;
1182
+ return (_a = zodStringChecks.includes) == null ? void 0 : _a.map((includeCheck) => {
1183
+ if (includeCheck.position === 0) {
1184
+ return `^${includeCheck.value}`;
379
1185
  }
380
- pathsObject[singlePath] = createPathItem(pathItemObject, registry, [
381
- ...path,
382
- singlePath
383
- ]);
1186
+ if (includeCheck.position) {
1187
+ return `^.{${includeCheck.position}}${includeCheck.value}`;
1188
+ }
1189
+ return includeCheck.value;
1190
+ });
1191
+ };
1192
+ const mapStringFormat = (zodStringChecks) => {
1193
+ var _a, _b, _c, _d;
1194
+ if (zodStringChecks.uuid) {
1195
+ return "uuid";
1196
+ }
1197
+ if (zodStringChecks.datetime) {
1198
+ return "date-time";
1199
+ }
1200
+ if (zodStringChecks.date) {
1201
+ return "date";
1202
+ }
1203
+ if (zodStringChecks.time) {
1204
+ return "time";
1205
+ }
1206
+ if (zodStringChecks.duration) {
1207
+ return "duration";
384
1208
  }
385
- return pathsObject;
1209
+ if (zodStringChecks.email) {
1210
+ return "email";
1211
+ }
1212
+ if (zodStringChecks.url) {
1213
+ return "uri";
1214
+ }
1215
+ if ((_a = zodStringChecks.ip) == null ? void 0 : _a.every((ip) => ip.version === "v4")) {
1216
+ return "ipv4";
1217
+ }
1218
+ if ((_b = zodStringChecks.ip) == null ? void 0 : _b.every((ip) => ip.version === "v6")) {
1219
+ return "ipv6";
1220
+ }
1221
+ if ((_c = zodStringChecks.cidr) == null ? void 0 : _c.every((ip) => ip.version === "v4")) {
1222
+ return "ipv4";
1223
+ }
1224
+ if ((_d = zodStringChecks.cidr) == null ? void 0 : _d.every((ip) => ip.version === "v6")) {
1225
+ return "ipv6";
1226
+ }
1227
+ return void 0;
386
1228
  };
387
- const createCallback = (callbackObject, registry, path) => {
388
- const seenCallback = registry.callbacks.seen.get(callbackObject);
389
- if (seenCallback) {
390
- return seenCallback;
1229
+ const mapContentEncoding = (zodStringChecks) => {
1230
+ if (zodStringChecks.base64) {
1231
+ return "base64";
391
1232
  }
392
- const { id, ...rest } = callbackObject;
393
- const callback = {};
394
- for (const [name, pathItem] of Object.entries(rest)) {
395
- if (isISpecificationExtension(name)) {
396
- callback[name] = pathItem;
397
- continue;
1233
+ return void 0;
1234
+ };
1235
+ const createTupleSchema = (zodTuple, state) => {
1236
+ const items = zodTuple.items;
1237
+ const rest = zodTuple._def.rest;
1238
+ const prefixItems = mapPrefixItems(items, state);
1239
+ if (satisfiesVersion(state.components.openapi, "3.1.0")) {
1240
+ if (!rest) {
1241
+ return {
1242
+ type: "schema",
1243
+ schema: {
1244
+ type: "array",
1245
+ maxItems: items.length,
1246
+ minItems: items.length,
1247
+ ...prefixItems && {
1248
+ prefixItems: prefixItems.schemas.map((item) => item.schema)
1249
+ }
1250
+ },
1251
+ effects: prefixItems == null ? void 0 : prefixItems.effects
1252
+ };
398
1253
  }
399
- callback[name] = createPathItem(
400
- pathItem,
401
- registry,
402
- [...path, name]
403
- );
1254
+ const itemSchema = createSchemaObject(rest, state, ["tuple items"]);
1255
+ return {
1256
+ type: "schema",
1257
+ schema: {
1258
+ type: "array",
1259
+ items: itemSchema.schema,
1260
+ ...prefixItems && {
1261
+ prefixItems: prefixItems.schemas.map((item) => item.schema)
1262
+ }
1263
+ },
1264
+ effects: flattenEffects([prefixItems == null ? void 0 : prefixItems.effects, itemSchema.effects])
1265
+ };
404
1266
  }
405
- if (id) {
406
- const ref = {
407
- $ref: `#/components/callbacks/${id}`
1267
+ if (!rest) {
1268
+ return {
1269
+ type: "schema",
1270
+ schema: {
1271
+ type: "array",
1272
+ maxItems: items.length,
1273
+ minItems: items.length,
1274
+ ...prefixItems && {
1275
+ items: { oneOf: prefixItems.schemas.map((item) => item.schema) }
1276
+ }
1277
+ },
1278
+ effects: prefixItems == null ? void 0 : prefixItems.effects
408
1279
  };
409
- registry.callbacks.ids.set(id, callback);
410
- registry.callbacks.seen.set(callbackObject, ref);
411
- return ref;
412
1280
  }
413
- registry.callbacks.seen.set(callbackObject, callback);
414
- return callback;
1281
+ if (prefixItems) {
1282
+ const restSchema = createSchemaObject(rest, state, ["tuple items"]);
1283
+ return {
1284
+ type: "schema",
1285
+ schema: {
1286
+ type: "array",
1287
+ items: {
1288
+ oneOf: [
1289
+ ...prefixItems.schemas.map((item) => item.schema),
1290
+ restSchema.schema
1291
+ ]
1292
+ }
1293
+ },
1294
+ effects: flattenEffects([restSchema.effects, prefixItems.effects])
1295
+ };
1296
+ }
1297
+ return {
1298
+ type: "schema",
1299
+ schema: {
1300
+ type: "array"
1301
+ }
1302
+ };
415
1303
  };
416
- const createCallbacks = (callbacks, registry, path) => {
417
- if (!callbacks) {
418
- return void 0;
1304
+ const mapPrefixItems = (items, state) => {
1305
+ if (items.length) {
1306
+ const schemas = items.map(
1307
+ (item, index) => createSchemaObject(item, state, [`tuple item ${index}`])
1308
+ );
1309
+ return {
1310
+ effects: flattenEffects(schemas.map((s) => s.effects)),
1311
+ schemas
1312
+ };
419
1313
  }
420
- const callbacksObject = {};
421
- for (const [name, value] of Object.entries(callbacks)) {
422
- if (isISpecificationExtension(name)) {
423
- callbacksObject[name] = value;
424
- continue;
1314
+ return void 0;
1315
+ };
1316
+ const createUnionSchema = (zodUnion, state) => {
1317
+ var _a, _b, _c;
1318
+ const schemas = zodUnion.options.reduce((acc, option, index) => {
1319
+ if (!isOptionalObjectKey(option)) {
1320
+ acc.push(createSchemaObject(option, state, [`union option ${index}`]));
425
1321
  }
426
- callbacksObject[name] = createCallback(
427
- value,
428
- registry,
429
- [...path, name]
1322
+ return acc;
1323
+ }, []);
1324
+ if (((_b = (_a = zodUnion._def.zodOpenApi) == null ? void 0 : _a.openapi) == null ? void 0 : _b.unionOneOf) ?? ((_c = state.documentOptions) == null ? void 0 : _c.unionOneOf)) {
1325
+ return {
1326
+ type: "schema",
1327
+ schema: {
1328
+ oneOf: schemas.map((s) => s.schema)
1329
+ },
1330
+ effects: flattenEffects(schemas.map((s) => s.effects))
1331
+ };
1332
+ }
1333
+ return {
1334
+ type: "schema",
1335
+ schema: {
1336
+ anyOf: schemas.map((s) => s.schema)
1337
+ },
1338
+ effects: flattenEffects(schemas.map((s) => s.effects))
1339
+ };
1340
+ };
1341
+ const createUnknownSchema = (_zodUnknown) => ({
1342
+ type: "schema",
1343
+ schema: {}
1344
+ });
1345
+ const createSchemaSwitch = (zodSchema, previous, state) => {
1346
+ var _a, _b;
1347
+ if ((_b = (_a = zodSchema._def.zodOpenApi) == null ? void 0 : _a.openapi) == null ? void 0 : _b.type) {
1348
+ return createManualTypeSchema(zodSchema, state);
1349
+ }
1350
+ if (isZodType(zodSchema, "ZodString")) {
1351
+ return createStringSchema(zodSchema, state);
1352
+ }
1353
+ if (isZodType(zodSchema, "ZodNumber")) {
1354
+ return createNumberSchema(zodSchema, state);
1355
+ }
1356
+ if (isZodType(zodSchema, "ZodBoolean")) {
1357
+ return createBooleanSchema();
1358
+ }
1359
+ if (isZodType(zodSchema, "ZodEnum")) {
1360
+ return createEnumSchema(zodSchema);
1361
+ }
1362
+ if (isZodType(zodSchema, "ZodLiteral")) {
1363
+ return createLiteralSchema(zodSchema, state);
1364
+ }
1365
+ if (isZodType(zodSchema, "ZodNativeEnum")) {
1366
+ return createNativeEnumSchema(zodSchema, state);
1367
+ }
1368
+ if (isZodType(zodSchema, "ZodArray")) {
1369
+ return createArraySchema(zodSchema, state);
1370
+ }
1371
+ if (isZodType(zodSchema, "ZodObject")) {
1372
+ return createObjectSchema(zodSchema, previous, state);
1373
+ }
1374
+ if (isZodType(zodSchema, "ZodUnion")) {
1375
+ return createUnionSchema(zodSchema, state);
1376
+ }
1377
+ if (isZodType(zodSchema, "ZodDiscriminatedUnion")) {
1378
+ return createDiscriminatedUnionSchema(zodSchema, state);
1379
+ }
1380
+ if (isZodType(zodSchema, "ZodNull")) {
1381
+ return createNullSchema();
1382
+ }
1383
+ if (isZodType(zodSchema, "ZodNullable")) {
1384
+ return createNullableSchema(zodSchema, state);
1385
+ }
1386
+ if (isZodType(zodSchema, "ZodOptional")) {
1387
+ return createOptionalSchema(zodSchema, state);
1388
+ }
1389
+ if (isZodType(zodSchema, "ZodReadonly")) {
1390
+ return createReadonlySchema(zodSchema, state);
1391
+ }
1392
+ if (isZodType(zodSchema, "ZodDefault")) {
1393
+ return createDefaultSchema(zodSchema, state, previous);
1394
+ }
1395
+ if (isZodType(zodSchema, "ZodRecord")) {
1396
+ return createRecordSchema(zodSchema, state);
1397
+ }
1398
+ if (isZodType(zodSchema, "ZodTuple")) {
1399
+ return createTupleSchema(zodSchema, state);
1400
+ }
1401
+ if (isZodType(zodSchema, "ZodDate")) {
1402
+ return createDateSchema(zodSchema, state);
1403
+ }
1404
+ if (isZodType(zodSchema, "ZodPipeline")) {
1405
+ return createPipelineSchema(zodSchema, state);
1406
+ }
1407
+ if (isZodType(zodSchema, "ZodEffects") && zodSchema._def.effect.type === "transform") {
1408
+ return createTransformSchema(zodSchema, state);
1409
+ }
1410
+ if (isZodType(zodSchema, "ZodEffects") && zodSchema._def.effect.type === "preprocess") {
1411
+ return createPreprocessSchema(zodSchema, state);
1412
+ }
1413
+ if (isZodType(zodSchema, "ZodEffects") && zodSchema._def.effect.type === "refinement") {
1414
+ return createRefineSchema(zodSchema, state);
1415
+ }
1416
+ if (isZodType(zodSchema, "ZodNativeEnum")) {
1417
+ return createNativeEnumSchema(zodSchema, state);
1418
+ }
1419
+ if (isZodType(zodSchema, "ZodIntersection")) {
1420
+ return createIntersectionSchema(zodSchema, state);
1421
+ }
1422
+ if (isZodType(zodSchema, "ZodCatch")) {
1423
+ return createCatchSchema(zodSchema, state, previous);
1424
+ }
1425
+ if (isZodType(zodSchema, "ZodUnknown") || isZodType(zodSchema, "ZodAny")) {
1426
+ return createUnknownSchema();
1427
+ }
1428
+ if (isZodType(zodSchema, "ZodLazy")) {
1429
+ return createLazySchema(zodSchema, state);
1430
+ }
1431
+ if (isZodType(zodSchema, "ZodBranded")) {
1432
+ return createBrandedSchema(zodSchema, state);
1433
+ }
1434
+ if (isZodType(zodSchema, "ZodSet")) {
1435
+ return createSetSchema(zodSchema, state);
1436
+ }
1437
+ if (isZodType(zodSchema, "ZodBigInt")) {
1438
+ return createBigIntSchema();
1439
+ }
1440
+ return createManualTypeSchema(zodSchema, state);
1441
+ };
1442
+ const createNewSchema = ({
1443
+ zodSchema,
1444
+ previous,
1445
+ state
1446
+ }) => {
1447
+ var _a;
1448
+ if (state.visited.has(zodSchema)) {
1449
+ throw new Error(
1450
+ `The schema at ${state.path.join(
1451
+ " > "
1452
+ )} needs to be registered because it's circularly referenced`
430
1453
  );
431
1454
  }
432
- return callbacksObject;
433
- };
434
- const override = (ctx) => {
435
- const def = ctx.zodSchema._zod.def;
436
- switch (def.type) {
437
- case "bigint": {
438
- ctx.jsonSchema.type = "integer";
439
- ctx.jsonSchema.format = "int64";
440
- break;
441
- }
442
- case "union": {
443
- if ("discriminator" in def && typeof def.discriminator === "string") {
444
- ctx.jsonSchema.oneOf = ctx.jsonSchema.anyOf;
445
- delete ctx.jsonSchema.anyOf;
446
- ctx.jsonSchema.type = "object";
447
- ctx.jsonSchema.discriminator = {
448
- propertyName: def.discriminator
449
- };
450
- const mapping = {};
451
- for (const [index, obj] of Object.entries(
452
- ctx.jsonSchema.oneOf
453
- )) {
454
- const ref = obj.$ref;
455
- if (!ref) {
456
- return;
457
- }
458
- const discriminatorValues = def.options[Number(index)]._zod.propValues[def.discriminator];
459
- if (!(discriminatorValues == null ? void 0 : discriminatorValues.size)) {
460
- return;
461
- }
462
- for (const value of [...discriminatorValues ?? []]) {
463
- if (typeof value !== "string") {
464
- return;
465
- }
466
- mapping[value] = ref;
467
- }
468
- }
469
- ctx.jsonSchema.discriminator.mapping = mapping;
1455
+ state.visited.add(zodSchema);
1456
+ const {
1457
+ effectType,
1458
+ param,
1459
+ header,
1460
+ ref,
1461
+ refType,
1462
+ unionOneOf,
1463
+ ...additionalMetadata
1464
+ } = ((_a = zodSchema._def.zodOpenApi) == null ? void 0 : _a.openapi) ?? {};
1465
+ const schema = createSchemaSwitch(zodSchema, previous, state);
1466
+ const schemaWithMetadata = enhanceWithMetadata(
1467
+ schema,
1468
+ additionalMetadata,
1469
+ state,
1470
+ previous
1471
+ );
1472
+ state.visited.delete(zodSchema);
1473
+ return schemaWithMetadata;
1474
+ };
1475
+ const createNewRef = ({
1476
+ previous,
1477
+ ref,
1478
+ zodSchema,
1479
+ state
1480
+ }) => {
1481
+ var _a;
1482
+ state.components.schemas.set(zodSchema, {
1483
+ type: "in-progress",
1484
+ ref
1485
+ });
1486
+ const newSchema = createNewSchema({
1487
+ zodSchema,
1488
+ previous,
1489
+ state: {
1490
+ ...state,
1491
+ visited: /* @__PURE__ */ new Set()
1492
+ }
1493
+ });
1494
+ state.components.schemas.set(zodSchema, {
1495
+ type: "complete",
1496
+ ref,
1497
+ schemaObject: newSchema.schema,
1498
+ effects: newSchema.effects
1499
+ });
1500
+ return {
1501
+ type: "ref",
1502
+ schema: {
1503
+ $ref: createComponentSchemaRef(
1504
+ ref,
1505
+ (_a = state.documentOptions) == null ? void 0 : _a.componentRefPath
1506
+ )
1507
+ },
1508
+ schemaObject: newSchema.schema,
1509
+ effects: newSchema.effects ? [
1510
+ {
1511
+ type: "component",
1512
+ zodType: zodSchema,
1513
+ path: [...state.path]
470
1514
  }
471
- const meta = ctx.zodSchema.meta();
472
- if (typeof (meta == null ? void 0 : meta.unionOneOf) === "boolean") {
473
- if (meta.unionOneOf) {
474
- ctx.jsonSchema.oneOf = ctx.jsonSchema.anyOf;
475
- delete ctx.jsonSchema.anyOf;
1515
+ ] : void 0,
1516
+ zodType: zodSchema
1517
+ };
1518
+ };
1519
+ const createExistingRef = (zodSchema, component, state) => {
1520
+ var _a, _b;
1521
+ if (component && component.type === "complete") {
1522
+ return {
1523
+ type: "ref",
1524
+ schema: {
1525
+ $ref: createComponentSchemaRef(
1526
+ component.ref,
1527
+ (_a = state.documentOptions) == null ? void 0 : _a.componentRefPath
1528
+ )
1529
+ },
1530
+ schemaObject: component.schemaObject,
1531
+ effects: component.effects ? [
1532
+ {
1533
+ type: "component",
1534
+ zodType: zodSchema,
1535
+ path: [...state.path]
476
1536
  }
477
- delete ctx.jsonSchema.unionOneOf;
478
- }
479
- break;
480
- }
481
- case "date": {
482
- ctx.jsonSchema.type = "string";
483
- break;
1537
+ ] : void 0,
1538
+ zodType: zodSchema
1539
+ };
1540
+ }
1541
+ if (component && component.type === "in-progress") {
1542
+ return {
1543
+ type: "ref",
1544
+ schema: {
1545
+ $ref: createComponentSchemaRef(
1546
+ component.ref,
1547
+ (_b = state.documentOptions) == null ? void 0 : _b.componentRefPath
1548
+ )
1549
+ },
1550
+ schemaObject: void 0,
1551
+ effects: [
1552
+ {
1553
+ type: "component",
1554
+ zodType: zodSchema,
1555
+ path: [...state.path]
1556
+ }
1557
+ ],
1558
+ zodType: zodSchema
1559
+ };
1560
+ }
1561
+ return;
1562
+ };
1563
+ const createSchemaOrRef = (zodSchema, state, onlyRef) => {
1564
+ var _a, _b, _c, _d;
1565
+ const component = state.components.schemas.get(zodSchema);
1566
+ const existingRef = createExistingRef(zodSchema, component, state);
1567
+ if (existingRef) {
1568
+ return existingRef;
1569
+ }
1570
+ const previous = ((_a = zodSchema._def.zodOpenApi) == null ? void 0 : _a[extendZodSymbols.previousSymbol]) ? createSchemaOrRef(
1571
+ zodSchema._def.zodOpenApi[extendZodSymbols.previousSymbol],
1572
+ state,
1573
+ true
1574
+ ) : void 0;
1575
+ const current = ((_b = zodSchema._def.zodOpenApi) == null ? void 0 : _b[extendZodSymbols.currentSymbol]) && zodSchema._def.zodOpenApi[extendZodSymbols.currentSymbol] !== zodSchema ? createSchemaOrRef(
1576
+ zodSchema._def.zodOpenApi[extendZodSymbols.currentSymbol],
1577
+ state,
1578
+ true
1579
+ ) : void 0;
1580
+ const ref = ((_d = (_c = zodSchema._def.zodOpenApi) == null ? void 0 : _c.openapi) == null ? void 0 : _d.ref) ?? (component == null ? void 0 : component.ref);
1581
+ if (ref) {
1582
+ return current ? createNewSchema({ zodSchema, previous: current, state }) : createNewRef({ ref, zodSchema, previous, state });
1583
+ }
1584
+ if (onlyRef) {
1585
+ return previous ?? current;
1586
+ }
1587
+ return createNewSchema({ zodSchema, previous: previous ?? current, state });
1588
+ };
1589
+ const createSchemaObject = (zodSchema, state, subpath) => {
1590
+ state.path.push(...subpath);
1591
+ const schema = createSchemaOrRef(zodSchema, state);
1592
+ if (!schema) {
1593
+ throw new Error("Schema does not exist");
1594
+ }
1595
+ state.path.pop();
1596
+ return schema;
1597
+ };
1598
+ const createSchema = (zodSchema, state, subpath) => {
1599
+ const schema = createSchemaObject(zodSchema, state, subpath);
1600
+ if (schema.effects) {
1601
+ verifyEffects(schema.effects, state);
1602
+ }
1603
+ return schema.schema;
1604
+ };
1605
+ const createMediaTypeSchema = (schemaObject, components, type, subpath, documentOptions) => {
1606
+ if (!schemaObject) {
1607
+ return void 0;
1608
+ }
1609
+ if (!isAnyZodType(schemaObject)) {
1610
+ return schemaObject;
1611
+ }
1612
+ return createSchema(
1613
+ schemaObject,
1614
+ {
1615
+ components,
1616
+ type,
1617
+ path: [],
1618
+ visited: /* @__PURE__ */ new Set(),
1619
+ documentOptions
1620
+ },
1621
+ subpath
1622
+ );
1623
+ };
1624
+ const createMediaTypeObject = (mediaTypeObject, components, type, subpath, documentOptions) => {
1625
+ if (!mediaTypeObject) {
1626
+ return void 0;
1627
+ }
1628
+ return {
1629
+ ...mediaTypeObject,
1630
+ schema: createMediaTypeSchema(
1631
+ mediaTypeObject.schema,
1632
+ components,
1633
+ type,
1634
+ [...subpath, "schema"],
1635
+ documentOptions
1636
+ )
1637
+ };
1638
+ };
1639
+ const createContent = (contentObject, components, type, subpath, documentOptions) => Object.entries(contentObject).reduce(
1640
+ (acc, [mediaType, zodOpenApiMediaTypeObject]) => {
1641
+ const mediaTypeObject = createMediaTypeObject(
1642
+ zodOpenApiMediaTypeObject,
1643
+ components,
1644
+ type,
1645
+ [...subpath, mediaType],
1646
+ documentOptions
1647
+ );
1648
+ if (mediaTypeObject) {
1649
+ acc[mediaType] = mediaTypeObject;
484
1650
  }
485
- case "literal": {
486
- if (def.values.includes(void 0)) {
487
- break;
488
- }
489
- break;
1651
+ return acc;
1652
+ },
1653
+ {}
1654
+ );
1655
+ const createComponentParamRef = (ref) => `#/components/parameters/${ref}`;
1656
+ const createBaseParameter = (schema, components, subpath, documentOptions) => {
1657
+ var _a, _b, _c, _d;
1658
+ const { ref, ...rest } = ((_b = (_a = schema._def.zodOpenApi) == null ? void 0 : _a.openapi) == null ? void 0 : _b.param) ?? {};
1659
+ const state = {
1660
+ components,
1661
+ type: "input",
1662
+ path: [],
1663
+ visited: /* @__PURE__ */ new Set(),
1664
+ documentOptions
1665
+ };
1666
+ const schemaObject = createSchema(schema, state, [...subpath, "schema"]);
1667
+ const required = !schema.isOptional();
1668
+ const description = ((_d = (_c = schema._def.zodOpenApi) == null ? void 0 : _c.openapi) == null ? void 0 : _d.description) ?? schema._def.description;
1669
+ return {
1670
+ ...description && { description },
1671
+ ...rest,
1672
+ ...schema && { schema: schemaObject },
1673
+ ...required && { required }
1674
+ };
1675
+ };
1676
+ const createParamOrRef = (zodSchema, components, subpath, type, name, documentOptions) => {
1677
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
1678
+ const component = components.parameters.get(zodSchema);
1679
+ const paramType = ((_c = (_b = (_a = zodSchema._def.zodOpenApi) == null ? void 0 : _a.openapi) == null ? void 0 : _b.param) == null ? void 0 : _c.in) ?? (component == null ? void 0 : component.in) ?? type;
1680
+ const paramName = ((_f = (_e = (_d = zodSchema._def.zodOpenApi) == null ? void 0 : _d.openapi) == null ? void 0 : _e.param) == null ? void 0 : _f.name) ?? (component == null ? void 0 : component.name) ?? name;
1681
+ if (!paramType) {
1682
+ throw new Error("Parameter type missing");
1683
+ }
1684
+ if (!paramName) {
1685
+ throw new Error("Parameter name missing");
1686
+ }
1687
+ if (component && component.type === "complete") {
1688
+ if (!("$ref" in component.paramObject) && (component.in !== paramType || component.name !== paramName)) {
1689
+ throw new Error(`parameterRef "${component.ref}" is already registered`);
490
1690
  }
1691
+ return {
1692
+ $ref: createComponentParamRef(component.ref)
1693
+ };
1694
+ }
1695
+ const baseParamOrRef = createBaseParameter(
1696
+ zodSchema,
1697
+ components,
1698
+ subpath,
1699
+ documentOptions
1700
+ );
1701
+ if ("$ref" in baseParamOrRef) {
1702
+ throw new Error("Unexpected Error: received a reference object");
1703
+ }
1704
+ const ref = ((_i = (_h = (_g = zodSchema == null ? void 0 : zodSchema._def.zodOpenApi) == null ? void 0 : _g.openapi) == null ? void 0 : _h.param) == null ? void 0 : _i.ref) ?? (component == null ? void 0 : component.ref);
1705
+ const paramObject = {
1706
+ in: paramType,
1707
+ name: paramName,
1708
+ ...baseParamOrRef
1709
+ };
1710
+ if (ref) {
1711
+ components.parameters.set(zodSchema, {
1712
+ type: "complete",
1713
+ paramObject,
1714
+ ref,
1715
+ in: paramType,
1716
+ name: paramName
1717
+ });
1718
+ return {
1719
+ $ref: createComponentParamRef(ref)
1720
+ };
1721
+ }
1722
+ return paramObject;
1723
+ };
1724
+ const createParameters = (type, zodObjectType, components, subpath, documentOptions) => {
1725
+ if (!zodObjectType) {
1726
+ return [];
1727
+ }
1728
+ const zodObject = getZodObject(zodObjectType, "input").shape;
1729
+ return Object.entries(zodObject).map(
1730
+ ([key, zodSchema]) => createParamOrRef(
1731
+ zodSchema,
1732
+ components,
1733
+ [...subpath, key],
1734
+ type,
1735
+ key,
1736
+ documentOptions
1737
+ )
1738
+ );
1739
+ };
1740
+ const createRequestParams = (requestParams, components, subpath, documentOptions) => {
1741
+ if (!requestParams) {
1742
+ return [];
1743
+ }
1744
+ const pathParams = createParameters(
1745
+ "path",
1746
+ requestParams.path,
1747
+ components,
1748
+ [...subpath, "path"],
1749
+ documentOptions
1750
+ );
1751
+ const queryParams = createParameters(
1752
+ "query",
1753
+ requestParams.query,
1754
+ components,
1755
+ [...subpath, "query"],
1756
+ documentOptions
1757
+ );
1758
+ const cookieParams = createParameters(
1759
+ "cookie",
1760
+ requestParams.cookie,
1761
+ components,
1762
+ [...subpath, "cookie"],
1763
+ documentOptions
1764
+ );
1765
+ const headerParams = createParameters(
1766
+ "header",
1767
+ requestParams.header,
1768
+ components,
1769
+ [...subpath, "header"],
1770
+ documentOptions
1771
+ );
1772
+ return [...pathParams, ...queryParams, ...cookieParams, ...headerParams];
1773
+ };
1774
+ const createManualParameters = (parameters, components, subpath, documentOptions) => (parameters == null ? void 0 : parameters.map((param, index) => {
1775
+ if (isAnyZodType(param)) {
1776
+ return createParamOrRef(
1777
+ param,
1778
+ components,
1779
+ [...subpath, `param index ${index}`],
1780
+ void 0,
1781
+ void 0,
1782
+ documentOptions
1783
+ );
491
1784
  }
1785
+ return param;
1786
+ })) ?? [];
1787
+ const createParametersObject = (parameters, requestParams, components, subpath, documentOptions) => {
1788
+ const manualParameters = createManualParameters(
1789
+ parameters,
1790
+ components,
1791
+ subpath,
1792
+ documentOptions
1793
+ );
1794
+ const createdParams = createRequestParams(
1795
+ requestParams,
1796
+ components,
1797
+ subpath,
1798
+ documentOptions
1799
+ );
1800
+ const combinedParameters = [
1801
+ ...manualParameters,
1802
+ ...createdParams
1803
+ ];
1804
+ return combinedParameters.length ? combinedParameters : void 0;
492
1805
  };
493
- const validate = (ctx, opts) => {
494
- var _a;
495
- if (Object.keys(ctx.jsonSchema).length) {
496
- return;
1806
+ const getZodObject = (schema, type) => {
1807
+ if (isZodType(schema, "ZodObject")) {
1808
+ return schema;
497
1809
  }
498
- const def = ctx.zodSchema._zod.def;
499
- if ((_a = opts.allowEmptySchema) == null ? void 0 : _a[def.type]) {
500
- return;
1810
+ if (isZodType(schema, "ZodLazy")) {
1811
+ return getZodObject(schema.schema, type);
501
1812
  }
502
- switch (def.type) {
503
- case "any": {
504
- return;
505
- }
506
- case "unknown": {
507
- return;
508
- }
509
- case "pipe": {
510
- if (ctx.io === "output") {
511
- throw new Error(
512
- "Zod transform schemas are not supported in output schemas. Please use `.overwrite()` or wrap the schema in a `.pipe()`"
513
- );
514
- }
515
- return;
516
- }
517
- case "transform": {
518
- if (ctx.io === "output") {
519
- return;
520
- }
521
- break;
522
- }
523
- case "literal": {
524
- if (def.values.includes(void 0)) {
525
- throw new Error(
526
- "Zod literal schemas cannot include `undefined` as a value. Please use `z.undefined()` or `.optional()` instead."
527
- );
528
- }
529
- return;
1813
+ if (isZodType(schema, "ZodEffects")) {
1814
+ return getZodObject(schema.innerType(), type);
1815
+ }
1816
+ if (isZodType(schema, "ZodBranded")) {
1817
+ return getZodObject(schema.unwrap(), type);
1818
+ }
1819
+ if (isZodType(schema, "ZodPipeline")) {
1820
+ if (type === "input") {
1821
+ return getZodObject(schema._def.in, type);
530
1822
  }
1823
+ return getZodObject(schema._def.out, type);
531
1824
  }
532
- throw new Error(
533
- `Zod schema of type \`${def.type}\` cannot be represented in OpenAPI. Please assign it metadata with \`.meta()\``
534
- );
1825
+ throw new Error("failed to find ZodObject in schema");
535
1826
  };
536
- const renameComponents = (components, outputIds, ctx) => {
537
- const componentsToRename = /* @__PURE__ */ new Map();
538
- const componentDependencies = /* @__PURE__ */ new Map();
539
- const stringifiedComponents = /* @__PURE__ */ new Map();
540
- for (const [key, value] of Object.entries(components)) {
541
- const stringified = JSON.stringify(value);
542
- const matches = stringified.matchAll(/"#\/components\/schemas\/([^"]+)"/g);
543
- const dependencies = /* @__PURE__ */ new Set();
544
- for (const match of matches) {
545
- const dep = match[1];
546
- if (dep !== key) {
547
- dependencies.add(dep);
548
- }
549
- }
550
- stringifiedComponents.set(key, stringified);
551
- componentDependencies.set(key, {
552
- dependencies
553
- });
1827
+ const isISpecificationExtension = (key) => key.startsWith("x-");
1828
+ const createResponseHeaders = (responseHeaders, components, documentOptions) => {
1829
+ if (!responseHeaders) {
1830
+ return void 0;
554
1831
  }
555
- for (const [key] of stringifiedComponents) {
556
- const registeredComponent = ctx.registry.schemas.ids.get(key);
557
- if (!registeredComponent) {
558
- continue;
559
- }
560
- if (isDependencyPure(
561
- componentDependencies,
562
- stringifiedComponents,
563
- ctx.registry,
564
- key
565
- )) {
566
- continue;
567
- }
568
- const newName = outputIds.get(key) ?? `${key}Output`;
569
- componentsToRename.set(key, newName);
570
- components[newName] = components[key];
571
- delete components[key];
572
- continue;
1832
+ if (isAnyZodType(responseHeaders)) {
1833
+ return Object.entries(responseHeaders.shape).reduce((acc, [key, zodSchema]) => {
1834
+ acc[key] = createHeaderOrRef(zodSchema, components, documentOptions);
1835
+ return acc;
1836
+ }, {});
573
1837
  }
574
- return componentsToRename;
1838
+ return responseHeaders;
575
1839
  };
576
- const isDependencyPure = (componentDependencies, stringifiedComponents, registry, key, visited = /* @__PURE__ */ new Set()) => {
577
- if (visited.has(key)) {
578
- return true;
1840
+ const createHeaderOrRef = (schema, components, documentOptions) => {
1841
+ var _a, _b, _c;
1842
+ const component = components.headers.get(schema);
1843
+ if (component && component.type === "complete") {
1844
+ return {
1845
+ $ref: createComponentHeaderRef(component.ref)
1846
+ };
579
1847
  }
580
- const dependencies = componentDependencies.get(key);
581
- if (dependencies.pure !== void 0) {
582
- return dependencies.pure;
1848
+ const baseHeader = createBaseHeader(schema, components, documentOptions);
1849
+ if ("$ref" in baseHeader) {
1850
+ throw new Error("Unexpected Error: received a reference object");
583
1851
  }
584
- const stringified = stringifiedComponents.get(key);
585
- const component = registry.schemas.ids.get(key);
586
- if (component && stringified !== JSON.stringify(component)) {
587
- dependencies.pure = false;
588
- return false;
1852
+ const ref = ((_c = (_b = (_a = schema._def.zodOpenApi) == null ? void 0 : _a.openapi) == null ? void 0 : _b.header) == null ? void 0 : _c.ref) ?? (component == null ? void 0 : component.ref);
1853
+ if (ref) {
1854
+ components.headers.set(schema, {
1855
+ type: "complete",
1856
+ headerObject: baseHeader,
1857
+ ref
1858
+ });
1859
+ return {
1860
+ $ref: createComponentHeaderRef(ref)
1861
+ };
589
1862
  }
590
- visited.add(key);
591
- const result = [...dependencies.dependencies].every(
592
- (dep) => isDependencyPure(
593
- componentDependencies,
594
- stringifiedComponents,
595
- registry,
596
- dep,
597
- new Set(visited)
598
- )
599
- );
600
- dependencies.pure = result;
601
- return result;
602
- };
603
- const deleteZodOpenApiMeta = (jsonSchema) => {
604
- delete jsonSchema.param;
605
- delete jsonSchema.header;
606
- delete jsonSchema.unusedIO;
607
- delete jsonSchema.override;
608
- delete jsonSchema.outputId;
609
- };
610
- const createSchema = (schema, ctx = {
611
- registry: createRegistry(),
612
- io: "output",
613
- opts: {}
614
- }) => {
615
- ctx.registry ?? (ctx.registry = createRegistry());
616
- ctx.opts ?? (ctx.opts = {});
617
- ctx.io ?? (ctx.io = "output");
618
- const registrySchemas = Object.fromEntries(
619
- ctx.registry.schemas[ctx.io].schemas
620
- );
621
- const schemas = {
622
- zodOpenApiCreateSchema: { zodType: schema }
1863
+ return baseHeader;
1864
+ };
1865
+ const createBaseHeader = (schema, components, documentOptions) => {
1866
+ var _a, _b;
1867
+ const { ref, ...rest } = ((_b = (_a = schema._def.zodOpenApi) == null ? void 0 : _a.openapi) == null ? void 0 : _b.header) ?? {};
1868
+ const state = {
1869
+ components,
1870
+ type: "output",
1871
+ path: [],
1872
+ visited: /* @__PURE__ */ new Set(),
1873
+ documentOptions
623
1874
  };
624
- Object.assign(schemas, registrySchemas);
625
- const jsonSchemas = createSchemas(schemas, {
626
- registry: ctx.registry,
627
- io: ctx.io,
628
- opts: ctx.opts
629
- });
1875
+ const schemaObject = createSchema(schema, state, ["header"]);
1876
+ const optionalResult = schema.safeParse(void 0);
1877
+ const required = !optionalResult.success || optionalResult !== void 0;
630
1878
  return {
631
- schema: jsonSchemas.schemas.zodOpenApiCreateSchema,
632
- components: jsonSchemas.components
1879
+ ...rest,
1880
+ ...schema && { schema: schemaObject },
1881
+ ...required && { required }
633
1882
  };
634
1883
  };
635
- const createSchemas = (schemas, {
636
- registry,
637
- io,
638
- opts
639
- }) => {
640
- var _a, _b, _c, _d, _e, _f;
641
- const schemaRegistry = v4.registry();
642
- const globalsInSchemas = /* @__PURE__ */ new Map();
643
- for (const [name, { zodType }] of Object.entries(schemas)) {
644
- const id = (_a = v4.globalRegistry.get(zodType)) == null ? void 0 : _a.id;
645
- if (id) {
646
- globalsInSchemas.set(name, id);
647
- }
648
- schemaRegistry.add(zodType, { id: name });
649
- }
650
- const outputIds = /* @__PURE__ */ new Map();
651
- const jsonSchema = v4.toJSONSchema(schemaRegistry, {
652
- override(ctx) {
653
- const meta = ctx.zodSchema.meta();
654
- if ((meta == null ? void 0 : meta.outputId) && (meta == null ? void 0 : meta.id)) {
655
- outputIds.set(meta.id, meta.outputId);
656
- }
657
- if (ctx.jsonSchema.$ref) {
658
- return;
659
- }
660
- const enrichedContext = { ...ctx, io };
661
- override(enrichedContext);
662
- if (typeof opts.override === "function") {
663
- opts.override(enrichedContext);
664
- }
665
- if (typeof (meta == null ? void 0 : meta.override) === "function") {
666
- meta.override(enrichedContext);
667
- delete ctx.jsonSchema.override;
668
- }
669
- if (typeof (meta == null ? void 0 : meta.override) === "object" && meta.override !== null) {
670
- Object.assign(ctx.jsonSchema, meta.override);
671
- delete ctx.jsonSchema.override;
672
- }
673
- delete ctx.jsonSchema.$schema;
674
- delete ctx.jsonSchema.id;
675
- deleteZodOpenApiMeta(ctx.jsonSchema);
676
- validate(enrichedContext, opts);
677
- },
678
- io,
679
- unrepresentable: "any",
680
- uri: (id) => `#/components/schemas/${id}`
681
- });
682
- const sharedDefs = ((_b = jsonSchema.schemas.__shared) == null ? void 0 : _b.$defs) ?? {};
683
- (_c = jsonSchema.schemas).__shared ?? (_c.__shared = { $defs: sharedDefs });
684
- const componentsToReplace = /* @__PURE__ */ new Map();
685
- for (const [key, value] of Object.entries(sharedDefs)) {
686
- if (/^schema\d+$/.exec(key)) {
687
- const componentName = `__schema${registry.schemas.dynamicSchemaCount++}`;
688
- componentsToReplace.set(`__shared#/$defs/${key}`, componentName);
689
- delete sharedDefs[key];
690
- sharedDefs[componentName] = value;
691
- continue;
692
- }
693
- componentsToReplace.set(`__shared#/$defs/${key}`, key);
694
- }
695
- for (const value of Object.values(jsonSchema.schemas)) {
696
- delete value.$schema;
697
- delete value.id;
698
- }
699
- const dynamicComponent = /* @__PURE__ */ new Map();
700
- const patched = JSON.stringify(jsonSchema).replace(
701
- /"#\/components\/schemas\/([^"]+)"/g,
702
- (_, match) => {
703
- const replacement = componentsToReplace.get(match);
704
- if (replacement) {
705
- return `"#/components/schemas/${replacement}"`;
706
- }
707
- const component = registry.schemas.ids.get(match);
708
- if (component) {
709
- return `"#/components/schemas/${match}`;
710
- }
711
- const globalInSchema = globalsInSchemas.get(match);
712
- if (globalInSchema) {
713
- componentsToReplace.set(match, globalInSchema);
714
- dynamicComponent.set(match, globalInSchema);
715
- return `"#/components/schemas/${globalInSchema}"`;
716
- }
717
- const manualSchema = registry.schemas.manual.get(match);
718
- if (manualSchema) {
719
- componentsToReplace.set(match, manualSchema.key);
720
- dynamicComponent.set(match, manualSchema.key);
721
- manualSchema.io[io].used = true;
722
- return `"#/components/schemas/${manualSchema.key}"`;
723
- }
724
- const componentName = `__schema${registry.schemas.dynamicSchemaCount++}`;
725
- componentsToReplace.set(match, componentName);
726
- dynamicComponent.set(match, componentName);
727
- return `"#/components/schemas/${componentName}"`;
728
- }
1884
+ const createComponentHeaderRef = (ref) => `#/components/headers/${ref}`;
1885
+ const createResponse = (responseObject, components, subpath, documentOptions) => {
1886
+ if ("$ref" in responseObject) {
1887
+ return responseObject;
1888
+ }
1889
+ const component = components.responses.get(responseObject);
1890
+ if (component && component.type === "complete") {
1891
+ return { $ref: createComponentResponseRef(component.ref) };
1892
+ }
1893
+ const { content, headers, ref, ...rest } = responseObject;
1894
+ const maybeHeaders = createResponseHeaders(
1895
+ headers,
1896
+ components,
1897
+ documentOptions
729
1898
  );
730
- const patchedJsonSchema = JSON.parse(patched);
731
- const components = ((_d = patchedJsonSchema.schemas.__shared) == null ? void 0 : _d.$defs) ?? {};
732
- (_e = patchedJsonSchema.schemas).__shared ?? (_e.__shared = { $defs: components });
733
- for (const [key, value] of registry.schemas.manual) {
734
- if (value.io[io].used) {
735
- dynamicComponent.set(key, value.key);
1899
+ const response = {
1900
+ ...rest,
1901
+ ...maybeHeaders && { headers: maybeHeaders },
1902
+ ...content && {
1903
+ content: createContent(
1904
+ content,
1905
+ components,
1906
+ "output",
1907
+ [...subpath, "content"],
1908
+ documentOptions
1909
+ )
736
1910
  }
1911
+ };
1912
+ const responseRef = ref ?? (component == null ? void 0 : component.ref);
1913
+ if (responseRef) {
1914
+ components.responses.set(responseObject, {
1915
+ responseObject: response,
1916
+ ref: responseRef,
1917
+ type: "complete"
1918
+ });
1919
+ return {
1920
+ $ref: createComponentResponseRef(responseRef)
1921
+ };
737
1922
  }
738
- for (const [key, value] of globalsInSchemas) {
739
- dynamicComponent.set(key, value);
1923
+ return response;
1924
+ };
1925
+ const createResponses = (responsesObject, components, subpath, documentOptions) => Object.entries(responsesObject).reduce(
1926
+ (acc, [statusCode, responseObject]) => {
1927
+ if (isISpecificationExtension(statusCode)) {
1928
+ acc[statusCode] = responseObject;
1929
+ return acc;
1930
+ }
1931
+ acc[statusCode] = createResponse(
1932
+ responseObject,
1933
+ components,
1934
+ [...subpath, statusCode],
1935
+ documentOptions
1936
+ );
1937
+ return acc;
1938
+ },
1939
+ {}
1940
+ );
1941
+ const createRequestBody = (requestBodyObject, components, subpath, documentOptions) => {
1942
+ if (!requestBodyObject) {
1943
+ return void 0;
740
1944
  }
741
- for (const [key, value] of dynamicComponent) {
742
- const component = patchedJsonSchema.schemas[key];
743
- patchedJsonSchema.schemas[key] = {
744
- $ref: `#/components/schemas/${value}`
1945
+ const component = components.requestBodies.get(requestBodyObject);
1946
+ if (component && component.type === "complete") {
1947
+ return {
1948
+ $ref: createComponentRequestBodyRef(component.ref)
745
1949
  };
746
- components[value] = component;
747
1950
  }
748
- const renamedComponents = renameComponents(components, outputIds, {
749
- registry
750
- });
751
- if (renamedComponents.size === 0) {
752
- delete patchedJsonSchema.schemas.__shared;
1951
+ const { ref: reqBodyRef, ...cleanRequestBody } = requestBodyObject;
1952
+ const ref = reqBodyRef ?? (component == null ? void 0 : component.ref);
1953
+ const requestBody = {
1954
+ ...cleanRequestBody,
1955
+ content: createContent(
1956
+ cleanRequestBody.content,
1957
+ components,
1958
+ "input",
1959
+ [...subpath, "content"],
1960
+ documentOptions
1961
+ )
1962
+ };
1963
+ if (ref) {
1964
+ components.requestBodies.set(requestBodyObject, {
1965
+ type: "complete",
1966
+ ref,
1967
+ requestBodyObject: requestBody
1968
+ });
753
1969
  return {
754
- schemas: patchedJsonSchema.schemas,
755
- components
1970
+ $ref: createComponentRequestBodyRef(ref)
756
1971
  };
757
1972
  }
758
- const renamedStringified = JSON.stringify(patchedJsonSchema).replace(
759
- /"#\/components\/schemas\/([^"]+)"/g,
760
- (_, match) => {
761
- const newName = renamedComponents.get(match);
762
- if (newName) {
763
- return `"#/components/schemas/${newName}"`;
764
- }
765
- return `"#/components/schemas/${match}"`;
766
- }
1973
+ return requestBody;
1974
+ };
1975
+ const createOperation = (operationObject, components, subpath, documentOptions) => {
1976
+ const { parameters, requestParams, requestBody, responses, ...rest } = operationObject;
1977
+ const maybeParameters = createParametersObject(
1978
+ parameters,
1979
+ requestParams,
1980
+ components,
1981
+ [...subpath, "parameters"],
1982
+ documentOptions
1983
+ );
1984
+ const maybeRequestBody = createRequestBody(
1985
+ operationObject.requestBody,
1986
+ components,
1987
+ [...subpath, "request body"],
1988
+ documentOptions
1989
+ );
1990
+ const maybeResponses = createResponses(
1991
+ operationObject.responses,
1992
+ components,
1993
+ [...subpath, "responses"],
1994
+ documentOptions
1995
+ );
1996
+ const maybeCallbacks = createCallbacks(
1997
+ operationObject.callbacks,
1998
+ components,
1999
+ [...subpath, "callbacks"],
2000
+ documentOptions
767
2001
  );
768
- const renamedJsonSchema = JSON.parse(renamedStringified);
769
- const renamedJsonSchemaComponents = ((_f = renamedJsonSchema.schemas.__shared) == null ? void 0 : _f.$defs) ?? {};
770
- delete renamedJsonSchema.schemas.__shared;
771
2002
  return {
772
- schemas: renamedJsonSchema.schemas,
773
- components: renamedJsonSchemaComponents
2003
+ ...rest,
2004
+ ...maybeParameters && { parameters: maybeParameters },
2005
+ ...maybeRequestBody && { requestBody: maybeRequestBody },
2006
+ ...maybeResponses && { responses: maybeResponses },
2007
+ ...maybeCallbacks && { callbacks: maybeCallbacks }
774
2008
  };
775
2009
  };
776
- const createRegistry = (components) => {
777
- const registry = {
778
- schemas: {
779
- dynamicSchemaCount: 0,
780
- input: {
781
- seen: /* @__PURE__ */ new WeakMap(),
782
- schemas: /* @__PURE__ */ new Map()
783
- },
784
- output: {
785
- seen: /* @__PURE__ */ new WeakMap(),
786
- schemas: /* @__PURE__ */ new Map()
787
- },
788
- ids: /* @__PURE__ */ new Map(),
789
- manual: /* @__PURE__ */ new Map(),
790
- setSchema: (key, schema, io) => {
791
- const seenSchema = registry.schemas[io].seen.get(schema);
792
- if (seenSchema) {
793
- if (seenSchema.type === "manual") {
794
- const manualSchema = registry.schemas.manual.get(seenSchema.id);
795
- if (!manualSchema) {
796
- throw new Error(
797
- `Manual schema "${key}" not found in registry for ${io} IO.`
798
- );
799
- }
800
- manualSchema.io[io].used = true;
801
- }
802
- return seenSchema.schemaObject;
803
- }
804
- const schemaObject = {};
805
- registry.schemas[io].schemas.set(key, {
806
- schemaObject,
807
- zodType: schema
808
- });
809
- registry.schemas[io].seen.set(schema, { type: "schema", schemaObject });
810
- return schemaObject;
2010
+ const createPathItem = (pathObject, components, path, documentOptions) => Object.entries(pathObject).reduce(
2011
+ (acc, [key, value]) => {
2012
+ if (!value) {
2013
+ return acc;
2014
+ }
2015
+ if (key === "get" || key === "put" || key === "post" || key === "delete" || key === "options" || key === "head" || key === "patch" || key === "trace") {
2016
+ acc[key] = createOperation(
2017
+ value,
2018
+ components,
2019
+ [...path, key],
2020
+ documentOptions
2021
+ );
2022
+ return acc;
2023
+ }
2024
+ acc[key] = value;
2025
+ return acc;
2026
+ },
2027
+ {}
2028
+ );
2029
+ const createPaths = (pathsObject, components, documentOptions) => {
2030
+ if (!pathsObject) {
2031
+ return void 0;
2032
+ }
2033
+ return Object.entries(pathsObject).reduce(
2034
+ (acc, [path, pathItemObject]) => {
2035
+ if (isISpecificationExtension(path)) {
2036
+ acc[path] = pathItemObject;
2037
+ return acc;
811
2038
  }
2039
+ acc[path] = createPathItem(
2040
+ pathItemObject,
2041
+ components,
2042
+ [path],
2043
+ documentOptions
2044
+ );
2045
+ return acc;
812
2046
  },
813
- headers: {
814
- ids: /* @__PURE__ */ new Map(),
815
- seen: /* @__PURE__ */ new WeakMap()
816
- },
817
- requestBodies: {
818
- ids: /* @__PURE__ */ new Map(),
819
- seen: /* @__PURE__ */ new WeakMap()
820
- },
821
- responses: {
822
- ids: /* @__PURE__ */ new Map(),
823
- seen: /* @__PURE__ */ new WeakMap()
824
- },
825
- parameters: {
826
- ids: /* @__PURE__ */ new Map(),
827
- seen: /* @__PURE__ */ new WeakMap()
828
- },
829
- callbacks: {
830
- ids: /* @__PURE__ */ new Map(),
831
- seen: /* @__PURE__ */ new WeakMap()
832
- },
833
- pathItems: {
834
- ids: /* @__PURE__ */ new Map(),
835
- seen: /* @__PURE__ */ new WeakMap()
2047
+ {}
2048
+ );
2049
+ };
2050
+ const createCallback = (callbackObject, components, subpath, documentOptions) => {
2051
+ const { ref, ...callbacks } = callbackObject;
2052
+ const callback = Object.entries(
2053
+ callbacks
2054
+ ).reduce((acc, [callbackName, pathItemObject]) => {
2055
+ if (isISpecificationExtension(callbackName)) {
2056
+ acc[callbackName] = pathItemObject;
2057
+ return acc;
836
2058
  }
2059
+ acc[callbackName] = createPathItem(
2060
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
2061
+ pathItemObject,
2062
+ components,
2063
+ [...subpath, callbackName],
2064
+ documentOptions
2065
+ );
2066
+ return acc;
2067
+ }, {});
2068
+ if (ref) {
2069
+ components.callbacks.set(callbackObject, {
2070
+ type: "complete",
2071
+ ref,
2072
+ callbackObject: callback
2073
+ });
2074
+ return {
2075
+ $ref: createComponentCallbackRef(ref)
2076
+ };
2077
+ }
2078
+ return callback;
2079
+ };
2080
+ const createCallbacks = (callbacksObject, components, subpath, documentOptions) => {
2081
+ if (!callbacksObject) {
2082
+ return void 0;
2083
+ }
2084
+ return Object.entries(callbacksObject).reduce(
2085
+ (acc, [callbackName, callbackObject]) => {
2086
+ if (isISpecificationExtension(callbackName)) {
2087
+ acc[callbackName] = callbackObject;
2088
+ return acc;
2089
+ }
2090
+ acc[callbackName] = createCallback(
2091
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
2092
+ callbackObject,
2093
+ components,
2094
+ [...subpath, callbackName],
2095
+ documentOptions
2096
+ );
2097
+ return acc;
2098
+ },
2099
+ {}
2100
+ );
2101
+ };
2102
+ const getDefaultComponents = (componentsObject, openapi = "3.1.0") => {
2103
+ const defaultComponents = {
2104
+ schemas: /* @__PURE__ */ new Map(),
2105
+ parameters: /* @__PURE__ */ new Map(),
2106
+ headers: /* @__PURE__ */ new Map(),
2107
+ requestBodies: /* @__PURE__ */ new Map(),
2108
+ responses: /* @__PURE__ */ new Map(),
2109
+ callbacks: /* @__PURE__ */ new Map(),
2110
+ openapi
837
2111
  };
838
- registerSchemas(components == null ? void 0 : components.schemas, registry);
839
- registerParameters(components == null ? void 0 : components.parameters, registry);
840
- registerHeaders(components == null ? void 0 : components.headers, registry);
841
- registerResponses(components == null ? void 0 : components.responses, registry);
842
- registerPathItems(components == null ? void 0 : components.pathItems, registry);
843
- registerRequestBodies(components == null ? void 0 : components.requestBodies, registry);
844
- registerCallbacks(components == null ? void 0 : components.callbacks, registry);
845
- return registry;
846
- };
847
- const registerSchemas = (schemas, registry) => {
2112
+ if (!componentsObject) {
2113
+ return defaultComponents;
2114
+ }
2115
+ getSchemas(componentsObject.schemas, defaultComponents);
2116
+ getParameters(componentsObject.parameters, defaultComponents);
2117
+ getRequestBodies(componentsObject.requestBodies, defaultComponents);
2118
+ getHeaders(componentsObject.headers, defaultComponents);
2119
+ getResponses(componentsObject.responses, defaultComponents);
2120
+ getCallbacks(componentsObject.callbacks, defaultComponents);
2121
+ return defaultComponents;
2122
+ };
2123
+ const getSchemas = (schemas, components) => {
848
2124
  if (!schemas) {
849
2125
  return;
850
2126
  }
851
- for (const [key, schema] of Object.entries(schemas)) {
852
- if (registry.schemas.ids.has(key)) {
853
- throw new Error(`Schema "${key}" is already registered`);
854
- }
2127
+ Object.entries(schemas).forEach(([key, schema]) => {
2128
+ var _a, _b;
855
2129
  if (isAnyZodType(schema)) {
856
- const inputSchemaObject = {};
857
- const outputSchemaObject = {};
858
- const identifier = `components > schemas > ${key}`;
859
- registry.schemas.input.schemas.set(identifier, {
860
- zodType: schema,
861
- schemaObject: inputSchemaObject
862
- });
863
- registry.schemas.input.seen.set(schema, {
864
- type: "manual",
865
- schemaObject: inputSchemaObject,
866
- id: identifier
867
- });
868
- registry.schemas.output.schemas.set(identifier, {
869
- zodType: schema,
870
- schemaObject: outputSchemaObject
871
- });
872
- registry.schemas.output.seen.set(schema, {
2130
+ if (components.schemas.has(schema)) {
2131
+ throw new Error(
2132
+ `Schema ${JSON.stringify(schema._def)} is already registered`
2133
+ );
2134
+ }
2135
+ const ref = ((_b = (_a = schema._def.zodOpenApi) == null ? void 0 : _a.openapi) == null ? void 0 : _b.ref) ?? key;
2136
+ components.schemas.set(schema, {
873
2137
  type: "manual",
874
- schemaObject: outputSchemaObject,
875
- id: identifier
2138
+ ref
876
2139
  });
877
- registry.schemas.manual.set(identifier, {
878
- key,
879
- io: {
880
- input: {
881
- schemaObject: inputSchemaObject
882
- },
883
- output: {
884
- schemaObject: outputSchemaObject
885
- }
886
- },
887
- zodType: schema
888
- });
889
- continue;
890
2140
  }
891
- registry.schemas.ids.set(key, schema);
892
- }
2141
+ });
893
2142
  };
894
- const registerParameters = (parameters, registry) => {
2143
+ const getParameters = (parameters, components) => {
895
2144
  if (!parameters) {
896
2145
  return;
897
2146
  }
898
- for (const [key, schema] of Object.entries(parameters)) {
899
- if (registry.parameters.ids.has(key)) {
900
- throw new Error(`Parameter "${key}" is already registered`);
901
- }
2147
+ Object.entries(parameters).forEach(([key, schema]) => {
2148
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
902
2149
  if (isAnyZodType(schema)) {
903
- const path = ["components", "parameters", key];
904
- const paramObject = createParameter(
905
- schema,
906
- void 0,
907
- {
908
- registry,
909
- io: "input"
910
- },
911
- path
912
- );
913
- registry.parameters.ids.set(key, paramObject);
914
- registry.parameters.seen.set(schema, paramObject);
915
- continue;
2150
+ if (components.parameters.has(schema)) {
2151
+ throw new Error(
2152
+ `Parameter ${JSON.stringify(schema._def)} is already registered`
2153
+ );
2154
+ }
2155
+ const ref = ((_c = (_b = (_a = schema._def.zodOpenApi) == null ? void 0 : _a.openapi) == null ? void 0 : _b.param) == null ? void 0 : _c.ref) ?? key;
2156
+ const name = (_f = (_e = (_d = schema._def.zodOpenApi) == null ? void 0 : _d.openapi) == null ? void 0 : _e.param) == null ? void 0 : _f.name;
2157
+ const location = (_i = (_h = (_g = schema._def.zodOpenApi) == null ? void 0 : _g.openapi) == null ? void 0 : _h.param) == null ? void 0 : _i.in;
2158
+ if (!name || !location) {
2159
+ throw new Error("`name` or `in` missing in .openapi()");
2160
+ }
2161
+ components.parameters.set(schema, {
2162
+ type: "manual",
2163
+ ref,
2164
+ in: location,
2165
+ name
2166
+ });
916
2167
  }
917
- registry.parameters.ids.set(key, schema);
918
- }
2168
+ });
919
2169
  };
920
- const registerHeaders = (headers, registry) => {
921
- if (!headers) {
2170
+ const getHeaders = (responseHeaders, components) => {
2171
+ if (!responseHeaders) {
922
2172
  return;
923
2173
  }
924
- for (const [key, schema] of Object.entries(headers)) {
925
- if (registry.headers.ids.has(key)) {
926
- throw new Error(`Header "${key}" is already registered`);
927
- }
2174
+ Object.entries(responseHeaders).forEach(([key, schema]) => {
2175
+ var _a, _b, _c;
928
2176
  if (isAnyZodType(schema)) {
929
- const path = ["components", "headers", key];
930
- const headerObject = createHeader(
931
- schema,
932
- {
933
- registry,
934
- io: "output"
935
- },
936
- path
937
- );
938
- registry.headers.ids.set(key, headerObject);
939
- registry.headers.seen.set(schema, headerObject);
940
- continue;
2177
+ if (components.parameters.has(schema)) {
2178
+ throw new Error(
2179
+ `Header ${JSON.stringify(schema._def)} is already registered`
2180
+ );
2181
+ }
2182
+ const ref = ((_c = (_b = (_a = schema._def.zodOpenApi) == null ? void 0 : _a.openapi) == null ? void 0 : _b.param) == null ? void 0 : _c.ref) ?? key;
2183
+ components.headers.set(schema, {
2184
+ type: "manual",
2185
+ ref
2186
+ });
941
2187
  }
942
- registry.headers.ids.set(key, schema);
943
- }
2188
+ });
944
2189
  };
945
- const registerResponses = (responses, registry) => {
2190
+ const getResponses = (responses, components) => {
946
2191
  if (!responses) {
947
2192
  return;
948
2193
  }
949
- for (const [key, schema] of Object.entries(responses)) {
950
- const path = ["components", "responses", key];
951
- if (registry.responses.ids.has(key)) {
952
- throw new Error(`Response "${key}" is already registered`);
2194
+ Object.entries(responses).forEach(([key, responseObject]) => {
2195
+ if (components.responses.has(responseObject)) {
2196
+ throw new Error(
2197
+ `Header ${JSON.stringify(responseObject)} is already registered`
2198
+ );
953
2199
  }
954
- const responseObject = createResponse(
955
- schema,
956
- {
957
- registry,
958
- io: "output"
959
- },
960
- path
961
- );
962
- registry.responses.ids.set(key, responseObject);
963
- registry.responses.seen.set(schema, responseObject);
964
- }
2200
+ const ref = (responseObject == null ? void 0 : responseObject.ref) ?? key;
2201
+ components.responses.set(responseObject, {
2202
+ type: "manual",
2203
+ ref
2204
+ });
2205
+ });
965
2206
  };
966
- const registerRequestBodies = (requestBodies, registry) => {
2207
+ const getRequestBodies = (requestBodies, components) => {
967
2208
  if (!requestBodies) {
968
2209
  return;
969
2210
  }
970
- for (const [key, schema] of Object.entries(requestBodies)) {
971
- if (registry.requestBodies.ids.has(key)) {
972
- throw new Error(`RequestBody "${key}" is already registered`);
973
- }
974
- if (isAnyZodType(schema)) {
975
- const path = ["components", "requestBodies", key];
976
- const requestBodyObject = createRequestBody(
977
- schema,
978
- {
979
- registry,
980
- io: "input"
981
- },
982
- path
2211
+ Object.entries(requestBodies).forEach(([key, requestBody]) => {
2212
+ if (components.requestBodies.has(requestBody)) {
2213
+ throw new Error(
2214
+ `Header ${JSON.stringify(requestBody)} is already registered`
983
2215
  );
984
- registry.requestBodies.ids.set(key, requestBodyObject);
985
- continue;
986
2216
  }
987
- registry.requestBodies.ids.set(key, schema);
988
- }
2217
+ const ref = (requestBody == null ? void 0 : requestBody.ref) ?? key;
2218
+ components.requestBodies.set(requestBody, {
2219
+ type: "manual",
2220
+ ref
2221
+ });
2222
+ });
989
2223
  };
990
- const registerCallbacks = (callbacks, registry) => {
2224
+ const getCallbacks = (callbacks, components) => {
991
2225
  if (!callbacks) {
992
2226
  return;
993
2227
  }
994
- for (const [key, schema] of Object.entries(callbacks)) {
995
- if (registry.callbacks.ids.has(key)) {
996
- throw new Error(`Callback "${key}" is already registered`);
2228
+ Object.entries(callbacks).forEach(([key, callback]) => {
2229
+ if (components.callbacks.has(callback)) {
2230
+ throw new Error(
2231
+ `Callback ${JSON.stringify(callback)} is already registered`
2232
+ );
997
2233
  }
998
- const path = ["components", "callbacks", key];
999
- const callbackObject = createCallback(schema, registry, path);
1000
- registry.callbacks.ids.set(key, callbackObject);
1001
- registry.callbacks.seen.set(schema, callbackObject);
1002
- }
2234
+ const ref = (callback == null ? void 0 : callback.ref) ?? key;
2235
+ components.callbacks.set(callback, {
2236
+ type: "manual",
2237
+ ref
2238
+ });
2239
+ });
1003
2240
  };
1004
- const registerPathItems = (pathItems, registry) => {
1005
- if (!pathItems) {
1006
- return;
1007
- }
1008
- for (const [key, schema] of Object.entries(pathItems)) {
1009
- if (registry.pathItems.ids.has(key)) {
1010
- throw new Error(`PathItem "${key}" is already registered`);
2241
+ const createComponentSchemaRef = (schemaRef, componentPath) => `${componentPath ?? "#/components/schemas/"}${schemaRef}`;
2242
+ const createComponentResponseRef = (responseRef) => `#/components/responses/${responseRef}`;
2243
+ const createComponentRequestBodyRef = (requestBodyRef) => `#/components/requestBodies/${requestBodyRef}`;
2244
+ const createComponentCallbackRef = (callbackRef) => `#/components/callbacks/${callbackRef}`;
2245
+ const createComponents = (componentsObject, components, documentOptions) => {
2246
+ const combinedSchemas = createSchemaComponents(
2247
+ componentsObject,
2248
+ components,
2249
+ documentOptions
2250
+ );
2251
+ const combinedParameters = createParamComponents(
2252
+ componentsObject,
2253
+ components,
2254
+ documentOptions
2255
+ );
2256
+ const combinedHeaders = createHeaderComponents(
2257
+ componentsObject,
2258
+ components,
2259
+ documentOptions
2260
+ );
2261
+ const combinedResponses = createResponseComponents(
2262
+ components,
2263
+ documentOptions
2264
+ );
2265
+ const combinedRequestBodies = createRequestBodiesComponents(
2266
+ components,
2267
+ documentOptions
2268
+ );
2269
+ const combinedCallbacks = createCallbackComponents(
2270
+ components,
2271
+ documentOptions
2272
+ );
2273
+ const { schemas, parameters, headers, responses, requestBodies, ...rest } = componentsObject;
2274
+ const finalComponents = {
2275
+ ...rest,
2276
+ ...combinedSchemas && { schemas: combinedSchemas },
2277
+ ...combinedParameters && { parameters: combinedParameters },
2278
+ ...combinedRequestBodies && { requestBodies: combinedRequestBodies },
2279
+ ...combinedHeaders && { headers: combinedHeaders },
2280
+ ...combinedResponses && { responses: combinedResponses },
2281
+ ...combinedCallbacks && { callbacks: combinedCallbacks }
2282
+ };
2283
+ return Object.keys(finalComponents).length ? finalComponents : void 0;
2284
+ };
2285
+ const createSchemaComponents = (componentsObject, components, documentOptions) => {
2286
+ Array.from(components.schemas).forEach(([schema, { type }], index) => {
2287
+ var _a, _b;
2288
+ if (type === "manual") {
2289
+ const state = {
2290
+ components,
2291
+ type: ((_b = (_a = schema._def.zodOpenApi) == null ? void 0 : _a.openapi) == null ? void 0 : _b.refType) ?? "output",
2292
+ path: [],
2293
+ visited: /* @__PURE__ */ new Set(),
2294
+ documentOptions
2295
+ };
2296
+ createSchema(schema, state, [`component schema index ${index}`]);
1011
2297
  }
1012
- const path = ["components", "pathItems", key];
1013
- const pathItemObject = createPathItem(schema, registry, path);
1014
- registry.pathItems.ids.set(key, pathItemObject);
1015
- registry.pathItems.seen.set(schema, pathItemObject);
1016
- continue;
1017
- }
2298
+ });
2299
+ const customComponents = Object.entries(
2300
+ componentsObject.schemas ?? {}
2301
+ ).reduce(
2302
+ (acc, [key, value]) => {
2303
+ if (isAnyZodType(value)) {
2304
+ return acc;
2305
+ }
2306
+ if (acc[key]) {
2307
+ throw new Error(`Schema "${key}" is already registered`);
2308
+ }
2309
+ acc[key] = value;
2310
+ return acc;
2311
+ },
2312
+ {}
2313
+ );
2314
+ const finalComponents = Array.from(components.schemas).reduce((acc, [_zodType, component]) => {
2315
+ if (component.type === "complete") {
2316
+ if (acc[component.ref]) {
2317
+ throw new Error(`Schema "${component.ref}" is already registered`);
2318
+ }
2319
+ acc[component.ref] = component.schemaObject;
2320
+ }
2321
+ return acc;
2322
+ }, customComponents);
2323
+ return Object.keys(finalComponents).length ? finalComponents : void 0;
1018
2324
  };
1019
- const createIOSchemas = (ctx) => {
1020
- const { schemas, components } = createSchemas(
1021
- Object.fromEntries(ctx.registry.schemas[ctx.io].schemas),
1022
- ctx
2325
+ const createParamComponents = (componentsObject, components, documentOptions) => {
2326
+ Array.from(components.parameters).forEach(([schema, component], index) => {
2327
+ if (component.type === "manual") {
2328
+ createParamOrRef(
2329
+ schema,
2330
+ components,
2331
+ [`component parameter index ${index}`],
2332
+ component.in,
2333
+ component.ref,
2334
+ documentOptions
2335
+ );
2336
+ }
2337
+ });
2338
+ const customComponents = Object.entries(
2339
+ componentsObject.parameters ?? {}
2340
+ ).reduce(
2341
+ (acc, [key, value]) => {
2342
+ if (!isAnyZodType(value)) {
2343
+ if (acc[key]) {
2344
+ throw new Error(`Parameter "${key}" is already registered`);
2345
+ }
2346
+ acc[key] = value;
2347
+ }
2348
+ return acc;
2349
+ },
2350
+ {}
1023
2351
  );
1024
- for (const [key, schema] of Object.entries(components)) {
1025
- ctx.registry.schemas.ids.set(key, schema);
1026
- }
1027
- for (const [key, schema] of Object.entries(schemas)) {
1028
- const ioSchema = ctx.registry.schemas[ctx.io].schemas.get(key);
1029
- if (ioSchema) {
1030
- Object.assign(ioSchema.schemaObject, schema);
2352
+ const finalComponents = Array.from(components.parameters).reduce((acc, [_zodType, component]) => {
2353
+ if (component.type === "complete") {
2354
+ if (acc[component.ref]) {
2355
+ throw new Error(`Parameter "${component.ref}" is already registered`);
2356
+ }
2357
+ acc[component.ref] = component.paramObject;
1031
2358
  }
1032
- }
2359
+ return acc;
2360
+ }, customComponents);
2361
+ return Object.keys(finalComponents).length ? finalComponents : void 0;
1033
2362
  };
1034
- const createManualSchemas = (registry) => {
1035
- var _a;
1036
- for (const [, value] of registry.schemas.manual) {
1037
- if (!value.io.input.used && !value.io.output.used) {
1038
- const io = ((_a = core.globalRegistry.get(value.zodType)) == null ? void 0 : _a.unusedIO) ?? "output";
1039
- const schema = value.io[io].schemaObject;
1040
- registry.schemas.ids.set(value.key, schema);
2363
+ const createHeaderComponents = (componentsObject, components, documentOptions) => {
2364
+ Array.from(components.headers).forEach(([schema, component]) => {
2365
+ if (component.type === "manual") {
2366
+ createHeaderOrRef(schema, components, documentOptions);
1041
2367
  }
1042
- }
2368
+ });
2369
+ const headers = componentsObject.headers ?? {};
2370
+ const customComponents = Object.entries(headers).reduce((acc, [key, value]) => {
2371
+ if (!isAnyZodType(value)) {
2372
+ if (acc[key]) {
2373
+ throw new Error(`Header Ref "${key}" is already registered`);
2374
+ }
2375
+ acc[key] = value;
2376
+ }
2377
+ return acc;
2378
+ }, {});
2379
+ const finalComponents = Array.from(components.headers).reduce((acc, [_zodType, component]) => {
2380
+ if (component.type === "complete") {
2381
+ if (acc[component.ref]) {
2382
+ throw new Error(`Header "${component.ref}" is already registered`);
2383
+ }
2384
+ acc[component.ref] = component.headerObject;
2385
+ }
2386
+ return acc;
2387
+ }, customComponents);
2388
+ return Object.keys(finalComponents).length ? finalComponents : void 0;
1043
2389
  };
1044
- const createComponents = (registry, opts) => {
1045
- createIOSchemas({ registry, io: "input", opts });
1046
- createIOSchemas({ registry, io: "output", opts });
1047
- createManualSchemas(registry);
1048
- const components = {};
1049
- if (registry.schemas.ids.size > 0) {
1050
- components.schemas = Object.fromEntries(registry.schemas.ids);
1051
- }
1052
- if (registry.headers.ids.size > 0) {
1053
- components.headers = Object.fromEntries(registry.headers.ids);
1054
- }
1055
- if (registry.requestBodies.ids.size > 0) {
1056
- components.requestBodies = Object.fromEntries(registry.requestBodies.ids);
1057
- }
1058
- if (registry.responses.ids.size > 0) {
1059
- components.responses = Object.fromEntries(registry.responses.ids);
1060
- }
1061
- if (registry.parameters.ids.size > 0) {
1062
- components.parameters = Object.fromEntries(registry.parameters.ids);
1063
- }
1064
- if (registry.callbacks.ids.size > 0) {
1065
- components.callbacks = Object.fromEntries(registry.callbacks.ids);
1066
- }
1067
- if (registry.pathItems.ids.size > 0) {
1068
- components.pathItems = Object.fromEntries(registry.pathItems.ids);
1069
- }
1070
- return components;
2390
+ const createResponseComponents = (components, documentOptions) => {
2391
+ Array.from(components.responses).forEach(([schema, component], index) => {
2392
+ if (component.type === "manual") {
2393
+ createResponse(
2394
+ schema,
2395
+ components,
2396
+ [`component response index ${index}`],
2397
+ documentOptions
2398
+ );
2399
+ }
2400
+ });
2401
+ const finalComponents = Array.from(components.responses).reduce((acc, [_zodType, component]) => {
2402
+ if (component.type === "complete") {
2403
+ if (acc[component.ref]) {
2404
+ throw new Error(`Response "${component.ref}" is already registered`);
2405
+ }
2406
+ acc[component.ref] = component.responseObject;
2407
+ }
2408
+ return acc;
2409
+ }, {});
2410
+ return Object.keys(finalComponents).length ? finalComponents : void 0;
2411
+ };
2412
+ const createRequestBodiesComponents = (components, documentOptions) => {
2413
+ Array.from(components.requestBodies).forEach(([schema, component], index) => {
2414
+ if (component.type === "manual") {
2415
+ createRequestBody(
2416
+ schema,
2417
+ components,
2418
+ [`component request body ${index}`],
2419
+ documentOptions
2420
+ );
2421
+ }
2422
+ });
2423
+ const finalComponents = Array.from(components.requestBodies).reduce((acc, [_zodType, component]) => {
2424
+ if (component.type === "complete") {
2425
+ if (acc[component.ref]) {
2426
+ throw new Error(`RequestBody "${component.ref}" is already registered`);
2427
+ }
2428
+ acc[component.ref] = component.requestBodyObject;
2429
+ }
2430
+ return acc;
2431
+ }, {});
2432
+ return Object.keys(finalComponents).length ? finalComponents : void 0;
2433
+ };
2434
+ const createCallbackComponents = (components, documentOptions) => {
2435
+ Array.from(components.callbacks).forEach(([schema, component], index) => {
2436
+ if (component.type === "manual") {
2437
+ createCallback(
2438
+ schema,
2439
+ components,
2440
+ [`component callback ${index}`],
2441
+ documentOptions
2442
+ );
2443
+ }
2444
+ });
2445
+ const finalComponents = Array.from(components.callbacks).reduce((acc, [_zodType, component]) => {
2446
+ if (component.type === "complete") {
2447
+ if (acc[component.ref]) {
2448
+ throw new Error(`Callback "${component.ref}" is already registered`);
2449
+ }
2450
+ acc[component.ref] = component.callbackObject;
2451
+ }
2452
+ return acc;
2453
+ }, {});
2454
+ return Object.keys(finalComponents).length ? finalComponents : void 0;
1071
2455
  };
1072
2456
  exports.createComponents = createComponents;
1073
- exports.createMediaTypeObject = createMediaTypeObject;
1074
- exports.createParameter = createParameter;
2457
+ exports.createMediaTypeSchema = createMediaTypeSchema;
2458
+ exports.createParamOrRef = createParamOrRef;
1075
2459
  exports.createPaths = createPaths;
1076
- exports.createRegistry = createRegistry;
1077
2460
  exports.createSchema = createSchema;
1078
- exports.unwrapZodObject = unwrapZodObject;
2461
+ exports.createSchemaComponents = createSchemaComponents;
2462
+ exports.getDefaultComponents = getDefaultComponents;
2463
+ exports.getZodObject = getZodObject;