zod-openapi 5.0.0-beta.3 → 5.0.0-beta.5

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,1024 +1,2464 @@
1
- import { globalRegistry as globalRegistry$1 } from "zod/v4/core";
2
- import { globalRegistry, object, 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
+ };
27
261
  }
28
- return zodType._zod.optout === void 0;
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
+ };
272
+ }
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;
450
+ }
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);
70
459
  }
71
- ctx.registry.parameters.seen.set(parameter, parameterObject);
72
- return parameterObject;
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
+ }
135
617
  return {
136
- ...mediaTypeObject,
137
- schema: schemaObject
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
138
627
  };
139
628
  }
140
- return mediaTypeObject;
629
+ if (schemaObject.type === "ref") {
630
+ return {
631
+ type: "schema",
632
+ schema: {
633
+ allOf: [schemaObject.schema],
634
+ nullable: true
635
+ },
636
+ effects: schemaObject.effects
637
+ };
638
+ }
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) {
739
+ return void 0;
740
+ }
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"]);
744
+ }
745
+ const completeComponent = state.components.schemas.get(baseZodObject);
746
+ if (!completeComponent) {
211
747
  return void 0;
212
748
  }
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;
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
219
757
  }
220
- return headersObject;
758
+ );
759
+ if (!diffOpts) {
760
+ return void 0;
221
761
  }
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;
229
- }
230
- const { content, headers, id, ...rest } = response;
231
- const responseObject = rest;
232
- const maybeHeaders = createHeaders(headers, ctx, [...path, "headers"]);
233
- if (maybeHeaders) {
234
- responseObject.headers = maybeHeaders;
235
- }
236
- if (content) {
237
- responseObject.content = createContent(content, ctx, [...path, "content"]);
238
- }
239
- if (id) {
240
- const ref = {
241
- $ref: `#/components/responses/${id}`
762
+ const diffShape = createShapeDiff(
763
+ baseZodObject._def.shape(),
764
+ zodObject._def.shape()
765
+ );
766
+ if (!diffShape) {
767
+ return void 0;
768
+ }
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
242
799
  };
243
- ctx.registry.responses.ids.set(id, responseObject);
244
- ctx.registry.responses.seen.set(response, ref);
245
- return ref;
246
800
  }
247
- ctx.registry.responses.seen.set(response, responseObject);
248
- return responseObject;
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
+ );
817
+ }
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
+ };
249
843
  };
250
- const createResponses = (responses, ctx, path) => {
251
- if (!responses) {
844
+ const createDiffOpts = (baseOpts, extendedOpts) => {
845
+ if (baseOpts.unknownKeys === "strict" || !isZodType(baseOpts.catchAll, "ZodNever")) {
252
846
  return void 0;
253
847
  }
254
- const responsesObject = {};
255
- for (const [statusCode, response] of Object.entries(responses)) {
256
- if (!response) {
257
- continue;
258
- }
259
- if (isISpecificationExtension(statusCode)) {
260
- 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) {
261
858
  continue;
262
859
  }
263
- if ("$ref" in response) {
264
- responsesObject[statusCode] = response;
860
+ if (baseValue === void 0) {
861
+ acc[key] = extendedObj[key];
265
862
  continue;
266
863
  }
267
- const responseObject = createResponse(
268
- response,
269
- ctx,
270
- [...path, statusCode]
271
- );
272
- responsesObject[statusCode] = responseObject;
864
+ return null;
273
865
  }
274
- return responsesObject;
866
+ return acc;
275
867
  };
276
- const createOperation = (operationObject, registry, path) => {
277
- const {
278
- parameters,
279
- requestParams,
280
- requestBody,
281
- responses,
282
- callbacks,
283
- ...rest
284
- } = operationObject;
285
- const operation = rest;
286
- const maybeManualParameters = createManualParameters(
287
- parameters,
288
- {
289
- registry,
290
- io: "input"
291
- },
292
- [...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
293
886
  );
294
- const maybeRequestParams = createParameters(
295
- requestParams,
296
- {
297
- registry,
298
- 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
+ }
299
896
  },
300
- [...path, "requestParams"]
301
- );
302
- if (maybeRequestParams || maybeManualParameters) {
303
- operation.parameters = [
304
- ...maybeRequestParams ?? [],
305
- ...maybeManualParameters ?? []
306
- ];
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;
307
907
  }
308
- const maybeRequestBody = createRequestBody(
309
- requestBody,
310
- {
311
- registry,
312
- 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;
313
938
  },
314
- [...path, "requestBody"]
939
+ {
940
+ required: [],
941
+ effects: []
942
+ }
315
943
  );
316
- if (maybeRequestBody) {
317
- 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;
318
950
  }
319
- const maybeResponses = createResponses(
320
- responses,
321
- {
322
- registry,
323
- 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;
324
961
  },
325
- [...path, "responses"]
962
+ {
963
+ schemas: {},
964
+ properties: {},
965
+ effects: []
966
+ }
326
967
  );
327
- if (maybeResponses) {
328
- 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"]);
973
+ }
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
+ };
329
995
  }
330
- const maybeCallbacks = createCallbacks(callbacks, registry, [
331
- ...path,
332
- "callbacks"
996
+ const schema = createSchemaObject(zodPipeline._def.out, state, [
997
+ "pipeline output"
333
998
  ]);
334
- if (maybeCallbacks) {
335
- operation.callbacks = maybeCallbacks;
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"
1027
+ ]);
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
+ };
1050
+ }
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
+ };
336
1064
  }
