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