-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathremove-request-body.js
102 lines (88 loc) · 3.1 KB
/
remove-request-body.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/**
* @copyright Copyright 2021 Kevin Locke <kevin@kevinlocke.name>
* @license MIT
* @module "openapi-transformers/remove-request-body.js"
*/
import OpenApiTransformerBase from 'openapi-transformer-base';
import visit from 'openapi-transformer-base/visit.js';
const defaultMethodSet = new Set([
// https://datatracker.ietf.org/doc/html/rfc7231#section-4.3.5
// "A payload within a DELETE request message has no defined semantics"
// However, I suspect it may not be uncommon for API developers to do so.
// 'DELETE',
// https://datatracker.ietf.org/doc/html/rfc7231#section-4.3.1
// "A payload within a GET request message has no defined semantics"
'get',
// https://datatracker.ietf.org/doc/html/rfc7231#section-4.3.2
// "A payload within a HEAD request message has no defined semantics"
'head',
// https://datatracker.ietf.org/doc/html/rfc7231#section-4.3.8
// "A client MUST NOT send a message body in a TRACE request."
'trace',
]);
const httpMethodSetSymbol = Symbol('httpMethodSet');
/**
* Transformer to remove requestBody from operations on a given set of HTTP
* methods.
*
* This often occurs due to authoring errors where an operation which expects
* a request body is copied to one that does not.
*/
export default class RemoveRequestBodyTransformer
extends OpenApiTransformerBase {
/** Constructs a RemoveRequestBodyTransformer for a given set of HTTP methods.
*
* @param {!module:globals.Iterable=} methods HTTP Methods for which to
* remove requestBody. (default: [GET, HEAD, TRACE])
*/
constructor(methods) {
super();
this[httpMethodSetSymbol] =
methods === undefined ? defaultMethodSet : new Set(
[...methods].map((method) => method.toLowerCase()),
);
}
transformPathItem(pathItem) {
if (typeof pathItem !== 'object'
|| pathItem === null
|| Array.isArray(pathItem)) {
this.warn('Ignoring non-object Path Item', pathItem);
return pathItem;
}
const newPathItem = { ...pathItem };
const httpMethodSet = this[httpMethodSetSymbol];
for (const [method, operation] of Object.entries(pathItem)) {
if (operation !== undefined && httpMethodSet.has(method.toLowerCase())) {
newPathItem[method] = visit(
this,
this.transformOperation,
method,
operation,
);
}
}
return newPathItem;
}
transformOperation(operation) {
if (typeof operation !== 'object'
|| operation === null
|| Array.isArray(operation)) {
this.warn('Ignoring non-object Operation', operation);
return operation;
}
const { requestBody, ...newOperation } = operation;
const { parameters } = operation;
if (parameters !== undefined) {
if (!Array.isArray(parameters)) {
this.transformPath.push('parameters');
this.warn('Ignoring non-Array Parameters', parameters);
this.transformPath.pop();
} else {
newOperation.parameters = parameters
.filter((parameter) => !parameter
|| (parameter.in !== 'formData' && parameter.in !== 'body'));
}
}
return newOperation;
}
}