337
- return operation;
1065
+ return {
1066
+ type: "schema",
1067
+ schema: {
1068
+ type: "object",
1069
+ additionalProperties: additionalProperties.schema
1070
+ },
1071
+ effects: additionalProperties.effects
1072
+ };
338
1073
  };
339
- const createPathItem = (pathItem, registry, path) => {
340
- const pathItemObject = {};
341
- const { id, ...rest } = pathItem;
342
- for (const [key, value] of Object.entries(rest)) {
343
- if (key === "get" || key === "put" || key === "post" || key === "delete" || key === "options" || key === "head" || key === "patch" || key === "trace") {
344
- pathItemObject[key] = createOperation(
345
- value,
346
- registry,
347
- [...path, key]
348
- );
349
- continue;
350
- }
351
- if (key === "parameters") {
352
- pathItemObject[key] = createManualParameters(
353
- 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: [
354
1118
  {
355
- registry,
356
- 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 }
357
1125
  },
358
- [...path, key]
359
- );
360
- continue;
1126
+ ...patterns.slice(1).map(
1127
+ (pattern) => ({
1128
+ type: "string",
1129
+ pattern
1130
+ })
1131
+ )
1132
+ ]
361
1133
  }
362
- pathItemObject[key] = value;
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}`;
363
1165
  }
364
- if (id) {
365
- const ref = {
366
- $ref: `#/components/pathItems/${id}`
367
- };
368
- registry.pathItems.ids.set(id, pathItemObject);
369
- registry.pathItems.seen.set(pathItem, ref);
370
- return ref;
1166
+ return void 0;
1167
+ };
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}$`;
371
1172
  }
372
- registry.pathItems.seen.set(pathItem, pathItemObject);
373
- return pathItemObject;
1173
+ return void 0;
374
1174
  };
375
- const createPaths = (paths, registry, path) => {
376
- if (!paths) {
377
- return void 0;
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}`;
1184
+ }
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";
378
1195
  }
379
- const pathsObject = {};
380
- for (const [singlePath, pathItemObject] of Object.entries(paths)) {
381
- if (isISpecificationExtension(singlePath)) {
382
- pathsObject[singlePath] = pathItemObject;
383
- continue;
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";
1207
+ }
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;
1227
+ };
1228
+ const mapContentEncoding = (zodStringChecks) => {
1229
+ if (zodStringChecks.base64) {
1230
+ return "base64";
1231
+ }
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
+ };
384
1252
  }
385
- pathsObject[singlePath] = createPathItem(pathItemObject, registry, [
386
- ...path,
387
- singlePath
388
- ]);
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
+ };
1265
+ }
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
1278
+ };
1279
+ }
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
+ };
389
1295
  }
390
- return pathsObject;
1296
+ return {
1297
+ type: "schema",
1298
+ schema: {
1299
+ type: "array"
1300
+ }
1301
+ };
391
1302
  };
392
- const createCallback = (callbackObject, registry, path) => {
393
- const seenCallback = registry.callbacks.seen.get(callbackObject);
394
- if (seenCallback) {
395
- return seenCallback;
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
+ };
396
1312
  }
397
- const { id, ...rest } = callbackObject;
398
- const callback = {};
399
- for (const [name, pathItem] of Object.entries(rest)) {
400
- if (isISpecificationExtension(name)) {
401
- callback[name] = pathItem;
402
- 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}`]));
403
1320
  }
404
- callback[name] = createPathItem(
405
- pathItem,
406
- registry,
407
- [...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`
408
1452
  );
409
1453
  }
