oas 31.1.2 → 32.1.0

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 (70) hide show
  1. package/README.md +5 -0
  2. package/dist/analyzer/index.cjs +6 -7
  3. package/dist/analyzer/index.cjs.map +1 -1
  4. package/dist/analyzer/index.js +5 -6
  5. package/dist/analyzer/index.js.map +1 -1
  6. package/dist/{chunk-BRYRBTD7.cjs → chunk-4OCSFLJO.cjs} +537 -385
  7. package/dist/chunk-4OCSFLJO.cjs.map +1 -0
  8. package/dist/{chunk-HGVFNEKW.js → chunk-5245ZLBC.js} +476 -324
  9. package/dist/chunk-5245ZLBC.js.map +1 -0
  10. package/dist/{chunk-B5WP4BJM.cjs → chunk-7RDMAMMI.cjs} +511 -240
  11. package/dist/chunk-7RDMAMMI.cjs.map +1 -0
  12. package/dist/{chunk-LSH3X5NA.js → chunk-DVD6RE2D.js} +85 -48
  13. package/dist/chunk-DVD6RE2D.js.map +1 -0
  14. package/dist/{chunk-5EP6HY2E.js → chunk-HYH37HS2.js} +494 -223
  15. package/dist/chunk-HYH37HS2.js.map +1 -0
  16. package/dist/{chunk-7MARUOFZ.js → chunk-MNOEMVCF.js} +2 -2
  17. package/dist/chunk-MNOEMVCF.js.map +1 -0
  18. package/dist/{chunk-SYZDNSG6.cjs → chunk-WXNEGGLJ.cjs} +104 -67
  19. package/dist/chunk-WXNEGGLJ.cjs.map +1 -0
  20. package/dist/chunk-YPR7YTHM.cjs +24 -0
  21. package/dist/chunk-YPR7YTHM.cjs.map +1 -0
  22. package/dist/extensions.d.cts +3 -1
  23. package/dist/extensions.d.ts +3 -1
  24. package/dist/get-parameters-as-json-schema-BH81ZOnw.d.ts +36 -0
  25. package/dist/get-parameters-as-json-schema-DM1vWIEM.d.cts +36 -0
  26. package/dist/index.cjs +5 -6
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.cts +947 -7
  29. package/dist/index.d.ts +946 -8
  30. package/dist/index.js +4 -5
  31. package/dist/operation/index.cjs +4 -5
  32. package/dist/operation/index.cjs.map +1 -1
  33. package/dist/operation/index.d.cts +3 -1
  34. package/dist/operation/index.d.ts +3 -1
  35. package/dist/operation/index.js +3 -4
  36. package/dist/reducer/index.cjs +16 -18
  37. package/dist/reducer/index.cjs.map +1 -1
  38. package/dist/reducer/index.js +4 -6
  39. package/dist/reducer/index.js.map +1 -1
  40. package/dist/types.cjs +2 -2
  41. package/dist/types.d.cts +9 -1
  42. package/dist/types.d.ts +9 -1
  43. package/dist/types.js +1 -1
  44. package/dist/utils.cjs +4 -4
  45. package/dist/utils.cjs.map +1 -1
  46. package/dist/utils.d.cts +17 -3
  47. package/dist/utils.d.ts +17 -3
  48. package/dist/utils.js +5 -5
  49. package/package.json +3 -6
  50. package/dist/chunk-5EP6HY2E.js.map +0 -1
  51. package/dist/chunk-7MARUOFZ.js.map +0 -1
  52. package/dist/chunk-B5WP4BJM.cjs.map +0 -1
  53. package/dist/chunk-BRYRBTD7.cjs.map +0 -1
  54. package/dist/chunk-HGVFNEKW.js.map +0 -1
  55. package/dist/chunk-LSH3X5NA.js.map +0 -1
  56. package/dist/chunk-O3GIPZLC.cjs +0 -9
  57. package/dist/chunk-O3GIPZLC.cjs.map +0 -1
  58. package/dist/chunk-SYZDNSG6.cjs.map +0 -1
  59. package/dist/chunk-VA3NKXX7.js +0 -9
  60. package/dist/chunk-VA3NKXX7.js.map +0 -1
  61. package/dist/chunk-VQBEI5WI.cjs +0 -24
  62. package/dist/chunk-VQBEI5WI.cjs.map +0 -1
  63. package/dist/extensions-9XckV6aO.d.cts +0 -899
  64. package/dist/extensions-gq53-7Ux.d.ts +0 -899
  65. package/dist/operation/lib/get-parameters-as-json-schema.cjs +0 -11
  66. package/dist/operation/lib/get-parameters-as-json-schema.cjs.map +0 -1
  67. package/dist/operation/lib/get-parameters-as-json-schema.d.cts +0 -4
  68. package/dist/operation/lib/get-parameters-as-json-schema.d.ts +0 -4
  69. package/dist/operation/lib/get-parameters-as-json-schema.js +0 -11
  70. package/dist/operation/lib/get-parameters-as-json-schema.js.map +0 -1
@@ -1,128 +1,29 @@
1
1
  import {
2
- supportedMethods
3
- } from "./chunk-VA3NKXX7.js";
4
- import {
2
+ applyDiscriminatorOneOfToUsedSchemas,
5
3
  cloneObject,
4
+ decorateComponentSchemasWithRefName,
6
5
  dereferenceRef,
6
+ filterRequiredRefsToReferenced,
7
7
  getDereferencingOptions,
8
8
  getParametersAsJSONSchema,
9
9
  getSchemaVersionString,
10
10
  isObject,
11
11
  isPrimitive,
12
12
  matches_mimetype_default,
13
+ mergeReferencedSchemasIntoRoot,
14
+ supportedMethods,
13
15
  toJSONSchema
14
- } from "./chunk-5EP6HY2E.js";
16
+ } from "./chunk-HYH37HS2.js";
15
17
  import {
16
18
  getExtension
17
19
  } from "./chunk-S27IGTVG.js";
18
20
  import {
19
21
  isRef
20
- } from "./chunk-7MARUOFZ.js";
22
+ } from "./chunk-MNOEMVCF.js";
21
23
 
22
24
  // src/operation/index.ts
23
25
  import { $RefParser } from "@apidevtools/json-schema-ref-parser";
24
26
 
