@temporary-name/server 0.0.1-alpha.0cb08cf84b740850e7d8dcd1d8b87f78af26071b

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +31 -0
  3. package/dist/adapters/aws-lambda/index.d.mts +26 -0
  4. package/dist/adapters/aws-lambda/index.d.ts +26 -0
  5. package/dist/adapters/aws-lambda/index.mjs +30 -0
  6. package/dist/adapters/fastify/index.d.mts +23 -0
  7. package/dist/adapters/fastify/index.d.ts +23 -0
  8. package/dist/adapters/fastify/index.mjs +30 -0
  9. package/dist/adapters/fetch/index.d.mts +28 -0
  10. package/dist/adapters/fetch/index.d.ts +28 -0
  11. package/dist/adapters/fetch/index.mjs +32 -0
  12. package/dist/adapters/node/index.d.mts +26 -0
  13. package/dist/adapters/node/index.d.ts +26 -0
  14. package/dist/adapters/node/index.mjs +30 -0
  15. package/dist/handler/index.d.mts +22 -0
  16. package/dist/handler/index.d.ts +22 -0
  17. package/dist/handler/index.mjs +8 -0
  18. package/dist/helpers/index.d.mts +149 -0
  19. package/dist/helpers/index.d.ts +149 -0
  20. package/dist/helpers/index.mjs +142 -0
  21. package/dist/index.d.mts +395 -0
  22. package/dist/index.d.ts +395 -0
  23. package/dist/index.mjs +831 -0
  24. package/dist/openapi/index.d.mts +167 -0
  25. package/dist/openapi/index.d.ts +167 -0
  26. package/dist/openapi/index.mjs +15 -0
  27. package/dist/shared/server.BOkueCuE.d.ts +39 -0
  28. package/dist/shared/server.BTVDgKdb.d.mts +9552 -0
  29. package/dist/shared/server.BTVDgKdb.d.ts +9552 -0
  30. package/dist/shared/server.C1RJffw4.mjs +30 -0
  31. package/dist/shared/server.CWiZN27E.d.mts +39 -0
  32. package/dist/shared/server.CjPiuQYH.d.mts +51 -0
  33. package/dist/shared/server.CjPiuQYH.d.ts +51 -0
  34. package/dist/shared/server.D7jtfDRy.mjs +288 -0
  35. package/dist/shared/server.JwVIEHL6.mjs +386 -0
  36. package/dist/shared/server.RQr7F4gX.mjs +1292 -0
  37. package/package.json +87 -0