410
- if (id) {
411
- const ref = {
412
- $ref: `#/components/callbacks/${id}`
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]
1513
+ }
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]
1535
+ }
1536
+ ] : void 0,
1537
+ zodType: zodSchema
413
1538
  };
414
- registry.callbacks.ids.set(id, callback);
415
- registry.callbacks.seen.set(callbackObject, ref);
416
- return ref;
417
1539
  }
418
- registry.callbacks.seen.set(callbackObject, callback);
419
- return callback;
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;
420
1561
  };
421
- const createCallbacks = (callbacks, registry, path) => {
422
- if (!callbacks) {
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) {
423
1606
  return void 0;
424
1607
  }
425
- const callbacksObject = {};
426
- for (const [name, value] of Object.entries(callbacks)) {
427
- if (isISpecificationExtension(name)) {
428
- callbacksObject[name] = value;
429
- continue;
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;
430
1649
  }
431
- callbacksObject[name] = createCallback(
432
- value,
433
- registry,
434
- [...path, name]
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`);
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
435
1782
  );
436
1783
  }
437
- return callbacksObject;
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;
438
1804
  };
439
- const override = (ctx) => {
440
- var _a;
441
- const def = ctx.zodSchema._zod.def;
442
- switch (def.type) {
443
- case "bigint": {
444
- ctx.jsonSchema.type = "integer";
445
- ctx.jsonSchema.format = "int64";
446
- break;
447
- }
448
- case "union": {
449
- if ("discriminator" in def && typeof def.discriminator === "string") {
450
- ctx.jsonSchema.oneOf = ctx.jsonSchema.anyOf;
451
- delete ctx.jsonSchema.anyOf;
452
- ctx.jsonSchema.type = "object";
453
- ctx.jsonSchema.discriminator = {
454
- propertyName: def.discriminator
455
- };
456
- const mapping = {};
457
- for (const [index, obj] of Object.entries(
458
- ctx.jsonSchema.oneOf
459
- )) {
460
- const ref = obj.$ref;
461
- if (!ref) {
462
- return;
463
- }
464
- const discriminatorValues = (_a = def.options[Number(index)]._zod.propValues) == null ? void 0 : _a[def.discriminator];
465
- if (!(discriminatorValues == null ? void 0 : discriminatorValues.size)) {
466
- return;
467
- }
468
- for (const value of [...discriminatorValues ?? []]) {
469
- if (typeof value !== "string") {
470
- return;
471
- }
472
- mapping[value] = ref;
473
- }
474
- }
475
- ctx.jsonSchema.discriminator.mapping = mapping;
476
- }
477
- const meta = ctx.zodSchema.meta();
478
- if (typeof (meta == null ? void 0 : meta.unionOneOf) === "boolean") {
479
- if (meta.unionOneOf) {
480
- ctx.jsonSchema.oneOf = ctx.jsonSchema.anyOf;
481
- delete ctx.jsonSchema.anyOf;
482
- }
483
- delete ctx.jsonSchema.unionOneOf;
484
- }
485
- break;
486
- }
487
- case "date": {
488
- ctx.jsonSchema.type = "string";
489
- break;
490
- }
491
- case "literal": {
492
- if (def.values.includes(void 0)) {
493
- break;
494
- }
495
- break;
496
- }
1805
+ const getZodObject = (schema, type) => {
1806
+ if (isZodType(schema, "ZodObject")) {
1807
+ return schema;
497
1808
  }
498
- };
499
- const validate = (ctx, opts) => {
500
- var _a;
501
- if (Object.keys(ctx.jsonSchema).length) {
502
- return;
1809
+ if (isZodType(schema, "ZodLazy")) {
1810
+ return getZodObject(schema.schema, type);
503
1811
  }
504
- const def = ctx.zodSchema._zod.def;
505
- if ((_a = opts.allowEmptySchema) == null ? void 0 : _a[def.type]) {
506
- return;
1812
+ if (isZodType(schema, "ZodEffects")) {
1813
+ return getZodObject(schema.innerType(), type);
507
1814
  }
508
- switch (def.type) {
509
- case "any": {
510
- return;
511
- }
512
- case "unknown": {
513
- return;
514
- }
515
- case "pipe": {
516
- if (ctx.io === "output") {
517
- throw new Error(
518
- "Zod transform schemas are not supported in output schemas. Please use `.overwrite()` or wrap the schema in a `.pipe()`"
519
- );
520
- }
521
- return;
522
- }
523
- case "transform": {
524
- if (ctx.io === "output") {
525
- return;
526
- }
527
- break;
528
- }
529
- case "literal": {
530
- if (def.values.includes(void 0)) {
531
- throw new Error(
532
- "Zod literal schemas cannot include `undefined` as a value. Please use `z.undefined()` or `.optional()` instead."
533
- );
534
- }
535
- return;
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);
536
1821
  }
1822
+ return getZodObject(schema._def.out, type);
537
1823
  }
538
- throw new Error(
539
- `Zod schema of type \`${def.type}\` cannot be represented in OpenAPI. Please assign it metadata with \`.meta()\``
540
- );
1824
+ throw new Error("failed to find ZodObject in schema");
541
1825
  };
542
- const renameComponents = (components, outputIds, ctx) => {
543
- const componentsToRename = /* @__PURE__ */ new Map();
544
- const componentDependencies = /* @__PURE__ */ new Map();
545
- const stringifiedComponents = /* @__PURE__ */ new Map();
546
- for (const [key, value] of Object.entries(components)) {
547
- const stringified = JSON.stringify(value);
548
- const matches = stringified.matchAll(/"#\/components\/schemas\/([^"]+)"/g);
549
- const dependencies = /* @__PURE__ */ new Set();
550
- for (const match of matches) {
551
- const dep = match[1];
552
- if (dep !== key) {
553
- dependencies.add(dep);
554
- }
555
- }
556
- stringifiedComponents.set(key, stringified);
557
- componentDependencies.set(key, {
558
- dependencies
559
- });
1826
+ const isISpecificationExtension = (key) => key.startsWith("x-");
1827
+ const createResponseHeaders = (responseHeaders, components, documentOptions) => {
1828
+ if (!responseHeaders) {
1829
+ return void 0;
560
1830
  }
561
- for (const [key] of stringifiedComponents) {
562
- const registeredComponent = ctx.registry.schemas.ids.get(key);
563
- if (!registeredComponent) {
564
- continue;
565
- }
566
- if (isDependencyPure(
567
- componentDependencies,
568
- stringifiedComponents,
569
- ctx.registry,
570
- key
571
- )) {
572
- continue;
573
- }
574
- const newName = outputIds.get(key) ?? `${key}Output`;
575
- componentsToRename.set(key, newName);
576
- components[newName] = components[key];
577
- delete components[key];
578
- 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
+ }, {});
579
1836
  }
580
- return componentsToRename;
1837
+ return responseHeaders;
581
1838
  };