25
- // src/lib/build-discriminator-one-of.ts
26
- function hasDiscriminatorWithoutPolymorphism(schema) {
27
- if (!schema || typeof schema !== "object") return false;
28
- if (!("discriminator" in schema)) return false;
29
- if ("oneOf" in schema || "anyOf" in schema) return false;
30
- return true;
31
- }
32
- function allOfReferencesSchema(schema, targetSchemaName) {
33
- if (!schema || typeof schema !== "object") return false;
34
- if (!("allOf" in schema) || !Array.isArray(schema.allOf)) return false;
35
- return schema.allOf.some((item) => {
36
- if (isRef(item)) {
37
- const refParts = item.$ref.split("/");
38
- const refSchemaName = refParts[refParts.length - 1];
39
- return refSchemaName === targetSchemaName;
40
- }
41
- return false;
42
- });
43
- }
44
- function findDiscriminatorChildren(api) {
45
- const childrenMap = /* @__PURE__ */ new Map();
46
- const invertedChildrenMap = /* @__PURE__ */ new Map();
47
- if (!api?.components?.schemas || typeof api.components.schemas !== "object") {
48
- return { children: childrenMap, inverted: invertedChildrenMap };
49
- }
50
- const schemas = api.components.schemas;
51
- const schemaNames = Object.keys(schemas);
52
- const discriminatorSchemas = schemaNames.filter((name) => {
53
- return hasDiscriminatorWithoutPolymorphism(schemas[name]);
54
- });
55
- for (const baseName of discriminatorSchemas) {
56
- const baseSchema = schemas[baseName];
57
- const discriminator = baseSchema.discriminator;
58
- let childSchemaNames;
59
- if (discriminator.mapping && typeof discriminator.mapping === "object") {
60
- const mappingRefs = Object.values(discriminator.mapping);
61
- if (mappingRefs.length > 0) {
62
- childSchemaNames = mappingRefs.map((ref) => {
63
- const parts = ref.split("/");
64
- return parts[parts.length - 1];
65
- });
66
- }
67
- }
68
- if (!childSchemaNames || childSchemaNames.length === 0) {
69
- childSchemaNames = schemaNames.filter((name) => {
70
- if (name === baseName) return false;
71
- return allOfReferencesSchema(schemas[name], baseName);
72
- });
73
- }
74
- if (childSchemaNames.length > 0) {
75
- childrenMap.set(baseName, childSchemaNames);
76
- }
77
- }
78
- for (const [key, values] of childrenMap) {
79
- for (const value of values) {
80
- if (invertedChildrenMap.has(value)) {
81
- invertedChildrenMap.get(value)?.push(key);
82
- } else {
83
- invertedChildrenMap.set(value, [key]);
84
- }
85
- }
86
- }
87
- return { children: childrenMap, inverted: invertedChildrenMap };
88
- }
89
- function buildDiscriminatorOneOf(api, childrenMap) {
90
- if (!api?.components?.schemas || typeof api.components.schemas !== "object") {
91
- return;
92
- } else if (childrenMap.size === 0) {
93
- return;
94
- }
95
- for (const [schemaName, childNames] of childrenMap) {
96
- const schema = api.components.schemas[schemaName];
97
- if (!schema) continue;
98
- const oneOf = [];
99
- for (const childName of childNames) {
100
- if (api.components.schemas[childName]) {
101
- oneOf.push(cloneObject(api.components.schemas[childName]));
102
- }
103
- }
104
- if (oneOf.length > 0) {
105
- schema.oneOf = oneOf;
106
- }
107
- }
108
- for (const [parentSchemaName, childNames] of childrenMap) {
109
- for (const childName of childNames) {
110
- const childSchema = api.components.schemas[childName];
111
- if (!childSchema || !("allOf" in childSchema) || !Array.isArray(childSchema.allOf)) {
112
- continue;
113
- }
114
- for (let i = 0; i < childSchema.allOf.length; i++) {
115
- const item = childSchema.allOf[i];
116
- if (item && typeof item === "object" && "x-readme-ref-name" in item && item["x-readme-ref-name"] === parentSchemaName && "oneOf" in item) {
117
- const clonedItem = cloneObject(item);
118
- delete clonedItem.oneOf;
119
- childSchema.allOf[i] = clonedItem;
120
- }
121
- }
122
- }
123
- }
124
- }
125
-
126
27
  // src/operation/lib/dedupe-common-parameters.ts
