oas 17.8.0 → 17.8.1
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/@types/operation.d.ts +23 -4
- package/CHANGELOG.md +8 -0
- package/dist/operation.js +57 -6
- package/package.json +1 -1
- package/src/cli/lib/utils.js +1 -1
- package/src/operation.ts +72 -6
package/@types/operation.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { RequestBodyExamples } from './operation/get-requestbody-examples';
|
|
2
2
|
import type { CallbackExamples } from './operation/get-callback-examples';
|
|
3
3
|
import type { ResponseExamples } from './operation/get-response-examples';
|
|
4
|
+
import type { SchemaWrapper } from './operation/get-parameters-as-json-schema';
|
|
4
5
|
import * as RMOAS from './rmoas.types';
|
|
5
6
|
declare type SecurityType = 'Basic' | 'Bearer' | 'Query' | 'Header' | 'Cookie' | 'OAuth2' | 'http' | 'apiKey';
|
|
6
7
|
export default class Operation {
|
|
@@ -43,6 +44,10 @@ export default class Operation {
|
|
|
43
44
|
request: string[];
|
|
44
45
|
response: string[];
|
|
45
46
|
};
|
|
47
|
+
/**
|
|
48
|
+
* All parameters and request bodies converted into JSON Schema.
|
|
49
|
+
*/
|
|
50
|
+
parameterJsonSchema: SchemaWrapper[];
|
|
46
51
|
constructor(api: RMOAS.OASDocument, path: string, method: RMOAS.HttpMethods, operation: RMOAS.OperationObject);
|
|
47
52
|
getSummary(): string;
|
|
48
53
|
getDescription(): string;
|
|
@@ -84,11 +89,15 @@ export default class Operation {
|
|
|
84
89
|
*/
|
|
85
90
|
hasOperationId(): boolean;
|
|
86
91
|
/**
|
|
87
|
-
* Get an `operationId` for this operation. If one is not present (it's not required by the spec!)
|
|
88
|
-
* and method will be returned instead.
|
|
92
|
+
* Get an `operationId` for this operation. If one is not present (it's not required by the spec!)
|
|
93
|
+
* a hash of the path and method will be returned instead.
|
|
89
94
|
*
|
|
95
|
+
* @param opts
|
|
96
|
+
* @param opts.camelCase Generate a JS method-friendly operation ID when one isn't present.
|
|
90
97
|
*/
|
|
91
|
-
getOperationId(
|
|
98
|
+
getOperationId(opts?: {
|
|
99
|
+
camelCase: boolean;
|
|
100
|
+
}): string;
|
|
92
101
|
/**
|
|
93
102
|
* Return an array of all tags, and their metadata, that exist on this operation.
|
|
94
103
|
*
|
|
@@ -109,13 +118,18 @@ export default class Operation {
|
|
|
109
118
|
*
|
|
110
119
|
*/
|
|
111
120
|
getParameters(): RMOAS.ParameterObject[];
|
|
121
|
+
/**
|
|
122
|
+
* Determine if this operation has any required parameters.
|
|
123
|
+
*
|
|
124
|
+
*/
|
|
125
|
+
hasRequiredParameters(): boolean;
|
|
112
126
|
/**
|
|
113
127
|
* Convert the operation into an array of JSON Schema schemas for each available type of parameter available on the
|
|
114
128
|
* operation.
|
|
115
129
|
*
|
|
116
130
|
* @param globalDefaults Contains an object of user defined schema defaults.
|
|
117
131
|
*/
|
|
118
|
-
getParametersAsJsonSchema(globalDefaults?: Record<string, unknown>):
|
|
132
|
+
getParametersAsJsonSchema(globalDefaults?: Record<string, unknown>): SchemaWrapper[];
|
|
119
133
|
/**
|
|
120
134
|
* Get a single response for this status code, formatted as JSON schema.
|
|
121
135
|
*
|
|
@@ -144,6 +158,11 @@ export default class Operation {
|
|
|
144
158
|
* @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#mediaTypeObject}
|
|
145
159
|
*/
|
|
146
160
|
getRequestBodyMediaTypes(): string[];
|
|
161
|
+
/**
|
|
162
|
+
* Determine if this operation has a required request body.
|
|
163
|
+
*
|
|
164
|
+
*/
|
|
165
|
+
hasRequiredRequestBody(): boolean;
|
|
147
166
|
/**
|
|
148
167
|
* Retrieve a specific request body content schema off this operation.
|
|
149
168
|
*
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## <small>17.8.1 (2022-03-04)</small>
|
|
2
|
+
|
|
3
|
+
* fix: typo in the `--pattern` option ([42db80a](https://github.com/readmeio/oas/commit/42db80a))
|
|
4
|
+
* feat: adding new accessors for determining if an operation has required params (#615) ([c081d92](https://github.com/readmeio/oas/commit/c081d92)), closes [#615](https://github.com/readmeio/oas/issues/615)
|
|
5
|
+
* feat: optionally generate friendlier operationIds (#602) ([6826164](https://github.com/readmeio/oas/commit/6826164)), closes [#602](https://github.com/readmeio/oas/issues/602)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
1
9
|
## 17.8.0 (2022-03-02)
|
|
2
10
|
|
|
3
11
|
* chore(deps-dev): bump @commitlint/cli from 16.1.0 to 16.2.1 (#612) ([e7364dd](https://github.com/readmeio/oas/commit/e7364dd)), closes [#612](https://github.com/readmeio/oas/issues/612)
|
package/dist/operation.js
CHANGED
|
@@ -286,20 +286,33 @@ var Operation = /** @class */ (function () {
|
|
|
286
286
|
return 'operationId' in this.schema;
|
|
287
287
|
};
|
|
288
288
|
/**
|
|
289
|
-
* Get an `operationId` for this operation. If one is not present (it's not required by the spec!)
|
|
290
|
-
* and method will be returned instead.
|
|
289
|
+
* Get an `operationId` for this operation. If one is not present (it's not required by the spec!)
|
|
290
|
+
* a hash of the path and method will be returned instead.
|
|
291
291
|
*
|
|
292
|
+
* @param opts
|
|
293
|
+
* @param opts.camelCase Generate a JS method-friendly operation ID when one isn't present.
|
|
292
294
|
*/
|
|
293
|
-
Operation.prototype.getOperationId = function () {
|
|
295
|
+
Operation.prototype.getOperationId = function (opts) {
|
|
294
296
|
if ('operationId' in this.schema) {
|
|
295
297
|
return this.schema.operationId;
|
|
296
298
|
}
|
|
297
|
-
var
|
|
299
|
+
var method = this.method.toLowerCase();
|
|
300
|
+
var operationId = this.path
|
|
298
301
|
.replace(/[^a-zA-Z0-9]/g, '-') // Remove weird characters
|
|
299
302
|
.replace(/^-|-$/g, '') // Don't start or end with -
|
|
300
303
|
.replace(/--+/g, '-') // Remove double --'s
|
|
301
304
|
.toLowerCase();
|
|
302
|
-
|
|
305
|
+
if (opts === null || opts === void 0 ? void 0 : opts.camelCase) {
|
|
306
|
+
operationId = operationId.replace(/[^a-zA-Z0-9]+(.)/g, function (_, chr) { return chr.toUpperCase(); });
|
|
307
|
+
// If the generated operationId already starts with the method (eg. `getPets`) we don't want
|
|
308
|
+
// to double it up into `getGetPets`.
|
|
309
|
+
if (operationId.startsWith(method)) {
|
|
310
|
+
return operationId;
|
|
311
|
+
}
|
|
312
|
+
operationId = operationId.charAt(0).toUpperCase() + operationId.slice(1);
|
|
313
|
+
return "".concat(method).concat(operationId);
|
|
314
|
+
}
|
|
315
|
+
return "".concat(method, "_").concat(operationId);
|
|
303
316
|
};
|
|
304
317
|
/**
|
|
305
318
|
* Return an array of all tags, and their metadata, that exist on this operation.
|
|
@@ -358,6 +371,13 @@ var Operation = /** @class */ (function () {
|
|
|
358
371
|
}
|
|
359
372
|
return parameters;
|
|
360
373
|
};
|
|
374
|
+
/**
|
|
375
|
+
* Determine if this operation has any required parameters.
|
|
376
|
+
*
|
|
377
|
+
*/
|
|
378
|
+
Operation.prototype.hasRequiredParameters = function () {
|
|
379
|
+
return this.getParameters().some(function (param) { return 'required' in param && param.required; });
|
|
380
|
+
};
|
|
361
381
|
/**
|
|
362
382
|
* Convert the operation into an array of JSON Schema schemas for each available type of parameter available on the
|
|
363
383
|
* operation.
|
|
@@ -365,7 +385,11 @@ var Operation = /** @class */ (function () {
|
|
|
365
385
|
* @param globalDefaults Contains an object of user defined schema defaults.
|
|
366
386
|
*/
|
|
367
387
|
Operation.prototype.getParametersAsJsonSchema = function (globalDefaults) {
|
|
368
|
-
|
|
388
|
+
if (this.parameterJsonSchema) {
|
|
389
|
+
return this.parameterJsonSchema;
|
|
390
|
+
}
|
|
391
|
+
this.parameterJsonSchema = (0, get_parameters_as_json_schema_1["default"])(this, this.api, globalDefaults);
|
|
392
|
+
return this.parameterJsonSchema;
|
|
369
393
|
};
|
|
370
394
|
/**
|
|
371
395
|
* Get a single response for this status code, formatted as JSON schema.
|
|
@@ -407,6 +431,33 @@ var Operation = /** @class */ (function () {
|
|
|
407
431
|
}
|
|
408
432
|
return Object.keys(requestBody.content);
|
|
409
433
|
};
|
|
434
|
+
/**
|
|
435
|
+
* Determine if this operation has a required request body.
|
|
436
|
+
*
|
|
437
|
+
*/
|
|
438
|
+
Operation.prototype.hasRequiredRequestBody = function () {
|
|
439
|
+
if (!this.hasRequestBody()) {
|
|
440
|
+
return false;
|
|
441
|
+
}
|
|
442
|
+
var requestBody = this.schema.requestBody;
|
|
443
|
+
if (RMOAS.isRef(requestBody)) {
|
|
444
|
+
return false;
|
|
445
|
+
}
|
|
446
|
+
if (requestBody.required) {
|
|
447
|
+
return true;
|
|
448
|
+
}
|
|
449
|
+
// The OpenAPI spec isn't clear on the differentiation between schema `required` and
|
|
450
|
+
// `requestBody.required` because you can have required top-level schema properties but a
|
|
451
|
+
// non-required requestBody that negates each other.
|
|
452
|
+
//
|
|
453
|
+
// To kind of work ourselves around this and present a better QOL for this accessor, if at this
|
|
454
|
+
// final point where we don't have a required request body, but the underlying Media Type Object
|
|
455
|
+
// schema says that it has required properties then we should ultimately recognize that this
|
|
456
|
+
// request body is required -- even as the request body description says otherwise.
|
|
457
|
+
return !!this.getParametersAsJsonSchema()
|
|
458
|
+
.filter(function (js) { return ['body', 'formData'].includes(js.type); })
|
|
459
|
+
.find(function (js) { return js.schema && Array.isArray(js.schema.required) && js.schema.required.length; });
|
|
460
|
+
};
|
|
410
461
|
/**
|
|
411
462
|
* Retrieve a specific request body content schema off this operation.
|
|
412
463
|
*
|
package/package.json
CHANGED
package/src/cli/lib/utils.js
CHANGED
package/src/operation.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';
|
|
|
2
2
|
import type { RequestBodyExamples } from './operation/get-requestbody-examples';
|
|
3
3
|
import type { CallbackExamples } from './operation/get-callback-examples';
|
|
4
4
|
import type { ResponseExamples } from './operation/get-response-examples';
|
|
5
|
+
import type { SchemaWrapper } from './operation/get-parameters-as-json-schema';
|
|
5
6
|
|
|
6
7
|
import * as RMOAS from './rmoas.types';
|
|
7
8
|
import dedupeCommonParameters from './lib/dedupe-common-parameters';
|
|
@@ -65,6 +66,11 @@ export default class Operation {
|
|
|
65
66
|
response: string[];
|
|
66
67
|
};
|
|
67
68
|
|
|
69
|
+
/**
|
|
70
|
+
* All parameters and request bodies converted into JSON Schema.
|
|
71
|
+
*/
|
|
72
|
+
parameterJsonSchema: SchemaWrapper[];
|
|
73
|
+
|
|
68
74
|
constructor(api: RMOAS.OASDocument, path: string, method: RMOAS.HttpMethods, operation: RMOAS.OperationObject) {
|
|
69
75
|
this.schema = operation;
|
|
70
76
|
this.api = api;
|
|
@@ -323,22 +329,38 @@ export default class Operation {
|
|
|
323
329
|
}
|
|
324
330
|
|
|
325
331
|
/**
|
|
326
|
-
* Get an `operationId` for this operation. If one is not present (it's not required by the spec!)
|
|
327
|
-
* and method will be returned instead.
|
|
332
|
+
* Get an `operationId` for this operation. If one is not present (it's not required by the spec!)
|
|
333
|
+
* a hash of the path and method will be returned instead.
|
|
328
334
|
*
|
|
335
|
+
* @param opts
|
|
336
|
+
* @param opts.camelCase Generate a JS method-friendly operation ID when one isn't present.
|
|
329
337
|
*/
|
|
330
|
-
getOperationId(): string {
|
|
338
|
+
getOperationId(opts?: { camelCase: boolean }): string {
|
|
331
339
|
if ('operationId' in this.schema) {
|
|
332
340
|
return this.schema.operationId;
|
|
333
341
|
}
|
|
334
342
|
|
|
335
|
-
const
|
|
343
|
+
const method = this.method.toLowerCase();
|
|
344
|
+
let operationId = this.path
|
|
336
345
|
.replace(/[^a-zA-Z0-9]/g, '-') // Remove weird characters
|
|
337
346
|
.replace(/^-|-$/g, '') // Don't start or end with -
|
|
338
347
|
.replace(/--+/g, '-') // Remove double --'s
|
|
339
348
|
.toLowerCase();
|
|
340
349
|
|
|
341
|
-
|
|
350
|
+
if (opts?.camelCase) {
|
|
351
|
+
operationId = operationId.replace(/[^a-zA-Z0-9]+(.)/g, (_, chr) => chr.toUpperCase());
|
|
352
|
+
|
|
353
|
+
// If the generated operationId already starts with the method (eg. `getPets`) we don't want
|
|
354
|
+
// to double it up into `getGetPets`.
|
|
355
|
+
if (operationId.startsWith(method)) {
|
|
356
|
+
return operationId;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
operationId = operationId.charAt(0).toUpperCase() + operationId.slice(1);
|
|
360
|
+
return `${method}${operationId}`;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
return `${method}_${operationId}`;
|
|
342
364
|
}
|
|
343
365
|
|
|
344
366
|
/**
|
|
@@ -405,6 +427,14 @@ export default class Operation {
|
|
|
405
427
|
return parameters;
|
|
406
428
|
}
|
|
407
429
|
|
|
430
|
+
/**
|
|
431
|
+
* Determine if this operation has any required parameters.
|
|
432
|
+
*
|
|
433
|
+
*/
|
|
434
|
+
hasRequiredParameters() {
|
|
435
|
+
return this.getParameters().some(param => 'required' in param && param.required);
|
|
436
|
+
}
|
|
437
|
+
|
|
408
438
|
/**
|
|
409
439
|
* Convert the operation into an array of JSON Schema schemas for each available type of parameter available on the
|
|
410
440
|
* operation.
|
|
@@ -412,7 +442,12 @@ export default class Operation {
|
|
|
412
442
|
* @param globalDefaults Contains an object of user defined schema defaults.
|
|
413
443
|
*/
|
|
414
444
|
getParametersAsJsonSchema(globalDefaults?: Record<string, unknown>) {
|
|
415
|
-
|
|
445
|
+
if (this.parameterJsonSchema) {
|
|
446
|
+
return this.parameterJsonSchema;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
this.parameterJsonSchema = getParametersAsJsonSchema(this, this.api, globalDefaults);
|
|
450
|
+
return this.parameterJsonSchema;
|
|
416
451
|
}
|
|
417
452
|
|
|
418
453
|
/**
|
|
@@ -461,6 +496,37 @@ export default class Operation {
|
|
|
461
496
|
return Object.keys(requestBody.content);
|
|
462
497
|
}
|
|
463
498
|
|
|
499
|
+
/**
|
|
500
|
+
* Determine if this operation has a required request body.
|
|
501
|
+
*
|
|
502
|
+
*/
|
|
503
|
+
hasRequiredRequestBody() {
|
|
504
|
+
if (!this.hasRequestBody()) {
|
|
505
|
+
return false;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
const requestBody = this.schema.requestBody;
|
|
509
|
+
if (RMOAS.isRef(requestBody)) {
|
|
510
|
+
return false;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
if (requestBody.required) {
|
|
514
|
+
return true;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// The OpenAPI spec isn't clear on the differentiation between schema `required` and
|
|
518
|
+
// `requestBody.required` because you can have required top-level schema properties but a
|
|
519
|
+
// non-required requestBody that negates each other.
|
|
520
|
+
//
|
|
521
|
+
// To kind of work ourselves around this and present a better QOL for this accessor, if at this
|
|
522
|
+
// final point where we don't have a required request body, but the underlying Media Type Object
|
|
523
|
+
// schema says that it has required properties then we should ultimately recognize that this
|
|
524
|
+
// request body is required -- even as the request body description says otherwise.
|
|
525
|
+
return !!this.getParametersAsJsonSchema()
|
|
526
|
+
.filter(js => ['body', 'formData'].includes(js.type))
|
|
527
|
+
.find(js => js.schema && Array.isArray(js.schema.required) && js.schema.required.length);
|
|
528
|
+
}
|
|
529
|
+
|
|
464
530
|
/**
|
|
465
531
|
* Retrieve a specific request body content schema off this operation.
|
|
466
532
|
*
|