@readme/oas-to-har 14.0.3 → 15.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.
package/.github/workflows/ci.yml
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,44 @@
|
|
|
1
|
+
## 15.0.0 (2022-02-03)
|
|
2
|
+
|
|
3
|
+
> **BREAKING RELEASE**
|
|
4
|
+
>
|
|
5
|
+
> `oas-to-har` now assumes that the OpenAPI definition you're supplying it has been fully dereferenced.
|
|
6
|
+
|
|
7
|
+
* feat: upgrading oas and replacing some deprecated accessors (#58) ([ed97a5d](https://github.com/readmeio/oas-to-har/commit/ed97a5d)), closes [#58](https://github.com/readmeio/oas-to-har/issues/58)
|
|
8
|
+
* chore(deps-dev): bump @readme/eslint-config from 8.1.2 to 8.2.0 (#54) ([f783873](https://github.com/readmeio/oas-to-har/commit/f783873)), closes [#54](https://github.com/readmeio/oas-to-har/issues/54)
|
|
9
|
+
* chore(deps-dev): bump @readme/oas-examples from 4.3.3 to 4.4.0 (#53) ([fec1f82](https://github.com/readmeio/oas-to-har/commit/fec1f82)), closes [#53](https://github.com/readmeio/oas-to-har/issues/53)
|
|
10
|
+
* chore(deps-dev): bump eslint from 8.7.0 to 8.8.0 (#56) ([0559975](https://github.com/readmeio/oas-to-har/commit/0559975)), closes [#56](https://github.com/readmeio/oas-to-har/issues/56)
|
|
11
|
+
* chore(deps-dev): bump jest-expect-har from 3.0.1 to 3.0.2 (#57) ([cd2c19e](https://github.com/readmeio/oas-to-har/commit/cd2c19e)), closes [#57](https://github.com/readmeio/oas-to-har/issues/57)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## 14.1.0 (2022-01-25)
|
|
16
|
+
|
|
17
|
+
* chore(deps): bumping all out of date deps (#51) ([926763b](https://github.com/readmeio/oas-to-har/commit/926763b)), closes [#51](https://github.com/readmeio/oas-to-har/issues/51)
|
|
18
|
+
* chore(deps): bumping node-fetch ([1405d30](https://github.com/readmeio/oas-to-har/commit/1405d30))
|
|
19
|
+
* feat: add support for styles on multipart/form-data request bodies (#50) ([e7596bd](https://github.com/readmeio/oas-to-har/commit/e7596bd)), closes [#50](https://github.com/readmeio/oas-to-har/issues/50)
|
|
20
|
+
* fix: check for orphaned apiDefinition-less pages (#52) ([04ed408](https://github.com/readmeio/oas-to-har/commit/04ed408)), closes [#52](https://github.com/readmeio/oas-to-har/issues/52)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
## <small>14.0.5 (2022-01-03)</small>
|
|
25
|
+
|
|
26
|
+
* chore(deps-dev): bump @commitlint/cli from 15.0.0 to 16.0.1 (#45) ([4ce0b94](https://github.com/readmeio/oas-to-har/commit/4ce0b94)), closes [#45](https://github.com/readmeio/oas-to-har/issues/45)
|
|
27
|
+
* chore(deps-dev): bump @commitlint/config-conventional (#48) ([dc5195a](https://github.com/readmeio/oas-to-har/commit/dc5195a)), closes [#48](https://github.com/readmeio/oas-to-har/issues/48)
|
|
28
|
+
* chore(deps-dev): bump @readme/eslint-config from 8.0.4 to 8.1.1 (#46) ([8788c1e](https://github.com/readmeio/oas-to-har/commit/8788c1e)), closes [#46](https://github.com/readmeio/oas-to-har/issues/46)
|
|
29
|
+
* chore(deps-dev): bump eslint from 8.4.1 to 8.6.0 (#47) ([e211feb](https://github.com/readmeio/oas-to-har/commit/e211feb)), closes [#47](https://github.com/readmeio/oas-to-har/issues/47)
|
|
30
|
+
* chore(deps): bump actions/setup-node from 2.5.0 to 2.5.1 (#43) ([a05def3](https://github.com/readmeio/oas-to-har/commit/a05def3)), closes [#43](https://github.com/readmeio/oas-to-har/issues/43)
|
|
31
|
+
* chore(deps): bump oas from 17.3.2 to 17.4.0 (#44) ([8abb825](https://github.com/readmeio/oas-to-har/commit/8abb825)), closes [#44](https://github.com/readmeio/oas-to-har/issues/44)
|
|
32
|
+
* chore(deps): upgrading oas and @readme/oas-extensions (#49) ([822cb6d](https://github.com/readmeio/oas-to-har/commit/822cb6d)), closes [#49](https://github.com/readmeio/oas-to-har/issues/49)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
## <small>14.0.4 (2021-12-16)</small>
|
|
37
|
+
|
|
38
|
+
* fix: issue where we'd try to stylize iterate over a nullilsh value (#42) ([5baa462](https://github.com/readmeio/oas-to-har/commit/5baa462)), closes [#42](https://github.com/readmeio/oas-to-har/issues/42)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
1
42
|
## <small>14.0.3 (2021-12-16)</small>
|
|
2
43
|
|
|
3
44
|
* fix: cleaning up engine requirements and updating dev deps (#40) ([c377906](https://github.com/readmeio/oas-to-har/commit/c377906)), closes [#40](https://github.com/readmeio/oas-to-har/issues/40)
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@readme/oas-to-har",
|
|
3
3
|
"description": "Utility to transform an OAS operation into a HAR representation",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "15.0.0",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"author": "Jon Ursenbach <jon@ursenba.ch>",
|
|
7
7
|
"license": "ISC",
|
|
@@ -16,24 +16,24 @@
|
|
|
16
16
|
"lint": "eslint .",
|
|
17
17
|
"prepare": "husky install",
|
|
18
18
|
"pretest": "npm run lint",
|
|
19
|
-
"prettier": "prettier --list-different --write \"./**/**.{js
|
|
19
|
+
"prettier": "prettier --list-different --write \"./**/**.{js}\"",
|
|
20
20
|
"release": "npx conventional-changelog-cli -i CHANGELOG.md -s && git add CHANGELOG.md",
|
|
21
21
|
"test": "jest --coverage"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@readme/oas-extensions": "^14.
|
|
25
|
-
"oas": "^17.
|
|
24
|
+
"@readme/oas-extensions": "^14.1.1",
|
|
25
|
+
"oas": "^17.7.1",
|
|
26
26
|
"parse-data-url": "^4.0.1"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@commitlint/cli": "^
|
|
30
|
-
"@commitlint/config-conventional": "^
|
|
31
|
-
"@readme/eslint-config": "^8.
|
|
32
|
-
"@readme/oas-examples": "^4.3.
|
|
29
|
+
"@commitlint/cli": "^16.1.0",
|
|
30
|
+
"@commitlint/config-conventional": "^16.0.0",
|
|
31
|
+
"@readme/eslint-config": "^8.1.2",
|
|
32
|
+
"@readme/oas-examples": "^4.3.3",
|
|
33
33
|
"datauri": "^4.1.0",
|
|
34
|
-
"eslint": "^8.
|
|
34
|
+
"eslint": "^8.7.0",
|
|
35
35
|
"husky": "^7.0.4",
|
|
36
|
-
"jest": "^27.4.
|
|
36
|
+
"jest": "^27.4.7",
|
|
37
37
|
"jest-expect-har": "^3.0.1",
|
|
38
38
|
"prettier": "^2.5.1"
|
|
39
39
|
},
|
package/src/index.js
CHANGED
|
@@ -6,7 +6,7 @@ const configureSecurity = require('./lib/configure-security');
|
|
|
6
6
|
const removeUndefinedObjects = require('./lib/remove-undefined-objects');
|
|
7
7
|
const formatStyle = require('./lib/style-formatting');
|
|
8
8
|
|
|
9
|
-
const {
|
|
9
|
+
const { jsonSchemaTypes } = utils;
|
|
10
10
|
|
|
11
11
|
function formatter(values, param, type, onlyIfExists) {
|
|
12
12
|
if (param.style) {
|
|
@@ -18,6 +18,7 @@ function formatter(values, param, type, onlyIfExists) {
|
|
|
18
18
|
|
|
19
19
|
let value;
|
|
20
20
|
|
|
21
|
+
// Handle missing values
|
|
21
22
|
if (typeof values[type][param.name] !== 'undefined') {
|
|
22
23
|
value = values[type][param.name];
|
|
23
24
|
} else if (onlyIfExists && !param.required) {
|
|
@@ -30,6 +31,11 @@ function formatter(values, param, type, onlyIfExists) {
|
|
|
30
31
|
return param.name;
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
// Handle file uploads. Specifically arrays of file uploads which need to be formatted very specifically.
|
|
35
|
+
if (param.schema && param.schema.type === 'array' && param.schema.items && param.schema.items.format === 'binary') {
|
|
36
|
+
return JSON.stringify(value);
|
|
37
|
+
}
|
|
38
|
+
|
|
33
39
|
if (value !== undefined) {
|
|
34
40
|
// Query params should always be formatted, even if they don't have a `style` serialization configured.
|
|
35
41
|
if (type === 'query') {
|
|
@@ -42,6 +48,39 @@ function formatter(values, param, type, onlyIfExists) {
|
|
|
42
48
|
return undefined;
|
|
43
49
|
}
|
|
44
50
|
|
|
51
|
+
function multipartBodyToFormatterParams(multipartBody, oasMediaTypeObject) {
|
|
52
|
+
const schema = oasMediaTypeObject.schema;
|
|
53
|
+
const encoding = oasMediaTypeObject.encoding;
|
|
54
|
+
|
|
55
|
+
if (typeof multipartBody === 'object' && multipartBody !== null) {
|
|
56
|
+
return Object.keys(multipartBody)
|
|
57
|
+
.map(key => {
|
|
58
|
+
// If we have an incoming parameter, but it's not in the schema
|
|
59
|
+
// ignore it
|
|
60
|
+
if (!schema.properties[key]) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const paramEncoding = encoding ? encoding[key] : undefined;
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
name: key,
|
|
68
|
+
// If the style isn't defined, use the default
|
|
69
|
+
style: paramEncoding ? paramEncoding.style : undefined,
|
|
70
|
+
// If explode isn't defined, use the default
|
|
71
|
+
explode: paramEncoding ? paramEncoding.explode : undefined,
|
|
72
|
+
required: schema.required && schema.required.includes(key),
|
|
73
|
+
schema: schema.properties[key],
|
|
74
|
+
in: 'body',
|
|
75
|
+
};
|
|
76
|
+
})
|
|
77
|
+
.filter(Boolean);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Pretty sure that we'll never have anything but an object for multipart bodies, so returning empty array if we get anything else.
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
|
|
45
84
|
const defaultFormDataTypes = Object.keys(jsonSchemaTypes).reduce((prev, curr) => {
|
|
46
85
|
return Object.assign(prev, { [curr]: {} });
|
|
47
86
|
}, {});
|
|
@@ -75,7 +114,7 @@ function stringifyParameter(param) {
|
|
|
75
114
|
return JSON.stringify(param);
|
|
76
115
|
}
|
|
77
116
|
|
|
78
|
-
function appendHarValue(harParam, name, value) {
|
|
117
|
+
function appendHarValue(harParam, name, value, addtlData = {}) {
|
|
79
118
|
if (typeof value === 'undefined') return;
|
|
80
119
|
|
|
81
120
|
if (Array.isArray(value)) {
|
|
@@ -91,6 +130,7 @@ function appendHarValue(harParam, name, value) {
|
|
|
91
130
|
} else {
|
|
92
131
|
// If the formatter gives us a non-array, non-object, we add it as is
|
|
93
132
|
harParam.push({
|
|
133
|
+
...addtlData,
|
|
94
134
|
name,
|
|
95
135
|
value: String(value),
|
|
96
136
|
});
|
|
@@ -148,22 +188,7 @@ module.exports = (
|
|
|
148
188
|
}
|
|
149
189
|
}
|
|
150
190
|
|
|
151
|
-
|
|
152
|
-
const parameters = [];
|
|
153
|
-
function addParameter(param) {
|
|
154
|
-
if (param.$ref) {
|
|
155
|
-
parameters.push(findSchemaDefinition(param.$ref, apiDefinition));
|
|
156
|
-
} else {
|
|
157
|
-
parameters.push(param);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
operation.getParameters().forEach(addParameter);
|
|
162
|
-
|
|
163
|
-
// Does this operation have any common parameters?
|
|
164
|
-
if (apiDefinition.paths && apiDefinition.paths[operation.path] && apiDefinition.paths[operation.path].parameters) {
|
|
165
|
-
apiDefinition.paths[operation.path].parameters.forEach(addParameter);
|
|
166
|
-
}
|
|
191
|
+
const parameters = operation.getParameters();
|
|
167
192
|
|
|
168
193
|
har.url = har.url.replace(/{([-_a-zA-Z0-9[\]]+)}/g, (full, key) => {
|
|
169
194
|
if (!operation || !parameters) return key; // No path params at all
|
|
@@ -254,14 +279,12 @@ module.exports = (
|
|
|
254
279
|
});
|
|
255
280
|
}
|
|
256
281
|
|
|
257
|
-
let requestBody =
|
|
258
|
-
if (
|
|
259
|
-
requestBody =
|
|
260
|
-
} else {
|
|
261
|
-
requestBody = { schema: {} };
|
|
282
|
+
let requestBody = false;
|
|
283
|
+
if (operation.hasRequestBody()) {
|
|
284
|
+
[, requestBody] = operation.getRequestBody();
|
|
262
285
|
}
|
|
263
286
|
|
|
264
|
-
if (requestBody.schema && Object.keys(requestBody.schema).length) {
|
|
287
|
+
if (requestBody && requestBody.schema && Object.keys(requestBody.schema).length) {
|
|
265
288
|
if (operation.isFormUrlEncoded()) {
|
|
266
289
|
if (Object.keys(formData.formData).length) {
|
|
267
290
|
const cleanFormData = removeUndefinedObjects(JSON.parse(JSON.stringify(formData.formData)));
|
|
@@ -300,39 +323,32 @@ module.exports = (
|
|
|
300
323
|
);
|
|
301
324
|
|
|
302
325
|
if (cleanBody !== undefined) {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
// stringifying the content instead of potentially including `fileName` properties.
|
|
308
|
-
if (Array.isArray(cleanBody[name])) {
|
|
309
|
-
har.postData.params.push({
|
|
310
|
-
name,
|
|
311
|
-
value: JSON.stringify(cleanBody[name]),
|
|
312
|
-
});
|
|
326
|
+
const multipartParams = multipartBodyToFormatterParams(
|
|
327
|
+
formData.body,
|
|
328
|
+
operation.schema.requestBody.content['multipart/form-data']
|
|
329
|
+
);
|
|
313
330
|
|
|
314
|
-
|
|
315
|
-
|
|
331
|
+
Object.keys(cleanBody).forEach(name => {
|
|
332
|
+
const param = multipartParams.find(multipartParam => multipartParam.name === name);
|
|
316
333
|
|
|
317
|
-
const
|
|
318
|
-
name,
|
|
319
|
-
value: String(cleanBody[name]),
|
|
320
|
-
};
|
|
334
|
+
const value = formatter(formData, param, 'body', true);
|
|
321
335
|
|
|
322
336
|
// If we're dealing with a binary type, and the value is a valid data URL we should parse out any
|
|
323
337
|
// available filename and content type to send along with the parameter to interpreters like `fetch-har`
|
|
324
338
|
// can make sense of it and send a usable payload.
|
|
339
|
+
const addtlData = {};
|
|
340
|
+
|
|
325
341
|
if (binaryTypes.includes(name)) {
|
|
326
|
-
const parsed = parseDataUrl(
|
|
342
|
+
const parsed = parseDataUrl(value);
|
|
327
343
|
if (parsed) {
|
|
328
|
-
|
|
344
|
+
addtlData.fileName = 'name' in parsed ? parsed.name : 'unknown';
|
|
329
345
|
if ('contentType' in parsed) {
|
|
330
|
-
|
|
346
|
+
addtlData.contentType = parsed.contentType;
|
|
331
347
|
}
|
|
332
348
|
}
|
|
333
349
|
}
|
|
334
350
|
|
|
335
|
-
har.postData.params
|
|
351
|
+
appendHarValue(har.postData.params, name, value, addtlData);
|
|
336
352
|
});
|
|
337
353
|
}
|
|
338
354
|
} else {
|
|
@@ -379,6 +395,8 @@ module.exports = (
|
|
|
379
395
|
}
|
|
380
396
|
}
|
|
381
397
|
} catch (e) {
|
|
398
|
+
// you should log this error if you're debugging why data is showing up in text, when it should show up in params
|
|
399
|
+
// console.log('catching ', e);
|
|
382
400
|
// If anything above fails for whatever reason, assume that whatever we had is invalid JSON and just treat it
|
|
383
401
|
// as raw text.
|
|
384
402
|
har.postData.text = stringify(formData.body);
|
|
@@ -396,7 +414,7 @@ module.exports = (
|
|
|
396
414
|
|
|
397
415
|
// Add a `Content-Type` header if there are any body values setup above or if there is a schema defined, but only do
|
|
398
416
|
// so if we don't already have a `Content-Type` present as it's impossible for a request to have multiple.
|
|
399
|
-
if ((har.postData.text || Object.keys(requestBody.schema).length) && !hasContentType) {
|
|
417
|
+
if ((har.postData.text || (requestBody && Object.keys(requestBody.schema).length)) && !hasContentType) {
|
|
400
418
|
har.headers.push({
|
|
401
419
|
name: 'Content-Type',
|
|
402
420
|
value: contentType,
|
|
@@ -195,7 +195,7 @@ function encodePrimitive({ location, key, value, style, escape }) {
|
|
|
195
195
|
const valueEncoder = str =>
|
|
196
196
|
module.exports.encodeDisallowedCharacters(str, {
|
|
197
197
|
escape,
|
|
198
|
-
returnIfEncoded: location === 'query',
|
|
198
|
+
returnIfEncoded: location === 'query' || location === 'body',
|
|
199
199
|
});
|
|
200
200
|
|
|
201
201
|
if (style === 'simple') {
|