@team-supercharge/oasg 8.0.2 → 9.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,24 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ## [9.1.0](https://gitlab.com/team-supercharge/oasg/compare/v9.0.0...v9.1.0) (2023-02-28)
6
+
7
+
8
+ ### Features
9
+
10
+ * **openapi:** add cleanup steps for openapi target ([01626ca](https://gitlab.com/team-supercharge/oasg/commit/01626ca1454be73afb420310503fd6af3b0164f9))
11
+
12
+ ## [9.0.0](https://gitlab.com/team-supercharge/oasg/compare/v8.0.2...v9.0.0) (2023-02-24)
13
+
14
+
15
+ ### ⚠ BREAKING CHANGES
16
+
17
+ * **spring-kotlin, spring, feign:** skip inline schema reusing by default
18
+
19
+ ### Features
20
+
21
+ * **spring-kotlin, spring, feign:** skip inline schema reusing by default ([c125332](https://gitlab.com/team-supercharge/oasg/commit/c125332cbd59dbd31b2e257060a716950ed3f03a))
22
+
5
23
  ### [8.0.2](https://gitlab.com/team-supercharge/oasg/compare/v8.0.1...v8.0.2) (2023-02-24)
6
24
 
7
25
 
package/README.md CHANGED
@@ -651,6 +651,7 @@ describe('Auth', function () {
651
651
  | bundle | Bundle specification into a single file | N | `true` |
652
652
  | sortSchemas | Sort `components.schemas` alphabetically | N | `true` |
653
653
  | decorators | Array of files for decorator functions | N | `[]` |
654
+ | cleanup | Cleans specification from unused paths, tags and schemas | N | `true` |
654
655
 
655
656
  The target specification is by default bundled into a single file (resolving external dependencies) using the [@redocly/cli package's](https://www.npmjs.com/package/@redocly/cli) `bundle` command.
656
657
 
@@ -668,7 +669,8 @@ Full example with decorators:
668
669
  "fileName": "my-openapi-file.yaml",
669
670
  "bundle": false,
670
671
  "sortSchemas": false,
671
- "decorators": ["decorators/one", "decorators/two"]
672
+ "decorators": ["decorators/one", "decorators/two"],
673
+ "cleanup": false
672
674
  }
673
675
  ```
674
676
 
@@ -684,6 +686,11 @@ function decorate(document) {
684
686
  exports.decorate = decorate;
685
687
  ```
686
688
 
689
+ After the decorators have run, the specification is by default cleaned up (can be turned off by setting the `"cleanup": false` option):
690
+ - `paths` with no methods in them are removed
691
+ - `tags` with no endpoints using them are removed
692
+ - `components` that are unused are removed (only if `bundle` option is also enabled)
693
+
687
694
  ## Template Customization
688
695
 
689
696
  Using the comming `templateDir` config parameter there is a possibility to customize the templates used during generation.
@@ -705,6 +712,66 @@ The **"project level"** customization can be configured using the `templateDir`
705
712
 
706
713
  This section covers the breaking changes and their migrations across major version upgrades.
707
714
 
715
+ ### From `8.x.x` to `9.0.0`
716
+
717
+ #### Skip Reusing Schemas in `spring-kotlin`, `spring` and `feign`
718
+
719
+ The newer versions of OpenAPI Generator adds the flag to skip the [automatic inline schema reusing](https://openapi-generator.tech/docs/customization/#inline-schema-naming) logic (see example what this means below).
720
+
721
+ From _OASg_ 9.0.0 the **default and recommended behaviour is to skip schema reusing** for the targets above. If you wish to resume schema reusing for compatibility reasons, add `--inline-schema-name-defaults SKIP_SCHEMA_REUSE=false` to `generatorCustomArgs` in the project's `config.json`
722
+
723
+ Take the following schema:
724
+
725
+ ```yaml
726
+ schemas:
727
+ Message:
728
+ type: object
729
+ properties: # messages have a topic and text
730
+ topic:
731
+ type: object
732
+ properties: # topics have id and name
733
+ id:
734
+ type: string
735
+ name:
736
+ type: string
737
+ text:
738
+ type: string
739
+
740
+ User:
741
+ type: object
742
+ properties: # users have a company, and firstName and lastName
743
+ company:
744
+ type: object
745
+ properties: # copmanies have id and name
746
+ id:
747
+ type: string
748
+ name:
749
+ type: string
750
+ firstName:
751
+ type: string
752
+ lastName:
753
+ type: string
754
+ ```
755
+
756
+ Previously the following DTO objects were generated from this schema:
757
+
758
+ ```java
759
+ Message(MessageTopic topic, String text)
760
+ MessageTopic(String id, String name)
761
+ User(MessageTopic company, String firstName, String lastName)
762
+ ```
763
+
764
+ Previously the generator reused internal schemas which had the exact same fields, ending up with a `MessageTopic` object for the users' Company, just because both had `id` and `name` string properties.
765
+
766
+ With defining `SKIP_SCHEMA_REUSE=true` the output will be more verbose, but schema names won't get mixed up:
767
+
768
+ ```java
769
+ Message(MessageTopic topic, String text)
770
+ MessageTopic(String id, String name)
771
+ User(UserCompany company, String firstName, String lastName)
772
+ UserCompany(String id, String name)
773
+ ```
774
+
708
775
  ### From `7.x.x` to `8.0.0`
709
776
 
710
777
  #### Linting
@@ -4,6 +4,10 @@ const SwaggerParser = require("@apidevtools/swagger-parser");
4
4
  const { dump } = require(`${__dirname}/dump.js`);
5
5
  const { exec } = require(`${__dirname}/exec.js`);
6
6
 
7
+ function bundleSpec(source, target, remove) {
8
+ exec(`npx redocly bundle ${source} --keep-url-references${remove ? ' --remove-unused-components' : ''} --output ${target}`, 'pipe');
9
+ }
10
+
7
11
  async function openApiTarget(target, source, version) {
8
12
  const outDir = `out/${target.id}`;
9
13
  let outFile = target.fileName || `openapi.yaml`;
@@ -17,7 +21,7 @@ async function openApiTarget(target, source, version) {
17
21
  // bundle spec to a single file by default
18
22
  const bundle = target.bundle === undefined || target.bundle;
19
23
  if (bundle) {
20
- exec(`npx redocly bundle ${source} --keep-url-references --output ${outFile}`, 'pipe');
24
+ bundleSpec(source, outFile, false);
21
25
  console.log(`bundled specification`);
22
26
  }
23
27
 
@@ -58,8 +62,68 @@ async function openApiTarget(target, source, version) {
58
62
  console.log(`applied decorator '${decoratorFile}'`);
59
63
  });
60
64
 
65
+ // clean up unused things
66
+ const cleanup = target.cleanup === undefined || target.cleanup;
67
+ if (cleanup) {
68
+ const removedPaths = [];
69
+ const removedTags = [];
70
+ const usedTags = [];
71
+
72
+ // remove empty paths & gather tags
73
+ const paths = document.paths;
74
+ for (const pathKey in paths) {
75
+ const path = document.paths[pathKey];
76
+
77
+ if (Object.keys(path).length === 0) {
78
+ removedPaths.push(pathKey);
79
+ delete paths[pathKey];
80
+ }
81
+
82
+ for (const methodKey in path) {
83
+ const operation = path[methodKey];
84
+
85
+ operation.tags.forEach(tag => {
86
+ if (!usedTags.includes(tag)) {
87
+ usedTags.push(tag);
88
+ }
89
+ });
90
+ }
91
+ }
92
+
93
+ if (removedPaths.length !== 0) {
94
+ console.log(`cleaned up unused paths:\n ${removedPaths.join('\n ')}`);
95
+ }
96
+
97
+ // remouve unused tags
98
+ const tags = [...document.tags];
99
+ tags.forEach(tag => {
100
+ if (!usedTags.includes(tag.name)) {
101
+ removedTags.push(tag.name);
102
+ document.tags.splice(document.tags.indexOf(tag), 1);
103
+ }
104
+ });
105
+
106
+ if (removedTags.length !== 0) {
107
+ console.log(`cleaned up unused tags:\n ${removedTags.join('\n ')}`);
108
+ }
109
+ }
110
+
61
111
  // write file
62
112
  dump(document, outFile);
113
+
114
+ // re-bundle to remove unused components
115
+ if (cleanup && bundle) {
116
+ console.log(`re-bundling specification to remove unused components`);
117
+ let currentSize;
118
+ let bundledSize;
119
+ do {
120
+ currentSize = fs.statSync(outFile).size;
121
+ bundleSpec(outFile, outFile, true);
122
+ console.log('.');
123
+ bundledSize = fs.statSync(outFile).size;
124
+ }
125
+ while (bundledSize !== currentSize)
126
+ }
63
127
  }
64
128
 
65
129
  exports.openApiTarget = openApiTarget;
package/config.schema.yml CHANGED
@@ -302,6 +302,8 @@ targets:
302
302
  type: array
303
303
  items:
304
304
  type: string
305
+ cleanup:
306
+ type: boolean
305
307
 
306
308
  definitions:
307
309
  # default
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@team-supercharge/oasg",
3
- "version": "8.0.2",
3
+ "version": "9.1.0",
4
4
  "description": "Node-based tool to lint OpenAPI documents and generate clients, servers and documentation from them",
5
5
  "author": "Supercharge",
6
6
  "license": "MIT",
@@ -19,6 +19,7 @@
19
19
  },
20
20
  "inlineSchemaNameDefaults": {
21
21
  "arrayItemSuffix": "",
22
- "mapItemSuffix": ""
22
+ "mapItemSuffix": "",
23
+ "SKIP_SCHEMA_REUSE": "true"
23
24
  }
24
25
  }
@@ -20,6 +20,7 @@
20
20
  },
21
21
  "inlineSchemaNameDefaults": {
22
22
  "arrayItemSuffix": "",
23
- "mapItemSuffix": ""
23
+ "mapItemSuffix": "",
24
+ "SKIP_SCHEMA_REUSE": "true"
24
25
  }
25
26
  }
@@ -20,6 +20,7 @@
20
20
  },
21
21
  "inlineSchemaNameDefaults": {
22
22
  "arrayItemSuffix": "",
23
- "mapItemSuffix": ""
23
+ "mapItemSuffix": "",
24
+ "SKIP_SCHEMA_REUSE": "true"
24
25
  }
25
26
  }