582
- const isDependencyPure = (componentDependencies, stringifiedComponents, registry, key, visited = /* @__PURE__ */ new Set()) => {
583
- if (visited.has(key)) {
584
- 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
+ };
585
1846
  }
586
- const dependencies = componentDependencies.get(key);
587
- if (dependencies.pure !== void 0) {
588
- 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");
589
1850
  }
590
- const stringified = stringifiedComponents.get(key);
591
- const component = registry.schemas.ids.get(key);
592
- if (component && stringified !== JSON.stringify(component)) {
593
- dependencies.pure = false;
594
- 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
+ };
595
1861
  }
596
- visited.add(key);
597
- const result = [...dependencies.dependencies].every(
598
- (dep) => isDependencyPure(
599
- componentDependencies,
600
- stringifiedComponents,
601
- registry,
602
- dep,
603
- new Set(visited)
604
- )
605
- );
606
- dependencies.pure = result;
607
- return result;
608
- };
609
- const deleteZodOpenApiMeta = (jsonSchema) => {
610
- delete jsonSchema.param;
611
- delete jsonSchema.header;
612
- delete jsonSchema.unusedIO;
613
- delete jsonSchema.override;
614
- delete jsonSchema.outputId;
615
- };
616
- const createSchema = (schema, ctx = {
617
- registry: createRegistry(),
618
- io: "output",
619
- opts: {}
620
- }) => {
621
- ctx.registry ?? (ctx.registry = createRegistry());
622
- ctx.opts ?? (ctx.opts = {});
623
- ctx.io ?? (ctx.io = "output");
624
- const registrySchemas = Object.fromEntries(ctx.registry.schemas[ctx.io]);
625
- const schemas = {
626
- 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
627
1873
  };
628
- Object.assign(schemas, registrySchemas);
629
- const jsonSchemas = createSchemas(schemas, {
630
- registry: ctx.registry,
631
- io: ctx.io,
632
- opts: ctx.opts
633
- });
1874
+ const schemaObject = createSchema(schema, state, ["header"]);
1875
+ const optionalResult = schema.safeParse(void 0);
1876
+ const required = !optionalResult.success || optionalResult !== void 0;
634
1877
  return {
635
- schema: jsonSchemas.schemas.zodOpenApiCreateSchema,
636
- components: jsonSchemas.components
1878
+ ...rest,
1879
+ ...schema && { schema: schemaObject },
1880
+ ...required && { required }
637
1881
  };
638
1882
  };
