oas 18.4.3 → 19.0.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.
@@ -0,0 +1,3 @@
1
+ {
2
+ "js/ts.implicitProjectConfig.strictNullChecks": false
3
+ }
package/CHANGELOG.md CHANGED
@@ -1,3 +1,29 @@
1
+ ## 19.0.0 (2022-10-10)
2
+
3
+ * docs: cleaning up some typescript options docs (#696) ([d200fef](https://github.com/readmeio/oas/commit/d200fef)), closes [#696](https://github.com/readmeio/oas/issues/696)
4
+ * feat: addition of a new JSON Schema transformer option + operationId fixes (#695) ([5609230](https://github.com/readmeio/oas/commit/5609230)), closes [#695](https://github.com/readmeio/oas/issues/695)
5
+ * chore(deps-dev): bump @commitlint/cli from 17.0.3 to 17.1.2 (#682) ([aacfcf9](https://github.com/readmeio/oas/commit/aacfcf9)), closes [#682](https://github.com/readmeio/oas/issues/682)
6
+ * chore(deps-dev): bump @commitlint/config-conventional (#685) ([4e928c0](https://github.com/readmeio/oas/commit/4e928c0)), closes [#685](https://github.com/readmeio/oas/issues/685)
7
+ * chore(deps-dev): bump @readme/eslint-config from 10.0.0 to 10.1.0 (#686) ([e008c85](https://github.com/readmeio/oas/commit/e008c85)), closes [#686](https://github.com/readmeio/oas/issues/686)
8
+ * chore(deps-dev): bump @readme/oas-examples from 5.5.0 to 5.6.0 (#684) ([2fa542e](https://github.com/readmeio/oas/commit/2fa542e)), closes [#684](https://github.com/readmeio/oas/issues/684)
9
+ * chore(deps-dev): bump @readme/oas-examples from 5.6.0 to 5.7.0 (#694) ([0cc78bc](https://github.com/readmeio/oas/commit/0cc78bc)), closes [#694](https://github.com/readmeio/oas/issues/694)
10
+ * chore(deps-dev): bump eslint from 8.21.0 to 8.23.0 (#683) ([fa1a266](https://github.com/readmeio/oas/commit/fa1a266)), closes [#683](https://github.com/readmeio/oas/issues/683)
11
+ * chore(deps-dev): bump eslint from 8.23.0 to 8.24.0 (#693) ([1e01334](https://github.com/readmeio/oas/commit/1e01334)), closes [#693](https://github.com/readmeio/oas/issues/693)
12
+ * chore(deps-dev): bump ts-jest from 28.0.7 to 28.0.8 (#689) ([e129ca4](https://github.com/readmeio/oas/commit/e129ca4)), closes [#689](https://github.com/readmeio/oas/issues/689)
13
+ * chore(deps-dev): bump typescript from 4.7.4 to 4.8.2 (#681) ([3d621b0](https://github.com/readmeio/oas/commit/3d621b0)), closes [#681](https://github.com/readmeio/oas/issues/681)
14
+ * chore(deps-dev): bump typescript from 4.8.2 to 4.8.4 (#692) ([9eb852b](https://github.com/readmeio/oas/commit/9eb852b)), closes [#692](https://github.com/readmeio/oas/issues/692)
15
+ * chore(deps): bump openapi-types from 12.0.0 to 12.0.2 (#688) ([61805d2](https://github.com/readmeio/oas/commit/61805d2)), closes [#688](https://github.com/readmeio/oas/issues/688)
16
+ * chore(deps): bump swagger-inline from 6.0.0 to 6.1.0 (#687) ([15b46f0](https://github.com/readmeio/oas/commit/15b46f0)), closes [#687](https://github.com/readmeio/oas/issues/687)
17
+ * 📝 Add commands section (#691) ([28afb82](https://github.com/readmeio/oas/commit/28afb82)), closes [#691](https://github.com/readmeio/oas/issues/691)
18
+
19
+
20
+
21
+ ## <small>18.4.4 (2022-08-23)</small>
22
+
23
+ * fix: bug in `getHeaders` where it wouldn't return `Authorization` if security was oauth2 (#680) ([9b49bec](https://github.com/readmeio/oas/commit/9b49bec)), closes [#680](https://github.com/readmeio/oas/issues/680)
24
+
25
+
26
+
1
27
  ## <small>18.4.3 (2022-08-22)</small>
2
28
 
3
29
  * fix: how we're importing `oas-normalize` ([071e282](https://github.com/readmeio/oas/commit/071e282))
@@ -1794,6 +1820,3 @@ Republishing 4.1.0 to 5.0.0 as `flattenSchema` is now an async method so it's a
1794
1820
  * Validate swagger files ([4bf6f73](https://github.com/readmeio/oas/commit/4bf6f73))
1795
1821
  * version 0.1.2 ([349ba96](https://github.com/readmeio/oas/commit/349ba96))
1796
1822
  * Weight help items ([fffc107](https://github.com/readmeio/oas/commit/fffc107))
1797
-
1798
-
1799
-
package/README.md CHANGED
@@ -25,6 +25,18 @@ oas init
25
25
 
26
26
  It will walk you through how to document your API with a OpenAPI 3.0 Spec.
27
27
 
28
+ #### Commands
29
+
30
+ ```
31
+ Usage: oas <command>
32
+
33
+ $ oas init Create a new OpenAPI definition
34
+ $ oas help Learn what you can do with oas
35
+ $ oas endpoint Learn how to document an endpoint
36
+ $ oas generate [oas.json] Output your OpenAPI definition (use --pretty for colors)
37
+ $ oas validate [oas.json] Validate your OpenAPI definition
38
+ ```
39
+
28
40
  ### Swagger Inline
29
41
 
30
42
  `oas` uses [swagger-inline](https://github.com/readmeio/swagger-inline) which allows you include a little OpenAPI snippet in a comment above your code, and collects them all together into one OpenAPI file:
package/dist/index.d.ts CHANGED
@@ -130,10 +130,11 @@ export default class Oas {
130
130
  *
131
131
  * @param path Path to lookup and retrieve.
132
132
  * @param method HTTP Method to retrieve on the path.
133
- * @param opts Options
134
- * @param opts.isWebhook If you prefer to first look for a webhook with this path and method.
135
133
  */
136
134
  operation(path: string, method: RMOAS.HttpMethods, opts?: {
135
+ /**
136
+ * If you prefer to first look for a webhook with this path and method.
137
+ */
137
138
  isWebhook?: boolean;
138
139
  }): Operation;
139
140
  findOperationMatches(url: string): PathMatches;
@@ -220,10 +221,11 @@ export default class Oas {
220
221
  * Dereference the current OAS definition so it can be parsed free of worries of `$ref` schemas
221
222
  * and circular structures.
222
223
  *
223
- * @param opts Options
224
- * @param opts.preserveRefAsJSONSchemaTitle Preserve component schema names within themselves as a `title`.
225
224
  */
226
225
  dereference(opts?: {
226
+ /**
227
+ * Preserve component schema names within themselves as a `title`.
228
+ */
227
229
  preserveRefAsJSONSchemaTitle: boolean;
228
230
  }): Promise<unknown>;
229
231
  }
package/dist/index.js CHANGED
@@ -459,8 +459,6 @@ var Oas = /** @class */ (function () {
459
459
  *
460
460
  * @param path Path to lookup and retrieve.
461
461
  * @param method HTTP Method to retrieve on the path.
462
- * @param opts Options
463
- * @param opts.isWebhook If you prefer to first look for a webhook with this path and method.
464
462
  */
465
463
  Oas.prototype.operation = function (path, method, opts) {
466
464
  var _a, _b, _c, _d;
@@ -724,8 +722,6 @@ var Oas = /** @class */ (function () {
724
722
  * Dereference the current OAS definition so it can be parsed free of worries of `$ref` schemas
725
723
  * and circular structures.
726
724
  *
727
- * @param opts Options
728
- * @param opts.preserveRefAsJSONSchemaTitle Preserve component schema names within themselves as a `title`.
729
725
  */
730
726
  Oas.prototype.dereference = function (opts) {
731
727
  if (opts === void 0) { opts = { preserveRefAsJSONSchemaTitle: false }; }
@@ -14,8 +14,14 @@ export declare type MediaTypeExample = {
14
14
  * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#mediaTypeObject}
15
15
  * @param mediaType The media type that we're looking for examples for.
16
16
  * @param mediaTypeObject The media type object that we're looking for examples for.
17
- * @param opts Options
18
- * @param opts.includeReadOnly If you wish to include data that's flagged as `readOnly`.
19
- * @param opts.includeWriteOnly If you wish to include data that's flatted as `writeOnly`.
20
17
  */
21
- export default function getMediaTypeExamples(mediaType: string, mediaTypeObject: RMOAS.MediaTypeObject, opts?: {}): MediaTypeExample[];
18
+ export default function getMediaTypeExamples(mediaType: string, mediaTypeObject: RMOAS.MediaTypeObject, opts?: {
19
+ /**
20
+ * If you wish to include data that's flagged as `readOnly`.
21
+ */
22
+ includeReadOnly?: boolean;
23
+ /**
24
+ * If you wish to include data that's flatted as `writeOnly`.
25
+ */
26
+ includeWriteOnly?: boolean;
27
+ }): MediaTypeExample[];
@@ -14,9 +14,6 @@ var matches_mimetype_1 = __importDefault(require("./matches-mimetype"));
14
14
  * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#mediaTypeObject}
15
15
  * @param mediaType The media type that we're looking for examples for.
16
16
  * @param mediaTypeObject The media type object that we're looking for examples for.
17
- * @param opts Options
18
- * @param opts.includeReadOnly If you wish to include data that's flagged as `readOnly`.
19
- * @param opts.includeWriteOnly If you wish to include data that's flatted as `writeOnly`.
20
17
  */
21
18
  function getMediaTypeExamples(mediaType, mediaTypeObject, opts) {
22
19
  if (opts === void 0) { opts = {}; }
@@ -1,12 +1,34 @@
1
1
  import * as RMOAS from '../rmoas.types';
2
2
  declare type PrevSchemasType = RMOAS.SchemaObject[];
3
3
  export declare type toJSONSchemaOptions = {
4
+ /**
5
+ * Whether or not to extend descriptions with a list of any present enums.
6
+ */
4
7
  addEnumsToDescriptions?: boolean;
8
+ /**
9
+ * Current location within the schema -- this is a JSON pointer.
10
+ */
5
11
  currentLocation?: string;
12
+ /**
13
+ * Object containing a global set of defaults that we should apply to schemas that match it.
14
+ */
6
15
  globalDefaults?: Record<string, unknown>;
16
+ /**
17
+ * Is this schema the child of a polymorphic `allOf` schema?
18
+ */
7
19
  isPolymorphicAllOfChild?: boolean;
20
+ /**
21
+ * Array of parent schemas to utilize when attempting to path together examples.
22
+ */
8
23
  prevSchemas?: PrevSchemasType;
24
+ /**
25
+ * A function that's called anytime a (circular) `$ref` is found.
26
+ */
9
27
  refLogger?: (ref: string) => void;
28
+ /**
29
+ * A function that's called to potentially transform any discovered schema.
30
+ */
31
+ transformer?: (schema: RMOAS.SchemaObject) => RMOAS.SchemaObject;
10
32
  };
11
33
  export declare function getSchemaVersionString(schema: RMOAS.SchemaObject, api: RMOAS.OASDocument): string;
12
34
  export declare function isPrimitive(val: unknown): boolean;
@@ -45,13 +67,6 @@ export declare function isPrimitive(val: unknown): boolean;
45
67
  * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#schemaObject}
46
68
  * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#schemaObject}
47
69
  * @param data OpenAPI Schema Object to convert to pure JSON Schema.
48
- * @param opts Options
49
- * @param opts.addEnumsToDescriptions Whether or not to extend descriptions with a list of any present enums.
50
- * @param opts.currentLocation Current location within the schema -- this is a JSON pointer.
51
- * @param opts.globalDefaults Object containing a global set of defaults that we should apply to schemas that match it.
52
- * @param opts.isPolymorphicAllOfChild Is this schema the child of a polymorphic `allOf` schema?
53
- * @param opts.prevSchemas Array of parent schemas to utilize when attempting to path together examples.
54
- * @param opts.refLogger A function that's called anytime a (circular) `$ref` is found.
55
70
  */
56
71
  export default function toJSONSchema(data: RMOAS.SchemaObject | boolean, opts?: toJSONSchemaOptions): RMOAS.SchemaObject;
57
72
  export {};
@@ -260,26 +260,19 @@ function searchForExampleByPointer(pointer, examples) {
260
260
  * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#schemaObject}
261
261
  * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#schemaObject}
262
262
  * @param data OpenAPI Schema Object to convert to pure JSON Schema.
263
- * @param opts Options
264
- * @param opts.addEnumsToDescriptions Whether or not to extend descriptions with a list of any present enums.
265
- * @param opts.currentLocation Current location within the schema -- this is a JSON pointer.
266
- * @param opts.globalDefaults Object containing a global set of defaults that we should apply to schemas that match it.
267
- * @param opts.isPolymorphicAllOfChild Is this schema the child of a polymorphic `allOf` schema?
268
- * @param opts.prevSchemas Array of parent schemas to utilize when attempting to path together examples.
269
- * @param opts.refLogger A function that's called anytime a (circular) `$ref` is found.
270
263
  */
271
264
  function toJSONSchema(data, opts) {
272
265
  if (opts === void 0) { opts = {}; }
273
266
  var schema = data === true ? {} : __assign({}, data);
274
267
  var schemaAdditionalProperties = RMOAS.isSchema(schema) ? schema.additionalProperties : null;
275
- var _a = __assign({ addEnumsToDescriptions: false, currentLocation: '', globalDefaults: {}, isPolymorphicAllOfChild: false, prevSchemas: [], refLogger: function () { return true; } }, opts), addEnumsToDescriptions = _a.addEnumsToDescriptions, currentLocation = _a.currentLocation, globalDefaults = _a.globalDefaults, isPolymorphicAllOfChild = _a.isPolymorphicAllOfChild, prevSchemas = _a.prevSchemas, refLogger = _a.refLogger;
268
+ var _a = __assign({ addEnumsToDescriptions: false, currentLocation: '', globalDefaults: {}, isPolymorphicAllOfChild: false, prevSchemas: [], refLogger: function () { return true; }, transformer: function (s) { return s; } }, opts), addEnumsToDescriptions = _a.addEnumsToDescriptions, currentLocation = _a.currentLocation, globalDefaults = _a.globalDefaults, isPolymorphicAllOfChild = _a.isPolymorphicAllOfChild, prevSchemas = _a.prevSchemas, refLogger = _a.refLogger, transformer = _a.transformer;
276
269
  // If this schema contains a `$ref`, it's circular and we shouldn't try to resolve it. Just
277
270
  // return and move along.
278
271
  if (RMOAS.isRef(schema)) {
279
272
  refLogger(schema.$ref);
280
- return {
273
+ return transformer({
281
274
  $ref: schema.$ref
282
- };
275
+ });
283
276
  }
284
277
  // If we don't have a set type, but are dealing with an `anyOf`, `oneOf`, or `allOf`
285
278
  // representation let's run through them and make sure they're good.
@@ -325,7 +318,8 @@ function toJSONSchema(data, opts) {
325
318
  globalDefaults: globalDefaults,
326
319
  isPolymorphicAllOfChild: false,
327
320
  prevSchemas: prevSchemas,
328
- refLogger: refLogger
321
+ refLogger: refLogger,
322
+ transformer: transformer
329
323
  };
330
324
  // When `properties` or `items` are present alongside a polymorphic schema instead of
331
325
  // letting whatever JSON Schema interpreter is handling these constructed schemas we can
@@ -461,7 +455,8 @@ function toJSONSchema(data, opts) {
461
455
  currentLocation: "".concat(currentLocation, "/0"),
462
456
  globalDefaults: globalDefaults,
463
457
  prevSchemas: prevSchemas,
464
- refLogger: refLogger
458
+ refLogger: refLogger,
459
+ transformer: transformer
465
460
  });
466
461
  }
467
462
  }
@@ -482,7 +477,7 @@ function toJSONSchema(data, opts) {
482
477
  }
483
478
  else if (schema.type === 'object') {
484
479
  if ('properties' in schema) {
485
- Object.keys(schema.properties).map(function (prop) {
480
+ Object.keys(schema.properties).forEach(function (prop) {
486
481
  if (Array.isArray(schema.properties[prop]) ||
487
482
  (typeof schema.properties[prop] === 'object' && schema.properties[prop] !== null)) {
488
483
  schema.properties[prop] = toJSONSchema(schema.properties[prop], {
@@ -490,10 +485,10 @@ function toJSONSchema(data, opts) {
490
485
  currentLocation: "".concat(currentLocation, "/").concat(encodePointer(prop)),
491
486
  globalDefaults: globalDefaults,
492
487
  prevSchemas: prevSchemas,
493
- refLogger: refLogger
488
+ refLogger: refLogger,
489
+ transformer: transformer
494
490
  });
495
491
  }
496
- return true;
497
492
  });
498
493
  }
499
494
  if (typeof schemaAdditionalProperties === 'object' && schemaAdditionalProperties !== null) {
@@ -512,7 +507,8 @@ function toJSONSchema(data, opts) {
512
507
  currentLocation: currentLocation,
513
508
  globalDefaults: globalDefaults,
514
509
  prevSchemas: prevSchemas,
515
- refLogger: refLogger
510
+ refLogger: refLogger,
511
+ transformer: transformer
516
512
  });
517
513
  }
518
514
  }
@@ -612,6 +608,6 @@ function toJSONSchema(data, opts) {
612
608
  // typing won't work
613
609
  delete schema[UNSUPPORTED_SCHEMA_PROPS[i]];
614
610
  }
615
- return schema;
611
+ return transformer(schema);
616
612
  }
617
613
  exports["default"] = toJSONSchema;
@@ -19,6 +19,5 @@ export declare type ReducerOptions = {
19
19
  * { APIDEFINITION, { paths: { '/pet': '*' } } }
20
20
  *
21
21
  * @param definition A valid OpenAPI 3.x definition
22
- * @param opts Option configuration to reduce by.
23
22
  */
24
23
  export default function reducer(definition: OASDocument, opts?: ReducerOptions): OASDocument;
@@ -53,7 +53,6 @@ function accumulateUsedRefs(schema, $refs, $ref) {
53
53
  * { APIDEFINITION, { paths: { '/pet': '*' } } }
54
54
  *
55
55
  * @param definition A valid OpenAPI 3.x definition
56
- * @param opts Option configuration to reduce by.
57
56
  */
58
57
  function reducer(definition, opts) {
59
58
  if (opts === void 0) { opts = {}; }
@@ -15,8 +15,9 @@ export declare type SchemaWrapper = {
15
15
  * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameterObject}
16
16
  */
17
17
  export declare const types: Record<keyof OASDocument, string>;
18
- export default function getParametersAsJsonSchema(operation: Operation, api: OASDocument, opts?: {
18
+ export default function getParametersAsJSONSchema(operation: Operation, api: OASDocument, opts?: {
19
19
  globalDefaults?: Record<string, unknown>;
20
20
  mergeIntoBodyAndMetadata?: boolean;
21
21
  retainDeprecatedProperties?: boolean;
22
+ transformer?: (schema: SchemaObject) => SchemaObject;
22
23
  }): SchemaWrapper[];
@@ -58,7 +58,7 @@ exports.types = {
58
58
  header: 'Headers',
59
59
  metadata: 'Metadata'
60
60
  };
61
- function getParametersAsJsonSchema(operation, api, opts) {
61
+ function getParametersAsJSONSchema(operation, api, opts) {
62
62
  var _a;
63
63
  var hasCircularRefs = false;
64
64
  function refLogger() {
@@ -92,7 +92,8 @@ function getParametersAsJsonSchema(operation, api, opts) {
92
92
  var deprecatedSchema = (0, openapi_to_json_schema_1["default"])(deprecatedBody, {
93
93
  globalDefaults: opts.globalDefaults,
94
94
  prevSchemas: [],
95
- refLogger: refLogger
95
+ refLogger: refLogger,
96
+ transformer: opts.transformer
96
97
  });
97
98
  // Check if the schema wasn't created or there's no deprecated properties
98
99
  if (Object.keys(deprecatedSchema).length === 0 || Object.keys(deprecatedSchema.properties).length === 0) {
@@ -138,7 +139,12 @@ function getParametersAsJsonSchema(operation, api, opts) {
138
139
  // We're cloning the request schema because we've had issues with request schemas that were
139
140
  // dereferenced being processed multiple times because their component is also processed.
140
141
  var requestSchema = (0, clone_object_1["default"])(mediaTypeObject.schema);
141
- var cleanedSchema = (0, openapi_to_json_schema_1["default"])(requestSchema, { globalDefaults: opts.globalDefaults, prevSchemas: prevSchemas, refLogger: refLogger });
142
+ var cleanedSchema = (0, openapi_to_json_schema_1["default"])(requestSchema, {
143
+ globalDefaults: opts.globalDefaults,
144
+ prevSchemas: prevSchemas,
145
+ refLogger: refLogger,
146
+ transformer: opts.transformer
147
+ });
142
148
  // If this schema is **still** empty, don't bother returning it.
143
149
  if (!Object.keys(cleanedSchema).length) {
144
150
  return null;
@@ -169,7 +175,8 @@ function getParametersAsJsonSchema(operation, api, opts) {
169
175
  var componentSchema = (0, clone_object_1["default"])(api.components[componentType][schemaName]);
170
176
  components[componentType][schemaName] = (0, openapi_to_json_schema_1["default"])(componentSchema, {
171
177
  globalDefaults: opts.globalDefaults,
172
- refLogger: refLogger
178
+ refLogger: refLogger,
179
+ transformer: opts.transformer
173
180
  });
174
181
  });
175
182
  }
@@ -206,7 +213,8 @@ function getParametersAsJsonSchema(operation, api, opts) {
206
213
  schema = __assign(__assign({}, (0, openapi_to_json_schema_1["default"])(currentSchema, {
207
214
  currentLocation: "/".concat(current.name),
208
215
  globalDefaults: opts.globalDefaults,
209
- refLogger: refLogger
216
+ refLogger: refLogger,
217
+ transformer: opts.transformer
210
218
  })), {
211
219
  // Note: this applies a $schema version to each field in the larger schema object.
212
220
  // It's not really *correct* but it's what we have to do because there's a chance that
@@ -251,7 +259,8 @@ function getParametersAsJsonSchema(operation, api, opts) {
251
259
  schema = __assign(__assign({}, (0, openapi_to_json_schema_1["default"])(currentSchema, {
252
260
  currentLocation: "/".concat(current.name),
253
261
  globalDefaults: opts.globalDefaults,
254
- refLogger: refLogger
262
+ refLogger: refLogger,
263
+ transformer: opts.transformer
255
264
  })), {
256
265
  // Note: this applies a $schema version to each field in the larger schema object.
257
266
  // It's not really *correct* but it's what we have to do because there's a chance
@@ -343,4 +352,4 @@ function getParametersAsJsonSchema(operation, api, opts) {
343
352
  return typeKeys.indexOf(a.type) - typeKeys.indexOf(b.type);
344
353
  });
345
354
  }
346
- exports["default"] = getParametersAsJsonSchema;
355
+ exports["default"] = getParametersAsJSONSchema;
@@ -1,7 +1,7 @@
1
1
  import type Operation from 'operation';
2
2
  import type { OASDocument, SchemaObject } from 'rmoas.types';
3
3
  /**
4
- * Extract all the response schemas, matching the format of get-parameters-as-json-schema.
4
+ * Extract all the response schemas, matching the format of `get-parameters-as-json-schema`.
5
5
  *
6
6
  * Note: This expects a dereferenced schema.
7
7
  *
@@ -9,7 +9,14 @@ import type { OASDocument, SchemaObject } from 'rmoas.types';
9
9
  * @param api The OpenAPI definition that this operation originates.
10
10
  * @param statusCode The response status code to generate a schema for.
11
11
  */
12
- export default function getResponseAsJsonSchema(operation: Operation, api: OASDocument, statusCode: string | number): {
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
+ */
18
+ transformer?: (schema: SchemaObject) => SchemaObject;
19
+ }): {
13
20
  type: string | string[];
14
21
  schema: SchemaObject;
15
22
  label: string;
@@ -50,7 +50,7 @@ var isJSON = matches_mimetype_1["default"].json;
50
50
  * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.3.md#headerObject}
51
51
  * @param response Response object to build a JSON Schema object for its headers for.
52
52
  */
53
- function buildHeadersSchema(response) {
53
+ function buildHeadersSchema(response, opts) {
54
54
  var headers = response.headers;
55
55
  var headersSchema = {
56
56
  type: 'object',
@@ -62,7 +62,10 @@ function buildHeadersSchema(response) {
62
62
  // TODO: Response headers are essentially parameters in OAS
63
63
  // This means they can have content instead of schema.
64
64
  // We should probably support that in the future
65
- headersSchema.properties[key] = (0, openapi_to_json_schema_1["default"])(header.schema, { addEnumsToDescriptions: true });
65
+ headersSchema.properties[key] = (0, openapi_to_json_schema_1["default"])(header.schema, {
66
+ addEnumsToDescriptions: true,
67
+ transformer: opts.transformer
68
+ });
66
69
  if (header.description) {
67
70
  headersSchema.properties[key].description = header.description;
68
71
  }
@@ -79,7 +82,7 @@ function buildHeadersSchema(response) {
79
82
  return headersWrapper;
80
83
  }
81
84
  /**
82
- * Extract all the response schemas, matching the format of get-parameters-as-json-schema.
85
+ * Extract all the response schemas, matching the format of `get-parameters-as-json-schema`.
83
86
  *
84
87
  * Note: This expects a dereferenced schema.
85
88
  *
@@ -87,7 +90,7 @@ function buildHeadersSchema(response) {
87
90
  * @param api The OpenAPI definition that this operation originates.
88
91
  * @param statusCode The response status code to generate a schema for.
89
92
  */
90
- function getResponseAsJsonSchema(operation, api, statusCode) {
93
+ function getResponseAsJSONSchema(operation, api, statusCode, opts) {
91
94
  var response = operation.getResponseByStatusCode(statusCode);
92
95
  var jsonSchema = [];
93
96
  if (!response) {
@@ -112,13 +115,21 @@ function getResponseAsJsonSchema(operation, api, statusCode) {
112
115
  // eslint-disable-next-line no-plusplus
113
116
  for (var i = 0; i < contentTypes.length; i++) {
114
117
  if (isJSON(contentTypes[i])) {
115
- return (0, openapi_to_json_schema_1["default"])((0, clone_object_1["default"])(content[contentTypes[i]].schema), { addEnumsToDescriptions: true, refLogger: refLogger });
118
+ return (0, openapi_to_json_schema_1["default"])((0, clone_object_1["default"])(content[contentTypes[i]].schema), {
119
+ addEnumsToDescriptions: true,
120
+ refLogger: refLogger,
121
+ transformer: opts.transformer
122
+ });
116
123
  }
117
124
  }
118
125
  // We always want to prefer the JSON-compatible content types over everything else but if we
119
126
  // haven't found one we should default to the first available.
120
127
  var contentType = contentTypes.shift();
121
- return (0, openapi_to_json_schema_1["default"])((0, clone_object_1["default"])(content[contentType].schema), { addEnumsToDescriptions: true, refLogger: refLogger });
128
+ return (0, openapi_to_json_schema_1["default"])((0, clone_object_1["default"])(content[contentType].schema), {
129
+ addEnumsToDescriptions: true,
130
+ refLogger: refLogger,
131
+ transformer: opts.transformer
132
+ });
122
133
  }
123
134
  var foundSchema = getPreferredSchema(response.content);
124
135
  if (foundSchema) {
@@ -148,8 +159,8 @@ function getResponseAsJsonSchema(operation, api, statusCode) {
148
159
  }
149
160
  // 3.0.3 and earlier headers. TODO: New format for 3.1.0
150
161
  if (response.headers) {
151
- jsonSchema.push(buildHeadersSchema(response));
162
+ jsonSchema.push(buildHeadersSchema(response, opts));
152
163
  }
153
164
  return jsonSchema.length ? jsonSchema : null;
154
165
  }
155
- exports["default"] = getResponseAsJsonSchema;
166
+ exports["default"] = getResponseAsJSONSchema;
@@ -89,10 +89,11 @@ export default class Operation {
89
89
  * Get an `operationId` for this operation. If one is not present (it's not required by the spec!)
90
90
  * a hash of the path and method will be returned instead.
91
91
  *
92
- * @param opts Options
93
- * @param opts.camelCase Generate a JS method-friendly operation ID when one isn't present.
94
92
  */
95
93
  getOperationId(opts?: {
94
+ /**
95
+ * Generate a JS method-friendly operation ID when one isn't present.
96
+ */
96
97
  camelCase: boolean;
97
98
  }): string;
98
99
  /**
@@ -124,25 +125,42 @@ export default class Operation {
124
125
  * Convert the operation into an array of JSON Schema schemas for each available type of
125
126
  * parameter available on the operation.
126
127
  *
127
- * @param opts Options
128
- * @param opts.globalDefaults Contains an object of user defined schema defaults.
129
- * @param opts.mergeIntoBodyAndMetadata If you want the output to be two objects: body (contains
130
- * `body` and `formData` JSON Schema) and metadata (contains `path`, `query`, `cookie`, and
131
- * `header`).
132
- * @param opts.retainDeprecatedProperties If you wish to **not** split out deprecated properties
133
- * into a separate `deprecatedProps` object.
134
- */
135
- getParametersAsJsonSchema(opts?: {
128
+ */
129
+ getParametersAsJSONSchema(opts?: {
130
+ /**
131
+ * Contains an object of user defined schema defaults.
132
+ */
136
133
  globalDefaults?: Record<string, unknown>;
134
+ /**
135
+ * If you want the output to be two objects: body (contains `body` and `formData` JSON
136
+ * Schema) and metadata (contains `path`, `query`, `cookie`, and `header`).
137
+ */
137
138
  mergeIntoBodyAndMetadata?: boolean;
139
+ /**
140
+ * If you wish to **not** split out deprecated properties into a separate `deprecatedProps`
141
+ * object.
142
+ */
138
143
  retainDeprecatedProperties?: boolean;
144
+ /**
145
+ * With a transformer you can transform any data within a given schema, like say if you want
146
+ * to rewrite a potentially unsafe `title` that might be eventually used as a JS variable
147
+ * name, just make sure to return your transformed schema.
148
+ */
149
+ transformer?: (schema: RMOAS.SchemaObject) => RMOAS.SchemaObject;
139
150
  }): import("./operation/get-parameters-as-json-schema").SchemaWrapper[];
140
151
  /**
141
152
  * Get a single response for this status code, formatted as JSON schema.
142
153
  *
143
154
  * @param statusCode Status code to pull a JSON Schema response for.
144
155
  */
145
- getResponseAsJsonSchema(statusCode: string | number): {
156
+ getResponseAsJSONSchema(statusCode: string | number, opts?: {
157
+ /**
158
+ * With a transformer you can transform any data within a given schema, like say if you want
159
+ * to rewrite a potentially unsafe `title` that might be eventually used as a JS variable
160
+ * name, just make sure to return your transformed schema.
161
+ */
162
+ transformer?: (schema: RMOAS.SchemaObject) => RMOAS.SchemaObject;
163
+ }): {
146
164
  type: string | string[];
147
165
  schema: RMOAS.SchemaObject;
148
166
  label: string;
package/dist/operation.js CHANGED
@@ -244,7 +244,7 @@ var Operation = /** @class */ (function () {
244
244
  return h.name;
245
245
  });
246
246
  }
247
- if (security.Bearer || security.Basic) {
247
+ if (security.Bearer || security.Basic || security.OAuth2) {
248
248
  this.headers.request.push('Authorization');
249
249
  }
250
250
  if (security.Cookie) {
@@ -304,24 +304,27 @@ var Operation = /** @class */ (function () {
304
304
  * Get an `operationId` for this operation. If one is not present (it's not required by the spec!)
305
305
  * a hash of the path and method will be returned instead.
306
306
  *
307
- * @param opts Options
308
- * @param opts.camelCase Generate a JS method-friendly operation ID when one isn't present.
309
307
  */
310
308
  Operation.prototype.getOperationId = function (opts) {
309
+ function sanitize(id) {
310
+ return id
311
+ .replace(/[^a-zA-Z0-9_]/g, '-') // Remove weird characters
312
+ .replace(/^-|-$/g, '') // Don't start or end with -
313
+ .replace(/--+/g, '-'); // Remove double --'s
314
+ }
311
315
  var operationId;
312
316
  if (this.hasOperationId()) {
313
317
  operationId = this.schema.operationId;
314
318
  }
315
319
  else {
316
- operationId = this.path
317
- .replace(/[^a-zA-Z0-9]/g, '-') // Remove weird characters
318
- .replace(/^-|-$/g, '') // Don't start or end with -
319
- .replace(/--+/g, '-') // Remove double --'s
320
- .toLowerCase();
320
+ operationId = sanitize(this.path).toLowerCase();
321
321
  }
322
322
  var method = this.method.toLowerCase();
323
323
  if (opts === null || opts === void 0 ? void 0 : opts.camelCase) {
324
324
  operationId = operationId.replace(/[^a-zA-Z0-9_]+(.)/g, function (_, chr) { return chr.toUpperCase(); });
325
+ if (this.hasOperationId()) {
326
+ operationId = sanitize(operationId);
327
+ }
325
328
  // If the generated `operationId` already starts with the method (eg. `getPets`) we don't want
326
329
  // to double it up into `getGetPets`.
327
330
  if (operationId.startsWith(method)) {
@@ -408,16 +411,12 @@ var Operation = /** @class */ (function () {
408
411
  * Convert the operation into an array of JSON Schema schemas for each available type of
409
412
  * parameter available on the operation.
410
413
  *
411
- * @param opts Options
412
- * @param opts.globalDefaults Contains an object of user defined schema defaults.
413
- * @param opts.mergeIntoBodyAndMetadata If you want the output to be two objects: body (contains
414
- * `body` and `formData` JSON Schema) and metadata (contains `path`, `query`, `cookie`, and
415
- * `header`).
416
- * @param opts.retainDeprecatedProperties If you wish to **not** split out deprecated properties
417
- * into a separate `deprecatedProps` object.
418
414
  */
419
- Operation.prototype.getParametersAsJsonSchema = function (opts) {
415
+ Operation.prototype.getParametersAsJSONSchema = function (opts) {
420
416
  if (opts === void 0) { opts = {}; }
417
+ if (!opts.transformer) {
418
+ opts.transformer = function (s) { return s; };
419
+ }
421
420
  return (0, get_parameters_as_json_schema_1["default"])(this, this.api, opts);
422
421
  };
423
422
  /**
@@ -425,8 +424,11 @@ var Operation = /** @class */ (function () {
425
424
  *
426
425
  * @param statusCode Status code to pull a JSON Schema response for.
427
426
  */
428
- Operation.prototype.getResponseAsJsonSchema = function (statusCode) {
429
- return (0, get_response_as_json_schema_1["default"])(this, this.api, statusCode);
427
+ 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);
430
432
  };
431
433
  /**
432
434
  * Get an array of all valid response status codes for this operation.
@@ -483,7 +485,7 @@ var Operation = /** @class */ (function () {
483
485
  // final point where we don't have a required request body, but the underlying Media Type Object
484
486
  // schema says that it has required properties then we should ultimately recognize that this
485
487
  // request body is required -- even as the request body description says otherwise.
486
- return !!this.getParametersAsJsonSchema()
488
+ return !!this.getParametersAsJSONSchema()
487
489
  .filter(function (js) { return ['body', 'formData'].includes(js.type); })
488
490
  .find(function (js) { return js.schema && Array.isArray(js.schema.required) && js.schema.required.length; });
489
491
  };
@@ -12,13 +12,15 @@ import memoize from 'memoizee';
12
12
  * the schema.
13
13
  *
14
14
  * @param schema JSON Schema to generate a sample for.
15
- * @param opts Options
16
- * @param opts.includeReadOnly If you wish to include data that's flagged as `readOnly`.
17
- * @param opts.includeWriteOnly If you wish to include data that's flatted as `writeOnly`.
18
- * @returns A generated piece of data based off the JSON Schema that was supplied.
19
15
  */
20
16
  declare function sampleFromSchema(schema: RMOAS.SchemaObject, opts?: {
17
+ /**
18
+ * If you wish to include data that's flagged as `readOnly`.
19
+ */
21
20
  includeReadOnly?: boolean;
21
+ /**
22
+ * If you wish to include data that's flatted as `writeOnly`.
23
+ */
22
24
  includeWriteOnly?: boolean;
23
25
  }): string | number | boolean | null | unknown[] | Record<string, unknown> | undefined;
24
26
  declare const _default: typeof sampleFromSchema & memoize.Memoized<typeof sampleFromSchema>;
@@ -42,10 +42,6 @@ var primitive = function (schema) {
42
42
  * the schema.
43
43
  *
44
44
  * @param schema JSON Schema to generate a sample for.
45
- * @param opts Options
46
- * @param opts.includeReadOnly If you wish to include data that's flagged as `readOnly`.
47
- * @param opts.includeWriteOnly If you wish to include data that's flatted as `writeOnly`.
48
- * @returns A generated piece of data based off the JSON Schema that was supplied.
49
45
  */
50
46
  function sampleFromSchema(schema, opts) {
51
47
  if (opts === void 0) { opts = {}; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oas",
3
- "version": "18.4.3",
3
+ "version": "19.0.0",
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)",
@@ -75,6 +75,7 @@
75
75
  "@types/json-schema-merge-allof": "^0.6.1",
76
76
  "@types/jsonpath": "^0.2.0",
77
77
  "@types/memoizee": "^0.4.6",
78
+ "@types/node": "^18.8.2",
78
79
  "eslint": "^8.20.0",
79
80
  "husky": "^8.0.1",
80
81
  "jest": "^28.1.3",
package/src/index.ts CHANGED
@@ -466,10 +466,17 @@ export default class Oas {
466
466
  *
467
467
  * @param path Path to lookup and retrieve.
468
468
  * @param method HTTP Method to retrieve on the path.
469
- * @param opts Options
470
- * @param opts.isWebhook If you prefer to first look for a webhook with this path and method.
471
469
  */
472
- operation(path: string, method: RMOAS.HttpMethods, opts: { isWebhook?: boolean } = {}) {
470
+ operation(
471
+ path: string,
472
+ method: RMOAS.HttpMethods,
473
+ opts: {
474
+ /**
475
+ * If you prefer to first look for a webhook with this path and method.
476
+ */
477
+ isWebhook?: boolean;
478
+ } = {}
479
+ ) {
473
480
  // If we're unable to locate an operation for this path+method combination within the API
474
481
  // definition, we should still set an empty schema on the operation in the `Operation` class
475
482
  // because if we don't trying to use any of the accessors on that class are going to fail as
@@ -758,10 +765,15 @@ export default class Oas {
758
765
  * Dereference the current OAS definition so it can be parsed free of worries of `$ref` schemas
759
766
  * and circular structures.
760
767
  *
761
- * @param opts Options
762
- * @param opts.preserveRefAsJSONSchemaTitle Preserve component schema names within themselves as a `title`.
763
768
  */
764
- async dereference(opts = { preserveRefAsJSONSchemaTitle: false }) {
769
+ async dereference(
770
+ opts: {
771
+ /**
772
+ * Preserve component schema names within themselves as a `title`.
773
+ */
774
+ preserveRefAsJSONSchemaTitle: boolean;
775
+ } = { preserveRefAsJSONSchemaTitle: false }
776
+ ) {
765
777
  if (this.dereferencing.complete) {
766
778
  return new Promise(resolve => {
767
779
  resolve(true);
@@ -20,11 +20,22 @@ export type MediaTypeExample = {
20
20
  * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#mediaTypeObject}
21
21
  * @param mediaType The media type that we're looking for examples for.
22
22
  * @param mediaTypeObject The media type object that we're looking for examples for.
23
- * @param opts Options
24
- * @param opts.includeReadOnly If you wish to include data that's flagged as `readOnly`.
25
- * @param opts.includeWriteOnly If you wish to include data that's flatted as `writeOnly`.
26
23
  */
27
- export default function getMediaTypeExamples(mediaType: string, mediaTypeObject: RMOAS.MediaTypeObject, opts = {}) {
24
+ export default function getMediaTypeExamples(
25
+ mediaType: string,
26
+ mediaTypeObject: RMOAS.MediaTypeObject,
27
+ opts: {
28
+ /**
29
+ * If you wish to include data that's flagged as `readOnly`.
30
+ */
31
+ includeReadOnly?: boolean;
32
+
33
+ /**
34
+ * If you wish to include data that's flatted as `writeOnly`.
35
+ */
36
+ includeWriteOnly?: boolean;
37
+ } = {}
38
+ ) {
28
39
  if (mediaTypeObject.example) {
29
40
  return [
30
41
  {
@@ -28,12 +28,40 @@ const UNSUPPORTED_SCHEMA_PROPS: ('nullable' | 'xml' | 'externalDocs' | 'example'
28
28
  type PrevSchemasType = RMOAS.SchemaObject[];
29
29
 
30
30
  export type toJSONSchemaOptions = {
31
+ /**
32
+ * Whether or not to extend descriptions with a list of any present enums.
33
+ */
31
34
  addEnumsToDescriptions?: boolean;
35
+
36
+ /**
37
+ * Current location within the schema -- this is a JSON pointer.
38
+ */
32
39
  currentLocation?: string;
40
+
41
+ /**
42
+ * Object containing a global set of defaults that we should apply to schemas that match it.
43
+ */
33
44
  globalDefaults?: Record<string, unknown>;
45
+
46
+ /**
47
+ * Is this schema the child of a polymorphic `allOf` schema?
48
+ */
34
49
  isPolymorphicAllOfChild?: boolean;
50
+
51
+ /**
52
+ * Array of parent schemas to utilize when attempting to path together examples.
53
+ */
35
54
  prevSchemas?: PrevSchemasType;
55
+
56
+ /**
57
+ * A function that's called anytime a (circular) `$ref` is found.
58
+ */
36
59
  refLogger?: (ref: string) => void;
60
+
61
+ /**
62
+ * A function that's called to potentially transform any discovered schema.
63
+ */
64
+ transformer?: (schema: RMOAS.SchemaObject) => RMOAS.SchemaObject;
37
65
  };
38
66
 
39
67
  /**
@@ -237,13 +265,6 @@ function searchForExampleByPointer(pointer: string, examples: PrevSchemasType =
237
265
  * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#schemaObject}
238
266
  * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#schemaObject}
239
267
  * @param data OpenAPI Schema Object to convert to pure JSON Schema.
240
- * @param opts Options
241
- * @param opts.addEnumsToDescriptions Whether or not to extend descriptions with a list of any present enums.
242
- * @param opts.currentLocation Current location within the schema -- this is a JSON pointer.
243
- * @param opts.globalDefaults Object containing a global set of defaults that we should apply to schemas that match it.
244
- * @param opts.isPolymorphicAllOfChild Is this schema the child of a polymorphic `allOf` schema?
245
- * @param opts.prevSchemas Array of parent schemas to utilize when attempting to path together examples.
246
- * @param opts.refLogger A function that's called anytime a (circular) `$ref` is found.
247
268
  */
248
269
  export default function toJSONSchema(
249
270
  data: RMOAS.SchemaObject | boolean,
@@ -252,13 +273,22 @@ export default function toJSONSchema(
252
273
  let schema = data === true ? {} : { ...data };
253
274
  const schemaAdditionalProperties = RMOAS.isSchema(schema) ? schema.additionalProperties : null;
254
275
 
255
- const { addEnumsToDescriptions, currentLocation, globalDefaults, isPolymorphicAllOfChild, prevSchemas, refLogger } = {
276
+ const {
277
+ addEnumsToDescriptions,
278
+ currentLocation,
279
+ globalDefaults,
280
+ isPolymorphicAllOfChild,
281
+ prevSchemas,
282
+ refLogger,
283
+ transformer,
284
+ } = {
256
285
  addEnumsToDescriptions: false,
257
286
  currentLocation: '',
258
287
  globalDefaults: {},
259
288
  isPolymorphicAllOfChild: false,
260
289
  prevSchemas: [] as PrevSchemasType,
261
290
  refLogger: () => true,
291
+ transformer: (s: RMOAS.SchemaObject) => s,
262
292
  ...opts,
263
293
  };
264
294
 
@@ -267,9 +297,9 @@ export default function toJSONSchema(
267
297
  if (RMOAS.isRef(schema)) {
268
298
  refLogger(schema.$ref);
269
299
 
270
- return {
300
+ return transformer({
271
301
  $ref: schema.$ref,
272
- };
302
+ });
273
303
  }
274
304
 
275
305
  // If we don't have a set type, but are dealing with an `anyOf`, `oneOf`, or `allOf`
@@ -319,6 +349,7 @@ export default function toJSONSchema(
319
349
  isPolymorphicAllOfChild: false,
320
350
  prevSchemas,
321
351
  refLogger,
352
+ transformer,
322
353
  };
323
354
 
324
355
  // When `properties` or `items` are present alongside a polymorphic schema instead of
@@ -458,6 +489,7 @@ export default function toJSONSchema(
458
489
  globalDefaults,
459
490
  prevSchemas,
460
491
  refLogger,
492
+ transformer,
461
493
  });
462
494
  }
463
495
  } else if ('properties' in schema || 'additionalProperties' in schema) {
@@ -475,7 +507,7 @@ export default function toJSONSchema(
475
507
  }
476
508
  } else if (schema.type === 'object') {
477
509
  if ('properties' in schema) {
478
- Object.keys(schema.properties).map(prop => {
510
+ Object.keys(schema.properties).forEach(prop => {
479
511
  if (
480
512
  Array.isArray(schema.properties[prop]) ||
481
513
  (typeof schema.properties[prop] === 'object' && schema.properties[prop] !== null)
@@ -486,10 +518,9 @@ export default function toJSONSchema(
486
518
  globalDefaults,
487
519
  prevSchemas,
488
520
  refLogger,
521
+ transformer,
489
522
  });
490
523
  }
491
-
492
- return true;
493
524
  });
494
525
  }
495
526
 
@@ -511,6 +542,7 @@ export default function toJSONSchema(
511
542
  globalDefaults,
512
543
  prevSchemas,
513
544
  refLogger,
545
+ transformer,
514
546
  });
515
547
  }
516
548
  }
@@ -622,5 +654,5 @@ export default function toJSONSchema(
622
654
  delete (schema as Record<string, unknown>)[UNSUPPORTED_SCHEMA_PROPS[i]];
623
655
  }
624
656
 
625
- return schema;
657
+ return transformer(schema);
626
658
  }
@@ -62,7 +62,6 @@ function accumulateUsedRefs(schema: Record<string, unknown>, $refs: Set<string>,
62
62
  * { APIDEFINITION, { paths: { '/pet': '*' } } }
63
63
  *
64
64
  * @param definition A valid OpenAPI 3.x definition
65
- * @param opts Option configuration to reduce by.
66
65
  */
67
66
  export default function reducer(definition: OASDocument, opts: ReducerOptions = {}) {
68
67
  const reduceTags = 'tags' in opts ? opts.tags : [];
@@ -33,13 +33,14 @@ export const types: Record<keyof OASDocument, string> = {
33
33
  metadata: 'Metadata', // This a special type reserved for https://npm.im/api
34
34
  };
35
35
 
36
- export default function getParametersAsJsonSchema(
36
+ export default function getParametersAsJSONSchema(
37
37
  operation: Operation,
38
38
  api: OASDocument,
39
39
  opts?: {
40
40
  globalDefaults?: Record<string, unknown>;
41
41
  mergeIntoBodyAndMetadata?: boolean;
42
42
  retainDeprecatedProperties?: boolean;
43
+ transformer?: (schema: SchemaObject) => SchemaObject;
43
44
  }
44
45
  ) {
45
46
  let hasCircularRefs = false;
@@ -82,6 +83,7 @@ export default function getParametersAsJsonSchema(
82
83
  globalDefaults: opts.globalDefaults,
83
84
  prevSchemas: [],
84
85
  refLogger,
86
+ transformer: opts.transformer,
85
87
  });
86
88
 
87
89
  // Check if the schema wasn't created or there's no deprecated properties
@@ -136,7 +138,12 @@ export default function getParametersAsJsonSchema(
136
138
  // We're cloning the request schema because we've had issues with request schemas that were
137
139
  // dereferenced being processed multiple times because their component is also processed.
138
140
  const requestSchema = cloneObject(mediaTypeObject.schema);
139
- const cleanedSchema = toJSONSchema(requestSchema, { globalDefaults: opts.globalDefaults, prevSchemas, refLogger });
141
+ const cleanedSchema = toJSONSchema(requestSchema, {
142
+ globalDefaults: opts.globalDefaults,
143
+ prevSchemas,
144
+ refLogger,
145
+ transformer: opts.transformer,
146
+ });
140
147
 
141
148
  // If this schema is **still** empty, don't bother returning it.
142
149
  if (!Object.keys(cleanedSchema).length) {
@@ -177,6 +184,7 @@ export default function getParametersAsJsonSchema(
177
184
  components[componentType][schemaName] = toJSONSchema(componentSchema as SchemaObject, {
178
185
  globalDefaults: opts.globalDefaults,
179
186
  refLogger,
187
+ transformer: opts.transformer,
180
188
  });
181
189
  });
182
190
  }
@@ -221,6 +229,7 @@ export default function getParametersAsJsonSchema(
221
229
  currentLocation: `/${current.name}`,
222
230
  globalDefaults: opts.globalDefaults,
223
231
  refLogger,
232
+ transformer: opts.transformer,
224
233
  }),
225
234
 
226
235
  // Note: this applies a $schema version to each field in the larger schema object.
@@ -268,6 +277,7 @@ export default function getParametersAsJsonSchema(
268
277
  currentLocation: `/${current.name}`,
269
278
  globalDefaults: opts.globalDefaults,
270
279
  refLogger,
280
+ transformer: opts.transformer,
271
281
  }),
272
282
 
273
283
  // Note: this applies a $schema version to each field in the larger schema object.
@@ -23,7 +23,17 @@ const isJSON = matches.json;
23
23
  * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.3.md#headerObject}
24
24
  * @param response Response object to build a JSON Schema object for its headers for.
25
25
  */
26
- function buildHeadersSchema(response: ResponseObject) {
26
+ function buildHeadersSchema(
27
+ response: ResponseObject,
28
+ opts?: {
29
+ /**
30
+ * With a transformer you can transform any data within a given schema, like say if you want to
31
+ * rewrite a potentially unsafe `title` that might be eventually used as a JS variable name,
32
+ * just make sure to return your transformed schema.
33
+ */
34
+ transformer?: (schema: SchemaObject) => SchemaObject;
35
+ }
36
+ ) {
27
37
  const headers = response.headers;
28
38
 
29
39
  const headersSchema: SchemaObject = {
@@ -38,7 +48,10 @@ function buildHeadersSchema(response: ResponseObject) {
38
48
  // TODO: Response headers are essentially parameters in OAS
39
49
  // This means they can have content instead of schema.
40
50
  // We should probably support that in the future
41
- headersSchema.properties[key] = toJSONSchema(header.schema, { addEnumsToDescriptions: true });
51
+ headersSchema.properties[key] = toJSONSchema(header.schema, {
52
+ addEnumsToDescriptions: true,
53
+ transformer: opts.transformer,
54
+ });
42
55
 
43
56
  if (header.description) {
44
57
  (headersSchema.properties[key] as HeaderObject).description = header.description;
@@ -65,7 +78,7 @@ function buildHeadersSchema(response: ResponseObject) {
65
78
  }
66
79
 
67
80
  /**
68
- * Extract all the response schemas, matching the format of get-parameters-as-json-schema.
81
+ * Extract all the response schemas, matching the format of `get-parameters-as-json-schema`.
69
82
  *
70
83
  * Note: This expects a dereferenced schema.
71
84
  *
@@ -73,7 +86,19 @@ function buildHeadersSchema(response: ResponseObject) {
73
86
  * @param api The OpenAPI definition that this operation originates.
74
87
  * @param statusCode The response status code to generate a schema for.
75
88
  */
76
- export default function getResponseAsJsonSchema(operation: Operation, api: OASDocument, statusCode: string | number) {
89
+ export default function getResponseAsJSONSchema(
90
+ operation: Operation,
91
+ api: OASDocument,
92
+ statusCode: string | number,
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
+ */
99
+ transformer?: (schema: SchemaObject) => SchemaObject;
100
+ }
101
+ ) {
77
102
  const response = operation.getResponseByStatusCode(statusCode);
78
103
  const jsonSchema = [];
79
104
 
@@ -104,14 +129,22 @@ export default function getResponseAsJsonSchema(operation: Operation, api: OASDo
104
129
  // eslint-disable-next-line no-plusplus
105
130
  for (let i = 0; i < contentTypes.length; i++) {
106
131
  if (isJSON(contentTypes[i])) {
107
- return toJSONSchema(cloneObject(content[contentTypes[i]].schema), { addEnumsToDescriptions: true, refLogger });
132
+ return toJSONSchema(cloneObject(content[contentTypes[i]].schema), {
133
+ addEnumsToDescriptions: true,
134
+ refLogger,
135
+ transformer: opts.transformer,
136
+ });
108
137
  }
109
138
  }
110
139
 
111
140
  // We always want to prefer the JSON-compatible content types over everything else but if we
112
141
  // haven't found one we should default to the first available.
113
142
  const contentType = contentTypes.shift();
114
- return toJSONSchema(cloneObject(content[contentType].schema), { addEnumsToDescriptions: true, refLogger });
143
+ return toJSONSchema(cloneObject(content[contentType].schema), {
144
+ addEnumsToDescriptions: true,
145
+ refLogger,
146
+ transformer: opts.transformer,
147
+ });
115
148
  }
116
149
 
117
150
  const foundSchema = getPreferredSchema((response as ResponseObject).content);
@@ -154,7 +187,7 @@ export default function getResponseAsJsonSchema(operation: Operation, api: OASDo
154
187
 
155
188
  // 3.0.3 and earlier headers. TODO: New format for 3.1.0
156
189
  if ((response as ResponseObject).headers) {
157
- jsonSchema.push(buildHeadersSchema(response as ResponseObject));
190
+ jsonSchema.push(buildHeadersSchema(response as ResponseObject, opts));
158
191
  }
159
192
 
160
193
  return jsonSchema.length ? jsonSchema : null;
package/src/operation.ts CHANGED
@@ -7,9 +7,9 @@ import dedupeCommonParameters from './lib/dedupe-common-parameters';
7
7
  import findSchemaDefinition from './lib/find-schema-definition';
8
8
  import matchesMimeType from './lib/matches-mimetype';
9
9
  import getCallbackExamples from './operation/get-callback-examples';
10
- import getParametersAsJsonSchema from './operation/get-parameters-as-json-schema';
10
+ import getParametersAsJSONSchema from './operation/get-parameters-as-json-schema';
11
11
  import getRequestBodyExamples from './operation/get-requestbody-examples';
12
- import getResponseAsJsonSchema from './operation/get-response-as-json-schema';
12
+ import getResponseAsJSONSchema from './operation/get-response-as-json-schema';
13
13
  import getResponseExamples from './operation/get-response-examples';
14
14
  import * as RMOAS from './rmoas.types';
15
15
  import { supportedMethods } from './utils';
@@ -260,7 +260,7 @@ export default class Operation {
260
260
  });
261
261
  }
262
262
 
263
- if (security.Bearer || security.Basic) {
263
+ if (security.Bearer || security.Basic || security.OAuth2) {
264
264
  this.headers.request.push('Authorization');
265
265
  }
266
266
 
@@ -332,24 +332,33 @@ export default class Operation {
332
332
  * Get an `operationId` for this operation. If one is not present (it's not required by the spec!)
333
333
  * a hash of the path and method will be returned instead.
334
334
  *
335
- * @param opts Options
336
- * @param opts.camelCase Generate a JS method-friendly operation ID when one isn't present.
337
335
  */
338
- getOperationId(opts?: { camelCase: boolean }): string {
336
+ getOperationId(opts?: {
337
+ /**
338
+ * Generate a JS method-friendly operation ID when one isn't present.
339
+ */
340
+ camelCase: boolean;
341
+ }): string {
342
+ function sanitize(id: string) {
343
+ return id
344
+ .replace(/[^a-zA-Z0-9_]/g, '-') // Remove weird characters
345
+ .replace(/^-|-$/g, '') // Don't start or end with -
346
+ .replace(/--+/g, '-'); // Remove double --'s
347
+ }
348
+
339
349
  let operationId;
340
350
  if (this.hasOperationId()) {
341
351
  operationId = this.schema.operationId;
342
352
  } else {
343
- operationId = this.path
344
- .replace(/[^a-zA-Z0-9]/g, '-') // Remove weird characters
345
- .replace(/^-|-$/g, '') // Don't start or end with -
346
- .replace(/--+/g, '-') // Remove double --'s
347
- .toLowerCase();
353
+ operationId = sanitize(this.path).toLowerCase();
348
354
  }
349
355
 
350
356
  const method = this.method.toLowerCase();
351
357
  if (opts?.camelCase) {
352
358
  operationId = operationId.replace(/[^a-zA-Z0-9_]+(.)/g, (_, chr) => chr.toUpperCase());
359
+ if (this.hasOperationId()) {
360
+ operationId = sanitize(operationId);
361
+ }
353
362
 
354
363
  // If the generated `operationId` already starts with the method (eg. `getPets`) we don't want
355
364
  // to double it up into `getGetPets`.
@@ -448,22 +457,39 @@ export default class Operation {
448
457
  * Convert the operation into an array of JSON Schema schemas for each available type of
449
458
  * parameter available on the operation.
450
459
  *
451
- * @param opts Options
452
- * @param opts.globalDefaults Contains an object of user defined schema defaults.
453
- * @param opts.mergeIntoBodyAndMetadata If you want the output to be two objects: body (contains
454
- * `body` and `formData` JSON Schema) and metadata (contains `path`, `query`, `cookie`, and
455
- * `header`).
456
- * @param opts.retainDeprecatedProperties If you wish to **not** split out deprecated properties
457
- * into a separate `deprecatedProps` object.
458
- */
459
- getParametersAsJsonSchema(
460
+ */
461
+ getParametersAsJSONSchema(
460
462
  opts: {
463
+ /**
464
+ * Contains an object of user defined schema defaults.
465
+ */
461
466
  globalDefaults?: Record<string, unknown>;
467
+
468
+ /**
469
+ * If you want the output to be two objects: body (contains `body` and `formData` JSON
470
+ * Schema) and metadata (contains `path`, `query`, `cookie`, and `header`).
471
+ */
462
472
  mergeIntoBodyAndMetadata?: boolean;
473
+
474
+ /**
475
+ * If you wish to **not** split out deprecated properties into a separate `deprecatedProps`
476
+ * object.
477
+ */
463
478
  retainDeprecatedProperties?: boolean;
479
+
480
+ /**
481
+ * With a transformer you can transform any data within a given schema, like say if you want
482
+ * to rewrite a potentially unsafe `title` that might be eventually used as a JS variable
483
+ * name, just make sure to return your transformed schema.
484
+ */
485
+ transformer?: (schema: RMOAS.SchemaObject) => RMOAS.SchemaObject;
464
486
  } = {}
465
487
  ) {
466
- return getParametersAsJsonSchema(this, this.api, opts);
488
+ if (!opts.transformer) {
489
+ opts.transformer = (s: RMOAS.SchemaObject) => s;
490
+ }
491
+
492
+ return getParametersAsJSONSchema(this, this.api, opts);
467
493
  }
468
494
 
469
495
  /**
@@ -471,8 +497,20 @@ export default class Operation {
471
497
  *
472
498
  * @param statusCode Status code to pull a JSON Schema response for.
473
499
  */
474
- getResponseAsJsonSchema(statusCode: string | number) {
475
- return getResponseAsJsonSchema(this, this.api, statusCode);
500
+ getResponseAsJSONSchema(
501
+ statusCode: string | number,
502
+ opts: {
503
+ /**
504
+ * With a transformer you can transform any data within a given schema, like say if you want
505
+ * to rewrite a potentially unsafe `title` that might be eventually used as a JS variable
506
+ * name, just make sure to return your transformed schema.
507
+ */
508
+ transformer?: (schema: RMOAS.SchemaObject) => RMOAS.SchemaObject;
509
+ } = {
510
+ transformer: (s: RMOAS.SchemaObject) => s,
511
+ }
512
+ ) {
513
+ return getResponseAsJSONSchema(this, this.api, statusCode, opts);
476
514
  }
477
515
 
478
516
  /**
@@ -538,7 +576,7 @@ export default class Operation {
538
576
  // final point where we don't have a required request body, but the underlying Media Type Object
539
577
  // schema says that it has required properties then we should ultimately recognize that this
540
578
  // request body is required -- even as the request body description says otherwise.
541
- return !!this.getParametersAsJsonSchema()
579
+ return !!this.getParametersAsJSONSchema()
542
580
  .filter(js => ['body', 'formData'].includes(js.type))
543
581
  .find(js => js.schema && Array.isArray(js.schema.required) && js.schema.required.length);
544
582
  }
@@ -51,14 +51,20 @@ const primitive = (schema: RMOAS.SchemaObject) => {
51
51
  * the schema.
52
52
  *
53
53
  * @param schema JSON Schema to generate a sample for.
54
- * @param opts Options
55
- * @param opts.includeReadOnly If you wish to include data that's flagged as `readOnly`.
56
- * @param opts.includeWriteOnly If you wish to include data that's flatted as `writeOnly`.
57
- * @returns A generated piece of data based off the JSON Schema that was supplied.
58
54
  */
59
55
  function sampleFromSchema(
60
56
  schema: RMOAS.SchemaObject,
61
- opts: { includeReadOnly?: boolean; includeWriteOnly?: boolean } = {}
57
+ opts: {
58
+ /**
59
+ * If you wish to include data that's flagged as `readOnly`.
60
+ */
61
+ includeReadOnly?: boolean;
62
+
63
+ /**
64
+ * If you wish to include data that's flatted as `writeOnly`.
65
+ */
66
+ includeWriteOnly?: boolean;
67
+ } = {}
62
68
  ): string | number | boolean | null | unknown[] | Record<string, unknown> | undefined {
63
69
  const objectifySchema = objectify(schema);
64
70
  let { type } = objectifySchema;