127
28
  function dedupeCommonParameters(parameters, commonParameters) {
128
29
  return commonParameters.filter((param) => {
@@ -224,27 +125,51 @@ var primitive = (schema) => {
224
125
  return `Unknown Type: ${objectifiedSchema.type}`;
225
126
  };
226
127
  function sampleFromSchema(schema, opts = {}) {
227
- const objectifySchema = objectify(schema);
228
- let { type } = objectifySchema;
229
- const hasPolymorphism = usesPolymorphism(objectifySchema);
128
+ const seenRefs = opts.seenRefs || /* @__PURE__ */ new Set();
129
+ let objectifySchema = objectify(schema);
130
+ let refToRelease;
131
+ if (opts.definition && isRef(objectifySchema)) {
132
+ refToRelease = objectifySchema.$ref;
133
+ if (seenRefs.has(refToRelease)) {
134
+ return void 0;
135
+ }
136
+ objectifySchema = dereferenceRef(objectifySchema, opts.definition, seenRefs);
137
+ if (!objectifySchema || isRef(objectifySchema)) {
138
+ return void 0;
139
+ }
140
+ }
141
+ try {
142
+ return sampleFromResolvedSchema(objectifySchema, opts, seenRefs);
143
+ } finally {
144
+ if (refToRelease) {
145
+ seenRefs.delete(refToRelease);
146
+ }
147
+ }
148
+ }
149
+ function sampleFromResolvedSchema(schema, opts, seenRefs) {
150
+ let { type } = schema;
151
+ const hasPolymorphism = usesPolymorphism(schema);
230
152
  if (hasPolymorphism === "allOf") {
231
153
  try {
232
154
  return sampleFromSchema(
233
- mergeJSONSchemaAllOf(objectifySchema, {
155
+ mergeJSONSchemaAllOf(schema, {
234
156
  resolvers: {
235
157
  // Ignore any unrecognized OAS-specific keywords that might be present on the schema
236
158
  // (like `xml`).
237
159
  defaultResolver: mergeJSONSchemaAllOf.options.resolvers.title
238
160
  }
239
161
  }),
240
- opts
162
+ {
163
+ ...opts,
164
+ seenRefs
165
+ }
241
166
  );
242
167
  } catch {
243
168
  return void 0;
244
169
  }
245
170
  } else if (hasPolymorphism) {
246
- const samples = objectifySchema[hasPolymorphism].map((s) => {
247
- return sampleFromSchema(s, opts);
171
+ const samples = schema[hasPolymorphism].map((s) => {
172
+ return sampleFromSchema(s, { ...opts, seenRefs });
248
173
  });
249
174
  if (samples.length === 1) {
250
175
  return samples[0];
@@ -253,7 +178,7 @@ function sampleFromSchema(schema, opts = {}) {
253
178
  }
254
179
  return samples[0];
255
180
  }
256
- const { example, additionalProperties, properties, items } = objectifySchema;
181
+ const { example, additionalProperties, properties, items } = schema;
257
182
  const { includeReadOnly, includeWriteOnly } = opts;
258
183
  if (example !== void 0) {
259
184
  return deeplyStripKey(example, "$$ref", (val) => {
@@ -286,13 +211,13 @@ function sampleFromSchema(schema, opts = {}) {
286
211
  obj[name] = props[name].examples[0];
287
212
  continue;
288
213
  }
289
- obj[name] = sampleFromSchema(props[name], opts);
214
+ obj[name] = sampleFromSchema(props[name], { ...opts, seenRefs });
290
215
  }
291
216
  if (additionalProperties === true) {
292
217
  obj.additionalProp = {};
293
218
  } else if (additionalProperties) {
294
219
  const additionalProps = objectify(additionalProperties);
295
- const additionalPropVal = sampleFromSchema(additionalProps, opts);
220
+ const additionalPropVal = sampleFromSchema(additionalProps, { ...opts, seenRefs });
296
221
  obj.additionalProp = additionalPropVal;
297
222
  }
298
223
  return obj;
@@ -302,12 +227,22 @@ function sampleFromSchema(schema, opts = {}) {
302
227
  return [];
303
228
  }
304
229
  if (Array.isArray(items.anyOf)) {
305
- return items.anyOf.map((i) => sampleFromSchema(i, opts));
230
+ return items.anyOf.map(
231
+ (i) => sampleFromSchema(i, {
232
+ ...opts,
233
+ seenRefs
234
+ })
235
+ );
306
236
  }
307
237
  if (Array.isArray(items.oneOf)) {
308
- return items.oneOf.map((i) => sampleFromSchema(i, opts));
238
+ return items.oneOf.map(
239
+ (i) => sampleFromSchema(i, {
240
+ ...opts,
241
+ seenRefs
242
+ })
243
+ );
309
244
  }
310
- return [sampleFromSchema(items, opts)];
245
+ return [sampleFromSchema(items, { ...opts, seenRefs })];
311
246
  }
312
247
  if (schema.enum) {
313
248
  if (schema.default) {
@@ -324,7 +259,7 @@ var memo = memoize(sampleFromSchema);
324
259
  var samples_default = memo;
325
260
 
326
261
  // src/operation/lib/get-mediatype-examples.ts
327
- function getMediaTypeExamples(mediaType, mediaTypeObject, opts = {}) {
262
+ function getMediaTypeExamples(mediaType, mediaTypeObject, definition, opts = {}) {
328
263
  if (mediaTypeObject.example) {
329
264
  return [
330
265
  {
@@ -365,7 +300,10 @@ function getMediaTypeExamples(mediaType, mediaTypeObject, opts = {}) {
365
300
  if (!matches_mimetype_default.xml(mediaType)) {
366
301
  return [
367
302
  {
368
- value: samples_default(JSON.parse(JSON.stringify(mediaTypeObject.schema)), opts)
303
+ value: samples_default(structuredClone(mediaTypeObject.schema), {
304
+ ...opts,
305
+ definition
306
+ })
369
307
  }
370
308
  ];
371
309
  }
@@ -374,19 +312,21 @@ function getMediaTypeExamples(mediaType, mediaTypeObject, opts = {}) {
374
312
  }
375
313
 
376
314
  // src/operation/lib/get-response-examples.ts
377
- function getResponseExamples(operation) {
315
+ function getResponseExamples(operation, definition) {
378
316
  return Object.keys(operation.responses || {}).map((status) => {
379
- const response = operation.responses?.[status];
317
+ let response = operation.responses?.[status];
380
318
  let onlyHeaders = false;
381
- if (!response || isRef(response)) {
382
- return false;
319
+ if (!response) return false;
320
+ if (isRef(response)) {
321
+ response = dereferenceRef(response, definition);
322
+ if (!response || isRef(response)) return false;
383
323
  }
384
324
  const mediaTypes = {};
385
325
  (response?.content ? Object.keys(response.content) : []).forEach((mediaType) => {
386
326
  if (!mediaType) return;
387
327
  const mediaTypeObject = response.content?.[mediaType];
388
328
  if (!mediaTypeObject) return;
389
- const examples = getMediaTypeExamples(mediaType, mediaTypeObject, {
329
+ const examples = getMediaTypeExamples(mediaType, mediaTypeObject, definition, {
390
330
  includeReadOnly: true,
391
331
  includeWriteOnly: false
392
332
  });
@@ -410,20 +350,31 @@ function getResponseExamples(operation) {
410
350
  }
411
351
 
412
352
  // src/operation/lib/get-callback-examples.ts
413
- function getCallbackExamples(operation) {
353
+ function getCallbackExamples(operation, definition) {
414
354
  if (!operation.callbacks) {
415
355
  return [];
416
356
  }
417
357
  const examples = Object.keys(operation.callbacks).map((identifier) => {
418
- const callback = operation.callbacks?.[identifier];
419
- if (!callback || isRef(callback)) {
420
- return [];
358
+ let callback = operation.callbacks?.[identifier];
359
+ if (!callback) return [];
360
+ if (isRef(callback)) {
361
+ callback = dereferenceRef(callback, definition);
362
+ if (!callback || isRef(callback)) return [];
421
363
  }
422
364
  const items = Object.keys(callback).map((expression) => {
423
- return Object.keys(callback[expression]).map((method) => {
424
- const pathItem = callback[expression];
425
- const example = getResponseExamples(pathItem[method]);
426
- if (example.length === 0) return false;
365
+ let callbackPath = callback[expression];
366
+ if (!callbackPath) return [];
367
+ if (isRef(callbackPath)) {
368
+ callbackPath = dereferenceRef(callbackPath, definition);
369
+ if (!callbackPath || isRef(callbackPath)) return [];
370
+ }
371
+ return Object.keys(callbackPath).map((method) => {
372
+ if (["servers", "parameters", "summary", "description"].includes(method)) {
373
+ return false;
374
+ }
375
+ const pathItem = callbackPath;
376
+ const example = getResponseExamples(pathItem[method], definition);
377
+ if (!example.length) return false;
427
378
  return {
428
379
  identifier,
429
380
  expression,
@@ -495,17 +446,19 @@ function getExampleGroups(operation) {
495
446
  }
496
447
  operation.getParameters().forEach((param) => {
497
448
  Object.entries(param.examples || {}).forEach(([exampleKey, paramExample]) => {
498
- if (isRef(paramExample)) {
499
- return;
449
+ let example = paramExample;
450
+ if (isRef(example)) {
451
+ example = dereferenceRef(example, operation.api);
452
+ if (!example || isRef(example)) return;
500
453
  }
501
454
  groups[exampleKey] = {
502
455
  ...groups[exampleKey],
503
- name: groups[exampleKey]?.name || paramExample.summary || exampleKey,
456
+ name: groups[exampleKey]?.name || example.summary || exampleKey,
504
457
  request: {
505
458
  ...groups[exampleKey]?.request,
506
459
  [param.in]: {
507
460
  ...groups[exampleKey]?.request?.[param.in],
508
- [param.name]: paramExample.value
461
+ [param.name]: example.value
509
462
  }
510
463
  }
511
464
  };
@@ -538,14 +491,19 @@ function getExampleGroups(operation) {
538
491
  }
539
492
 
540
493
  // src/operation/lib/get-requestbody-examples.ts
541
- function getRequestBodyExamples(operation) {
542
- const requestBody = operation.requestBody;
494
+ function getRequestBodyExamples(operation, definition) {
495
+ let requestBody = operation.requestBody;
496
+ if (!requestBody) {
497
+ return [];
498
+ } else if (isRef(requestBody)) {
499
+ requestBody = dereferenceRef(requestBody, definition);
500
+ }
543
501
  if (!requestBody || isRef(requestBody) || !requestBody.content) {
544
502
  return [];
545
503
  }
546
504
  return Object.keys(requestBody.content || {}).map((mediaType) => {
547
505
  const mediaTypeObject = requestBody.content[mediaType];
548
- const examples = getMediaTypeExamples(mediaType, mediaTypeObject, {
506
+ const examples = getMediaTypeExamples(mediaType, mediaTypeObject, definition, {
549
507
  includeReadOnly: false,
550
508
  includeWriteOnly: true
551
509
  });
@@ -559,9 +517,52 @@ function getRequestBodyExamples(operation) {
559
517
  }).filter((item) => item !== false);
560
518
  }
561
519
 
562
- // src/operation/lib/get-response-as-json-schema.ts
520
+ // src/operation/lib/operationId.ts
521
+ function hasOperationId(operation) {
522
+ return Boolean("operationId" in operation && operation.operationId?.length);
523
+ }
524
+ function getOperationId(path, method, operation, opts = {}) {
525
+ function sanitize(id) {
526
+ return id.replace(opts?.camelCase || opts?.friendlyCase ? /[^a-zA-Z0-9_]/g : /[^a-zA-Z0-9]/g, "-").replace(/--+/g, "-").replace(/^-|-$/g, "");
527
+ }
528
+ const operationIdExists = hasOperationId(operation);
529
+ let operationId;
530
+ if (operationIdExists) {
531
+ operationId = operation.operationId;
532
+ } else {
533
+ operationId = sanitize(path).toLowerCase();
534
+ }
535
+ const currMethod = method.toLowerCase();
536
+ if (opts?.camelCase || opts?.friendlyCase) {
537
+ if (opts?.friendlyCase) {
538
+ operationId = operationId.replaceAll("_", " ");
539
+ if (!operationIdExists) {
540
+ operationId = operationId.replace(/[^a-zA-Z0-9_]+(.)/g, (_, chr) => ` ${chr}`).split(" ").filter((word, i, arr) => word !== arr[i - 1]).join(" ");
541
+ }
542
+ }
543
+ operationId = operationId.replace(/[^a-zA-Z0-9_]+(.)/g, (_, chr) => chr.toUpperCase());
544
+ if (operationIdExists) {
545
+ operationId = sanitize(operationId);
546
+ }
547
+ operationId = operationId.replace(/^[0-9]/g, (match) => `_${match}`);
548
+ operationId = operationId.charAt(0).toLowerCase() + operationId.slice(1);
549
+ if (operationId.startsWith(currMethod)) {
550
+ return operationId;
551
+ }
552
+ if (operationIdExists) {
553
+ return operationId;
554
+ }
555
+ operationId = operationId.charAt(0).toUpperCase() + operationId.slice(1);
556
+ return `${currMethod}${operationId}`;
557
+ } else if (operationIdExists) {
558
+ return operationId;
559
+ }
560
+ return `${currMethod}_${operationId}`;
561
+ }
562
+
563
+ // src/operation/transformers/get-response-as-json-schema.ts
563
564
  var isJSON = matches_mimetype_default.json;
564
- function buildHeadersSchema(response, opts) {
565
+ function buildHeadersSchema(response, schemaOptions) {
565
566
  const headersSchema = {
566
567
  type: "object",
567
568
  properties: {}
@@ -578,7 +579,7 @@ function buildHeadersSchema(response, opts) {
578
579
  }
579
580
  headersSchema.properties[key] = toJSONSchema(header.schema, {
580
581
  addEnumsToDescriptions: true,
581
- transformer: opts?.transformer
582
+ ...schemaOptions
582
583
  });
583
584
  if (header.description) {
584
585
  headersSchema.properties[key].description = header.description;
@@ -602,15 +603,24 @@ function getResponseAsJSONSchema(operation, api, statusCode, opts) {
602
603
  if (!response) {
603
604
  return null;
604
605
  }
605
- let hasCircularRefs = false;
606
- let hasDiscriminatorMappingRefs = false;
607
- function refLogger(ref, type) {
608
- if (type === "ref") {
609
- hasCircularRefs = true;
610
- } else {
611
- hasDiscriminatorMappingRefs = true;
612
- }
613
- }
606
+ const usedSchemas = /* @__PURE__ */ new Map();
607
+ const seenRefs = /* @__PURE__ */ new Set();
608
+ const refsByGroup = /* @__PURE__ */ new Map();
609
+ function refLoggerForSchemaGroup(group) {
610
+ let set = refsByGroup.get(group);
611
+ if (!set) {
612
+ set = /* @__PURE__ */ new Set();
613
+ refsByGroup.set(group, set);
614
+ }
615
+ return set;
616
+ }
617
+ const baseSchemaOptions = {
618
+ addEnumsToDescriptions: true,
619
+ definition: api,
620
+ seenRefs,
621
+ usedSchemas,
622
+ refLogger: (ref) => refLoggerForSchemaGroup("body").add(ref)
623
+ };
614
624
  function getPreferredSchema(content, preferredContentType) {
615
625
  if (!content) {
616
626
  return null;
@@ -625,11 +635,7 @@ function getResponseAsJSONSchema(operation, api, statusCode, opts) {
625
635
  if (!schema2) {
626
636
  return null;
627
637
  }
628
- return toJSONSchema(schema2, {
629
- addEnumsToDescriptions: true,
630
- refLogger,
631
- transformer: opts?.transformer
632
- });
638
+ return toJSONSchema(schema2, baseSchemaOptions);
633
639
  }
634
640
  return null;
635
641
  }
@@ -639,11 +645,7 @@ function getResponseAsJSONSchema(operation, api, statusCode, opts) {
639
645
  if (!schema2) {
640
646
  return {};
641
647
  }
642
- return toJSONSchema(schema2, {
643
- addEnumsToDescriptions: true,
644
- refLogger,
645
- transformer: opts?.transformer
646
- });
648
+ return toJSONSchema(schema2, baseSchemaOptions);
647
649
  }
648
650
  }
649
651
  const contentType = contentTypes.shift();
@@ -654,23 +656,25 @@ function getResponseAsJSONSchema(operation, api, statusCode, opts) {
654
656
  if (!schema) {
655
657
  return {};
656
658
  }
657
- return toJSONSchema(schema, {
658
- addEnumsToDescriptions: true,
659
- refLogger,
660
- transformer: opts?.transformer
661
- });
659
+ return toJSONSchema(schema, baseSchemaOptions);
662
660
  }
663
661
  const foundSchema = getPreferredSchema(response.content, opts?.contentType);
664
662
  if (opts?.contentType && !foundSchema) {
665
663
  return null;
666
664
  }
667
665
  if (foundSchema) {
668
- const schema = cloneObject(foundSchema);
666
+ const schema = structuredClone(foundSchema);
667
+ let schemaType = foundSchema.type;
668
+ if (schemaType === void 0 && isRef(foundSchema) && usedSchemas.size > 0) {
669
+ const resolvedSchema = usedSchemas.get(foundSchema.$ref);
670
+ const resolvedType = resolvedSchema && typeof resolvedSchema === "object" && "type" in resolvedSchema ? resolvedSchema.type : void 0;
671
+ schemaType = Array.isArray(resolvedType) ? resolvedType[0] : resolvedType;
672
+ }
669
673
  const schemaWrapper = {
670
674
  // If there's no `type` then the root schema is a circular `$ref` that we likely won't be
671
675
  // able to render so instead of generating a JSON Schema with an `undefined` type we should
672
676
  // default to `string` so there's at least *something* the end-user can interact with.
673
- type: foundSchema.type || "string",
677
+ type: schemaType ?? "string",
674
678
  schema: isPrimitive(schema) ? schema : {
675
679
  ...schema,
676
680
  $schema: getSchemaVersionString(schema, api)
@@ -680,66 +684,55 @@ function getResponseAsJSONSchema(operation, api, statusCode, opts) {
680
684
  if (response.description && schemaWrapper.schema) {
681
685
  schemaWrapper.description = response.description;
682
686
  }
683
- if (api.components && schemaWrapper.schema) {
684
- if (hasCircularRefs || hasDiscriminatorMappingRefs && opts?.includeDiscriminatorMappingRefs) {
685
- schemaWrapper.schema.components = cloneObject(
686
- api.components
687
- );
687
+ applyDiscriminatorOneOfToUsedSchemas(api, usedSchemas, (ref) => {
688
+ if (usedSchemas.has(ref)) {
689
+ return usedSchemas.get(ref);
690
+ }
691
+ try {
692
+ const resolved = dereferenceRef({ $ref: ref }, api, seenRefs);
693
+ if (isRef(resolved)) return void 0;
694
+ const converted = toJSONSchema(structuredClone(resolved), {
695
+ ...baseSchemaOptions,
696
+ seenRefs
697
+ });
698
+ usedSchemas.set(ref, converted);
699
+ return converted;
700
+ } catch {
701
+ return void 0;
702
+ }
703
+ });
704
+ if (schemaWrapper.schema && usedSchemas.size > 0) {
705
+ const refsInGroup = refsByGroup.get("body") ?? /* @__PURE__ */ new Set();
706
+ const referencedSchemas = filterRequiredRefsToReferenced(refsInGroup, usedSchemas);
707
+ if (referencedSchemas.size > 0) {
708
+ mergeReferencedSchemasIntoRoot(schemaWrapper.schema, referencedSchemas);
688
709
  }
689
710
  }
690
711
  jsonSchema.push(schemaWrapper);
691
712
  }
692
713
  if (response.headers) {
693
- jsonSchema.push(buildHeadersSchema(response, opts));
694
- }
695
- return jsonSchema.length ? jsonSchema : null;
696
- }
697
-
698
- // src/operation/lib/operationId.ts
699
- function hasOperationId(operation) {
700
- return Boolean("operationId" in operation && operation.operationId?.length);
701
- }
702
- function getOperationId(path, method, operation, opts = {}) {
703
- function sanitize(id) {
704
- return id.replace(opts?.camelCase || opts?.friendlyCase ? /[^a-zA-Z0-9_]/g : /[^a-zA-Z0-9]/g, "-").replace(/--+/g, "-").replace(/^-|-$/g, "");
705
- }
706
- const operationIdExists = hasOperationId(operation);
707
- let operationId;
708
- if (operationIdExists) {
709
- operationId = operation.operationId;
710
- } else {
711
- operationId = sanitize(path).toLowerCase();
712
- }
713
- const currMethod = method.toLowerCase();
714
- if (opts?.camelCase || opts?.friendlyCase) {
715
- if (opts?.friendlyCase) {
716
- operationId = operationId.replaceAll("_", " ");
717
- if (!operationIdExists) {
718
- operationId = operationId.replace(/[^a-zA-Z0-9_]+(.)/g, (_, chr) => ` ${chr}`).split(" ").filter((word, i, arr) => word !== arr[i - 1]).join(" ");
714
+ const headersWrapper = buildHeadersSchema(response, {
715
+ ...baseSchemaOptions,
716
+ refLogger: (ref) => refLoggerForSchemaGroup("headers").add(ref)
717
+ });
718
+ if (headersWrapper.schema && usedSchemas.size > 0) {
719
+ const refsInGroup = refsByGroup.get("headers") ?? /* @__PURE__ */ new Set();
720
+ const referencedSchemas = filterRequiredRefsToReferenced(refsInGroup, usedSchemas);
721
+ if (referencedSchemas.size > 0) {
722
+ mergeReferencedSchemasIntoRoot(headersWrapper.schema, referencedSchemas);
719
723
  }
720
724
  }
721
- operationId = operationId.replace(/[^a-zA-Z0-9_]+(.)/g, (_, chr) => chr.toUpperCase());
722
- if (operationIdExists) {
723
- operationId = sanitize(operationId);
724
- }
725
- operationId = operationId.replace(/^[0-9]/g, (match) => `_${match}`);
726
- operationId = operationId.charAt(0).toLowerCase() + operationId.slice(1);
727
- if (operationId.startsWith(currMethod)) {
728
- return operationId;
729
- }
730
- if (operationIdExists) {
731
- return operationId;
732
- }
733
- operationId = operationId.charAt(0).toUpperCase() + operationId.slice(1);
734
- return `${currMethod}${operationId}`;
735
- } else if (operationIdExists) {
736
- return operationId;
725
+ jsonSchema.push(headersWrapper);
737
726
  }
738
- return `${currMethod}_${operationId}`;
727
+ return jsonSchema.length ? jsonSchema : null;
739
728
  }
740
729
 
741
730
  // src/operation/index.ts
742
731
  var Operation = class {
732
+ /**
733
+ * The `Oas` instance that this operation belongs to.
734
+ */
735
+ oas;
743
736
  /**
744
737
  * Schema of the operation from the API Definition.
745
738
  */
@@ -791,9 +784,17 @@ var Operation = class {
791
784
  * it doesn't initiate multiple dereferencing processes.
792
785
  */
793
786
  dereferencing;
794
- constructor(api, path, method, operation) {
787
+ /**
788
+ * Have the component schemas within this API definition been decorated with our
789
+ * `x-readme-ref-name` extension?
790
+ *
791
+ * @see {@link decorateComponentSchemas}
792
+ */
793
+ schemasDecorated = false;
794
+ constructor(oas, path, method, operation) {
795
+ this.oas = oas;
795
796
  this.schema = operation;
796
- this.api = api;
797
+ this.api = oas.api;
797
798
  this.path = path;
798
799
  this.method = method;
799
800
  this.contentType = void 0;
@@ -954,14 +955,16 @@ var Operation = class {
954
955
  const keysWithTypes = keys.map((key) => {
955
956
  let security;
956
957
  try {
957
- if (!this.api.components?.securitySchemes?.[key] || isRef(this.api.components.securitySchemes[key])) {
958
- return false;
958
+ security = this.api?.components?.securitySchemes?.[key];
959
+ if (!security) return false;
960
+ if (isRef(security)) {
961
+ security = dereferenceRef(security, this.api);
962
+ if (!security || isRef(security)) return false;
959
963
  }
960
- security = this.api.components.securitySchemes[key];
961
964
  } catch {
962
965
  return false;
963
966
  }
964
- if (!security) return false;
967
+ if (!security || isRef(security)) return false;
965
968
  let type = null;
966
969
  if (security.type === "http") {
967
970
  if (security.scheme === "basic") type = "Basic";
@@ -1034,37 +1037,56 @@ var Operation = class {
1034
1037
  if (this.schema.parameters) {
1035
1038
  this.headers.request = this.headers.request.concat(
1036
1039
  this.schema.parameters.map((p) => {
1037
- if (isRef(p)) {
1038
- return void 0;
1040
+ let param = p;
1041
+ if (isRef(param)) {
1042
+ param = dereferenceRef(param, this.api);
1043
+ if (!param || isRef(param)) return void 0;
1039
1044
  }
1040
- if (p.in && p.in === "header") return p.name;
1045
+ if (param.in && param.in === "header") return param.name;
1041
1046
  return void 0;
1042
1047
  }).filter((item) => item !== void 0)
1043
1048
  );
1044
1049
  }
1045
1050
  if (this.schema.responses) {
1046
1051
  this.headers.response = Object.keys(this.schema.responses).map((r) => {
1047
- const response = this.schema.responses?.[r];
1048
- if (!response || isRef(response)) {
1049
- return [];
1052
+ let response = this.schema.responses[r];
1053
+ if (!response) return [];
1054
+ if (isRef(response)) {
1055
+ this.schema.responses[r] = dereferenceRef(response, this.api);
1056
+ response = this.schema.responses[r];
1057
+ if (!response || isRef(response)) {
1058
+ return [];
1059
+ }
1050
1060
  }
1051
1061
  return response?.headers ? Object.keys(response.headers) : [];
1052
1062
  }).reduce((a, b) => a.concat(b), []);
1053
1063
  }
1054
1064
  if (!this.headers.request.includes("Content-Type") && this.schema.requestBody) {
1055
- const requestBody = this.schema.requestBody;
1056
- if (requestBody && !isRef(requestBody) && "content" in requestBody && Object.keys(requestBody.content)) {
1057
- this.headers.request.push("Content-Type");
1065
+ let requestBody = this.schema.requestBody;
1066
+ if (requestBody) {
1067
+ if (isRef(requestBody)) {
1068
+ this.schema.requestBody = dereferenceRef(requestBody, this.api);
1069
+ requestBody = this.schema.requestBody;
1070
+ }
1071
+ if (requestBody && !isRef(requestBody) && "content" in requestBody && Object.keys(requestBody.content)) {
1072
+ this.headers.request.push("Content-Type");
1073
+ }
1058
1074
  }
1059
1075
  }
1060
1076
  if (this.schema.responses) {
1061
- if (Object.keys(this.schema.responses).some((r) => {
1062
- const response = this.schema.responses?.[r];
1063
- if (!response || isRef(response)) {
1064
- return false;
1077
+ const hasResponseContent = Object.keys(this.schema.responses).some((r) => {
1078
+ let response = this.schema.responses?.[r];
1079
+ if (!response) return false;
1080
+ if (isRef(response)) {
1081
+ this.schema.responses[r] = dereferenceRef(response, this.api);
1082
+ response = this.schema.responses[r];
1083
+ if (!response || isRef(response)) {
1084
+ return false;
1085
+ }
1065
1086
  }
1066
- return response?.content && Object.keys(response.content).length > 0;
1067
- })) {
1087
+ return response.content && Object.keys(response.content).length > 0;
1088
+ });
1089
+ if (hasResponseContent) {
1068
1090
  if (!this.headers.request.includes("Accept")) this.headers.request.push("Accept");
1069
1091
  if (!this.headers.response.includes("Content-Type")) this.headers.response.push("Content-Type");
1070
1092
  }
@@ -1159,17 +1181,26 @@ var Operation = class {
1159
1181
  /**
1160
1182
  * Return the parameters (non-request body) on the operation.
1161
1183
  *
1162
- * @todo Add support for `ReferenceObject`
1163
1184
  * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#user-content-operationparameters}
1164
1185
  * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.2.md#user-content-operation-parameters}
1165
1186
  */
1166
1187
  getParameters() {
1167
- let parameters = (this.schema?.parameters || []).filter(
1168
- (param) => param && !isRef(param)
1169
- );
1170
- const commonParams = (this.api?.paths?.[this.path]?.parameters || []).filter(
1171
- (param) => param && !isRef(param)
1172
- );
1188
+ let parameters = (this.schema?.parameters || []).map((p) => {
1189
+ let param = p;
1190
+ if (isRef(param)) {
1191
+ param = dereferenceRef(param, this.api);
1192
+ if (!param || isRef(param)) return void 0;
1193
+ }
1194
+ return param;
1195
+ }).filter((param) => param !== void 0);
1196
+ const commonParams = (this.api?.paths?.[this.path]?.parameters || []).map((p) => {
1197
+ let param = p;
1198
+ if (isRef(param)) {
1199
+ param = dereferenceRef(param, this.api);
1200
+ if (!param || isRef(param)) return void 0;
1201
+ }
1202
+ return param;
1203
+ }).filter((param) => param !== void 0);
1173
1204
  if (commonParams.length) {
1174
1205
  parameters = parameters.concat(dedupeCommonParameters(parameters, commonParams) || []);
1175
1206
  }
@@ -1188,26 +1219,54 @@ var Operation = class {
1188
1219
  * Convert the operation into an array of JSON Schema schemas for each available type of
1189
1220
  * parameter available on the operation.
1190
1221
  *
1222
+ * Note that this method is not compatible with an operation or OpenAPI definition that has been
1223
+ * processed with `.dereference()`. This method can only be called with the _original_ API
1224
+ * definition that was used to initialize the `Operation` and `Oas` instance. If a dereferenced
1225
+ * schema is present when this is called a `TypeError` will be thrown.
1226
+ *
1227
+ * @throws {TypeError} If the operation or OpenAPI definition has been run through `.dereference().`
1228
+ *
1191
1229
  */
1192
1230
  getParametersAsJSONSchema(opts = {}) {
1231
+ if (this.isDereferenced()) {
1232
+ throw new Error(
1233
+ "`.getParametersAsJSONSchema()` is not compatible with an operation or OpenAPI definition that has been run through `.dereference().`"
1234
+ );
1235
+ }
1236
+ if (!this.schemasDecorated) {
1237
+ decorateComponentSchemasWithRefName(this.api);
1238
+ this.schemasDecorated = true;
1239
+ }
1193
1240
  return getParametersAsJSONSchema(this, this.api, {
1194
1241
  includeDiscriminatorMappingRefs: true,
1195
- transformer: (s) => s,
1196
1242
  ...opts
1197
1243
  });
1198
1244
  }
1199
1245
  /**
1200
1246
  * Get a single response for this status code, formatted as JSON schema.
1201
1247
  *
1248
+ * Note that this method is not compatible with an operation or OpenAPI definition that has been
1249
+ * processed with `.dereference()`. This method can only be called with the _original_ API
1250
+ * definition that was used to initialize the `Operation` and `Oas` instance. If a dereferenced
1251
+ * schema is present when this is called a `TypeError` will be thrown.
1252
+ *
1202
1253
  * @param statusCode Status code to pull a JSON Schema response for.
1203
1254
  * @param opts Options for schema generation.
1204
1255
  * @param opts.contentType Optional content-type to use. If specified and the response doesn't have
1205
1256
  * this content-type, the function will return null.
1206
1257
  */
1207
1258
  getResponseAsJSONSchema(statusCode, opts = {}) {
1259
+ if (this.isDereferenced()) {
1260
+ throw new Error(
1261
+ "`.getResponseAsJSONSchema()` is not compatible with an operation or OpenAPI definition that has been run through `.dereference().`"
1262
+ );
1263
+ }
1264
+ if (!this.schemasDecorated) {
1265
+ decorateComponentSchemasWithRefName(this.api);
1266
+ this.schemasDecorated = true;
1267
+ }
1208
1268
  return getResponseAsJSONSchema(this, this.api, statusCode, {
1209
1269
  includeDiscriminatorMappingRefs: true,
1210
- transformer: (s) => s,
1211
1270
  ...opts
1212
1271
  });
1213
1272
  }
@@ -1218,6 +1277,30 @@ var Operation = class {
1218
1277
  getResponseStatusCodes() {
1219
1278
  return this.schema.responses ? Object.keys(this.schema.responses) : [];
1220
1279
  }
1280
+ /**
1281
+ * Retrieve an array of all content types that this operation can return.
1282
+ *
1283
+ * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#response-object}
1284
+ * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.2.md#response-object}
1285
+ */
1286
+ getResponseContentTypes() {
1287
+ if (!this.schema.responses) return [];
1288
+ const contentTypes = /* @__PURE__ */ new Set();
1289
+ Object.values(this.schema.responses).forEach((response) => {
1290
+ let resp = response;
1291
+ if (!resp) return;
1292
+ if (isRef(resp)) {
1293
+ resp = dereferenceRef(resp, this.api);
1294
+ if (!resp || isRef(resp)) {
1295
+ return;
1296
+ }
1297
+ }
1298
+ Object.keys(resp.content || {}).forEach((mimeType) => {
1299
+ contentTypes.add(mimeType);
1300
+ });
1301
+ });
1302
+ return Array.from(contentTypes);
1303
+ }
1221
1304
  /**
1222
1305
  * Determine if the operation has any request bodies.
1223
1306
  *
@@ -1227,6 +1310,23 @@ var Operation = class {
1227
1310
  hasRequestBody() {
1228
1311
  return !!this.schema.requestBody;
1229
1312
  }
1313
+ /**
1314
+ * Return the current `requestBody` object, dereferencing it in the process if it's a `$ref`
1315
+ * pointer.
1316
+ *
1317
+ */
1318
+ getResolvedRequestBody() {
1319
+ let requestBody = this.schema.requestBody;
1320
+ if (!requestBody) return false;
1321
+ if (isRef(requestBody)) {
1322
+ this.schema.requestBody = dereferenceRef(requestBody, this.api);
1323
+ requestBody = this.schema.requestBody;
1324
+ if (!requestBody || isRef(requestBody)) {
1325
+ return false;
1326
+ }
1327
+ }
1328
+ return requestBody;
1329
+ }
1230
1330
  /**
1231
1331
  * Retrieve the list of all available media types that the operations request body can accept.
1232
1332
  *
@@ -1237,10 +1337,8 @@ var Operation = class {
1237
1337
  if (!this.hasRequestBody()) {
1238
1338
  return [];
1239
1339
  }
1240
- const requestBody = this.schema.requestBody;
1241
- if (!requestBody || isRef(requestBody)) {
1242
- return [];
1243
- }
1340
+ const requestBody = this.getResolvedRequestBody();
1341
+ if (!requestBody) return [];
1244
1342
  return Object.keys(requestBody.content);
1245
1343
  }
1246
1344
  /**
@@ -1253,10 +1351,8 @@ var Operation = class {
1253
1351
  if (!this.hasRequestBody()) {
1254
1352
  return false;
1255
1353
  }
1256
- const requestBody = this.schema.requestBody;
1257
- if (!requestBody || isRef(requestBody)) {
1258
- return false;
1259
- }
1354
+ const requestBody = this.getResolvedRequestBody();
1355
+ if (!requestBody) return false;
1260
1356
  if (requestBody.required) {
1261
1357
  return true;
1262
1358
  }
@@ -1282,10 +1378,8 @@ var Operation = class {
1282
1378
  if (!this.hasRequestBody()) {
1283
1379
  return false;
1284
1380
  }
1285
- const requestBody = this.schema.requestBody;
1286
- if (!requestBody || isRef(requestBody)) {
1287
- return false;
1288
- }
1381
+ const requestBody = this.getResolvedRequestBody();
1382
+ if (!requestBody) return false;
1289
1383
  if (mediaType) {
1290
1384
  if (!(mediaType in requestBody.content)) {
1291
1385
  return false;
@@ -1326,7 +1420,7 @@ var Operation = class {
1326
1420
  if (this.requestBodyExamples && isRequestExampleValueDefined) {
1327
1421
  return this.requestBodyExamples;
1328
1422
  }
1329
- this.requestBodyExamples = getRequestBodyExamples(this.schema);
1423
+ this.requestBodyExamples = getRequestBodyExamples(this.schema, this.api);
1330
1424
  return this.requestBodyExamples;
1331
1425
  }
1332
1426
  /**
@@ -1340,9 +1434,14 @@ var Operation = class {
1340
1434
  if (!this.schema.responses) {
1341
1435
  return false;
1342
1436
  }
1343
- const response = this.schema.responses[statusCode];
1344
- if (!response || isRef(response)) {
1345
- return false;
1437
+ let response = this.schema.responses[statusCode];
1438
+ if (!response) return false;
1439
+ if (isRef(response)) {
1440
+ this.schema.responses[statusCode] = dereferenceRef(response, this.api);
1441
+ response = this.schema.responses[statusCode];
1442
+ if (!response || isRef(response)) {
1443
+ return false;
1444
+ }
1346
1445
  }
1347
1446
  return response;
1348
1447
  }
@@ -1356,7 +1455,7 @@ var Operation = class {
1356
1455
  if (this.responseExamples) {
1357
1456
  return this.responseExamples;
1358
1457
  }
1359
- this.responseExamples = getResponseExamples(this.schema);
1458
+ this.responseExamples = getResponseExamples(this.schema, this.api);
1360
1459
  return this.responseExamples;
1361
1460
  }
1362
1461
  /**
@@ -1379,15 +1478,28 @@ var Operation = class {
1379
1478
  */
1380
1479
  getCallback(identifier, expression, method) {
1381
1480
  if (!this.schema.callbacks) return false;
1382
- const callbackObj = this.schema.callbacks[identifier];
1383
- if (!callbackObj || isRef(callbackObj)) {
1384
- return false;
1481
+ let callbackObj = this.schema.callbacks[identifier];
1482
+ if (!callbackObj) return false;
1483
+ if (isRef(callbackObj)) {
1484
+ this.schema.callbacks[identifier] = dereferenceRef(callbackObj, this.api);
1485
+ callbackObj = this.schema.callbacks[identifier];
1486
+ if (!callbackObj || isRef(callbackObj)) {
1487
+ return false;
1488
+ }
1489
+ }
1490
+ let callback = callbackObj[expression];
1491
+ if (!callback) return false;
1492
+ if (isRef(callback)) {
1493
+ callbackObj[expression] = dereferenceRef(callback, this.api);
1494
+ callback = callbackObj[expression];
1495
+ if (!callback || isRef(callback)) {
1496
+ return false;
1497
+ }
1385
1498
  }
1386
- const callback = callbackObj[expression];
1387
- if (!callback || isRef(callback) || !callback[method]) {
1499
+ if (!callback[method]) {
1388
1500
  return false;
1389
1501
  }
1390
- return new Callback(this.api, expression, method, callback[method], identifier, callback);
1502
+ return new Callback(this.oas, expression, method, callback[method], identifier, callback);
1391
1503
  }
1392
1504
  /**
1393
1505
  * Retrieve an array of operations created from each callback.
@@ -1398,17 +1510,27 @@ var Operation = class {
1398
1510
  getCallbacks() {
1399
1511
  if (!this.hasCallbacks()) return [];
1400
1512
  const callbacks = [];
1401
- Object.keys(this.schema.callbacks || {}).forEach((callback) => {
1402
- const cb = this.schema.callbacks?.[callback];
1403
- if (!cb || isRef(cb)) {
1404
- return;
1513
+ Object.keys(this.schema.callbacks).forEach((callback) => {
1514
+ let cb = this.schema.callbacks?.[callback];
1515
+ if (!cb) return;
1516
+ if (isRef(cb)) {
1517
+ this.schema.callbacks[callback] = dereferenceRef(cb, this.api);
1518
+ cb = this.schema.callbacks[callback];
1519
+ if (!cb || isRef(cb)) {
1520
+ return;
1521
+ }
1405
1522
  }
1406
1523
  Object.keys(cb).forEach((expression) => {
1407
- const exp = cb[expression];
1408
- if (!exp || isRef(exp)) {
1409
- return;
1524
+ let callbackPath = cb[expression];
1525
+ if (!callbackPath) return;
1526
+ if (isRef(callbackPath)) {
1527
+ cb[expression] = dereferenceRef(callbackPath, this.api);
1528
+ callbackPath = cb[expression];
1529
+ if (!callbackPath || isRef(callbackPath)) {
1530
+ return;
1531
+ }
1410
1532
  }
1411
- Object.keys(exp).forEach((method) => {
1533
+ Object.keys(callbackPath).forEach((method) => {
1412
1534
  if (!supportedMethods.includes(method)) return;
1413
1535
  const found = this.getCallback(callback, expression, method);
1414
1536
  if (found) {
@@ -1429,7 +1551,7 @@ var Operation = class {
1429
1551
  if (this.callbackExamples) {
1430
1552
  return this.callbackExamples;
1431
1553
  }
1432
- this.callbackExamples = getCallbackExamples(this.schema);
1554
+ this.callbackExamples = getCallbackExamples(this.schema, this.api);
1433
1555
  return this.callbackExamples;
1434
1556
  }
1435
1557
  /**
@@ -1486,16 +1608,11 @@ var Operation = class {
1486
1608
  });
1487
1609
  }
1488
1610
  this.dereferencing.processing = true;
1489
- const { children: discriminatorChildrenMap, inverted: discriminatorChildrenMapInverted } = findDiscriminatorChildren(this.api);
1490
- const { api, schema, promises } = this;
1491
- if (api?.components?.schemas && typeof api.components.schemas === "object") {
1492
- Object.keys(api.components.schemas).forEach((schemaName) => {
1493
- if (isPrimitive(api.components?.schemas?.[schemaName]) || Array.isArray(api.components?.schemas?.[schemaName]) || api.components?.schemas?.[schemaName] === null) {
1494
- return;
1495
- }
1496
- (api.components?.schemas?.[schemaName])["x-readme-ref-name"] = schemaName;
1497
- });
1611
+ if (!this.schemasDecorated) {
1612
+ decorateComponentSchemasWithRefName(this.api);
1613
+ this.schemasDecorated = true;
1498
1614
  }
1615
+ const { api, schema, promises } = this;
1499
1616
  const circularRefs = /* @__PURE__ */ new Set();
1500
1617
  const dereferencingOptions = getDereferencingOptions(circularRefs);
1501
1618
  const parser = new $RefParser();
@@ -1530,30 +1647,12 @@ var Operation = class {
1530
1647
  if (path === "#/paths" || path.startsWith("#/paths/")) {
1531
1648
  return true;
1532
1649
  }
1533
- if (discriminatorChildrenMap.size > 0 || discriminatorChildrenMapInverted.size > 0) {
1534
- if (path.startsWith("#/components/") && path !== "#/components/schemas" && !path.startsWith("#/components/schemas/")) {
1535
- return true;
1536
- }
1537
- if (path.startsWith("#/components/schemas/")) {
1538
- const schemaName = path.split("/").pop();
1539
- if (schemaName && (discriminatorChildrenMap.has(schemaName) || discriminatorChildrenMapInverted.has(schemaName))) {
1540
- if (path === `#/components/schemas/${schemaName}` || path.startsWith(`#/components/schemas/${schemaName}/`)) {
1541
- return false;
1542
- }
1543
- return true;
1544
- }
1545
- }
1546
- return false;
1547
- }
1548
1650
  return path === "#/components" || path.startsWith("#/components/");
1549
1651
  }
1550
1652
  }
1551
1653
  }
1552
1654
  ).then((res) => {
1553
1655
  const dereferenced = res;
1554
- if (dereferenced?.components?.schemas && discriminatorChildrenMap.size > 0) {
1555
- buildDiscriminatorOneOf({ components: dereferenced.components }, discriminatorChildrenMap);
1556
- }
1557
1656
  this.schema = dereferenced.__INTERNAL__;
1558
1657
  this.promises = promises;
1559
1658
  this.dereferencing = {
@@ -1573,6 +1672,15 @@ var Operation = class {
1573
1672
  throw err;
1574
1673
  });
1575
1674
  }
1675
+ /**
1676
+ * Determine if the current operation schema, or the OpenAPI definition it's part of, has been
1677
+ * dereferenced or not with `.dereference()`.
1678
+ *
1679
+ * @see Operation.dereference
1680
+ */
1681
+ isDereferenced() {
1682
+ return this.oas.isDereferenced() || this.dereferencing.processing || this.dereferencing.complete;
1683
+ }
1576
1684
  /**
1577
1685
  * Retrieve any circular `$ref` pointers that maybe present within operation schema.
1578
1686
  *
@@ -1610,6 +1718,12 @@ var Callback = class extends Operation {
1610
1718
  getIdentifier() {
1611
1719
  return this.identifier;
1612
1720
  }
1721
+ /**
1722
+ * Retrieve the `summary` for this callback.
1723
+ *
1724
+ * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#user-content-operationsummary}
1725
+ * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.2.md#user-content-operation-summary}
1726
+ */
1613
1727
  getSummary() {
1614
1728
  if (this.schema?.summary && typeof this.schema.summary === "string") {
1615
1729
  return this.schema.summary;
@@ -1618,6 +1732,12 @@ var Callback = class extends Operation {
1618
1732
  }
1619
1733
  return void 0;
1620
1734
  }
1735
+ /**
1736
+ * Retrieve the `description` for this operation.
1737
+ *
1738
+ * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#user-content-operationdescription}
1739
+ * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.2.md#user-content-operation-description}
1740
+ */
1621
1741
  getDescription() {
1622
1742
  if (this.schema?.description && typeof this.schema.description === "string") {
1623
1743
  return this.schema.description;
@@ -1626,9 +1746,29 @@ var Callback = class extends Operation {
1626
1746
  }
1627
1747
  return void 0;
1628
1748
  }
1749
+ /**
1750
+ * Return the parameters (non-request body) on the operation.
1751
+ *
1752
+ * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#user-content-operationparameters}
1753
+ * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.2.md#user-content-operation-parameters}
1754
+ */
1629
1755
  getParameters() {
1630
- let parameters = this.schema?.parameters || [];
1631
- const commonParams = this.parentSchema.parameters || [];
1756
+ let parameters = (this.schema?.parameters || []).map((p) => {
1757
+ let param = p;
1758
+ if (isRef(param)) {
1759
+ param = dereferenceRef(param, this.api);
1760
+ if (!param || isRef(param)) return void 0;
1761
+ }
1762
+ return param;
1763
+ }).filter((param) => param !== void 0);
1764
+ const commonParams = (this.parentSchema.parameters || []).map((p) => {
1765
+ let param = p;
1766
+ if (isRef(param)) {
1767
+ param = dereferenceRef(param, this.api);
1768
+ if (!param || isRef(param)) return void 0;
1769
+ }
1770
+ return param;
1771
+ }).filter((param) => param !== void 0);
1632
1772
  if (commonParams.length) {
1633
1773
  parameters = parameters.concat(dedupeCommonParameters(parameters, commonParams) || []);
1634
1774
  }
@@ -1636,35 +1776,47 @@ var Callback = class extends Operation {
1636
1776
  }
1637
1777
  };
1638
1778
  var Webhook = class extends Operation {
1779
+ /**
1780
+ * Retrieve the `summary` for this callback.
1781
+ *
1782
+ * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#user-content-operationsummary}
1783
+ * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.2.md#user-content-operation-summary}
1784
+ */
1639
1785
  getSummary() {
1640
1786
  if (this.schema?.summary && typeof this.schema.summary === "string") {
1641
1787
  return this.schema.summary;
1788
+ } else if (!this.api.webhooks) {
1789
+ return void 0;
1642
1790
  }
1643
- const webhookPath = this.api.webhooks?.[this.path];
1644
- if (webhookPath && !isRef(webhookPath)) {
1645
- if (webhookPath?.summary && typeof webhookPath.summary === "string") {
1646
- return webhookPath.summary;
1647
- }
1791
+ let webhookPath = this.api.webhooks[this.path];
1792
+ if (isRef(webhookPath)) {
1793
+ this.api.webhooks[this.path] = dereferenceRef(webhookPath, this.api);
1794
+ webhookPath = this.api.webhooks[this.path];
1648
1795
  }
1649
- return void 0;
1796
+ return webhookPath?.summary;
1650
1797
  }
1798
+ /**
1799
+ * Retrieve the `description` for this operation.
1800
+ *
1801
+ * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#user-content-operationdescription}
1802
+ * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.2.md#user-content-operation-description}
1803
+ */
1651
1804
  getDescription() {
1652
1805
  if (this.schema?.description && typeof this.schema.description === "string") {
1653
1806
  return this.schema.description;
1807
+ } else if (!this.api.webhooks) {
1808
+ return void 0;
1654
1809
  }
1655
- const webhookPath = this.api.webhooks?.[this.path];
1656
- if (webhookPath && !isRef(webhookPath)) {
1657
- if (webhookPath?.description && typeof webhookPath.description === "string") {
1658
- return webhookPath.description;
1659
- }
1810
+ let webhookPath = this.api.webhooks[this.path];
1811
+ if (isRef(webhookPath)) {
1812
+ this.api.webhooks[this.path] = dereferenceRef(webhookPath, this.api);
1813
+ webhookPath = this.api.webhooks[this.path];
1660
1814
  }
1661
- return void 0;
1815
+ return webhookPath?.description;
1662
1816
  }
1663
1817
  };
1664
1818
 
1665
1819
  export {
1666
- findDiscriminatorChildren,
1667
- buildDiscriminatorOneOf,
1668
1820
  Operation,
1669
1821
  Callback,
1670
1822
  Webhook
@@ -1681,4 +1833,4 @@ export {
1681
1833
  * @license Apache-2.0
1682
1834
  * @see {@link https://github.com/swagger-api/swagger-ui/blob/master/src/core/plugins/samples/fn.js}
1683
1835
  */
1684
- //# sourceMappingURL=chunk-HGVFNEKW.js.map
1836
+ //# sourceMappingURL=chunk-5245ZLBC.js.map