zod-openapi 5.0.0-beta.19 → 5.0.0-beta.2

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.
@@ -0,0 +1,1086 @@
1
+ import { globalRegistry as globalRegistry$1 } from "zod/v4/core";
2
+ import { globalRegistry, registry, toJSONSchema } from "zod/v4";
3
+ const isAnyZodType = (schema) => typeof schema === "object" && schema !== null && "_zod" in schema;
4
+ const unwrapZodObject = (zodType, io, path) => {
5
+ const def = zodType._zod.def;
6
+ switch (def.type) {
7
+ case "object": {
8
+ return zodType;
9
+ }
10
+ case "lazy": {
11
+ return unwrapZodObject(def.getter(), io, path);
12
+ }
13
+ case "pipe": {
14
+ if (io === "input") {
15
+ return unwrapZodObject(def.in, io, path);
16
+ }
17
+ return unwrapZodObject(def.out, io, path);
18
+ }
19
+ }
20
+ throw new Error(
21
+ `Failed to unwrap ZodObject from type: ${zodType._zod.def.type} at ${path.join(" > ")}`
22
+ );
23
+ };
24
+ const isRequired = (zodType, io) => {
25
+ if (io === "input") {
26
+ return zodType._zod.optin === void 0;
27
+ }
28
+ return zodType._zod.optout === void 0;
29
+ };
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) {
40
+ throw new Error(
41
+ `Parameter at ${path.join(" > ")} is missing \`.meta({ param: { name, in } })\` information`
42
+ );
43
+ }
44
+ const computedPath = [...path, inLocation, name].join(" > ");
45
+ const schemaObject = ctx.registry.schemas.setSchema(
46
+ computedPath,
47
+ parameter,
48
+ ctx.io
49
+ );
50
+ const { id, ...rest } = (meta == null ? void 0 : meta.param) ?? {};
51
+ const parameterObject = {
52
+ ...rest,
53
+ name,
54
+ in: inLocation,
55
+ schema: schemaObject
56
+ };
57
+ if (isRequired(parameter, ctx.io)) {
58
+ parameterObject.required = true;
59
+ }
60
+ if (!parameterObject.description && (meta == null ? void 0 : meta.description)) {
61
+ parameterObject.description = meta.description;
62
+ }
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;
70
+ }
71
+ ctx.registry.parameters.seen.set(parameter, parameterObject);
72
+ return parameterObject;
73
+ };
74
+ const createManualParameters = (parameters, ctx, path) => {
75
+ if (!parameters) {
76
+ return void 0;
77
+ }
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;
85
+ }
86
+ const paramObject = createParameter(parameter, void 0, ctx, [
87
+ ...path,
88
+ "parameters"
89
+ ]);
90
+ parameterObjects.push(paramObject);
91
+ continue;
92
+ }
93
+ parameterObjects.push(parameter);
94
+ }
95
+ return parameterObjects;
96
+ };
97
+ const createParameters = (requestParams, ctx, path) => {
98
+ if (!requestParams) {
99
+ return void 0;
100
+ }
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;
112
+ }
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
+ }
124
+ }
125
+ return parameterObjects;
126
+ };
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
134
+ );
135
+ return {
136
+ ...mediaTypeObject,
137
+ schema: schemaObject
138
+ };
139
+ }
140
+ return mediaTypeObject;
141
+ };
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
+ ]);
150
+ }
151
+ }
152
+ return contentObject;
153
+ };
154
+ const createRequestBody = (requestBody, ctx, path) => {
155
+ if (!requestBody) {
156
+ return void 0;
157
+ }
158
+ const seenRequestBody = ctx.registry.requestBodies.seen.get(requestBody);
159
+ if (seenRequestBody) {
160
+ return seenRequestBody;
161
+ }
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
197
+ );
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;
205
+ }
206
+ ctx.registry.headers.seen.set(header, headerObject);
207
+ return headerObject;
208
+ };
209
+ const createHeaders = (headers, ctx, path) => {
210
+ if (!headers) {
211
+ return void 0;
212
+ }
213
+ if (isAnyZodType(headers)) {
214
+ const zodObject = unwrapZodObject(headers, ctx.io, path);
215
+ const headersObject = {};
216
+ for (const [key, zodSchema] of Object.entries(zodObject._zod.def.shape)) {
217
+ const header = createHeader(zodSchema, ctx, [...path, key]);
218
+ headersObject[key] = header;
219
+ }
220
+ return headersObject;
221
+ }
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}`
242
+ };
243
+ ctx.registry.responses.ids.set(id, responseObject);
244
+ ctx.registry.responses.seen.set(response, ref);
245
+ return ref;
246
+ }
247
+ ctx.registry.responses.seen.set(response, responseObject);
248
+ return responseObject;
249
+ };
250
+ const createResponses = (responses, ctx, path) => {
251
+ if (!responses) {
252
+ return void 0;
253
+ }
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;
261
+ continue;
262
+ }
263
+ if ("$ref" in response) {
264
+ responsesObject[statusCode] = response;
265
+ continue;
266
+ }
267
+ const responseObject = createResponse(
268
+ response,
269
+ ctx,
270
+ [...path, statusCode]
271
+ );
272
+ responsesObject[statusCode] = responseObject;
273
+ }
274
+ return responsesObject;
275
+ };
276
+ const createOperation = (operationObject, registry2, 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: registry2,
290
+ io: "input"
291
+ },
292
+ [...path, "parameters"]
293
+ );
294
+ const maybeRequestParams = createParameters(
295
+ requestParams,
296
+ {
297
+ registry: registry2,
298
+ io: "input"
299
+ },
300
+ [...path, "requestParams"]
301
+ );
302
+ if (maybeRequestParams || maybeManualParameters) {
303
+ operation.parameters = [
304
+ ...maybeRequestParams ?? [],
305
+ ...maybeManualParameters ?? []
306
+ ];
307
+ }
308
+ const maybeRequestBody = createRequestBody(
309
+ requestBody,
310
+ {
311
+ registry: registry2,
312
+ io: "input"
313
+ },
314
+ [...path, "requestBody"]
315
+ );
316
+ if (maybeRequestBody) {
317
+ operation.requestBody = maybeRequestBody;
318
+ }
319
+ const maybeResponses = createResponses(
320
+ responses,
321
+ {
322
+ registry: registry2,
323
+ io: "output"
324
+ },
325
+ [...path, "responses"]
326
+ );
327
+ if (maybeResponses) {
328
+ operation.responses = maybeResponses;
329
+ }
330
+ const maybeCallbacks = createCallbacks(callbacks, registry2, [
331
+ ...path,
332
+ "callbacks"
333
+ ]);
334
+ if (maybeCallbacks) {
335
+ operation.callbacks = maybeCallbacks;
336
+ }
337
+ return operation;
338
+ };
339
+ const createPathItem = (pathItem, registry2, 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
+ registry2,
347
+ [...path, key]
348
+ );
349
+ continue;
350
+ }
351
+ if (key === "parameters") {
352
+ pathItemObject[key] = createManualParameters(
353
+ value,
354
+ {
355
+ registry: registry2,
356
+ io: "input"
357
+ },
358
+ [...path, key]
359
+ );
360
+ continue;
361
+ }
362
+ pathItemObject[key] = value;
363
+ }
364
+ if (id) {
365
+ const ref = {
366
+ $ref: `#/components/pathItems/${id}`
367
+ };
368
+ registry2.pathItems.ids.set(id, pathItemObject);
369
+ registry2.pathItems.seen.set(pathItem, ref);
370
+ return ref;
371
+ }
372
+ registry2.pathItems.seen.set(pathItem, pathItemObject);
373
+ return pathItemObject;
374
+ };
375
+ const createPaths = (paths, registry2, path) => {
376
+ if (!paths) {
377
+ return void 0;
378
+ }
379
+ const pathsObject = {};
380
+ for (const [singlePath, pathItemObject] of Object.entries(paths)) {
381
+ if (isISpecificationExtension(singlePath)) {
382
+ pathsObject[singlePath] = pathItemObject;
383
+ continue;
384
+ }
385
+ pathsObject[singlePath] = createPathItem(pathItemObject, registry2, [
386
+ ...path,
387
+ singlePath
388
+ ]);
389
+ }
390
+ return pathsObject;
391
+ };
392
+ const createCallback = (callbackObject, registry2, path) => {
393
+ const seenCallback = registry2.callbacks.seen.get(callbackObject);
394
+ if (seenCallback) {
395
+ return seenCallback;
396
+ }
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;
403
+ }
404
+ callback[name] = createPathItem(
405
+ pathItem,
406
+ registry2,
407
+ [...path, name]
408
+ );
409
+ }
410
+ if (id) {
411
+ const ref = {
412
+ $ref: `#/components/callbacks/${id}`
413
+ };
414
+ registry2.callbacks.ids.set(id, callback);
415
+ registry2.callbacks.seen.set(callbackObject, ref);
416
+ return ref;
417
+ }
418
+ registry2.callbacks.seen.set(callbackObject, callback);
419
+ return callback;
420
+ };
421
+ const createCallbacks = (callbacks, registry2, path) => {
422
+ if (!callbacks) {
423
+ return void 0;
424
+ }
425
+ const callbacksObject = {};
426
+ for (const [name, value] of Object.entries(callbacks)) {
427
+ if (isISpecificationExtension(name)) {
428
+ callbacksObject[name] = value;
429
+ continue;
430
+ }
431
+ callbacksObject[name] = createCallback(
432
+ value,
433
+ registry2,
434
+ [...path, name]
435
+ );
436
+ }
437
+ return callbacksObject;
438
+ };
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
+ }
497
+ }
498
+ };
499
+ const validate = (ctx, opts) => {
500
+ var _a;
501
+ if (Object.keys(ctx.jsonSchema).length) {
502
+ return;
503
+ }
504
+ const def = ctx.zodSchema._zod.def;
505
+ if ((_a = opts.allowEmptySchema) == null ? void 0 : _a[def.type]) {
506
+ return;
507
+ }
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;
536
+ }
537
+ }
538
+ throw new Error(
539
+ `Zod schema of type \`${def.type}\` cannot be represented in OpenAPI. Please assign it metadata with \`.meta()\``
540
+ );
541
+ };
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
+ });
560
+ }
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;
579
+ }
580
+ return componentsToRename;
581
+ };
582
+ const isDependencyPure = (componentDependencies, stringifiedComponents, registry2, key, visited = /* @__PURE__ */ new Set()) => {
583
+ if (visited.has(key)) {
584
+ return true;
585
+ }
586
+ const dependencies = componentDependencies.get(key);
587
+ if (dependencies.pure !== void 0) {
588
+ return dependencies.pure;
589
+ }
590
+ const stringified = stringifiedComponents.get(key);
591
+ const component = registry2.schemas.ids.get(key);
592
+ if (component && stringified !== JSON.stringify(component)) {
593
+ dependencies.pure = false;
594
+ return false;
595
+ }
596
+ visited.add(key);
597
+ const result = [...dependencies.dependencies].every(
598
+ (dep) => isDependencyPure(
599
+ componentDependencies,
600
+ stringifiedComponents,
601
+ registry2,
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(
625
+ ctx.registry.schemas[ctx.io].schemas
626
+ );
627
+ const schemas = {
628
+ zodOpenApiCreateSchema: { zodType: schema }
629
+ };
630
+ Object.assign(schemas, registrySchemas);
631
+ const jsonSchemas = createSchemas(schemas, {
632
+ registry: ctx.registry,
633
+ io: ctx.io,
634
+ opts: ctx.opts
635
+ });
636
+ return {
637
+ schema: jsonSchemas.schemas.zodOpenApiCreateSchema,
638
+ components: jsonSchemas.components
639
+ };
640
+ };
641
+ const createSchemas = (schemas, {
642
+ registry: registry$1,
643
+ io,
644
+ opts
645
+ }) => {
646
+ var _a, _b, _c, _d, _e, _f;
647
+ const schemaRegistry = registry();
648
+ const globalsInSchemas = /* @__PURE__ */ new Map();
649
+ for (const [name, { zodType }] of Object.entries(schemas)) {
650
+ const id = (_a = globalRegistry.get(zodType)) == null ? void 0 : _a.id;
651
+ if (id) {
652
+ globalsInSchemas.set(name, id);
653
+ }
654
+ schemaRegistry.add(zodType, { id: name });
655
+ }
656
+ const outputIds = /* @__PURE__ */ new Map();
657
+ const jsonSchema = toJSONSchema(schemaRegistry, {
658
+ override(ctx) {
659
+ const meta = ctx.zodSchema.meta();
660
+ if ((meta == null ? void 0 : meta.outputId) && (meta == null ? void 0 : meta.id)) {
661
+ outputIds.set(meta.id, meta.outputId);
662
+ }
663
+ if (ctx.jsonSchema.$ref) {
664
+ return;
665
+ }
666
+ const enrichedContext = { ...ctx, io };
667
+ override(enrichedContext);
668
+ if (typeof opts.override === "function") {
669
+ opts.override(enrichedContext);
670
+ }
671
+ if (typeof (meta == null ? void 0 : meta.override) === "function") {
672
+ meta.override(enrichedContext);
673
+ delete ctx.jsonSchema.override;
674
+ }
675
+ if (typeof (meta == null ? void 0 : meta.override) === "object" && meta.override !== null) {
676
+ Object.assign(ctx.jsonSchema, meta.override);
677
+ delete ctx.jsonSchema.override;
678
+ }
679
+ delete ctx.jsonSchema.$schema;
680
+ delete ctx.jsonSchema.id;
681
+ deleteZodOpenApiMeta(ctx.jsonSchema);
682
+ validate(enrichedContext, opts);
683
+ },
684
+ io,
685
+ unrepresentable: "any",
686
+ uri: (id) => `#/components/schemas/${id}`
687
+ });
688
+ const sharedDefs = ((_b = jsonSchema.schemas.__shared) == null ? void 0 : _b.$defs) ?? {};
689
+ (_c = jsonSchema.schemas).__shared ?? (_c.__shared = { $defs: sharedDefs });
690
+ const componentsToReplace = /* @__PURE__ */ new Map();
691
+ for (const [key, value] of Object.entries(sharedDefs)) {
692
+ if (/^schema\d+$/.exec(key)) {
693
+ const componentName = `__schema${registry$1.schemas.dynamicSchemaCount++}`;
694
+ componentsToReplace.set(`__shared#/$defs/${key}`, componentName);
695
+ delete sharedDefs[key];
696
+ sharedDefs[componentName] = value;
697
+ continue;
698
+ }
699
+ componentsToReplace.set(`__shared#/$defs/${key}`, key);
700
+ }
701
+ for (const value of Object.values(jsonSchema.schemas)) {
702
+ delete value.$schema;
703
+ delete value.id;
704
+ }
705
+ const dynamicComponent = /* @__PURE__ */ new Map();
706
+ const patched = JSON.stringify(jsonSchema).replace(
707
+ /"#\/components\/schemas\/([^"]+)"/g,
708
+ (_, match) => {
709
+ const replacement = componentsToReplace.get(match);
710
+ if (replacement) {
711
+ return `"#/components/schemas/${replacement}"`;
712
+ }
713
+ const component = registry$1.schemas.ids.get(match);
714
+ if (component) {
715
+ return `"#/components/schemas/${match}`;
716
+ }
717
+ const globalInSchema = globalsInSchemas.get(match);
718
+ if (globalInSchema) {
719
+ componentsToReplace.set(match, globalInSchema);
720
+ dynamicComponent.set(match, globalInSchema);
721
+ return `"#/components/schemas/${globalInSchema}"`;
722
+ }
723
+ const manualSchema = registry$1.schemas.manual.get(match);
724
+ if (manualSchema) {
725
+ componentsToReplace.set(match, manualSchema.key);
726
+ dynamicComponent.set(match, manualSchema.key);
727
+ manualSchema.io[io].used = true;
728
+ return `"#/components/schemas/${manualSchema.key}"`;
729
+ }
730
+ const componentName = `__schema${registry$1.schemas.dynamicSchemaCount++}`;
731
+ componentsToReplace.set(match, componentName);
732
+ dynamicComponent.set(match, componentName);
733
+ return `"#/components/schemas/${componentName}"`;
734
+ }
735
+ );
736
+ const patchedJsonSchema = JSON.parse(patched);
737
+ const components = ((_d = patchedJsonSchema.schemas.__shared) == null ? void 0 : _d.$defs) ?? {};
738
+ (_e = patchedJsonSchema.schemas).__shared ?? (_e.__shared = { $defs: components });
739
+ for (const [key, value] of registry$1.schemas.manual) {
740
+ if (value.io[io].used) {
741
+ dynamicComponent.set(key, value.key);
742
+ }
743
+ }
744
+ for (const [key, value] of globalsInSchemas) {
745
+ dynamicComponent.set(key, value);
746
+ }
747
+ for (const [key, value] of dynamicComponent) {
748
+ const component = patchedJsonSchema.schemas[key];
749
+ patchedJsonSchema.schemas[key] = {
750
+ $ref: `#/components/schemas/${value}`
751
+ };
752
+ components[value] = component;
753
+ }
754
+ const renamedComponents = renameComponents(components, outputIds, {
755
+ registry: registry$1
756
+ });
757
+ if (renamedComponents.size === 0) {
758
+ delete patchedJsonSchema.schemas.__shared;
759
+ return {
760
+ schemas: patchedJsonSchema.schemas,
761
+ components
762
+ };
763
+ }
764
+ const renamedStringified = JSON.stringify(patchedJsonSchema).replace(
765
+ /"#\/components\/schemas\/([^"]+)"/g,
766
+ (_, match) => {
767
+ const newName = renamedComponents.get(match);
768
+ if (newName) {
769
+ return `"#/components/schemas/${newName}"`;
770
+ }
771
+ return `"#/components/schemas/${match}"`;
772
+ }
773
+ );
774
+ const renamedJsonSchema = JSON.parse(renamedStringified);
775
+ const renamedJsonSchemaComponents = ((_f = renamedJsonSchema.schemas.__shared) == null ? void 0 : _f.$defs) ?? {};
776
+ delete renamedJsonSchema.schemas.__shared;
777
+ return {
778
+ schemas: renamedJsonSchema.schemas,
779
+ components: renamedJsonSchemaComponents
780
+ };
781
+ };
782
+ const createRegistry = (components) => {
783
+ const registry2 = {
784
+ schemas: {
785
+ dynamicSchemaCount: 0,
786
+ input: {
787
+ seen: /* @__PURE__ */ new WeakMap(),
788
+ schemas: /* @__PURE__ */ new Map()
789
+ },
790
+ output: {
791
+ seen: /* @__PURE__ */ new WeakMap(),
792
+ schemas: /* @__PURE__ */ new Map()
793
+ },
794
+ ids: /* @__PURE__ */ new Map(),
795
+ manual: /* @__PURE__ */ new Map(),
796
+ setSchema: (key, schema, io) => {
797
+ const seenSchema = registry2.schemas[io].seen.get(schema);
798
+ if (seenSchema) {
799
+ if (seenSchema.type === "manual") {
800
+ const manualSchema = registry2.schemas.manual.get(seenSchema.id);
801
+ if (!manualSchema) {
802
+ throw new Error(
803
+ `Manual schema "${key}" not found in registry for ${io} IO.`
804
+ );
805
+ }
806
+ manualSchema.io[io].used = true;
807
+ }
808
+ return seenSchema.schemaObject;
809
+ }
810
+ const schemaObject = {};
811
+ registry2.schemas[io].schemas.set(key, {
812
+ schemaObject,
813
+ zodType: schema
814
+ });
815
+ registry2.schemas[io].seen.set(schema, { type: "schema", schemaObject });
816
+ return schemaObject;
817
+ }
818
+ },
819
+ headers: {
820
+ ids: /* @__PURE__ */ new Map(),
821
+ seen: /* @__PURE__ */ new WeakMap()
822
+ },
823
+ requestBodies: {
824
+ ids: /* @__PURE__ */ new Map(),
825
+ seen: /* @__PURE__ */ new WeakMap()
826
+ },
827
+ responses: {
828
+ ids: /* @__PURE__ */ new Map(),
829
+ seen: /* @__PURE__ */ new WeakMap()
830
+ },
831
+ parameters: {
832
+ ids: /* @__PURE__ */ new Map(),
833
+ seen: /* @__PURE__ */ new WeakMap()
834
+ },
835
+ callbacks: {
836
+ ids: /* @__PURE__ */ new Map(),
837
+ seen: /* @__PURE__ */ new WeakMap()
838
+ },
839
+ pathItems: {
840
+ ids: /* @__PURE__ */ new Map(),
841
+ seen: /* @__PURE__ */ new WeakMap()
842
+ }
843
+ };
844
+ registerSchemas(components == null ? void 0 : components.schemas, registry2);
845
+ registerParameters(components == null ? void 0 : components.parameters, registry2);
846
+ registerHeaders(components == null ? void 0 : components.headers, registry2);
847
+ registerResponses(components == null ? void 0 : components.responses, registry2);
848
+ registerPathItems(components == null ? void 0 : components.pathItems, registry2);
849
+ registerRequestBodies(components == null ? void 0 : components.requestBodies, registry2);
850
+ registerCallbacks(components == null ? void 0 : components.callbacks, registry2);
851
+ return registry2;
852
+ };
853
+ const registerSchemas = (schemas, registry2) => {
854
+ if (!schemas) {
855
+ return;
856
+ }
857
+ for (const [key, schema] of Object.entries(schemas)) {
858
+ if (registry2.schemas.ids.has(key)) {
859
+ throw new Error(`Schema "${key}" is already registered`);
860
+ }
861
+ if (isAnyZodType(schema)) {
862
+ const inputSchemaObject = {};
863
+ const outputSchemaObject = {};
864
+ const identifier = `components > schemas > ${key}`;
865
+ registry2.schemas.input.schemas.set(identifier, {
866
+ zodType: schema,
867
+ schemaObject: inputSchemaObject
868
+ });
869
+ registry2.schemas.input.seen.set(schema, {
870
+ type: "manual",
871
+ schemaObject: inputSchemaObject,
872
+ id: identifier
873
+ });
874
+ registry2.schemas.output.schemas.set(identifier, {
875
+ zodType: schema,
876
+ schemaObject: outputSchemaObject
877
+ });
878
+ registry2.schemas.output.seen.set(schema, {
879
+ type: "manual",
880
+ schemaObject: outputSchemaObject,
881
+ id: identifier
882
+ });
883
+ registry2.schemas.manual.set(identifier, {
884
+ key,
885
+ io: {
886
+ input: {
887
+ schemaObject: inputSchemaObject
888
+ },
889
+ output: {
890
+ schemaObject: outputSchemaObject
891
+ }
892
+ },
893
+ zodType: schema
894
+ });
895
+ continue;
896
+ }
897
+ registry2.schemas.ids.set(key, schema);
898
+ }
899
+ };
900
+ const registerParameters = (parameters, registry2) => {
901
+ if (!parameters) {
902
+ return;
903
+ }
904
+ for (const [key, schema] of Object.entries(parameters)) {
905
+ if (registry2.parameters.ids.has(key)) {
906
+ throw new Error(`Parameter "${key}" is already registered`);
907
+ }
908
+ if (isAnyZodType(schema)) {
909
+ const path = ["components", "parameters", key];
910
+ const paramObject = createParameter(
911
+ schema,
912
+ void 0,
913
+ {
914
+ registry: registry2,
915
+ io: "input"
916
+ },
917
+ path
918
+ );
919
+ registry2.parameters.ids.set(key, paramObject);
920
+ registry2.parameters.seen.set(schema, paramObject);
921
+ continue;
922
+ }
923
+ registry2.parameters.ids.set(key, schema);
924
+ }
925
+ };
926
+ const registerHeaders = (headers, registry2) => {
927
+ if (!headers) {
928
+ return;
929
+ }
930
+ for (const [key, schema] of Object.entries(headers)) {
931
+ if (registry2.headers.ids.has(key)) {
932
+ throw new Error(`Header "${key}" is already registered`);
933
+ }
934
+ if (isAnyZodType(schema)) {
935
+ const path = ["components", "headers", key];
936
+ const headerObject = createHeader(
937
+ schema,
938
+ {
939
+ registry: registry2,
940
+ io: "output"
941
+ },
942
+ path
943
+ );
944
+ registry2.headers.ids.set(key, headerObject);
945
+ registry2.headers.seen.set(schema, headerObject);
946
+ continue;
947
+ }
948
+ registry2.headers.ids.set(key, schema);
949
+ }
950
+ };
951
+ const registerResponses = (responses, registry2) => {
952
+ if (!responses) {
953
+ return;
954
+ }
955
+ for (const [key, schema] of Object.entries(responses)) {
956
+ const path = ["components", "responses", key];
957
+ if (registry2.responses.ids.has(key)) {
958
+ throw new Error(`Response "${key}" is already registered`);
959
+ }
960
+ const responseObject = createResponse(
961
+ schema,
962
+ {
963
+ registry: registry2,
964
+ io: "output"
965
+ },
966
+ path
967
+ );
968
+ registry2.responses.ids.set(key, responseObject);
969
+ registry2.responses.seen.set(schema, responseObject);
970
+ }
971
+ };
972
+ const registerRequestBodies = (requestBodies, registry2) => {
973
+ if (!requestBodies) {
974
+ return;
975
+ }
976
+ for (const [key, schema] of Object.entries(requestBodies)) {
977
+ if (registry2.requestBodies.ids.has(key)) {
978
+ throw new Error(`RequestBody "${key}" is already registered`);
979
+ }
980
+ if (isAnyZodType(schema)) {
981
+ const path = ["components", "requestBodies", key];
982
+ const requestBodyObject = createRequestBody(
983
+ schema,
984
+ {
985
+ registry: registry2,
986
+ io: "input"
987
+ },
988
+ path
989
+ );
990
+ registry2.requestBodies.ids.set(key, requestBodyObject);
991
+ continue;
992
+ }
993
+ registry2.requestBodies.ids.set(key, schema);
994
+ }
995
+ };
996
+ const registerCallbacks = (callbacks, registry2) => {
997
+ if (!callbacks) {
998
+ return;
999
+ }
1000
+ for (const [key, schema] of Object.entries(callbacks)) {
1001
+ if (registry2.callbacks.ids.has(key)) {
1002
+ throw new Error(`Callback "${key}" is already registered`);
1003
+ }
1004
+ const path = ["components", "callbacks", key];
1005
+ const callbackObject = createCallback(schema, registry2, path);
1006
+ registry2.callbacks.ids.set(key, callbackObject);
1007
+ registry2.callbacks.seen.set(schema, callbackObject);
1008
+ }
1009
+ };
1010
+ const registerPathItems = (pathItems, registry2) => {
1011
+ if (!pathItems) {
1012
+ return;
1013
+ }
1014
+ for (const [key, schema] of Object.entries(pathItems)) {
1015
+ if (registry2.pathItems.ids.has(key)) {
1016
+ throw new Error(`PathItem "${key}" is already registered`);
1017
+ }
1018
+ const path = ["components", "pathItems", key];
1019
+ const pathItemObject = createPathItem(schema, registry2, path);
1020
+ registry2.pathItems.ids.set(key, pathItemObject);
1021
+ registry2.pathItems.seen.set(schema, pathItemObject);
1022
+ continue;
1023
+ }
1024
+ };
1025
+ const createIOSchemas = (ctx) => {
1026
+ const { schemas, components } = createSchemas(
1027
+ Object.fromEntries(ctx.registry.schemas[ctx.io].schemas),
1028
+ ctx
1029
+ );
1030
+ for (const [key, schema] of Object.entries(components)) {
1031
+ ctx.registry.schemas.ids.set(key, schema);
1032
+ }
1033
+ for (const [key, schema] of Object.entries(schemas)) {
1034
+ const ioSchema = ctx.registry.schemas[ctx.io].schemas.get(key);
1035
+ if (ioSchema) {
1036
+ Object.assign(ioSchema.schemaObject, schema);
1037
+ }
1038
+ }
1039
+ };
1040
+ const createManualSchemas = (registry2) => {
1041
+ var _a;
1042
+ for (const [, value] of registry2.schemas.manual) {
1043
+ if (!value.io.input.used && !value.io.output.used) {
1044
+ const io = ((_a = globalRegistry$1.get(value.zodType)) == null ? void 0 : _a.unusedIO) ?? "output";
1045
+ const schema = value.io[io].schemaObject;
1046
+ registry2.schemas.ids.set(value.key, schema);
1047
+ }
1048
+ }
1049
+ };
1050
+ const createComponents = (registry2, opts) => {
1051
+ createIOSchemas({ registry: registry2, io: "input", opts });
1052
+ createIOSchemas({ registry: registry2, io: "output", opts });
1053
+ createManualSchemas(registry2);
1054
+ const components = {};
1055
+ if (registry2.schemas.ids.size > 0) {
1056
+ components.schemas = Object.fromEntries(registry2.schemas.ids);
1057
+ }
1058
+ if (registry2.headers.ids.size > 0) {
1059
+ components.headers = Object.fromEntries(registry2.headers.ids);
1060
+ }
1061
+ if (registry2.requestBodies.ids.size > 0) {
1062
+ components.requestBodies = Object.fromEntries(registry2.requestBodies.ids);
1063
+ }
1064
+ if (registry2.responses.ids.size > 0) {
1065
+ components.responses = Object.fromEntries(registry2.responses.ids);
1066
+ }
1067
+ if (registry2.parameters.ids.size > 0) {
1068
+ components.parameters = Object.fromEntries(registry2.parameters.ids);
1069
+ }
1070
+ if (registry2.callbacks.ids.size > 0) {
1071
+ components.callbacks = Object.fromEntries(registry2.callbacks.ids);
1072
+ }
1073
+ if (registry2.pathItems.ids.size > 0) {
1074
+ components.pathItems = Object.fromEntries(registry2.pathItems.ids);
1075
+ }
1076
+ return components;
1077
+ };
1078
+ export {
1079
+ createComponents,
1080
+ createMediaTypeObject,
1081
+ createParameter,
1082
+ createPaths,
1083
+ createRegistry,
1084
+ createSchema,
1085
+ unwrapZodObject
1086
+ };