oas 19.0.1 → 19.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## <small>19.0.2 (2022-10-26)</small>
2
+
3
+ * fix: quirks with discriminators and the `transformer` JSON Schema option (#698) ([b84c57f](https://github.com/readmeio/oas/commit/b84c57f)), closes [#698](https://github.com/readmeio/oas/issues/698)
4
+
5
+
6
+
1
7
  ## <small>19.0.1 (2022-10-14)</small>
2
8
 
3
9
  * feat: supporting transforming a schema object to a primitive (#697) ([048bfc6](https://github.com/readmeio/oas/commit/048bfc6)), closes [#697](https://github.com/readmeio/oas/issues/697)
@@ -24,7 +24,7 @@ export declare type toJSONSchemaOptions = {
24
24
  /**
25
25
  * A function that's called anytime a (circular) `$ref` is found.
26
26
  */
27
- refLogger?: (ref: string) => void;
27
+ refLogger?: (ref: string, type: 'ref' | 'discriminator') => void;
28
28
  /**
29
29
  * A function that's called to potentially transform any discovered schema.
30
30
  */
@@ -269,7 +269,7 @@ function toJSONSchema(data, opts) {
269
269
  // If this schema contains a `$ref`, it's circular and we shouldn't try to resolve it. Just
270
270
  // return and move along.
271
271
  if (RMOAS.isRef(schema)) {
272
- refLogger(schema.$ref);
272
+ refLogger(schema.$ref, 'ref');
273
273
  return transformer({
274
274
  $ref: schema.$ref
275
275
  });
@@ -345,7 +345,7 @@ function toJSONSchema(data, opts) {
345
345
  // them to the supplied `refLogger`.
346
346
  var mapping_1 = schema.discriminator.mapping;
347
347
  Object.keys(mapping_1).forEach(function (k) {
348
- refLogger(mapping_1[k]);
348
+ refLogger(mapping_1[k], 'discriminator');
349
349
  });
350
350
  }
351
351
  }
@@ -393,7 +393,7 @@ function toJSONSchema(data, opts) {
393
393
  if ('$ref' in example) {
394
394
  // no-op because any `$ref` example here after dereferencing is circular so we should
395
395
  // ignore it
396
- refLogger(example.$ref);
396
+ refLogger(example.$ref, 'ref');
397
397
  }
398
398
  else if ('value' in example) {
399
399
  if (isPrimitive(example.value)) {
@@ -446,7 +446,7 @@ function toJSONSchema(data, opts) {
446
446
  if (!Array.isArray(schema.items) && Object.keys(schema.items).length === 1 && RMOAS.isRef(schema.items)) {
447
447
  // `items` contains a `$ref`, so since it's circular we should do a no-op here and log
448
448
  // and ignore it.
449
- refLogger(schema.items.$ref);
449
+ refLogger(schema.items.$ref, 'ref');
450
450
  }
451
451
  else if (schema.items !== true) {
452
452
  // Run through the arrays contents and clean them up.
@@ -17,6 +17,7 @@ export declare type SchemaWrapper = {
17
17
  export declare const types: Record<keyof OASDocument, string>;
18
18
  export default function getParametersAsJSONSchema(operation: Operation, api: OASDocument, opts?: {
19
19
  globalDefaults?: Record<string, unknown>;
20
+ includeDiscriminatorMappingRefs?: boolean;
20
21
  mergeIntoBodyAndMetadata?: boolean;
21
22
  retainDeprecatedProperties?: boolean;
22
23
  transformer?: (schema: SchemaObject) => SchemaObject;
@@ -61,8 +61,14 @@ exports.types = {
61
61
  function getParametersAsJSONSchema(operation, api, opts) {
62
62
  var _a;
63
63
  var hasCircularRefs = false;
64
- function refLogger() {
65
- hasCircularRefs = true;
64
+ var hasDiscriminatorMappingRefs = false;
65
+ function refLogger(ref, type) {
66
+ if (type === 'ref') {
67
+ hasCircularRefs = true;
68
+ }
69
+ else {
70
+ hasDiscriminatorMappingRefs = true;
71
+ }
66
72
  }
67
73
  function getDeprecated(schema, type) {
68
74
  // If we wish to retain deprecated properties then we shouldn't split them out into the
@@ -349,9 +355,13 @@ function getParametersAsJSONSchema(operation, api, opts) {
349
355
  *
350
356
  * @todo
351
357
  */
352
- if (hasCircularRefs && components) {
353
- // Fixing typing and confused version mismatches
354
- group.schema.components = components;
358
+ if (components) {
359
+ // We should only include components if we've got circular refs or we have discriminator
360
+ // mapping refs (we want to include them).
361
+ if (hasCircularRefs || (hasDiscriminatorMappingRefs && opts.includeDiscriminatorMappingRefs)) {
362
+ // Fixing typing and confused version mismatches
363
+ group.schema.components = components;
364
+ }
355
365
  }
356
366
  // Delete deprecatedProps if it's null on the schema.
357
367
  if (!group.deprecatedProps)
@@ -10,11 +10,7 @@ import type { OASDocument, SchemaObject } from 'rmoas.types';
10
10
  * @param statusCode The response status code to generate a schema for.
11
11
  */
12
12
  export default function getResponseAsJSONSchema(operation: Operation, api: OASDocument, statusCode: string | number, opts?: {
13
- /**
14
- * With a transformer you can transform any data within a given schema, like say if you want to
15
- * rewrite a potentially unsafe `title` that might be eventually used as a JS variable name,
16
- * just make sure to return your transformed schema.
17
- */
13
+ includeDiscriminatorMappingRefs?: boolean;
18
14
  transformer?: (schema: SchemaObject) => SchemaObject;
19
15
  }): {
20
16
  type: string | string[];
@@ -97,8 +97,14 @@ function getResponseAsJSONSchema(operation, api, statusCode, opts) {
97
97
  return null;
98
98
  }
99
99
  var hasCircularRefs = false;
100
- function refLogger() {
101
- hasCircularRefs = true;
100
+ var hasDiscriminatorMappingRefs = false;
101
+ function refLogger(ref, type) {
102
+ if (type === 'ref') {
103
+ hasCircularRefs = true;
104
+ }
105
+ else {
106
+ hasDiscriminatorMappingRefs = true;
107
+ }
102
108
  }
103
109
  /**
104
110
  * @param content An array of `MediaTypeObject`'s to retrieve a preferred schema out of. We
@@ -154,8 +160,12 @@ function getResponseAsJSONSchema(operation, api, statusCode, opts) {
154
160
  *
155
161
  * @todo
156
162
  */
157
- if (hasCircularRefs && api.components && schemaWrapper.schema) {
158
- schemaWrapper.schema.components = api.components;
163
+ if (api.components && schemaWrapper.schema) {
164
+ // We should only include components if we've got circular refs or we have discriminator
165
+ // mapping refs (we want to include them).
166
+ if (hasCircularRefs || (hasDiscriminatorMappingRefs && opts.includeDiscriminatorMappingRefs)) {
167
+ schemaWrapper.schema.components = api.components;
168
+ }
159
169
  }
160
170
  jsonSchema.push(schemaWrapper);
161
171
  }
@@ -131,6 +131,11 @@ export default class Operation {
131
131
  * Contains an object of user defined schema defaults.
132
132
  */
133
133
  globalDefaults?: Record<string, unknown>;
134
+ /**
135
+ * If you wish to include discriminator mapping `$ref` components alongside your
136
+ * `discriminator` in schemas. Defaults to `true`.
137
+ */
138
+ includeDiscriminatorMappingRefs?: boolean;
134
139
  /**
135
140
  * If you want the output to be two objects: body (contains `body` and `formData` JSON
136
141
  * Schema) and metadata (contains `path`, `query`, `cookie`, and `header`).
@@ -154,6 +159,11 @@ export default class Operation {
154
159
  * @param statusCode Status code to pull a JSON Schema response for.
155
160
  */
156
161
  getResponseAsJSONSchema(statusCode: string | number, opts?: {
162
+ /**
163
+ * If you wish to include discriminator mapping `$ref` components alongside your
164
+ * `discriminator` in schemas. Defaults to `true`.
165
+ */
166
+ includeDiscriminatorMappingRefs?: boolean;
157
167
  /**
158
168
  * With a transformer you can transform any data within a given schema, like say if you want
159
169
  * to rewrite a potentially unsafe `title` that might be eventually used as a JS variable
package/dist/operation.js CHANGED
@@ -414,10 +414,7 @@ var Operation = /** @class */ (function () {
414
414
  */
415
415
  Operation.prototype.getParametersAsJSONSchema = function (opts) {
416
416
  if (opts === void 0) { opts = {}; }
417
- if (!opts.transformer) {
418
- opts.transformer = function (s) { return s; };
419
- }
420
- return (0, get_parameters_as_json_schema_1["default"])(this, this.api, opts);
417
+ return (0, get_parameters_as_json_schema_1["default"])(this, this.api, __assign({ includeDiscriminatorMappingRefs: true, transformer: function (s) { return s; } }, opts));
421
418
  };
422
419
  /**
423
420
  * Get a single response for this status code, formatted as JSON schema.
@@ -425,10 +422,8 @@ var Operation = /** @class */ (function () {
425
422
  * @param statusCode Status code to pull a JSON Schema response for.
426
423
  */
427
424
  Operation.prototype.getResponseAsJSONSchema = function (statusCode, opts) {
428
- if (opts === void 0) { opts = {
429
- transformer: function (s) { return s; }
430
- }; }
431
- return (0, get_response_as_json_schema_1["default"])(this, this.api, statusCode, opts);
425
+ if (opts === void 0) { opts = {}; }
426
+ return (0, get_response_as_json_schema_1["default"])(this, this.api, statusCode, __assign({ includeDiscriminatorMappingRefs: true, transformer: function (s) { return s; } }, opts));
432
427
  };
433
428
  /**
434
429
  * Get an array of all valid response status codes for this operation.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oas",
3
- "version": "19.0.1",
3
+ "version": "19.0.2",
4
4
  "description": "Working with OpenAPI definitions is hard. This makes it easier.",
5
5
  "license": "MIT",
6
6
  "author": "ReadMe <support@readme.io> (https://readme.com)",
@@ -56,7 +56,7 @@ export type toJSONSchemaOptions = {
56
56
  /**
57
57
  * A function that's called anytime a (circular) `$ref` is found.
58
58
  */
59
- refLogger?: (ref: string) => void;
59
+ refLogger?: (ref: string, type: 'ref' | 'discriminator') => void;
60
60
 
61
61
  /**
62
62
  * A function that's called to potentially transform any discovered schema.
@@ -295,7 +295,7 @@ export default function toJSONSchema(
295
295
  // If this schema contains a `$ref`, it's circular and we shouldn't try to resolve it. Just
296
296
  // return and move along.
297
297
  if (RMOAS.isRef(schema)) {
298
- refLogger(schema.$ref);
298
+ refLogger(schema.$ref, 'ref');
299
299
 
300
300
  return transformer({
301
301
  $ref: schema.$ref,
@@ -381,7 +381,7 @@ export default function toJSONSchema(
381
381
  // them to the supplied `refLogger`.
382
382
  const mapping = schema.discriminator.mapping;
383
383
  Object.keys(mapping).forEach(k => {
384
- refLogger(mapping[k]);
384
+ refLogger(mapping[k], 'discriminator');
385
385
  });
386
386
  }
387
387
  }
@@ -427,7 +427,7 @@ export default function toJSONSchema(
427
427
  if ('$ref' in example) {
428
428
  // no-op because any `$ref` example here after dereferencing is circular so we should
429
429
  // ignore it
430
- refLogger(example.$ref);
430
+ refLogger(example.$ref, 'ref');
431
431
  } else if ('value' in example) {
432
432
  if (isPrimitive(example.value)) {
433
433
  examples.push(example.value);
@@ -480,7 +480,7 @@ export default function toJSONSchema(
480
480
  if (!Array.isArray(schema.items) && Object.keys(schema.items).length === 1 && RMOAS.isRef(schema.items)) {
481
481
  // `items` contains a `$ref`, so since it's circular we should do a no-op here and log
482
482
  // and ignore it.
483
- refLogger(schema.items.$ref);
483
+ refLogger(schema.items.$ref, 'ref');
484
484
  } else if (schema.items !== true) {
485
485
  // Run through the arrays contents and clean them up.
486
486
  schema.items = toJSONSchema(schema.items as RMOAS.SchemaObject, {
@@ -38,15 +38,21 @@ export default function getParametersAsJSONSchema(
38
38
  api: OASDocument,
39
39
  opts?: {
40
40
  globalDefaults?: Record<string, unknown>;
41
+ includeDiscriminatorMappingRefs?: boolean;
41
42
  mergeIntoBodyAndMetadata?: boolean;
42
43
  retainDeprecatedProperties?: boolean;
43
44
  transformer?: (schema: SchemaObject) => SchemaObject;
44
45
  }
45
46
  ) {
46
47
  let hasCircularRefs = false;
48
+ let hasDiscriminatorMappingRefs = false;
47
49
 
48
- function refLogger() {
49
- hasCircularRefs = true;
50
+ function refLogger(ref: string, type: 'ref' | 'discriminator') {
51
+ if (type === 'ref') {
52
+ hasCircularRefs = true;
53
+ } else {
54
+ hasDiscriminatorMappingRefs = true;
55
+ }
50
56
  }
51
57
 
52
58
  function getDeprecated(schema: SchemaObject, type: string) {
@@ -381,9 +387,13 @@ export default function getParametersAsJSONSchema(
381
387
  *
382
388
  * @todo
383
389
  */
384
- if (hasCircularRefs && components) {
385
- // Fixing typing and confused version mismatches
386
- (group.schema.components as ComponentsObject) = components;
390
+ if (components) {
391
+ // We should only include components if we've got circular refs or we have discriminator
392
+ // mapping refs (we want to include them).
393
+ if (hasCircularRefs || (hasDiscriminatorMappingRefs && opts.includeDiscriminatorMappingRefs)) {
394
+ // Fixing typing and confused version mismatches
395
+ (group.schema.components as ComponentsObject) = components;
396
+ }
387
397
  }
388
398
 
389
399
  // Delete deprecatedProps if it's null on the schema.
@@ -91,11 +91,7 @@ export default function getResponseAsJSONSchema(
91
91
  api: OASDocument,
92
92
  statusCode: string | number,
93
93
  opts?: {
94
- /**
95
- * With a transformer you can transform any data within a given schema, like say if you want to
96
- * rewrite a potentially unsafe `title` that might be eventually used as a JS variable name,
97
- * just make sure to return your transformed schema.
98
- */
94
+ includeDiscriminatorMappingRefs?: boolean;
99
95
  transformer?: (schema: SchemaObject) => SchemaObject;
100
96
  }
101
97
  ) {
@@ -107,9 +103,14 @@ export default function getResponseAsJSONSchema(
107
103
  }
108
104
 
109
105
  let hasCircularRefs = false;
106
+ let hasDiscriminatorMappingRefs = false;
110
107
 
111
- function refLogger() {
112
- hasCircularRefs = true;
108
+ function refLogger(ref: string, type: 'ref' | 'discriminator') {
109
+ if (type === 'ref') {
110
+ hasCircularRefs = true;
111
+ } else {
112
+ hasDiscriminatorMappingRefs = true;
113
+ }
113
114
  }
114
115
 
115
116
  /**
@@ -180,8 +181,12 @@ export default function getResponseAsJSONSchema(
180
181
  *
181
182
  * @todo
182
183
  */
183
- if (hasCircularRefs && api.components && schemaWrapper.schema) {
184
- ((schemaWrapper.schema as SchemaObject).components as ComponentsObject) = api.components as ComponentsObject;
184
+ if (api.components && schemaWrapper.schema) {
185
+ // We should only include components if we've got circular refs or we have discriminator
186
+ // mapping refs (we want to include them).
187
+ if (hasCircularRefs || (hasDiscriminatorMappingRefs && opts.includeDiscriminatorMappingRefs)) {
188
+ ((schemaWrapper.schema as SchemaObject).components as ComponentsObject) = api.components as ComponentsObject;
189
+ }
185
190
  }
186
191
 
187
192
  jsonSchema.push(schemaWrapper);
package/src/operation.ts CHANGED
@@ -465,6 +465,12 @@ export default class Operation {
465
465
  */
466
466
  globalDefaults?: Record<string, unknown>;
467
467
 
468
+ /**
469
+ * If you wish to include discriminator mapping `$ref` components alongside your
470
+ * `discriminator` in schemas. Defaults to `true`.
471
+ */
472
+ includeDiscriminatorMappingRefs?: boolean;
473
+
468
474
  /**
469
475
  * If you want the output to be two objects: body (contains `body` and `formData` JSON
470
476
  * Schema) and metadata (contains `path`, `query`, `cookie`, and `header`).
@@ -485,11 +491,11 @@ export default class Operation {
485
491
  transformer?: (schema: RMOAS.SchemaObject) => RMOAS.SchemaObject;
486
492
  } = {}
487
493
  ) {
488
- if (!opts.transformer) {
489
- opts.transformer = (s: RMOAS.SchemaObject) => s;
490
- }
491
-
492
- return getParametersAsJSONSchema(this, this.api, opts);
494
+ return getParametersAsJSONSchema(this, this.api, {
495
+ includeDiscriminatorMappingRefs: true,
496
+ transformer: (s: RMOAS.SchemaObject) => s,
497
+ ...opts,
498
+ });
493
499
  }
494
500
 
495
501
  /**
@@ -500,17 +506,25 @@ export default class Operation {
500
506
  getResponseAsJSONSchema(
501
507
  statusCode: string | number,
502
508
  opts: {
509
+ /**
510
+ * If you wish to include discriminator mapping `$ref` components alongside your
511
+ * `discriminator` in schemas. Defaults to `true`.
512
+ */
513
+ includeDiscriminatorMappingRefs?: boolean;
514
+
503
515
  /**
504
516
  * With a transformer you can transform any data within a given schema, like say if you want
505
517
  * to rewrite a potentially unsafe `title` that might be eventually used as a JS variable
506
518
  * name, just make sure to return your transformed schema.
507
519
  */
508
520
  transformer?: (schema: RMOAS.SchemaObject) => RMOAS.SchemaObject;
509
- } = {
510
- transformer: (s: RMOAS.SchemaObject) => s,
511
- }
521
+ } = {}
512
522
  ) {
513
- return getResponseAsJSONSchema(this, this.api, statusCode, opts);
523
+ return getResponseAsJSONSchema(this, this.api, statusCode, {
524
+ includeDiscriminatorMappingRefs: true,
525
+ transformer: (s: RMOAS.SchemaObject) => s,
526
+ ...opts,
527
+ });
514
528
  }
515
529
 
516
530
  /**