639
- const createSchemas = (schemas, ctx) => {
640
- var _a, _b;
641
- const entries = {};
642
- for (const [name, { zodType }] of Object.entries(schemas)) {
643
- entries[name] = zodType;
644
- }
645
- const schemaRegistry = object(entries);
646
- const outputIds = /* @__PURE__ */ new Map();
647
- const jsonSchema = toJSONSchema(schemaRegistry, {
648
- override(context) {
649
- const meta = context.zodSchema.meta();
650
- if ((meta == null ? void 0 : meta.outputId) && (meta == null ? void 0 : meta.id)) {
651
- outputIds.set(meta.id, meta.outputId);
652
- }
653
- if (context.jsonSchema.$ref) {
654
- return;
655
- }
656
- const enrichedContext = { ...context, io: ctx.io };
657
- override(enrichedContext);
658
- if (typeof ctx.opts.override === "function") {
659
- ctx.opts.override(enrichedContext);
660
- }
661
- if (typeof (meta == null ? void 0 : meta.override) === "function") {
662
- meta.override(enrichedContext);
663
- delete context.jsonSchema.override;
664
- }
665
- if (typeof (meta == null ? void 0 : meta.override) === "object" && meta.override !== null) {
666
- Object.assign(context.jsonSchema, meta.override);
667
- delete context.jsonSchema.override;
668
- }
669
- delete context.jsonSchema.$schema;
670
- delete context.jsonSchema.id;
671
- deleteZodOpenApiMeta(context.jsonSchema);
672
- validate(enrichedContext, ctx.opts);
673
- },
674
- io: ctx.io,
675
- unrepresentable: "any"
676
- });
677
- const components = jsonSchema.$defs ?? {};
678
- const dynamicComponents = /* @__PURE__ */ new Map();
679
- for (const [key, value] of Object.entries(components)) {
680
- if (/^__schema\d+$/.test(key)) {
681
- const newName = `__schema${ctx.registry.schemas.dynamicSchemaCount++}`;
682
- dynamicComponents.set(key, `"#/components/schemas/${newName}"`);
683
- if (newName !== key) {
684
- components[newName] = value;
685
- delete components[key];
686
- }
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
1897
+ );
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
+ )
687
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
+ };
688
1921
  }
689
- const parsedJsonSchema = JSON.parse(
690
- JSON.stringify(jsonSchema).replace(
691
- /"#\/\$defs\/([^"]+)"/g,
692
- (_, match) => {
693
- const dynamic = dynamicComponents.get(match);
694
- if (dynamic) {
695
- return dynamic;
696
- }
697
- const manualComponent = ctx.registry.schemas.manual.get(match);
698
- if (manualComponent) {
699
- manualComponent.io[ctx.io].used++;
700
- }
701
- return `"#/components/schemas/${match}"`;
702
- }
703
- )
704
- );
705
- for (const [key, value] of ctx.registry.schemas.manual) {
706
- if (value.io[ctx.io].used === 1 && ((_a = parsedJsonSchema.properties) == null ? void 0 : _a[value.identifier]) && ((_b = parsedJsonSchema.$defs) == null ? void 0 : _b[key])) {
707
- parsedJsonSchema.properties[value.identifier] = parsedJsonSchema.$defs[key];
708
- delete parsedJsonSchema.$defs[key];
709
- continue;
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;
710
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;
711
1943
  }
712
- const renamedComponents = renameComponents(
713
- parsedJsonSchema.$defs ?? {},
714
- outputIds,
715
- ctx
716
- );
717
- if (!renamedComponents.size) {
1944
+ const component = components.requestBodies.get(requestBodyObject);
1945
+ if (component && component.type === "complete") {
718
1946
  return {
719
- schemas: parsedJsonSchema.properties,
720
- components: parsedJsonSchema.$defs ?? {}
1947
+ $ref: createComponentRequestBodyRef(component.ref)
721
1948
  };
722
1949
  }
723
- const renamedJsonSchema = JSON.parse(
724
- JSON.stringify(parsedJsonSchema).replace(
725
- /"#\/components\/schemas\/([^"]+)"/g,
726
- (_, match) => {
727
- const replacement = renamedComponents.get(match);
728
- if (replacement) {
729
- return `"#/components/schemas/${replacement}"`;
730
- }
731
- return `"#/components/schemas/${match}"`;
732
- }
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
733
1960
  )
1961
+ };
1962
+ if (ref) {
1963
+ components.requestBodies.set(requestBodyObject, {
1964
+ type: "complete",
1965
+ ref,
1966
+ requestBodyObject: requestBody
1967
+ });
1968
+ return {
1969
+ $ref: createComponentRequestBodyRef(ref)
1970
+ };
1971
+ }
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
734
2000
  );
