oas-toolkit 0.7.2 → 0.7.4

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/components.js CHANGED
@@ -1,13 +1,36 @@
1
1
  const traverse = require("traverse");
2
- const get = require("lodash.get");
2
+ const isEqual = require("lodash.isequal");
3
3
  const difference = require("lodash.difference");
4
+ const intersection = require("lodash.intersection");
4
5
 
5
6
  function removeUnusedComponents(oas) {
6
7
  const used = getReferencedComponents(oas);
7
8
  const defined = getDefinedComponents(oas);
8
- const unused = getUnusedComponents(defined, used);
9
+ const unused = getUnusedComponents(defined, used, oas);
9
10
 
10
- return removeSpecifiedComponents(oas, unused);
11
+ const result = removeSpecifiedComponents(oas, unused);
12
+
13
+ // If nothing was removed, we've removed all unused components
14
+ // including those referenced by other components that were unused
15
+ if (isEqual(oas, result)) {
16
+ return result;
17
+ }
18
+
19
+ return removeUnusedComponents(result);
20
+ }
21
+
22
+ function getReferencesToComponent(oas, component) {
23
+ return traverse(oas).reduce(function (acc, x) {
24
+ if (
25
+ this.isLeaf &&
26
+ this.key == "$ref" &&
27
+ x == `#/${component.replace(/\./g, "/")}`
28
+ ) {
29
+ acc.push(this.path.slice(0, 3).join("."));
30
+ }
31
+
32
+ return acc;
33
+ }, []);
11
34
  }
12
35
 
13
36
  function removeSpecifiedComponents(oas, unused) {
@@ -67,8 +90,18 @@ function getDefinedComponents(oas) {
67
90
  }, []);
68
91
  }
69
92
 
70
- function getUnusedComponents(all, referenced) {
71
- return difference(all, referenced);
93
+ function getUnusedComponents(all, referenced, oas) {
94
+ const unused = difference(all, referenced);
95
+
96
+ // If we have a component that is only referenced by itself, it's unused
97
+ const used = intersection(all, referenced);
98
+ for (let component of used) {
99
+ const references = getReferencesToComponent(oas, component);
100
+ if (references.length == 1 && references[0] === component) {
101
+ unused.push(component);
102
+ }
103
+ }
104
+ return unused;
72
105
  }
73
106
 
74
107
  module.exports = {
@@ -227,6 +227,139 @@ describe("#components", () => {
227
227
  });
228
228
  });
229
229
 
230
+ it("Removes schemas that are only referenced by removed schemas", () => {
231
+ expect(
232
+ c.removeUnusedComponents({
233
+ info: { title: "One" },
234
+ components: {
235
+ schemas: {
236
+ SubSchema: {
237
+ type: "string",
238
+ },
239
+ MySchema: {
240
+ type: "object",
241
+ properties: {
242
+ subSchema: {
243
+ $ref: "#/components/schemas/SubSchema",
244
+ },
245
+ },
246
+ },
247
+ },
248
+ },
249
+ })
250
+ ).toEqual({
251
+ info: { title: "One" },
252
+ components: {},
253
+ });
254
+ });
255
+
256
+ it("Removes schemas that are circular", () => {
257
+ expect(
258
+ c.removeUnusedComponents({
259
+ info: { title: "One" },
260
+ components: {
261
+ schemas: {
262
+ MySchema: {
263
+ type: "object",
264
+ properties: {
265
+ subSchema: {
266
+ $ref: "#/components/schemas/MySchema",
267
+ },
268
+ },
269
+ },
270
+ },
271
+ },
272
+ })
273
+ ).toEqual({
274
+ info: { title: "One" },
275
+ components: {},
276
+ });
277
+ });
278
+
279
+ it("Does not remove circular schemas that are also referenced elsewhere", () => {
280
+ expect(
281
+ c.removeUnusedComponents({
282
+ info: { title: "One" },
283
+ paths: {
284
+ "/foo": {
285
+ get: {
286
+ responses: {
287
+ 200: {
288
+ content: {
289
+ "application/json": {
290
+ schema: {
291
+ $ref: "#/components/schemas/AnotherSchema",
292
+ },
293
+ },
294
+ },
295
+ },
296
+ },
297
+ },
298
+ },
299
+ },
300
+ components: {
301
+ schemas: {
302
+ MySchema: {
303
+ type: "object",
304
+ properties: {
305
+ subSchema: {
306
+ $ref: "#/components/schemas/MySchema",
307
+ },
308
+ },
309
+ },
310
+ AnotherSchema: {
311
+ type: "object",
312
+ properties: {
313
+ Foo: {
314
+ $ref: "#/components/schemas/MySchema",
315
+ },
316
+ },
317
+ },
318
+ },
319
+ },
320
+ })
321
+ ).toEqual({
322
+ info: { title: "One" },
323
+ paths: {
324
+ "/foo": {
325
+ get: {
326
+ responses: {
327
+ 200: {
328
+ content: {
329
+ "application/json": {
330
+ schema: {
331
+ $ref: "#/components/schemas/AnotherSchema",
332
+ },
333
+ },
334
+ },
335
+ },
336
+ },
337
+ },
338
+ },
339
+ },
340
+ components: {
341
+ schemas: {
342
+ MySchema: {
343
+ type: "object",
344
+ properties: {
345
+ subSchema: {
346
+ $ref: "#/components/schemas/MySchema",
347
+ },
348
+ },
349
+ },
350
+ AnotherSchema: {
351
+ type: "object",
352
+ properties: {
353
+ Foo: {
354
+ $ref: "#/components/schemas/MySchema",
355
+ },
356
+ },
357
+ },
358
+ },
359
+ },
360
+ });
361
+ });
362
+
230
363
  it("removes unused security schemes", () => {
231
364
  const securityOas = {
232
365
  info: { title: "One" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oas-toolkit",
3
- "version": "0.7.2",
3
+ "version": "0.7.4",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -21,6 +21,7 @@
21
21
  "jsonpath-plus": "^7.2.0",
22
22
  "lodash.difference": "^4.5.0",
23
23
  "lodash.get": "^4.4.2",
24
+ "lodash.intersection": "^4.4.0",
24
25
  "lodash.isequal": "^4.5.0",
25
26
  "lodash.uniqwith": "^4.5.0",
26
27
  "mergician": "^1.1.0",