@@ -0,0 +1,1292 @@
1
+ import { isAsyncIteratorObject, toArray, isObject, stringifyJSON, findDeepMatches, clone, assertNever, fallbackContractConfig } from '@temporary-name/shared';
2
+ import * as z from '@temporary-name/zod';
3
+ import { custom, safeParseAsync } from '@temporary-name/zod';
4
+ import { V as ValidationError, s as standardizeHTTPPath, u as unlazyResources, g as getDynamicParams } from './server.D7jtfDRy.mjs';
5
+ import { mapEventIterator } from '@temporary-name/standard-server';
6
+ import { JSONSchemaFormat, JSONSchemaContentEncoding } from '@temporary-name/server/openapi';
7
+ import { registry, globalRegistry } from 'zod/v4/core';
8
+ import { TypeName } from '@temporary-name/interop/json-schema-typed/draft-2020-12';
9
+
10
+ const EVENT_ITERATOR_DETAILS_SYMBOL = Symbol("KRUSTY_EVENT_ITERATOR_DETAILS");
11
+ function eventIterator(yields, returns) {
12
+ const schema = custom(
13
+ (iterator) => isAsyncIteratorObject(iterator)
14
+ ).transform((iterator) => {
15
+ const mapped = mapEventIterator(iterator, {
16
+ async value(value, done) {
17
+ const schema2 = done ? returns : yields;
18
+ if (!schema2) {
19
+ return value;
20
+ }
21
+ const result = await safeParseAsync(schema2, value);
22
+ if (result.success) {
23
+ return result.data;
24
+ } else {
25
+ throw new Error("Event iterator validation failed", {
26
+ cause: new ValidationError({
27
+ issues: result.error.issues,
28
+ data: value
29
+ })
30
+ });
31
+ }
32
+ },
33
+ error: async (error) => error
34
+ });
35
+ return mapped;
36
+ });
37
+ schema[EVENT_ITERATOR_DETAILS_SYMBOL] = {
38
+ yields,
39
+ returns
40
+ };
41
+ return schema;
42
+ }
43
+ function getEventIteratorSchemaDetails(schema) {
44
+ if (schema === void 0) {
45
+ return void 0;
46
+ }
47
+ return schema[EVENT_ITERATOR_DETAILS_SYMBOL];
48
+ }
49
+
50
+ var JsonSchemaXNativeType = /* @__PURE__ */ ((JsonSchemaXNativeType2) => {
51
+ JsonSchemaXNativeType2["BigInt"] = "bigint";
52
+ JsonSchemaXNativeType2["RegExp"] = "regexp";
53
+ JsonSchemaXNativeType2["Date"] = "date";
54
+ JsonSchemaXNativeType2["Url"] = "url";
55
+ JsonSchemaXNativeType2["Set"] = "set";
56
+ JsonSchemaXNativeType2["Map"] = "map";
57
+ return JsonSchemaXNativeType2;
58
+ })(JsonSchemaXNativeType || {});
59
+
60
+ const JSON_SCHEMA_REGISTRY = registry();
61
+ const JSON_SCHEMA_INPUT_REGISTRY = registry();
62
+ const JSON_SCHEMA_OUTPUT_REGISTRY = registry();
63
+
64
+ class ZodToJsonSchemaConverter {
65
+ maxLazyDepth;
66
+ maxStructureDepth;
67
+ anyJsonSchema;
68
+ unsupportedJsonSchema;
69
+ undefinedJsonSchema;
70
+ constructor(options = {}) {
71
+ this.maxLazyDepth = options.maxLazyDepth ?? 2;
72
+ this.maxStructureDepth = options.maxStructureDepth ?? 10;
73
+ this.anyJsonSchema = options.anyJsonSchema ?? {};
74
+ this.unsupportedJsonSchema = options.unsupportedJsonSchema ?? { not: {} };
75
+ this.undefinedJsonSchema = options.undefinedJsonSchema ?? { not: {} };
76
+ }
77
+ convert = (schema, options) => {
78
+ return this.#convert(schema, options, 0, 0);
79
+ };
80
+ #convert(schema, options, lazyDepth, structureDepth, isHandledCustomJSONSchema = false) {
81
+ if (structureDepth > this.maxStructureDepth) {
82
+ return [false, this.anyJsonSchema];
83
+ }
84
+ if (!options.minStructureDepthForRef || options.minStructureDepthForRef <= structureDepth) {
85
+ const components = toArray(options.components);
86
+ for (const component of components) {
87
+ if (component.schema === schema && component.allowedStrategies.includes(options.strategy)) {
88
+ return [component.required, { $ref: component.ref }];
89
+ }
90
+ }
91
+ }
92
+ if (!isHandledCustomJSONSchema) {
93
+ const customJSONSchema = this.#getCustomJsonSchema(schema, options);
94
+ if (customJSONSchema) {
95
+ const [required, json] = this.#convert(schema, options, lazyDepth, structureDepth, true);
96
+ return [required, { ...json, ...customJSONSchema }];
97
+ }
98
+ }
99
+ switch (schema._zod.def.type) {
100
+ case "string": {
101
+ const string = schema;
102
+ const json = { type: "string" };
103
+ const { minimum, maximum, format, patterns, contentEncoding } = string._zod.bag;
104
+ if (typeof minimum === "number") {
105
+ json.minLength = minimum;
106
+ }
107
+ if (typeof maximum === "number") {
108
+ json.maxLength = maximum;
109
+ }
110
+ if (typeof contentEncoding === "string") {
111
+ json.contentEncoding = this.#handleContentEncoding(contentEncoding);
112
+ }
113
+ if (typeof format === "string" && format !== "regex" && json.contentEncoding === void 0) {
114
+ json.format = this.#handleStringFormat(format);
115
+ }
116
+ if (patterns instanceof Set && json.contentEncoding === void 0 && json.format === void 0) {
117
+ for (const pattern of patterns) {
118
+ if (json.pattern === void 0) {
119
+ json.pattern = pattern.source;
120
+ } else {
121
+ json.allOf ??= [];
122
+ json.allOf.push({ pattern: pattern.source });
123
+ }
124
+ }
125
+ }
126
+ if (format === "jwt" && json.contentEncoding === void 0 && json.format === void 0 && json.pattern === void 0) {
127
+ json.pattern = /^[\w-]+\.[\w-]+\.[\w-]+$/.source;
128
+ }
129
+ return [true, json];
130
+ }
131
+ case "number": {
132
+ const number = schema;
133
+ const json = { type: "number" };
134
+ const { minimum, maximum, format, multipleOf, exclusiveMaximum, exclusiveMinimum } = number._zod.bag;
135
+ if (typeof format === "string" && format?.includes("int")) {
136
+ json.type = "integer";
137
+ }
138
+ if (typeof minimum === "number") {
139
+ json.minimum = minimum;
140
+ }
141
+ if (typeof maximum === "number") {
142
+ json.maximum = maximum;
143
+ }
144
+ if (typeof exclusiveMinimum === "number") {
145
+ json.exclusiveMinimum = exclusiveMinimum;
146
+ }
147
+ if (typeof exclusiveMaximum === "number") {
148
+ json.exclusiveMaximum = exclusiveMaximum;
149
+ }
150
+ if (typeof multipleOf === "number") {
151
+ json.multipleOf = multipleOf;
152
+ }
153
+ return [true, json];
154
+ }
155
+ case "boolean": {
156
+ return [true, { type: "boolean" }];
157
+ }
158
+ case "bigint": {
159
+ return [
160
+ true,
161
+ {
162
+ type: "string",
163
+ pattern: "^-?[0-9]+$",
164
+ "x-native-type": JsonSchemaXNativeType.BigInt
165
+ }
166
+ ];
167
+ }
168
+ case "date": {
169
+ return [
170
+ true,
171
+ {
172
+ type: "string",
173
+ format: JSONSchemaFormat.DateTime,
174
+ "x-native-type": JsonSchemaXNativeType.Date
175
+ }
176
+ ];
177
+ }
178
+ case "null": {
179
+ return [true, { type: "null" }];
180
+ }
181
+ case "undefined":
182
+ case "void": {
183
+ return [false, this.undefinedJsonSchema];
184
+ }
185
+ case "any": {
186
+ return [false, this.anyJsonSchema];
187
+ }
188
+ case "unknown": {
189
+ return [false, this.anyJsonSchema];
190
+ }
191
+ case "never": {
192
+ return [true, this.unsupportedJsonSchema];
193
+ }
194
+ case "array": {
195
+ const array = schema;
196
+ const json = { type: "array" };
197
+ const { minimum, maximum } = array._zod.bag;
198
+ if (typeof minimum === "number") {
199
+ json.minItems = minimum;
200
+ }
201
+ if (typeof maximum === "number") {
202
+ json.maxItems = maximum;
203
+ }
204
+ json.items = this.#handleArrayItemJsonSchema(
205
+ this.#convert(array._zod.def.element, options, lazyDepth, structureDepth + 1),
206
+ options
207
+ );
208
+ return [true, json];
209
+ }
210
+ case "object": {
211
+ const object = schema;
212
+ const json = { type: "object" };
213
+ let required = true;
214
+ for (const [key, value] of Object.entries(object._zod.def.shape)) {
215
+ const [itemRequired, itemJson] = this.#convert(value, options, lazyDepth, structureDepth + 1);
216
+ json.properties ??= {};
217
+ json.properties[key] = itemJson;
218
+ if (itemRequired) {
219
+ json.required ??= [];
220
+ json.required.push(key);
221
+ }
222
+ }
223
+ const { catchall } = object._zod.def;
224
+ if (!catchall || catchall._zod.def.type === "never") {
225
+ json.additionalProperties = false;
226
+ } else if (catchall) {
227
+ const [_, addJson] = this.#convert(catchall, options, lazyDepth, structureDepth + 1);
228
+ json.additionalProperties = addJson;
229
+ }
230
+ if (options.strategy === "input" && structureDepth === 0 && (!json.properties || Object.keys(json.properties).length === 0)) {
231
+ required = false;
232
+ }
233
+ return [required, json];
234
+ }
235
+ case "union": {
236
+ const union = schema;
237
+ const anyOf = [];
238
+ let required = true;
239
+ for (const item of union._zod.def.options) {
240
+ const [itemRequired, itemJson] = this.#convert(item, options, lazyDepth, structureDepth);
241
+ if (!itemRequired) {
242
+ required = false;
243
+ }
244
+ if (options.strategy === "input") {
245
+ if (itemJson !== this.undefinedJsonSchema && itemJson !== this.unsupportedJsonSchema) {
246
+ anyOf.push(itemJson);
247
+ }
248
+ } else {
249
+ if (itemJson !== this.undefinedJsonSchema) {
250
+ anyOf.push(itemJson);
251
+ }
252
+ }
253
+ }
254
+ return [required, anyOf.length === 1 ? anyOf[0] : { anyOf }];
255
+ }
256
+ case "intersection": {
257
+ const intersection = schema;
258
+ const json = { allOf: [] };
259
+ let required = false;
260
+ for (const item of [intersection._zod.def.left, intersection._zod.def.right]) {
261
+ const [itemRequired, itemJson] = this.#convert(item, options, lazyDepth, structureDepth);
262
+ json.allOf.push(itemJson);
263
+ if (itemRequired) {
264
+ required = true;
265
+ }
266
+ }
267
+ return [required, json];
268
+ }
269
+ case "tuple": {
270
+ const tuple = schema;
271
+ const json = { type: "array", prefixItems: [] };
272
+ for (const item of tuple._zod.def.items) {
273
+ json.prefixItems.push(
274
+ this.#handleArrayItemJsonSchema(
275
+ this.#convert(item, options, lazyDepth, structureDepth + 1),
276
+ options
277
+ )
278
+ );
279
+ }
280
+ if (tuple._zod.def.rest) {
281
+ json.items = this.#handleArrayItemJsonSchema(
282
+ this.#convert(tuple._zod.def.rest, options, lazyDepth, structureDepth + 1),
283
+ options
284
+ );
285
+ }
286
+ const { minimum, maximum } = tuple._zod.bag;
287
+ if (typeof minimum === "number") {
288
+ json.minItems = minimum;
289
+ }
290
+ if (typeof maximum === "number") {
291
+ json.maxItems = maximum;
292
+ }
293
+ return [true, json];
294
+ }
295
+ case "record": {
296
+ const record = schema;
297
+ const json = { type: "object" };
298
+ json.propertyNames = this.#convert(
299
+ record._zod.def.keyType,
300
+ options,
301
+ lazyDepth,
302
+ structureDepth + 1
303
+ )[1];
304
+ json.additionalProperties = this.#convert(
305
+ record._zod.def.valueType,
306
+ options,
307
+ lazyDepth,
308
+ structureDepth + 1
309
+ )[1];
310
+ return [true, json];
311
+ }
312
+ case "map": {
313
+ const map = schema;
314
+ return [
315
+ true,
316
+ {
317
+ type: "array",
318
+ items: {
319
+ type: "array",
320
+ prefixItems: [
321
+ this.#handleArrayItemJsonSchema(
322
+ this.#convert(map._zod.def.keyType, options, lazyDepth, structureDepth + 1),
323
+ options
324
+ ),
325
+ this.#handleArrayItemJsonSchema(
326
+ this.#convert(map._zod.def.valueType, options, lazyDepth, structureDepth + 1),
327
+ options
328
+ )
329
+ ],
330
+ maxItems: 2,
331
+ minItems: 2
332
+ },
333
+ "x-native-type": JsonSchemaXNativeType.Map
334
+ }
335
+ ];
336
+ }
337
+ case "set": {
338
+ const set = schema;
339
+ return [
340
+ true,
341
+ {
342
+ type: "array",
343
+ uniqueItems: true,
344
+ items: this.#handleArrayItemJsonSchema(
345
+ this.#convert(set._zod.def.valueType, options, lazyDepth, structureDepth + 1),
346
+ options
347
+ ),
348
+ "x-native-type": JsonSchemaXNativeType.Set
349
+ }
350
+ ];
351
+ }
352
+ case "enum": {
353
+ const enum_ = schema;
354
+ return [true, { enum: Object.values(enum_._zod.def.entries) }];
355
+ }
356
+ case "literal": {
357
+ const literal = schema;
358
+ let required = true;
359
+ const values = /* @__PURE__ */ new Set();
360
+ for (const value of literal._zod.def.values) {
361
+ if (value === void 0) {
362
+ required = false;
363
+ } else {
364
+ values.add(typeof value === "bigint" ? value.toString() : value);
365
+ }
366
+ }
367
+ const json = values.size === 0 ? this.undefinedJsonSchema : values.size === 1 ? { const: values.values().next().value } : { enum: Array.from(values) };
368
+ return [required, json];
369
+ }
370
+ case "file": {
371
+ const file = schema;
372
+ const oneOf = [];
373
+ const { mime } = file._zod.bag;
374
+ if (mime === void 0 || Array.isArray(mime) && mime.every((m) => typeof m === "string")) {
375
+ for (const type of mime ?? ["*/*"]) {
376
+ oneOf.push({
377
+ type: "string",
378
+ contentMediaType: type
379
+ });
380
+ }
381
+ }
382
+ return [true, oneOf.length === 1 ? oneOf[0] : { anyOf: oneOf }];
383
+ }
384
+ case "transform": {
385
+ return [false, this.anyJsonSchema];
386
+ }
387
+ case "nullable": {
388
+ const nullable = schema;
389
+ const [required, json] = this.#convert(
390
+ nullable._zod.def.innerType,
391
+ options,
392
+ lazyDepth,
393
+ structureDepth
394
+ );
395
+ return [required, { anyOf: [json, { type: "null" }] }];
396
+ }
397
+ case "nonoptional": {
398
+ const nonoptional = schema;
399
+ const [, json] = this.#convert(nonoptional._zod.def.innerType, options, lazyDepth, structureDepth);
400
+ return [true, json];
401
+ }
402
+ case "success": {
403
+ return [true, { type: "boolean" }];
404
+ }
405
+ case "default":
406
+ case "prefault": {
407
+ const default_ = schema;
408
+ const [, json] = this.#convert(default_._zod.def.innerType, options, lazyDepth, structureDepth);
409
+ return [
410
+ false,
411
+ {
412
+ ...json,
413
+ default: default_._zod.def.defaultValue
414
+ }
415
+ ];
416
+ }
417
+ case "catch": {
418
+ const catch_ = schema;
419
+ return this.#convert(catch_._zod.def.innerType, options, lazyDepth, structureDepth);
420
+ }
421
+ case "nan": {
422
+ return [true, options.strategy === "input" ? this.unsupportedJsonSchema : { type: "null" }];
423
+ }
424
+ case "pipe": {
425
+ const pipe = schema;
426
+ return this.#convert(
427
+ options.strategy === "input" ? pipe._zod.def.in : pipe._zod.def.out,
428
+ options,
429
+ lazyDepth,
430
+ structureDepth
431
+ );
432
+ }
433
+ case "readonly": {
434
+ const readonly_ = schema;
435
+ const [required, json] = this.#convert(
436
+ readonly_._zod.def.innerType,
437
+ options,
438
+ lazyDepth,
439
+ structureDepth
440
+ );
441
+ return [required, { ...json, readOnly: true }];
442
+ }
443
+ case "template_literal": {
444
+ const templateLiteral = schema;
445
+ return [
446
+ true,
447
+ {
448
+ type: "string",
449
+ pattern: templateLiteral._zod.pattern.source
450
+ }
451
+ ];
452
+ }
453
+ case "optional": {
454
+ const optional = schema;
455
+ const [, json] = this.#convert(optional._zod.def.innerType, options, lazyDepth, structureDepth);
456
+ return [false, json];
457
+ }
458
+ case "lazy": {
459
+ const lazy = schema;
460
+ const currentLazyDepth = lazyDepth + 1;
461
+ if (currentLazyDepth > this.maxLazyDepth) {
462
+ return [false, this.anyJsonSchema];
463
+ }
464
+ return this.#convert(lazy._zod.def.getter(), options, currentLazyDepth, structureDepth);
465
+ }
466
+ default: {
467
+ schema._zod.def.type;
468
+ return [true, this.unsupportedJsonSchema];
469
+ }
470
+ }
471
+ }
472
+ #getCustomJsonSchema(schema, options) {
473
+ if (options.strategy === "input" && JSON_SCHEMA_INPUT_REGISTRY.has(schema)) {
474
+ return JSON_SCHEMA_INPUT_REGISTRY.get(schema);
475
+ }
476
+ if (options.strategy === "output" && JSON_SCHEMA_OUTPUT_REGISTRY.has(schema)) {
477
+ return JSON_SCHEMA_OUTPUT_REGISTRY.get(schema);
478
+ }
479
+ if (JSON_SCHEMA_REGISTRY.has(schema)) {
480
+ return JSON_SCHEMA_REGISTRY.get(schema);
481
+ }
482
+ const global = globalRegistry.get(schema);
483
+ if (global) {
484
+ return {
485
+ title: global.title,
486
+ description: global.description,
487
+ examples: Array.isArray(global.examples) ? global.examples : void 0
488
+ };
489
+ }
490
+ }
491
+ #handleArrayItemJsonSchema([required, schema], options) {
492
+ if (required || options.strategy === "input" || schema.default !== void 0) {
493
+ return schema;
494
+ }
495
+ if (schema === this.undefinedJsonSchema) {
496
+ return { type: "null" };
497
+ }
498
+ return {
499
+ anyOf: [
500
+ // schema can contain { type: 'null' } so we should use anyOf instead of oneOf
501
+ schema,
502
+ { type: "null" }
503
+ ]
504
+ };
505
+ }
506
+ #handleStringFormat(format) {
507
+ if (format === "guid") {
508
+ return JSONSchemaFormat.UUID;
509
+ }
510
+ if (format === "url") {
511
+ return JSONSchemaFormat.URI;
512
+ }
513
+ if (format === "datetime") {
514
+ return JSONSchemaFormat.DateTime;
515
+ }
516
+ return Object.values(JSONSchemaFormat).includes(format) ? format : void 0;
517
+ }
518
+ #handleContentEncoding(contentEncoding) {
519
+ return Object.values(JSONSchemaContentEncoding).includes(contentEncoding) ? contentEncoding : void 0;
520
+ }
521
+ }
522
+
523
+ const OPERATION_EXTENDER_SYMBOL = Symbol("KRUSTY_OPERATION_EXTENDER");
524
+ function customOpenAPIOperation(o, extend) {
525
+ return new Proxy(o, {
526
+ get(target, prop, receiver) {
527
+ if (prop === OPERATION_EXTENDER_SYMBOL) {
528
+ return extend;
529
+ }
530
+ return Reflect.get(target, prop, receiver);
531
+ }
532
+ });
533
+ }
534
+ function getCustomOpenAPIOperation(o) {
535
+ return o[OPERATION_EXTENDER_SYMBOL];
536
+ }
537
+ function applyCustomOpenAPIOperation(operation, contract) {
538
+ const operationCustoms = [];
539
+ for (const middleware of contract["~def"].middlewares) {
540
+ const maybeExtender = getCustomOpenAPIOperation(middleware);
541
+ if (maybeExtender) {
542
+ operationCustoms.push(maybeExtender);
543
+ }
544
+ }
545
+ let currentOperation = operation;
546
+ for (const custom of operationCustoms) {
547
+ if (typeof custom === "function") {
548
+ currentOperation = custom(currentOperation, contract);
549
+ } else {
550
+ currentOperation = {
551
+ ...currentOperation,
552
+ ...custom
553
+ };
554
+ }
555
+ }
556
+ return currentOperation;
557
+ }
558
+
559
+ const LOGIC_KEYWORDS = [
560
+ "$dynamicRef",
561
+ "$ref",
562
+ "additionalItems",
563
+ "additionalProperties",
564
+ "allOf",
565
+ "anyOf",
566
+ "const",
567
+ "contains",
568
+ "contentEncoding",
569
+ "contentMediaType",
570
+ "contentSchema",
571
+ "dependencies",
572
+ "dependentRequired",
573
+ "dependentSchemas",
574
+ "else",
575
+ "enum",
576
+ "exclusiveMaximum",
577
+ "exclusiveMinimum",
578
+ "format",
579
+ "if",
580
+ "items",
581
+ "maxContains",
582
+ "maximum",
583
+ "maxItems",
584
+ "maxLength",
585
+ "maxProperties",
586
+ "minContains",
587
+ "minimum",
588
+ "minItems",
589
+ "minLength",
590
+ "minProperties",
591
+ "multipleOf",
592
+ "not",
593
+ "oneOf",
594
+ "pattern",
595
+ "patternProperties",
596
+ "prefixItems",
597
+ "properties",
598
+ "propertyNames",
599
+ "required",
600
+ "then",
601
+ "type",
602
+ "unevaluatedItems",
603
+ "unevaluatedProperties",
604
+ "uniqueItems"
605
+ ];
606
+
607
+ function isFileSchema(schema) {
608
+ return isObject(schema) && schema.type === "string" && typeof schema.contentMediaType === "string";
609
+ }
610
+ function isObjectSchema(schema) {
611
+ return isObject(schema) && schema.type === "object";
612
+ }
613
+ function isAnySchema(schema) {
614
+ if (schema === true) {
615
+ return true;
616
+ }
617
+ if (Object.keys(schema).every((k) => !LOGIC_KEYWORDS.includes(k))) {
618
+ return true;
619
+ }
620
+ return false;
621
+ }
622
+ function separateObjectSchema(schema, separatedProperties) {
623
+ if (Object.keys(schema).some(
624
+ (k) => !["type", "properties", "required", "additionalProperties"].includes(k) && LOGIC_KEYWORDS.includes(k) && schema[k] !== void 0
625
+ )) {
626
+ return [{ type: "object" }, schema];
627
+ }
628
+ const matched = { ...schema };
629
+ const rest = { ...schema };
630
+ matched.properties = separatedProperties.reduce((acc, key) => {
631
+ const keySchema = schema.properties?.[key] ?? schema.additionalProperties;
632
+ if (keySchema !== void 0) {
633
+ acc[key] = keySchema;
634
+ }
635
+ return acc;
636
+ }, {});
637
+ matched.required = schema.required?.filter((key) => separatedProperties.includes(key));
638
+ matched.examples = schema.examples?.map((example) => {
639
+ if (!isObject(example)) {
640
+ return example;
641
+ }
642
+ return Object.entries(example).reduce(
643
+ (acc, [key, value]) => {
644
+ if (separatedProperties.includes(key)) {
645
+ acc[key] = value;
646
+ }
647
+ return acc;
648
+ },
649
+ {}
650
+ );
651
+ });
652
+ rest.properties = schema.properties && Object.entries(schema.properties).filter(([key]) => !separatedProperties.includes(key)).reduce(
653
+ (acc, [key, value]) => {
654
+ acc[key] = value;
655
+ return acc;
656
+ },
657
+ {}
658
+ );
659
+ rest.required = schema.required?.filter((key) => !separatedProperties.includes(key));
660
+ rest.examples = schema.examples?.map((example) => {
661
+ if (!isObject(example)) {
662
+ return example;
663
+ }
664
+ return Object.entries(example).reduce(
665
+ (acc, [key, value]) => {
666
+ if (!separatedProperties.includes(key)) {
667
+ acc[key] = value;
668
+ }
669
+ return acc;
670
+ },
671
+ {}
672
+ );
673
+ });
674
+ return [matched, rest];
675
+ }
676
+ function filterSchemaBranches(schema, check, matches = []) {
677
+ if (check(schema)) {
678
+ matches.push(schema);
679
+ return [matches, void 0];
680
+ }
681
+ if (isObject(schema)) {
682
+ for (const keyword of ["anyOf", "oneOf"]) {
683
+ if (schema[keyword] && Object.keys(schema).every((k) => k === keyword || !LOGIC_KEYWORDS.includes(k))) {
684
+ const rest = schema[keyword].map((s) => filterSchemaBranches(s, check, matches)[1]).filter((v) => !!v);
685
+ if (rest.length === 1 && typeof rest[0] === "object") {
686
+ return [matches, { ...schema, [keyword]: void 0, ...rest[0] }];
687
+ }
688
+ return [matches, { ...schema, [keyword]: rest }];
689
+ }
690
+ }
691
+ }
692
+ return [matches, schema];
693
+ }
694
+ function applySchemaOptionality(required, schema) {
695
+ if (required) {
696
+ return schema;
697
+ }
698
+ return {
699
+ anyOf: [schema, { not: {} }]
700
+ };
701
+ }
702
+ function expandUnionSchema(schema) {
703
+ if (typeof schema === "object") {
704
+ for (const keyword of ["anyOf", "oneOf"]) {
705
+ if (schema[keyword] && Object.keys(schema).every((k) => k === keyword || !LOGIC_KEYWORDS.includes(k))) {
706
+ return schema[keyword].flatMap((s) => expandUnionSchema(s));
707
+ }
708
+ }
709
+ }
710
+ return [schema];
711
+ }
712
+ function expandArrayableSchema(schema) {
713
+ const schemas = expandUnionSchema(schema);
714
+ if (schemas.length !== 2) {
715
+ return void 0;
716
+ }
717
+ const arraySchema = schemas.find(
718
+ (s) => typeof s === "object" && s.type === "array" && Object.keys(s).filter((k) => LOGIC_KEYWORDS.includes(k)).every((k) => k === "type" || k === "items")
719
+ );
720
+ if (arraySchema === void 0) {
721
+ return void 0;
722
+ }
723
+ const items1 = arraySchema.items;
724
+ const items2 = schemas.find((s) => s !== arraySchema);
725
+ if (stringifyJSON(items1) !== stringifyJSON(items2)) {
726
+ return void 0;
727
+ }
728
+ return [items2, arraySchema];
729
+ }
730
+ const PRIMITIVE_SCHEMA_TYPES = /* @__PURE__ */ new Set([
731
+ TypeName.String,
732
+ TypeName.Number,
733
+ TypeName.Integer,
734
+ TypeName.Boolean,
735
+ TypeName.Null
736
+ ]);
737
+ function isPrimitiveSchema(schema) {
738
+ return expandUnionSchema(schema).every((s) => {
739
+ if (typeof s === "boolean") {
740
+ return false;
741
+ }
742
+ if (typeof s.type === "string" && PRIMITIVE_SCHEMA_TYPES.has(s.type)) {
743
+ return true;
744
+ }
745
+ if (s.const !== void 0) {
746
+ return true;
747
+ }
748
+ return false;
749
+ });
750
+ }
751
+
752
+ function toOpenAPIPath(path) {
753
+ return standardizeHTTPPath(path).replace(/\/\{\+([^}]+)\}/g, "/{$1}");
754
+ }
755
+ function toOpenAPIMethod(method) {
756
+ return method.toLocaleLowerCase();
757
+ }
758
+ function toOpenAPIContent(schema) {
759
+ const content = {};
760
+ const [matches, restSchema] = filterSchemaBranches(schema, isFileSchema);
761
+ for (const file of matches) {
762
+ content[file.contentMediaType] = {
763
+ schema: toOpenAPISchema(file)
764
+ };
765
+ }
766
+ if (restSchema !== void 0) {
767
+ content["application/json"] = {
768
+ schema: toOpenAPISchema(restSchema)
769
+ };
770
+ const isStillHasFileSchema = findDeepMatches((v) => isObject(v) && isFileSchema(v), restSchema).values.length > 0;
771
+ if (isStillHasFileSchema) {
772
+ content["multipart/form-data"] = {
773
+ schema: toOpenAPISchema(restSchema)
774
+ };
775
+ }
776
+ }
777
+ return content;
778
+ }
779
+ function toOpenAPIEventIteratorContent([yieldsRequired, yieldsSchema], [returnsRequired, returnsSchema]) {
780
+ return {
781
+ "text/event-stream": {
782
+ schema: toOpenAPISchema({
783
+ oneOf: [
784
+ {
785
+ type: "object",
786
+ properties: {
787
+ event: { const: "message" },
788
+ data: yieldsSchema,
789
+ id: { type: "string" },
790
+ retry: { type: "number" }
791
+ },
792
+ required: yieldsRequired ? ["event", "data"] : ["event"]
793
+ },
794
+ {
795
+ type: "object",
796
+ properties: {
797
+ event: { const: "done" },
798
+ data: returnsSchema,
799
+ id: { type: "string" },
800
+ retry: { type: "number" }
801
+ },
802
+ required: returnsRequired ? ["event", "data"] : ["event"]
803
+ },
804
+ {
805
+ type: "object",
806
+ properties: {
807
+ event: { const: "error" },
808
+ data: {},
809
+ id: { type: "string" },
810
+ retry: { type: "number" }
811
+ },
812
+ required: ["event"]
813
+ }
814
+ ]
815
+ })
816
+ }
817
+ };
818
+ }
819
+ function toOpenAPIParameters(schema, parameterIn) {
820
+ const parameters = [];
821
+ for (const key in schema.properties) {
822
+ const keySchema = schema.properties[key];
823
+ let isDeepObjectStyle = true;
824
+ if (parameterIn !== "query") {
825
+ isDeepObjectStyle = false;
826
+ } else if (isPrimitiveSchema(keySchema)) {
827
+ isDeepObjectStyle = false;
828
+ } else {
829
+ const [item] = expandArrayableSchema(keySchema) ?? [];
830
+ if (item !== void 0 && isPrimitiveSchema(item)) {
831
+ isDeepObjectStyle = false;
832
+ }
833
+ }
834
+ parameters.push({
835
+ name: key,
836
+ in: parameterIn,
837
+ required: schema.required?.includes(key),
838
+ schema: toOpenAPISchema(keySchema),
839
+ style: isDeepObjectStyle ? "deepObject" : void 0,
840
+ explode: isDeepObjectStyle ? true : void 0,
841
+ allowEmptyValue: parameterIn === "query" ? true : void 0,
842
+ allowReserved: parameterIn === "query" ? true : void 0
843
+ });
844
+ }
845
+ return parameters;
846
+ }
847
+ function checkParamsSchema(schema, params) {
848
+ const properties = Object.keys(schema.properties ?? {});
849
+ const required = schema.required ?? [];
850
+ if (properties.length !== params.length || properties.some((v) => !params.includes(v))) {
851
+ return false;
852
+ }
853
+ if (required.length !== params.length || required.some((v) => !params.includes(v))) {
854
+ return false;
855
+ }
856
+ return true;
857
+ }
858
+ function toOpenAPISchema(schema) {
859
+ if (schema === true) {
860
+ return {};
861
+ } else if (schema === false) {
862
+ return { not: {} };
863
+ }
864
+ if (schema.type === "object" && !schema.properties && schema.additionalProperties === false) {
865
+ return {
866
+ ...schema,
867
+ "x-stainless-empty-object": true
868
+ };
869
+ }
870
+ return schema;
871
+ }
872
+ const OPENAPI_JSON_SCHEMA_REF_PREFIX = "#/components/schemas/";
873
+ function resolveOpenAPIJsonSchemaRef(doc, schema) {
874
+ if (typeof schema !== "object" || !schema.$ref?.startsWith(OPENAPI_JSON_SCHEMA_REF_PREFIX)) {
875
+ return schema;
876
+ }
877
+ const name = schema.$ref.slice(OPENAPI_JSON_SCHEMA_REF_PREFIX.length);
878
+ const resolved = doc.components?.schemas?.[name];
879
+ return resolved ?? schema;
880
+ }
881
+
882
+ class OpenAPIGeneratorError extends Error {
883
+ }
884
+ async function generateOpenApiSpec(resources, options = {}) {
885
+ const converter = typeof options.schemaConverter === "function" ? options.schemaConverter : new ZodToJsonSchemaConverter(options.schemaConverter ?? {}).convert;
886
+ const doc = {
887
+ ...clone(options.spec),
888
+ info: options.spec?.info ?? { title: "API Reference", version: "0.0.0" },
889
+ openapi: "3.1.1"
890
+ };
891
+ const contractsById = /* @__PURE__ */ new Map();
892
+ const apiResources = await unlazyResources(resources);
893
+ for (const apiResource of apiResources) {
894
+ for (const [methodName, contract] of Object.entries(apiResource.methods)) {
895
+ const operationId = `${apiResource.name}.${methodName}`;
896
+ if (contractsById.has(operationId)) {
897
+ throw new Error(`Multiple ApiResources have the same name: "${operationId}"`);
898
+ }
899
+ contractsById.set(operationId, contract);
900
+ }
901
+ }
902
+ const combinedErrorMap = {};
903
+ for (const contract of contractsById.values()) {
904
+ const { errorMap } = contract["~def"];
905
+ for (const key in errorMap) {
906
+ if (!errorMap[key]) {
907
+ continue;
908
+ }
909
+ if (key in combinedErrorMap && combinedErrorMap[key] !== errorMap[key]) {
910
+ throw new OpenAPIGeneratorError(
911
+ `Conflicting error map entries for key "${key}". Please ensure that all error maps have unique keys or identical values for shared keys.`
912
+ );
913
+ }
914
+ combinedErrorMap[key] = errorMap[key];
915
+ }
916
+ }
917
+ const { baseSchemaConvertOptions } = await resolveCommonSchemas(doc, options.commonSchemas, converter);
918
+ const errorRefMap = await generateErrorComponents(
919
+ combinedErrorMap,
920
+ doc,
921
+ baseSchemaConvertOptions,
922
+ converter
923
+ );
924
+ const namesByAuthConfig = getNamesByAuthConfig(contractsById.values());
925
+ if (namesByAuthConfig.size > 0) {
926
+ doc.components ??= {};
927
+ const schemes = doc.components.securitySchemes ??= {};
928
+ for (const [authConfig, name] of namesByAuthConfig) {
929
+ schemes[name] ??= authConfigToSecurityScheme(authConfig);
930
+ }
931
+ }
932
+ const errors = [];
933
+ for (const [operationId, contract] of contractsById) {
934
+ const def = contract["~def"];
935
+ const path = def.methodConfig.path;
936
+ try {
937
+ const method = toOpenAPIMethod(def.methodConfig.method);
938
+ const httpPath = toOpenAPIPath(path);
939
+ let operationObjectRef;
940
+ if (def.methodConfig.spec !== void 0 && typeof def.methodConfig.spec !== "function") {
941
+ operationObjectRef = def.methodConfig.spec;
942
+ } else {
943
+ operationObjectRef = {
944
+ operationId,
945
+ summary: def.methodConfig.summary,
946
+ description: def.methodConfig.description,
947
+ deprecated: def.methodConfig.deprecated,
948
+ tags: def.methodConfig.tags?.map((tag) => tag)
949
+ };
950
+ const security = def.authConfigs.map(
951
+ (authConfig) => authConfig.type === "none" ? {} : { [namesByAuthConfig.get(authConfig)]: [] }
952
+ );
953
+ if (security.length > 0) {
954
+ operationObjectRef.security = security;
955
+ }
956
+ await handleRequest(doc, operationObjectRef, def, baseSchemaConvertOptions, converter);
957
+ await handleSuccessResponse(doc, operationObjectRef, def, baseSchemaConvertOptions, converter);
958
+ handleErrorResponse(operationObjectRef, def, errorRefMap);
959
+ }
960
+ if (typeof def.methodConfig.spec === "function") {
961
+ operationObjectRef = def.methodConfig.spec(operationObjectRef);
962
+ }
963
+ doc.paths ??= {};
964
+ doc.paths[httpPath] ??= {};
965
+ doc.paths[httpPath][method] = applyCustomOpenAPIOperation(operationObjectRef, contract);
966
+ } catch (e) {
967
+ if (!(e instanceof OpenAPIGeneratorError)) {
968
+ throw e;
969
+ }
970
+ errors.push(
971
+ `[OpenAPIGenerator] Error occurred while generating OpenAPI for method at path: ${path}
972
+ ${e.message}`
973
+ );
974
+ }
975
+ }
976
+ if (errors.length) {
977
+ throw new OpenAPIGeneratorError(
978
+ `Some error occurred during OpenAPI generation:
979
+
980
+ ${errors.join("\n\n")}`
981
+ );
982
+ }
983
+ return doc;
984
+ }
985
+ async function resolveCommonSchemas(doc, commonSchemas, converter) {
986
+ const baseSchemaConvertOptions = {};
987
+ if (commonSchemas) {
988
+ baseSchemaConvertOptions.components = [];
989
+ for (const key in commonSchemas) {
990
+ const options = commonSchemas[key];
991
+ if (options.schema === void 0) {
992
+ continue;
993
+ }
994
+ const { schema, strategy = "input" } = options;
995
+ const [required, json] = await converter(schema, { strategy });
996
+ const allowedStrategies = [strategy];
997
+ if (strategy === "input") {
998
+ const [outputRequired, outputJson] = await converter(schema, { strategy: "output" });
999
+ if (outputRequired === required && stringifyJSON(outputJson) === stringifyJSON(json)) {
1000
+ allowedStrategies.push("output");
1001
+ }
1002
+ } else if (strategy === "output") {
1003
+ const [inputRequired, inputJson] = await converter(schema, { strategy: "input" });
1004
+ if (inputRequired === required && stringifyJSON(inputJson) === stringifyJSON(json)) {
1005
+ allowedStrategies.push("input");
1006
+ }
1007
+ }
1008
+ baseSchemaConvertOptions.components.push({
1009
+ schema,
1010
+ required,
1011
+ ref: `#/components/schemas/${key}`,
1012
+ allowedStrategies
1013
+ });
1014
+ }
1015
+ doc.components ??= {};
1016
+ doc.components.schemas ??= {};
1017
+ for (const key in commonSchemas) {
1018
+ const options = commonSchemas[key];
1019
+ if (options.schema === void 0) {
1020
+ continue;
1021
+ }
1022
+ const { schema, strategy = "input" } = options;
1023
+ const [, json] = await converter(schema, {
1024
+ ...baseSchemaConvertOptions,
1025
+ strategy,
1026
+ minStructureDepthForRef: 1
1027
+ // not allow use $ref for root schemas
1028
+ });
1029
+ doc.components.schemas[key] = toOpenAPISchema(json);
1030
+ }
1031
+ }
1032
+ return { baseSchemaConvertOptions };
1033
+ }
1034
+ async function handleRequest(doc, ref, def, baseSchemaConvertOptions, converter) {
1035
+ const method = def.methodConfig.method;
1036
+ const dynamicParams = getDynamicParams(def.methodConfig.path)?.map((v) => v.name);
1037
+ const [_pathRequired, pathSchema] = await converter(def.schemas.pathSchema, {
1038
+ ...baseSchemaConvertOptions,
1039
+ strategy: "input",
1040
+ minStructureDepthForRef: 1
1041
+ });
1042
+ if (dynamicParams?.length) {
1043
+ const error = new OpenAPIGeneratorError(
1044
+ // TODO: fix this error
1045
+ 'When input structure is "compact", and path has dynamic params, input schema must be an object with all dynamic params as required.'
1046
+ );
1047
+ if (!isObjectSchema(pathSchema)) {
1048
+ throw error;
1049
+ }
1050
+ if (!checkParamsSchema(pathSchema, dynamicParams)) {
1051
+ throw error;
1052
+ }
1053
+ ref.parameters ??= [];
1054
+ ref.parameters.push(...toOpenAPIParameters(pathSchema, "path"));
1055
+ } else {
1056
+ const error = new OpenAPIGeneratorError("Path placeholders do not match the path schema");
1057
+ if (!isObjectSchema(pathSchema)) {
1058
+ throw error;
1059
+ }
1060
+ if (!checkParamsSchema(pathSchema, [])) {
1061
+ throw error;
1062
+ }
1063
+ }
1064
+ const [_queryRequired, querySchema] = await converter(def.schemas.querySchema, {
1065
+ ...baseSchemaConvertOptions,
1066
+ strategy: "input",
1067
+ minStructureDepthForRef: 0
1068
+ });
1069
+ if (!isAnySchema(querySchema)) {
1070
+ const resolvedSchema = resolveOpenAPIJsonSchemaRef(doc, querySchema);
1071
+ if (!isObjectSchema(resolvedSchema)) {
1072
+ throw new OpenAPIGeneratorError("Query param schema must satisfy: object | any | unknown");
1073
+ }
1074
+ ref.parameters ??= [];
1075
+ ref.parameters.push(...toOpenAPIParameters(resolvedSchema, "query"));
1076
+ }
1077
+ const [_headersRequired, headersSchema] = await converter(def.schemas.headersSchema, {
1078
+ ...baseSchemaConvertOptions,
1079
+ strategy: "input",
1080
+ minStructureDepthForRef: 0
1081
+ });
1082
+ if (!isAnySchema(headersSchema)) {
1083
+ const resolvedSchema = resolveOpenAPIJsonSchemaRef(doc, headersSchema);
1084
+ if (!isObjectSchema(resolvedSchema)) {
1085
+ throw new OpenAPIGeneratorError("Header schema must satisfy: object | any | unknown");
1086
+ }
1087
+ ref.parameters ??= [];
1088
+ ref.parameters.push(...toOpenAPIParameters(resolvedSchema, "header"));
1089
+ }
1090
+ if (method !== "GET") {
1091
+ const details = getEventIteratorSchemaDetails(def.schemas.bodySchema);
1092
+ if (details) {
1093
+ ref.requestBody = {
1094
+ required: true,
1095
+ content: toOpenAPIEventIteratorContent(
1096
+ await converter(details.yields, { ...baseSchemaConvertOptions, strategy: "input" }),
1097
+ await converter(details.returns, { ...baseSchemaConvertOptions, strategy: "input" })
1098
+ )
1099
+ };
1100
+ } else {
1101
+ const [bodyRequired, bodySchema] = await converter(def.schemas.bodySchema, {
1102
+ ...baseSchemaConvertOptions,
1103
+ strategy: "input",
1104
+ minStructureDepthForRef: 0
1105
+ });
1106
+ if (isAnySchema(bodySchema)) {
1107
+ return;
1108
+ }
1109
+ ref.requestBody = {
1110
+ required: bodyRequired,
1111
+ content: toOpenAPIContent(bodySchema)
1112
+ };
1113
+ }
1114
+ }
1115
+ }
1116
+ async function handleSuccessResponse(doc, ref, def, baseSchemaConvertOptions, converter) {
1117
+ const responseSchema = def.schemas.responseSchema;
1118
+ const status = fallbackContractConfig("defaultSuccessStatus", def.methodConfig.successStatus);
1119
+ const description = fallbackContractConfig(
1120
+ "defaultSuccessDescription",
1121
+ def.methodConfig?.successDescription
1122
+ );
1123
+ const eventIteratorSchemaDetails = getEventIteratorSchemaDetails(responseSchema);
1124
+ if (eventIteratorSchemaDetails) {
1125
+ ref.responses ??= {};
1126
+ ref.responses[status] = {
1127
+ description,
1128
+ content: toOpenAPIEventIteratorContent(
1129
+ await converter(eventIteratorSchemaDetails.yields, {
1130
+ ...baseSchemaConvertOptions,
1131
+ strategy: "output"
1132
+ }),
1133
+ await converter(eventIteratorSchemaDetails.returns, {
1134
+ ...baseSchemaConvertOptions,
1135
+ strategy: "output"
1136
+ })
1137
+ )
1138
+ };
1139
+ return;
1140
+ }
1141
+ const [required, json] = await converter(responseSchema, {
1142
+ ...baseSchemaConvertOptions,
1143
+ strategy: "output",
1144
+ minStructureDepthForRef: 0
1145
+ });
1146
+ ref.responses ??= {};
1147
+ ref.responses[status] = {
1148
+ description
1149
+ };
1150
+ ref.responses[status].content = toOpenAPIContent(applySchemaOptionality(required, json));
1151
+ }
1152
+ function getNamesByAuthConfig(contracts) {
1153
+ const namesByAuthConfig = /* @__PURE__ */ new Map();
1154
+ const authConfigNames = /* @__PURE__ */ new Set();
1155
+ for (const contract of contracts) {
1156
+ for (const authConfig of contract["~def"].authConfigs) {
1157
+ if (authConfig.type === "none" || namesByAuthConfig.has(authConfig)) {
1158
+ continue;
1159
+ }
1160
+ const oasNameBase = authConfig.oasName ?? `${authConfig.type}Auth`;
1161
+ let oasName = oasNameBase;
1162
+ for (let i = 2; authConfigNames.has(oasName); i++) {
1163
+ oasName = `${oasNameBase}${i}`;
1164
+ }
1165
+ namesByAuthConfig.set(authConfig, oasName);
1166
+ authConfigNames.add(oasName);
1167
+ }
1168
+ }
1169
+ return namesByAuthConfig;
1170
+ }
1171
+ function authConfigToSecurityScheme(authConfig) {
1172
+ switch (authConfig.type) {
1173
+ case "basic":
1174
+ return {
1175
+ type: "http",
1176
+ scheme: "basic",
1177
+ description: authConfig.oasDescription
1178
+ };
1179
+ case "bearer":
1180
+ return {
1181
+ type: "http",
1182
+ scheme: "bearer",
1183
+ description: authConfig.oasDescription,
1184
+ bearerFormat: authConfig.oasBearerFormat
1185
+ };
1186
+ case "header":
1187
+ return {
1188
+ type: "apiKey",
1189
+ in: "header",
1190
+ name: authConfig.name,
1191
+ description: authConfig.oasDescription
1192
+ };
1193
+ case "query":
1194
+ return {
1195
+ type: "apiKey",
1196
+ in: "query",
1197
+ name: authConfig.name,
1198
+ description: authConfig.oasDescription
1199
+ };
1200
+ case "cookie":
1201
+ return {
1202
+ type: "apiKey",
1203
+ in: "cookie",
1204
+ name: authConfig.name,
1205
+ description: authConfig.oasDescription
1206
+ };
1207
+ default:
1208
+ assertNever(authConfig, `Unsupported auth config type: ${authConfig.type}`);
1209
+ }
1210
+ }
1211
+ async function generateErrorComponents(combinedErrorMap, doc, baseSchemaConvertOptions, converter) {
1212
+ const refMap = /* @__PURE__ */ new Map();
1213
+ const schemas = {};
1214
+ for (const mapKey in combinedErrorMap) {
1215
+ const errorClass = combinedErrorMap[mapKey];
1216
+ if (!errorClass) {
1217
+ continue;
1218
+ }
1219
+ const extraZod = z.object(errorClass.extraSchema).strict();
1220
+ const [, extraSchema] = await converter(extraZod, {
1221
+ ...baseSchemaConvertOptions,
1222
+ strategy: "output"
1223
+ });
1224
+ if (!isObjectSchema(extraSchema)) {
1225
+ throw new OpenAPIGeneratorError(
1226
+ `Error response extra schema must be an object, but got: ${stringifyJSON(extraSchema)}`
1227
+ );
1228
+ }
1229
+ const schema = {
1230
+ type: "object",
1231
+ properties: {
1232
+ type: { const: errorClass.type },
1233
+ message: { type: "string", default: errorClass.defaultMessage },
1234
+ ...extraSchema.properties
1235
+ },
1236
+ required: ["type", "message", ...extraSchema.required ?? []]
1237
+ };
1238
+ schemas[mapKey] = toOpenAPISchema(schema);
1239
+ const ref = `#/components/schemas/${mapKey}`;
1240
+ refMap.set(mapKey, ref);
1241
+ }
1242
+ if (refMap.size > 0) {
1243
+ if (doc.components?.schemas?.Error) {
1244
+ throw new OpenAPIGeneratorError(
1245
+ '"Error" is a reserved name for models, please choose a different name.'
1246
+ );
1247
+ }
1248
+ schemas.Error = {
1249
+ oneOf: [...refMap.values()].map((ref) => ({ $ref: ref }))
1250
+ };
1251
+ }
1252
+ if (Object.keys(schemas).length > 0) {
1253
+ doc.components ??= {};
1254
+ doc.components.schemas ??= {};
1255
+ for (const key in doc.components.schemas) {
1256
+ if (Object.prototype.hasOwnProperty.call(schemas, key)) {
1257
+ throw new OpenAPIGeneratorError(
1258
+ `Model name "${key}" conflicts with an error class of the same name. Please rename one of them.`
1259
+ );
1260
+ }
1261
+ }
1262
+ Object.assign(doc.components.schemas, schemas);
1263
+ }
1264
+ return refMap;
1265
+ }
1266
+ function handleErrorResponse(ref, def, errorRefMap) {
1267
+ const errorMap = def.errorMap;
1268
+ const errorResponsesByStatus = {};
1269
+ for (const mapKey in errorMap) {
1270
+ const errorClass = errorMap[mapKey];
1271
+ const errorRef = errorRefMap.get(mapKey);
1272
+ if (!errorClass || !errorRef) {
1273
+ continue;
1274
+ }
1275
+ errorResponsesByStatus[errorClass.status] ??= { status: errorClass.status, refs: [] };
1276
+ errorResponsesByStatus[errorClass.status].refs.push({ $ref: errorRef });
1277
+ }
1278
+ ref.responses ??= {};
1279
+ for (const statusString in errorResponsesByStatus) {
1280
+ const errorResponse = errorResponsesByStatus[statusString];
1281
+ ref.responses[statusString] = {
1282
+ description: statusString,
1283
+ content: toOpenAPIContent(
1284
+ errorResponse.refs.length === 1 ? errorResponse.refs[0] : {
1285
+ oneOf: errorResponse.refs
1286
+ }
1287
+ )
1288
+ };
1289
+ }
1290
+ }
1291
+
1292
+ export { JSON_SCHEMA_OUTPUT_REGISTRY as A, JsonSchemaXNativeType as J, LOGIC_KEYWORDS as L, ZodToJsonSchemaConverter as Z, applyCustomOpenAPIOperation as a, generateOpenApiSpec as b, customOpenAPIOperation as c, getNamesByAuthConfig as d, toOpenAPIMethod as e, toOpenAPIContent as f, getCustomOpenAPIOperation as g, toOpenAPIEventIteratorContent as h, toOpenAPIParameters as i, checkParamsSchema as j, toOpenAPISchema as k, isFileSchema as l, isObjectSchema as m, isAnySchema as n, filterSchemaBranches as o, applySchemaOptionality as p, expandUnionSchema as q, resolveOpenAPIJsonSchemaRef as r, separateObjectSchema as s, toOpenAPIPath as t, expandArrayableSchema as u, isPrimitiveSchema as v, eventIterator as w, getEventIteratorSchemaDetails as x, JSON_SCHEMA_REGISTRY as y, JSON_SCHEMA_INPUT_REGISTRY as z };