735
2001
  return {
736
- schemas: renamedJsonSchema.properties,
737
- components: renamedJsonSchema.$defs ?? {}
2002
+ ...rest,
2003
+ ...maybeParameters && { parameters: maybeParameters },
2004
+ ...maybeRequestBody && { requestBody: maybeRequestBody },
2005
+ ...maybeResponses && { responses: maybeResponses },
2006
+ ...maybeCallbacks && { callbacks: maybeCallbacks }
738
2007
  };
739
2008
  };
740
- const createRegistry = (components) => {
741
- const registry = {
742
- schemas: {
743
- dynamicSchemaCount: 0,
744
- input: /* @__PURE__ */ new Map(),
745
- output: /* @__PURE__ */ new Map(),
746
- ids: /* @__PURE__ */ new Map(),
747
- manual: /* @__PURE__ */ new Map(),
748
- setSchema: (key, schema, io) => {
749
- const schemaObject = {};
750
- registry.schemas[io].set(key, {
751
- schemaObject,
752
- zodType: schema
753
- });
754
- 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;
755
2037
  }
2038
+ acc[path] = createPathItem(
2039
+ pathItemObject,
2040
+ components,
2041
+ [path],
2042
+ documentOptions
2043
+ );
2044
+ return acc;
756
2045
  },
757
- headers: {
758
- ids: /* @__PURE__ */ new Map(),
759
- seen: /* @__PURE__ */ new WeakMap()
760
- },
761
- requestBodies: {
762
- ids: /* @__PURE__ */ new Map(),
763
- seen: /* @__PURE__ */ new WeakMap()
764
- },
765
- responses: {
766
- ids: /* @__PURE__ */ new Map(),
767
- seen: /* @__PURE__ */ new WeakMap()
768
- },
769
- parameters: {
770
- ids: /* @__PURE__ */ new Map(),
771
- seen: /* @__PURE__ */ new WeakMap()
772
- },
773
- callbacks: {
774
- ids: /* @__PURE__ */ new Map(),
775
- seen: /* @__PURE__ */ new WeakMap()
776
- },
777
- pathItems: {
778
- ids: /* @__PURE__ */ new Map(),
779
- 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;
780
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
781
2110
  };
782
- registerSchemas(components == null ? void 0 : components.schemas, registry);
783
- registerParameters(components == null ? void 0 : components.parameters, registry);
784
- registerHeaders(components == null ? void 0 : components.headers, registry);
785
- registerResponses(components == null ? void 0 : components.responses, registry);
786
- registerPathItems(components == null ? void 0 : components.pathItems, registry);
787
- registerRequestBodies(components == null ? void 0 : components.requestBodies, registry);
788
- registerCallbacks(components == null ? void 0 : components.callbacks, registry);
789
- return registry;
790
- };
791
- const registerSchemas = (schemas, registry) => {
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) => {
792
2123
  if (!schemas) {
793
2124
  return;
794
2125
  }
795
- for (const [key, schema] of Object.entries(schemas)) {
796
- if (registry.schemas.ids.has(key)) {
797
- throw new Error(`Schema "${key}" is already registered`);
798
- }
2126
+ Object.entries(schemas).forEach(([key, schema]) => {
2127
+ var _a, _b;
799
2128
  if (isAnyZodType(schema)) {
800
- const inputSchemaObject = {};
801
- const outputSchemaObject = {};
802
- const identifier = `components > schemas > ${key}`;
803
- registry.schemas.input.set(identifier, {
804
- zodType: schema,
805
- schemaObject: inputSchemaObject
806
- });
807
- registry.schemas.output.set(identifier, {
808
- zodType: schema,
809
- schemaObject: outputSchemaObject
810
- });
811
- registry.schemas.manual.set(key, {
812
- identifier,
813
- io: {
814
- input: {
815
- schemaObject: inputSchemaObject,
816
- used: 0
817
- },
818
- output: {
819
- schemaObject: outputSchemaObject,
820
- used: 0
821
- }
822
- },
823
- zodType: schema
824
- });
825
- const meta = globalRegistry$1.get(schema);
826
- if (meta == null ? void 0 : meta.id) {
827
- continue;
2129
+ if (components.schemas.has(schema)) {
2130
+ throw new Error(
2131
+ `Schema ${JSON.stringify(schema._def)} is already registered`
2132
+ );
828
2133
  }
829
- globalRegistry$1.add(schema, {
830
- ...meta,
831
- id: key
2134
+ const ref = ((_b = (_a = schema._def.zodOpenApi) == null ? void 0 : _a.openapi) == null ? void 0 : _b.ref) ?? key;
2135
+ components.schemas.set(schema, {
2136
+ type: "manual",
2137
+ ref
832
2138
  });
833
- continue;
834
2139
  }
835
- registry.schemas.ids.set(key, schema);
836
- }
2140
+ });
837
2141
  };
838
- const registerParameters = (parameters, registry) => {
2142
+ const getParameters = (parameters, components) => {
839
2143
  if (!parameters) {
840
2144
  return;
841
2145
  }
842
- for (const [key, schema] of Object.entries(parameters)) {
843
- if (registry.parameters.ids.has(key)) {
844
- throw new Error(`Parameter "${key}" is already registered`);
845
- }
2146
+ Object.entries(parameters).forEach(([key, schema]) => {
2147
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
846
2148
  if (isAnyZodType(schema)) {
847
- const path = ["components", "parameters", key];
848
- const paramObject = createParameter(
849
- schema,
850
- void 0,
851
- {
852
- registry,
853
- io: "input"
854
- },
855
- path
856
- );
857
- registry.parameters.ids.set(key, paramObject);
858
- registry.parameters.seen.set(schema, paramObject);
859
- 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
+ });
860
2166
  }
861
- registry.parameters.ids.set(key, schema);
862
- }
2167
+ });
863
2168
  };
864
- const registerHeaders = (headers, registry) => {
865
- if (!headers) {
2169
+ const getHeaders = (responseHeaders, components) => {
2170
+ if (!responseHeaders) {
866
2171
  return;
867
2172
  }
868
- for (const [key, schema] of Object.entries(headers)) {
869
- if (registry.headers.ids.has(key)) {
870
- throw new Error(`Header "${key}" is already registered`);
871
- }
2173
+ Object.entries(responseHeaders).forEach(([key, schema]) => {
2174
+ var _a, _b, _c;
872
2175
  if (isAnyZodType(schema)) {
873
- const path = ["components", "headers", key];
874
- const headerObject = createHeader(
875
- schema,
876
- {
877
- registry,
878
- io: "output"
879
- },
880
- path
881
- );
882
- registry.headers.ids.set(key, headerObject);
883
- registry.headers.seen.set(schema, headerObject);
884
- 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
+ });
885
2186
  }
886
- registry.headers.ids.set(key, schema);
887
- }
2187
+ });
888
2188
  };
889
- const registerResponses = (responses, registry) => {
2189
+ const getResponses = (responses, components) => {
890
2190
  if (!responses) {
891
2191
  return;
892
2192
  }
893
- for (const [key, schema] of Object.entries(responses)) {
894
- const path = ["components", "responses", key];
895
- if (registry.responses.ids.has(key)) {
896
- 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
+ );
897
2198
  }
898
- const responseObject = createResponse(
899
- schema,
900
- {
901
- registry,
902
- io: "output"
903
- },
904
- path
905
- );
906
- registry.responses.ids.set(key, responseObject);
907
- registry.responses.seen.set(schema, responseObject);
908
- }
2199
+ const ref = (responseObject == null ? void 0 : responseObject.ref) ?? key;
2200
+ components.responses.set(responseObject, {
2201
+ type: "manual",
2202
+ ref
2203
+ });
2204
+ });
909
2205
  };
910
- const registerRequestBodies = (requestBodies, registry) => {
2206
+ const getRequestBodies = (requestBodies, components) => {
911
2207
  if (!requestBodies) {
912
2208
  return;
913
2209
  }
914
- for (const [key, schema] of Object.entries(requestBodies)) {
915
- if (registry.requestBodies.ids.has(key)) {
916
- throw new Error(`RequestBody "${key}" is already registered`);
917
- }
918
- if (isAnyZodType(schema)) {
919
- const path = ["components", "requestBodies", key];
920
- const requestBodyObject = createRequestBody(
921
- schema,
922
- {
923
- registry,
924
- io: "input"
925
- },
926
- 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`
927
2214
  );
928
- registry.requestBodies.ids.set(key, requestBodyObject);
929
- continue;
930
2215
  }
931
- registry.requestBodies.ids.set(key, schema);
932
- }
2216
+ const ref = (requestBody == null ? void 0 : requestBody.ref) ?? key;
2217
+ components.requestBodies.set(requestBody, {
2218
+ type: "manual",
2219
+ ref
2220
+ });
2221
+ });
933
2222
  };
934
- const registerCallbacks = (callbacks, registry) => {
2223
+ const getCallbacks = (callbacks, components) => {
935
2224
  if (!callbacks) {
936
2225
  return;
937
2226
  }
938
- for (const [key, schema] of Object.entries(callbacks)) {
939
- if (registry.callbacks.ids.has(key)) {
940
- 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
+ );
941
2232
  }
942
- const path = ["components", "callbacks", key];
943
- const callbackObject = createCallback(schema, registry, path);
944
- registry.callbacks.ids.set(key, callbackObject);
945
- registry.callbacks.seen.set(schema, callbackObject);
946
- }
2233
+ const ref = (callback == null ? void 0 : callback.ref) ?? key;
2234
+ components.callbacks.set(callback, {
2235
+ type: "manual",
2236
+ ref
2237
+ });
2238
+ });
947
2239
  };
948
- const registerPathItems = (pathItems, registry) => {
949
- if (!pathItems) {
950
- return;
951
- }
952
- for (const [key, schema] of Object.entries(pathItems)) {
953
- if (registry.pathItems.ids.has(key)) {
954
- 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}`]);
955
2296
  }
956
- const path = ["components", "pathItems", key];
957
- const pathItemObject = createPathItem(schema, registry, path);
958
- registry.pathItems.ids.set(key, pathItemObject);
959
- registry.pathItems.seen.set(schema, pathItemObject);
960
- continue;
961
- }
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;
962
2323
  };
963
- const createIOSchemas = (ctx) => {
964
- const { schemas, components } = createSchemas(
965
- Object.fromEntries(ctx.registry.schemas[ctx.io]),
966
- 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
+ {}
967
2350
  );
968
- for (const [key, schema] of Object.entries(components)) {
969
- ctx.registry.schemas.ids.set(key, schema);
970
- }
971
- for (const [key, schema] of Object.entries(schemas)) {
972
- const ioSchema = ctx.registry.schemas[ctx.io].get(key);
973
- if (ioSchema) {
974
- 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;
975
2357
  }
976
- }
2358
+ return acc;
2359
+ }, customComponents);
2360
+ return Object.keys(finalComponents).length ? finalComponents : void 0;
977
2361
  };
