@readme/oas-to-har 14.0.2 → 14.1.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.
@@ -13,13 +13,10 @@ jobs:
13
13
  - uses: actions/checkout@v2.4.0
14
14
 
15
15
  - name: Use Node.js ${{ matrix.node-version }}
16
- uses: actions/setup-node@v2.5.0
16
+ uses: actions/setup-node@v2.5.1
17
17
  with:
18
18
  node-version: ${{ matrix.node-version }}
19
19
 
20
- - name: Install npm@7
21
- run: npm install -g npm@7
22
-
23
20
  - name: Install deps
24
21
  run: npm ci
25
22
 
package/CHANGELOG.md CHANGED
@@ -1,3 +1,37 @@
1
+ ## 14.1.0 (2022-01-25)
2
+
3
+ * 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)
4
+ * chore(deps): bumping node-fetch ([1405d30](https://github.com/readmeio/oas-to-har/commit/1405d30))
5
+ * 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)
6
+ * 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)
7
+
8
+
9
+
10
+ ## <small>14.0.5 (2022-01-03)</small>
11
+
12
+ * 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)
13
+ * 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)
14
+ * 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)
15
+ * 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)
16
+ * 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)
17
+ * 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)
18
+ * 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)
19
+
20
+
21
+
22
+ ## <small>14.0.4 (2021-12-16)</small>
23
+
24
+ * 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)
25
+
26
+
27
+
28
+ ## <small>14.0.3 (2021-12-16)</small>
29
+
30
+ * 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)
31
+ * test: overhauling the test suite to make it easier to maintain (#41) ([e04944d](https://github.com/readmeio/oas-to-har/commit/e04944d)), closes [#41](https://github.com/readmeio/oas-to-har/issues/41)
32
+
33
+
34
+
1
35
  ## <small>14.0.2 (2021-12-01)</small>
2
36
 
3
37
  * chore(deps-dev): bump @commitlint/cli from 14.1.0 to 15.0.0 (#33) ([64cf308](https://github.com/readmeio/oas-to-har/commit/64cf308)), closes [#33](https://github.com/readmeio/oas-to-har/issues/33)
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": "14.0.2",
4
+ "version": "14.1.0",
5
5
  "main": "src/index.js",
6
6
  "author": "Jon Ursenbach <jon@ursenba.ch>",
7
7
  "license": "ISC",
@@ -10,33 +10,32 @@
10
10
  "url": "git://github.com/readmeio/oas-to-har.git"
11
11
  },
12
12
  "engines": {
13
- "node": "^12 || ^14 || ^16",
14
- "npm": "^7"
13
+ "node": "^12 || ^14 || ^16"
15
14
  },
16
15
  "scripts": {
17
16
  "lint": "eslint .",
18
17
  "prepare": "husky install",
19
18
  "pretest": "npm run lint",
20
- "prettier": "prettier --list-different --write \"./**/**.{js,jsx}\"",
19
+ "prettier": "prettier --list-different --write \"./**/**.{js}\"",
21
20
  "release": "npx conventional-changelog-cli -i CHANGELOG.md -s && git add CHANGELOG.md",
22
21
  "test": "jest --coverage"
23
22
  },
24
23
  "dependencies": {
25
- "@readme/oas-extensions": "^14.0.0",
26
- "oas": "^17.1.0",
24
+ "@readme/oas-extensions": "^14.1.0",
25
+ "oas": "^17.5.0",
27
26
  "parse-data-url": "^4.0.1"
28
27
  },
29
28
  "devDependencies": {
30
- "@commitlint/cli": "^15.0.0",
31
- "@commitlint/config-conventional": "^15.0.0",
32
- "@readme/eslint-config": "^8.0.2",
33
- "@readme/oas-examples": "^4.3.2",
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",
34
33
  "datauri": "^4.1.0",
35
- "eslint": "^8.2.0",
34
+ "eslint": "^8.7.0",
36
35
  "husky": "^7.0.4",
37
- "jest": "^27.3.1",
38
- "jest-expect-har": "^3.0.0",
39
- "prettier": "^2.4.1"
36
+ "jest": "^27.4.7",
37
+ "jest-expect-har": "^3.0.1",
38
+ "prettier": "^2.5.1"
40
39
  },
41
40
  "prettier": "@readme/eslint-config/prettier",
42
41
  "commitlint": {
package/src/index.js CHANGED
@@ -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
  });