978
- const createManualSchemas = (registry) => {
979
- var _a;
980
- for (const [key, value] of registry.schemas.manual) {
981
- if (value.io.input.used === 1) {
982
- const io = ((_a = globalRegistry$1.get(value.zodType)) == null ? void 0 : _a.unusedIO) ?? "output";
983
- const schema = value.io[io].schemaObject;
984
- registry.schemas.ids.set(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);
985
2366
  }
986
- }
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;
987
2388
  };
988
- const createComponents = (registry, opts) => {
989
- createIOSchemas({ registry, io: "input", opts });
990
- createIOSchemas({ registry, io: "output", opts });
991
- createManualSchemas(registry);
992
- const components = {};
993
- if (registry.schemas.ids.size > 0) {
994
- components.schemas = Object.fromEntries(registry.schemas.ids);
995
- }
996
- if (registry.headers.ids.size > 0) {
997
- components.headers = Object.fromEntries(registry.headers.ids);
998
- }
999
- if (registry.requestBodies.ids.size > 0) {
1000
- components.requestBodies = Object.fromEntries(registry.requestBodies.ids);
1001
- }
1002
- if (registry.responses.ids.size > 0) {
1003
- components.responses = Object.fromEntries(registry.responses.ids);
1004
- }
1005
- if (registry.parameters.ids.size > 0) {
1006
- components.parameters = Object.fromEntries(registry.parameters.ids);
1007
- }
1008
- if (registry.callbacks.ids.size > 0) {
1009
- components.callbacks = Object.fromEntries(registry.callbacks.ids);
1010
- }
1011
- if (registry.pathItems.ids.size > 0) {
1012
- components.pathItems = Object.fromEntries(registry.pathItems.ids);
1013
- }
1014
- 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;
1015
2454
  };
1016
2455
  export {
1017
2456
  createComponents,
1018
- createMediaTypeObject,
1019
- createParameter,
2457
+ createMediaTypeSchema,
2458
+ createParamOrRef,
1020
2459
  createPaths,
1021
- createRegistry,
1022
2460
  createSchema,
1023
- unwrapZodObject
2461
+ createSchemaComponents,
2462
+ getDefaultComponents,
2463
+ getZodObject
1024
2464
  };