@@ -161,7 +201,12 @@ module.exports = (
161
201
  operation.getParameters().forEach(addParameter);
162
202
 
163
203
  // Does this operation have any common parameters?
164
- if (apiDefinition.paths && apiDefinition.paths[operation.path] && apiDefinition.paths[operation.path].parameters) {
204
+ if (
205
+ apiDefinition &&
206
+ apiDefinition.paths &&
207
+ apiDefinition.paths[operation.path] &&
208
+ apiDefinition.paths[operation.path].parameters
209
+ ) {
165
210
  apiDefinition.paths[operation.path].parameters.forEach(addParameter);
166
211
  }
167
212
 
@@ -230,7 +275,7 @@ module.exports = (
230
275
  });
231
276
  }
232
277
 
233
- // Are there `x-static` static headers configured for this OAS?
278
+ // Are there `x-headers` static headers configured for this OAS?
234
279
  const userDefinedHeaders = extensions.getExtension(extensions.HEADERS, oas, operation);
235
280
  if (userDefinedHeaders) {
236
281
  userDefinedHeaders.forEach(header => {
@@ -300,39 +345,32 @@ module.exports = (
300
345
  );
301
346
 
302
347
  if (cleanBody !== undefined) {
303
- Object.keys(cleanBody).forEach(name => {
304
- // We neither have an easy way to transform `name` into `name[]` to signify that it's an array payload
305
- // (and for all we know it might be an array of objects!), but also at the same time the HAR spec
306
- // doesn't give any guidance for these kinds of cases so instead we're just falling back to
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
- });
348
+ const multipartParams = multipartBodyToFormatterParams(
349
+ formData.body,
350
+ operation.schema.requestBody.content['multipart/form-data']
351
+ );
313
352
 
314
- return;
315
- }
353
+ Object.keys(cleanBody).forEach(name => {
354
+ const param = multipartParams.find(multipartParam => multipartParam.name === name);
316
355
 
317
- const data = {
318
- name,
319
- value: String(cleanBody[name]),
320
- };
356
+ const value = formatter(formData, param, 'body', true);
321
357
 
322
358
  // If we're dealing with a binary type, and the value is a valid data URL we should parse out any
323
359
  // available filename and content type to send along with the parameter to interpreters like `fetch-har`
324
360
  // can make sense of it and send a usable payload.
361
+ const addtlData = {};
362
+
325
363
  if (binaryTypes.includes(name)) {
326
- const parsed = parseDataUrl(data.value);
364
+ const parsed = parseDataUrl(value);
327
365
  if (parsed) {
328
- data.fileName = 'name' in parsed ? parsed.name : 'unknown';
366
+ addtlData.fileName = 'name' in parsed ? parsed.name : 'unknown';
329
367
  if ('contentType' in parsed) {
330
- data.contentType = parsed.contentType;
368
+ addtlData.contentType = parsed.contentType;
331
369
  }
332
370
  }
333
371
  }
334
372
 
335
- har.postData.params.push(data);
373
+ appendHarValue(har.postData.params, name, value, addtlData);
336
374
  });
337
375
  }
338
376
  } else {
@@ -364,6 +402,7 @@ module.exports = (
364
402
  }
365
403
  });
366
404
 
405
+ // `RAW_BODY` is a ReadMe-specific thing where we'll interpret its contents as raw JSON.
367
406
  if (typeof cleanBody.RAW_BODY !== 'undefined') {
368
407
  cleanBody = cleanBody.RAW_BODY;
369
408
  }
@@ -378,6 +417,8 @@ module.exports = (
378
417
  }
379
418
  }
380
419
  } catch (e) {
420
+ // you should log this error if you're debugging why data is showing up in text, when it should show up in params
421
+ // console.log('catching ', e);
381
422
  // If anything above fails for whatever reason, assume that whatever we had is invalid JSON and just treat it
382
423
  // as raw text.
383
424
  har.postData.text = stringify(formData.body);
@@ -114,7 +114,7 @@ function handleExplode(value, parameter) {
114
114
  });
115
115
  }
116
116
 
117
- if (typeof value === 'object') {
117
+ if (typeof value === 'object' && value !== null) {
118
118
  const newObj = {};
119
119
 
120
120
  Object.keys(value).forEach(key => {
@@ -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') {