@amartus/oas-utils 0.1.0 → 0.3.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/README.md +135 -5
- package/dist/cli.js +52 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/allOfToOneOf.d.ts +23 -0
- package/dist/lib/allOfToOneOf.d.ts.map +1 -0
- package/dist/lib/allOfToOneOf.js +189 -0
- package/dist/lib/allOfToOneOf.js.map +1 -0
- package/dist/lib/cleanupDiscriminatorMappings.d.ts +21 -0
- package/dist/lib/cleanupDiscriminatorMappings.d.ts.map +1 -0
- package/dist/lib/cleanupDiscriminatorMappings.js +64 -0
- package/dist/lib/cleanupDiscriminatorMappings.js.map +1 -0
- package/dist/lib/cliActions.d.ts +37 -2
- package/dist/lib/cliActions.d.ts.map +1 -1
- package/dist/lib/cliActions.js +108 -12
- package/dist/lib/cliActions.js.map +1 -1
- package/dist/lib/oasUtils.d.ts +27 -0
- package/dist/lib/oasUtils.d.ts.map +1 -1
- package/dist/lib/oasUtils.js +92 -0
- package/dist/lib/oasUtils.js.map +1 -1
- package/dist/lib/removeFromOneOfByName.d.ts +1 -0
- package/dist/lib/removeFromOneOfByName.d.ts.map +1 -1
- package/dist/lib/removeFromOneOfByName.js +10 -48
- package/dist/lib/removeFromOneOfByName.js.map +1 -1
- package/dist/lib/schemaTransformUtils.d.ts +83 -0
- package/dist/lib/schemaTransformUtils.d.ts.map +1 -0
- package/dist/lib/schemaTransformUtils.js +192 -0
- package/dist/lib/schemaTransformUtils.js.map +1 -0
- package/dist/lib/sealSchema.d.ts +22 -0
- package/dist/lib/sealSchema.d.ts.map +1 -0
- package/dist/lib/sealSchema.js +354 -0
- package/dist/lib/sealSchema.js.map +1 -0
- package/dist/redocly/allof-to-oneof-decorator.d.ts +6 -0
- package/dist/redocly/allof-to-oneof-decorator.d.ts.map +1 -0
- package/dist/redocly/allof-to-oneof-decorator.js +15 -0
- package/dist/redocly/allof-to-oneof-decorator.js.map +1 -0
- package/dist/redocly/cleanup-discriminator-decorator.d.ts +6 -0
- package/dist/redocly/cleanup-discriminator-decorator.d.ts.map +1 -0
- package/dist/redocly/cleanup-discriminator-decorator.js +17 -0
- package/dist/redocly/cleanup-discriminator-decorator.js.map +1 -0
- package/dist/redocly/plugin.d.ts +9 -0
- package/dist/redocly/plugin.d.ts.map +1 -1
- package/dist/redocly/plugin.js +9 -0
- package/dist/redocly/plugin.js.map +1 -1
- package/dist/redocly/seal-schema-decorator.d.ts +6 -0
- package/dist/redocly/seal-schema-decorator.d.ts.map +1 -0
- package/dist/redocly/seal-schema-decorator.js +13 -0
- package/dist/redocly/seal-schema-decorator.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# oas-utils
|
|
2
2
|
|
|
3
|
-
Utilities for working with OpenAPI (OAS) documents. Includes tools to remove unused schemas
|
|
3
|
+
Utilities for working with OpenAPI (OAS) documents. Includes tools to remove unused schemas, remove entries from oneOf, optimize allOf composition, convert allOf + discriminator patterns to oneOf + discriminator, and clean up discriminator mappings. Use them as a CLI or as Redocly decorators.
|
|
4
4
|
|
|
5
5
|
## Definition of "unused schema"
|
|
6
6
|
|
|
@@ -26,6 +26,8 @@ This makes the `oas-utils` CLI available system-wide.
|
|
|
26
26
|
|
|
27
27
|
## CLI usage
|
|
28
28
|
|
|
29
|
+
### remove-unused
|
|
30
|
+
|
|
29
31
|
```
|
|
30
32
|
oas-utils remove-unused <input.yaml> -o output.yaml [--keep Name1 Name2] [--aggressive] [--ignore-parents NameX]
|
|
31
33
|
# Read from stdin and write to stdout
|
|
@@ -37,6 +39,8 @@ Options:
|
|
|
37
39
|
- --aggressive: also prune other unused components referenced from paths (responses, headers, requestBodies, parameters, examples, links, callbacks, securitySchemes). Non-referenced entries in these sections are removed.
|
|
38
40
|
- --ignore-parents: schema names that shouldn't promote children via allOf (can be repeated). Useful to avoid allOf upward inclusion when the parent acts as an abstract/base.
|
|
39
41
|
|
|
42
|
+
### remove-oneof
|
|
43
|
+
|
|
40
44
|
Remove entries from oneOf and update discriminators:
|
|
41
45
|
|
|
42
46
|
```
|
|
@@ -47,11 +51,109 @@ oas-utils remove-oneof <input.yaml> --remove Cat
|
|
|
47
51
|
oas-utils remove-oneof <input.yaml> --parent Pet --remove Cat --guess
|
|
48
52
|
```
|
|
49
53
|
|
|
50
|
-
Options
|
|
54
|
+
Options:
|
|
51
55
|
- --parent: parent schema name containing oneOf; if omitted, removal is global across the document.
|
|
52
56
|
- --remove: schema name(s) to remove; can be repeated.
|
|
53
57
|
- --guess: expand each name to include variants starting with `<name>_`.
|
|
54
58
|
|
|
59
|
+
### optimize-allof
|
|
60
|
+
|
|
61
|
+
Optimize allOf composition by removing redundant references:
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
oas-utils optimize-allof <input.yaml> -o output.yaml
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Options:
|
|
68
|
+
- -o, --output: write result to this file (defaults to stdout).
|
|
69
|
+
|
|
70
|
+
### allof-to-oneof
|
|
71
|
+
|
|
72
|
+
Convert allOf + discriminator patterns to oneOf + discriminator. This is useful for transforming inheritance-based polymorphic schemas into composition-based ones.
|
|
73
|
+
|
|
74
|
+
Specifically, it:
|
|
75
|
+
1. Identifies base schemas with discriminators
|
|
76
|
+
2. Finds concrete schemas that extend the base via allOf
|
|
77
|
+
3. Optionally adds a const property to each concrete schema matching its discriminator value (enabled by default)
|
|
78
|
+
4. Creates a new oneOf wrapper schema containing all concrete types
|
|
79
|
+
5. Replaces references to the base schema with the wrapper schema (in polymorphic contexts)
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
oas-utils allof-to-oneof <input.yaml> -o output.yaml
|
|
83
|
+
# Optionally remove discriminator from base schema
|
|
84
|
+
oas-utils allof-to-oneof <input.yaml> -o output.yaml --remove-discriminator-from-base
|
|
85
|
+
# Optionally skip adding const to specialization schemas
|
|
86
|
+
oas-utils allof-to-oneof <input.yaml> -o output.yaml --no-add-discriminator-const
|
|
87
|
+
# Optionally skip transformation if only one specialization is found
|
|
88
|
+
oas-utils allof-to-oneof <input.yaml> -o output.yaml --ignore-single-specialization
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Options:
|
|
92
|
+
- -o, --output: write result to this file (defaults to stdout).
|
|
93
|
+
- --remove-discriminator-from-base: remove the discriminator from base schemas after conversion.
|
|
94
|
+
- --no-add-discriminator-const: do not add const property with discriminator value to specialization schemas.
|
|
95
|
+
- --ignore-single-specialization: skip oneOf transformation if only one specialization is found (useful for bases with only one concrete implementation).
|
|
96
|
+
|
|
97
|
+
Example transformation (with addDiscriminatorConst enabled, the default):
|
|
98
|
+
- Base schema `Animal` with discriminator `type` and mapping `{Cat: ..., Dog: ...}`
|
|
99
|
+
- Concrete schemas `Cat` and `Dog` with `allOf: [{$ref: Animal}, {...}]`
|
|
100
|
+
- Creates `AnimalPolymorphic` with `oneOf: [Cat, Dog]` and the same discriminator
|
|
101
|
+
- Adds `type: {const: "Cat"}` to Cat's properties and `type: {const: "Dog"}` to Dog's properties
|
|
102
|
+
- Replaces references to `Animal` with `AnimalPolymorphic` in array items and other polymorphic contexts
|
|
103
|
+
|
|
104
|
+
### cleanup-discriminators
|
|
105
|
+
|
|
106
|
+
Clean up discriminator mappings by removing entries that reference non-existent schemas. This is useful when schemas are removed but discriminator mappings are not updated, leaving dangling references.
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
oas-utils cleanup-discriminators <input.yaml> -o output.yaml
|
|
110
|
+
# Read from stdin and write to stdout
|
|
111
|
+
cat openapi.yaml | oas-utils cleanup-discriminators > cleaned.yaml
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Options:
|
|
115
|
+
- -o, --output: write result to this file (defaults to stdout).
|
|
116
|
+
|
|
117
|
+
Example:
|
|
118
|
+
- Original discriminator mapping: `{cat: '#/components/schemas/Cat', dog: '#/components/schemas/Dog', bird: '#/components/schemas/Bird'}`
|
|
119
|
+
- After removing `Bird` schema: mapping entries `bird` is invalid
|
|
120
|
+
- After cleanup: `{cat: '#/components/schemas/Cat', dog: '#/components/schemas/Dog'}`
|
|
121
|
+
|
|
122
|
+
### seal-schema
|
|
123
|
+
|
|
124
|
+
Seal object schemas to prevent additional properties. This ensures every final object shape exposed in the API is sealed (no additional properties allowed), without breaking schemas that are extended via `allOf`.
|
|
125
|
+
|
|
126
|
+
The algorithm:
|
|
127
|
+
1. Identifies schemas that are bases for extension (referenced in `allOf`)
|
|
128
|
+
2. For each such schema, creates a `Core` variant and a sealed wrapper
|
|
129
|
+
3. Rewrites `allOf` references to point to `Core` variants (allowing extension)
|
|
130
|
+
4. Seals composition roots (`allOf`, `anyOf`, `oneOf`) and direct-use schemas
|
|
131
|
+
|
|
132
|
+
This ensures:
|
|
133
|
+
- **Objects used directly** in fields or arrays are fully sealed
|
|
134
|
+
- **Objects used as bases** for extension remain unsealed internally but are sealed at the wrapper level
|
|
135
|
+
- **anyOf/oneOf compositions** remain valid alternatives and are sealed at the outer level
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
oas-utils seal-schema <input.yaml> -o output.yaml
|
|
139
|
+
# Use unevaluatedProperties: false (default, recommended for JSON Schema 2019-09+)
|
|
140
|
+
oas-utils seal-schema <input.yaml> -o output.yaml --use-unevaluated-properties
|
|
141
|
+
# Use additionalProperties: false instead
|
|
142
|
+
oas-utils seal-schema <input.yaml> -o output.yaml --use-additional-properties
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Options:
|
|
146
|
+
- -o, --output: write result to this file (defaults to stdout).
|
|
147
|
+
- --use-unevaluated-properties: use `unevaluatedProperties: false` (default, better for JSON Schema 2019-09+).
|
|
148
|
+
- --use-additional-properties: use `additionalProperties: false` instead.
|
|
149
|
+
|
|
150
|
+
Example transformation:
|
|
151
|
+
- Original `Animal` schema (object-like, referenced in `allOf` by `Cat`)
|
|
152
|
+
- Becomes: `AnimalCore` (unsealed original) + `Animal` wrapper with `allOf: [{$ref: AnimalCore}]` and `unevaluatedProperties: false`
|
|
153
|
+
- `Cat` now uses `allOf: [{$ref: AnimalCore}, {...}]` allowing safe extension
|
|
154
|
+
- Direct references to `Animal` point to the sealed wrapper
|
|
155
|
+
- Inline objects and composition roots are sealed with appropriate keywords
|
|
156
|
+
|
|
55
157
|
## As Redocly decorators
|
|
56
158
|
|
|
57
159
|
1) Add the plugin to `plugins` in your `redocly.yaml` (path relative to the config):
|
|
@@ -61,7 +163,7 @@ plugins:
|
|
|
61
163
|
- ./node_modules/oas-utils/dist/redocly/plugin.js
|
|
62
164
|
```
|
|
63
165
|
|
|
64
|
-
2) Enable the
|
|
166
|
+
2) Enable the decorators:
|
|
65
167
|
|
|
66
168
|
```
|
|
67
169
|
decorators:
|
|
@@ -75,6 +177,22 @@ decorators:
|
|
|
75
177
|
parent: Pet # optional; if omitted, removal is global
|
|
76
178
|
remove: [Cat, Cat_variant1]
|
|
77
179
|
guess: false
|
|
180
|
+
|
|
181
|
+
# Optimize allOf composition
|
|
182
|
+
oas-utils/optimize-allof: {}
|
|
183
|
+
|
|
184
|
+
# Convert allOf + discriminator to oneOf + discriminator
|
|
185
|
+
oas-utils/allof-to-oneof:
|
|
186
|
+
removeDiscriminatorFromBase: false
|
|
187
|
+
addDiscriminatorConst: true
|
|
188
|
+
ignoreSingleSpecialization: false
|
|
189
|
+
|
|
190
|
+
# Clean up discriminator mappings
|
|
191
|
+
oas-utils/cleanup-discriminators: {}
|
|
192
|
+
|
|
193
|
+
# Seal object schemas
|
|
194
|
+
oas-utils/seal-schema:
|
|
195
|
+
useUnevaluatedProperties: true
|
|
78
196
|
```
|
|
79
197
|
|
|
80
198
|
3) Run bundling with Redocly CLI and the decorators will apply the transformations. With `aggressive: true`, unused non-schema components (responses, headers, requestBodies, etc.) are removed as well.
|
|
@@ -85,8 +203,20 @@ Notes:
|
|
|
85
203
|
## Programmatic usage
|
|
86
204
|
|
|
87
205
|
```
|
|
88
|
-
import { removeUnusedSchemas } from 'oas-utils';
|
|
89
|
-
|
|
206
|
+
import { removeUnusedSchemas, allOfToOneOf, sealSchema, cleanupDiscriminatorMappings } from 'oas-utils';
|
|
207
|
+
|
|
208
|
+
// Remove unused schemas
|
|
209
|
+
removeUnusedSchemas(doc, { keep: ['CommonError'], aggressive: true });
|
|
210
|
+
|
|
211
|
+
// Convert allOf + discriminator to oneOf + discriminator
|
|
212
|
+
allOfToOneOf(doc, { removeDiscriminatorFromBase: false, addDiscriminatorConst: true });
|
|
213
|
+
|
|
214
|
+
// Clean up discriminator mappings
|
|
215
|
+
const result = cleanupDiscriminatorMappings(doc);
|
|
216
|
+
console.log(`Removed ${result.mappingsRemoved} invalid mappings from ${result.schemasChecked} schemas`);
|
|
217
|
+
|
|
218
|
+
// Seal object schemas
|
|
219
|
+
sealSchema(doc, { useUnevaluatedProperties: true });
|
|
90
220
|
```
|
|
91
221
|
|
|
92
222
|
## Notes
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import fs from "node:fs/promises";
|
|
3
3
|
import { Command } from "commander";
|
|
4
|
-
import { runRemoveUnused, runRemoveOneOf, optimizeAllOf } from "./lib/cliActions.js";
|
|
4
|
+
import { runRemoveUnused, runRemoveOneOf, optimizeAllOf, runAllOfToOneOf, runSealSchema, runCleanupDiscriminators } from "./lib/cliActions.js";
|
|
5
5
|
import YAML from "yaml";
|
|
6
6
|
const program = new Command();
|
|
7
7
|
program
|
|
@@ -49,6 +49,57 @@ program
|
|
|
49
49
|
.action(async (input, opts) => {
|
|
50
50
|
await optimizeAllOf(opts, format, () => reader(input));
|
|
51
51
|
});
|
|
52
|
+
program
|
|
53
|
+
.command("allof-to-oneof")
|
|
54
|
+
.showHelpAfterError()
|
|
55
|
+
.description("Convert allOf + discriminator patterns to oneOf + discriminator")
|
|
56
|
+
.argument("[input]", "Path to input OpenAPI file (YAML or JSON). If omitted, reads from stdin")
|
|
57
|
+
.option("-o, --output <file>", "Write result to this file (defaults to stdout)")
|
|
58
|
+
.option("--remove-discriminator-from-base", "Remove discriminator from base schemas after conversion", false)
|
|
59
|
+
.option("--no-add-discriminator-const", "Do not add const property with discriminator value to specialization schemas", true)
|
|
60
|
+
.option("--ignore-single-specialization", "Skip oneOf transformation if only one specialization is found", false)
|
|
61
|
+
.action(async (input, opts) => {
|
|
62
|
+
try {
|
|
63
|
+
await runAllOfToOneOf(opts, format, () => reader(input));
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
console.error(`Error: ${err?.message || String(err)}`);
|
|
67
|
+
process.exitCode = 1;
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
program
|
|
71
|
+
.command("seal-schema")
|
|
72
|
+
.showHelpAfterError()
|
|
73
|
+
.description("Seal object schemas to prevent additional properties")
|
|
74
|
+
.argument("[input]", "Path to input OpenAPI file (YAML or JSON). If omitted, reads from stdin")
|
|
75
|
+
.option("-o, --output <file>", "Write result to this file (defaults to stdout)")
|
|
76
|
+
.option("--use-unevaluated-properties", "Use unevaluatedProperties: false instead of additionalProperties: false (default: true)", true)
|
|
77
|
+
.option("--use-additional-properties", "Use additionalProperties: false instead of unevaluatedProperties: false", false)
|
|
78
|
+
.action(async (input, opts) => {
|
|
79
|
+
try {
|
|
80
|
+
const useUnevaluated = !opts.useAdditionalProperties;
|
|
81
|
+
await runSealSchema({ output: opts.output, useUnevaluatedProperties: useUnevaluated }, format, () => reader(input));
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
console.error(`Error: ${err?.message || String(err)}`);
|
|
85
|
+
process.exitCode = 1;
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
program
|
|
89
|
+
.command("cleanup-discriminators")
|
|
90
|
+
.showHelpAfterError()
|
|
91
|
+
.description("Clean up discriminator mappings by removing references to non-existent schemas")
|
|
92
|
+
.argument("[input]", "Path to input OpenAPI file (YAML or JSON). If omitted, reads from stdin")
|
|
93
|
+
.option("-o, --output <file>", "Write result to this file (defaults to stdout)")
|
|
94
|
+
.action(async (input, opts) => {
|
|
95
|
+
try {
|
|
96
|
+
await runCleanupDiscriminators(opts, format, () => reader(input));
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
console.error(`Error: ${err?.message || String(err)}`);
|
|
100
|
+
process.exitCode = 1;
|
|
101
|
+
}
|
|
102
|
+
});
|
|
52
103
|
if (process.argv.length <= 2) {
|
|
53
104
|
program.help();
|
|
54
105
|
}
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
export * from './lib/removeUnusedSchemas.js';
|
|
2
2
|
export * from './lib/removeFromOneOfByName.js';
|
|
3
3
|
export * from './lib/optimizeAllOfComposition.js';
|
|
4
|
+
export * from './lib/allOfToOneOf.js';
|
|
5
|
+
export * from './lib/sealSchema.js';
|
|
6
|
+
export * from './lib/oasUtils.js';
|
|
7
|
+
export * from './lib/cleanupDiscriminatorMappings.js';
|
|
8
|
+
export * from './lib/schemaTransformUtils.js';
|
|
4
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mCAAmC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mCAAmC,CAAC;AAClD,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
export * from './lib/removeUnusedSchemas.js';
|
|
2
2
|
export * from './lib/removeFromOneOfByName.js';
|
|
3
3
|
export * from './lib/optimizeAllOfComposition.js';
|
|
4
|
+
export * from './lib/allOfToOneOf.js';
|
|
5
|
+
export * from './lib/sealSchema.js';
|
|
6
|
+
export * from './lib/oasUtils.js';
|
|
7
|
+
export * from './lib/cleanupDiscriminatorMappings.js';
|
|
8
|
+
export * from './lib/schemaTransformUtils.js';
|
|
4
9
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mCAAmC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mCAAmC,CAAC;AAClD,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface AllOfToOneOfOptions {
|
|
2
|
+
/** If true, remove discriminator from base schema and let oneOf wrapper handle it */
|
|
3
|
+
removeDiscriminatorFromBase?: boolean;
|
|
4
|
+
/** If true, add const property with discriminator value to specialization schemas (default: true) */
|
|
5
|
+
addDiscriminatorConst?: boolean;
|
|
6
|
+
/** If true, skip oneOf transformation if only one specialization is found (default: false) */
|
|
7
|
+
ignoreSingleSpecialization?: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Convert allOf + discriminator patterns to oneOf + discriminator.
|
|
11
|
+
*
|
|
12
|
+
* This operation:
|
|
13
|
+
* 1. Finds base schemas with discriminators
|
|
14
|
+
* 2. Identifies concrete schemas that extend the base via allOf
|
|
15
|
+
* 3. For each concrete schema, adds a const property matching the discriminator value
|
|
16
|
+
* 4. Creates a new oneOf wrapper schema containing all concrete schemas
|
|
17
|
+
* 5. Replaces all references to the base schema with the wrapper schema (where polymorphism is used)
|
|
18
|
+
*
|
|
19
|
+
* @param doc - OpenAPI document to transform
|
|
20
|
+
* @param opts - Optional configuration
|
|
21
|
+
*/
|
|
22
|
+
export declare function allOfToOneOf(doc: any, opts?: AllOfToOneOfOptions): any;
|
|
23
|
+
//# sourceMappingURL=allOfToOneOf.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allOfToOneOf.d.ts","sourceRoot":"","sources":["../../src/lib/allOfToOneOf.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,mBAAmB;IAClC,qFAAqF;IACrF,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC,qGAAqG;IACrG,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,8FAA8F;IAC9F,0BAA0B,CAAC,EAAE,OAAO,CAAC;CACtC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,GAAE,mBAAwB,GAAG,GAAG,CAmF1E"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { refToName, buildInheritanceGraph } from "./oasUtils.js";
|
|
2
|
+
/**
|
|
3
|
+
* Convert allOf + discriminator patterns to oneOf + discriminator.
|
|
4
|
+
*
|
|
5
|
+
* This operation:
|
|
6
|
+
* 1. Finds base schemas with discriminators
|
|
7
|
+
* 2. Identifies concrete schemas that extend the base via allOf
|
|
8
|
+
* 3. For each concrete schema, adds a const property matching the discriminator value
|
|
9
|
+
* 4. Creates a new oneOf wrapper schema containing all concrete schemas
|
|
10
|
+
* 5. Replaces all references to the base schema with the wrapper schema (where polymorphism is used)
|
|
11
|
+
*
|
|
12
|
+
* @param doc - OpenAPI document to transform
|
|
13
|
+
* @param opts - Optional configuration
|
|
14
|
+
*/
|
|
15
|
+
export function allOfToOneOf(doc, opts = {}) {
|
|
16
|
+
if (!doc || typeof doc !== "object")
|
|
17
|
+
return doc;
|
|
18
|
+
const schemas = doc.components?.schemas;
|
|
19
|
+
if (!schemas || typeof schemas !== "object")
|
|
20
|
+
return doc;
|
|
21
|
+
// Step 1: Find all base schemas with discriminators
|
|
22
|
+
const baseSchemasWithDiscriminator = new Map();
|
|
23
|
+
for (const [name, schema] of Object.entries(schemas)) {
|
|
24
|
+
if (schema && typeof schema === "object" && schema.discriminator) {
|
|
25
|
+
const disc = schema.discriminator;
|
|
26
|
+
if (disc.propertyName && disc.mapping && typeof disc.mapping === "object") {
|
|
27
|
+
baseSchemasWithDiscriminator.set(name, {
|
|
28
|
+
propertyName: disc.propertyName,
|
|
29
|
+
mapping: { ...disc.mapping }
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (baseSchemasWithDiscriminator.size === 0) {
|
|
35
|
+
return doc; // Nothing to convert
|
|
36
|
+
}
|
|
37
|
+
// Step 2: For each base schema with discriminator, find concrete types extending it
|
|
38
|
+
const inheritanceGraph = buildInheritanceGraph(schemas);
|
|
39
|
+
const polymorphicWrappers = new Map();
|
|
40
|
+
for (const [baseName, discInfo] of baseSchemasWithDiscriminator.entries()) {
|
|
41
|
+
const concreteSchemas = Array.from(inheritanceGraph.get(baseName) || []);
|
|
42
|
+
if (opts.ignoreSingleSpecialization && concreteSchemas.length === 1) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (concreteSchemas.length > 0) {
|
|
46
|
+
const wrapperName = `${baseName}Polymorphic`;
|
|
47
|
+
polymorphicWrappers.set(baseName, { name: wrapperName, concreteSchemas });
|
|
48
|
+
// Step 3: For each concrete schema, optionally add const property for discriminator
|
|
49
|
+
if (opts.addDiscriminatorConst !== false) {
|
|
50
|
+
const cS = Object.fromEntries(concreteSchemas.map(name => [name, schemas[name]]));
|
|
51
|
+
addDiscriminatorConstToConcreteSchemas(cS, discInfo);
|
|
52
|
+
}
|
|
53
|
+
// Step 4: Create wrapper schema with oneOf
|
|
54
|
+
const wrapperSchema = {
|
|
55
|
+
oneOf: concreteSchemas.map(name => ({ $ref: `#/components/schemas/${name}` })),
|
|
56
|
+
discriminator: {
|
|
57
|
+
propertyName: discInfo.propertyName,
|
|
58
|
+
mapping: discInfo.mapping
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
// If available, preserve description from base
|
|
62
|
+
const baseSchema = schemas[baseName];
|
|
63
|
+
if (baseSchema && baseSchema.description) {
|
|
64
|
+
wrapperSchema.description = `OneOf polymorphic ${baseName}. Use the "${discInfo.propertyName}" property to identify the concrete schema.`;
|
|
65
|
+
}
|
|
66
|
+
schemas[wrapperName] = wrapperSchema;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Step 5: Replace references to base schemas with wrapper schemas where polymorphism is used
|
|
70
|
+
// We need to find where base schemas are referenced and check if they're used polymorphically
|
|
71
|
+
for (const [baseName, wrapperInfo] of polymorphicWrappers.entries()) {
|
|
72
|
+
replacePolymorhicReferences(schemas, baseName, wrapperInfo.name);
|
|
73
|
+
}
|
|
74
|
+
// Step 6: Optionally remove discriminator from base schemas
|
|
75
|
+
if (opts.removeDiscriminatorFromBase) {
|
|
76
|
+
for (const baseName of baseSchemasWithDiscriminator.keys()) {
|
|
77
|
+
if (schemas[baseName] && polymorphicWrappers.has(baseName)) {
|
|
78
|
+
delete schemas[baseName].discriminator;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return doc;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Replace references to a polymorphic base schema with references to its wrapper,
|
|
86
|
+
* but only in contexts where polymorphism would be used (e.g., in array items).
|
|
87
|
+
* Excludes references within concrete schemas' direct allOf references.
|
|
88
|
+
*/
|
|
89
|
+
function replacePolymorhicReferences(schemas, baseName, wrapperName) {
|
|
90
|
+
const baseRef = `#/components/schemas/${baseName}`;
|
|
91
|
+
const wrapperRef = `#/components/schemas/${wrapperName}`;
|
|
92
|
+
for (const schema of Object.values(schemas)) {
|
|
93
|
+
if (!schema || typeof schema !== "object")
|
|
94
|
+
continue;
|
|
95
|
+
replaceInSchema(schema, baseRef, wrapperRef, true);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Recursively replace $ref in a schema, particularly in polymorphic contexts like array items.
|
|
100
|
+
* When skipAllOfReplacement=true, skip replacing $ref directly within allOf arrays.
|
|
101
|
+
*/
|
|
102
|
+
function replaceInSchema(node, oldRef, newRef, skipDirectAllOfRefs = false) {
|
|
103
|
+
if (!node || typeof node !== "object")
|
|
104
|
+
return;
|
|
105
|
+
if (Array.isArray(node)) {
|
|
106
|
+
for (const item of node) {
|
|
107
|
+
if (item && typeof item === "object") {
|
|
108
|
+
if (item.$ref === oldRef) {
|
|
109
|
+
// Don't replace direct $ref in allOf when flag is set
|
|
110
|
+
if (skipDirectAllOfRefs) {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
item.$ref = newRef;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
replaceInSchema(item, oldRef, newRef, skipDirectAllOfRefs);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
// For object properties, replace all $ref occurrences
|
|
123
|
+
for (const [key, value] of Object.entries(node)) {
|
|
124
|
+
if (value && typeof value === "object") {
|
|
125
|
+
// Special handling for allOf: skip direct $ref replacements
|
|
126
|
+
if (skipDirectAllOfRefs && key === "allOf" && Array.isArray(value)) {
|
|
127
|
+
for (const item of value) {
|
|
128
|
+
if (item && typeof item === "object" && item.$ref !== oldRef) {
|
|
129
|
+
replaceInSchema(item, oldRef, newRef, skipDirectAllOfRefs);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
if (value.$ref === oldRef) {
|
|
135
|
+
value.$ref = newRef;
|
|
136
|
+
}
|
|
137
|
+
replaceInSchema(value, oldRef, newRef, skipDirectAllOfRefs);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Add const constraint to each concrete schema matching the discriminator value.
|
|
143
|
+
* Avoids duplicates by checking if the const constraint already exists.
|
|
144
|
+
*
|
|
145
|
+
* @param schemas - Concrete schemas extending a base with discriminator (name -> schema)
|
|
146
|
+
* @param discInfo - Discriminator info (propertyName, mapping)
|
|
147
|
+
*/
|
|
148
|
+
function addDiscriminatorConstToConcreteSchemas(schemas, discInfo) {
|
|
149
|
+
// Iterate through concrete schemas by name
|
|
150
|
+
for (const [concreteName, concreteSchema] of Object.entries(schemas)) {
|
|
151
|
+
if (!concreteSchema)
|
|
152
|
+
continue;
|
|
153
|
+
// Find the discriminator value for this concrete schema
|
|
154
|
+
let discriminatorValue;
|
|
155
|
+
for (const [value, ref] of Object.entries(discInfo.mapping)) {
|
|
156
|
+
if (typeof ref === "string" && refToName(ref) === concreteName) {
|
|
157
|
+
discriminatorValue = value;
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (discriminatorValue) {
|
|
162
|
+
// Ensure allOf exists
|
|
163
|
+
if (!Array.isArray(concreteSchema.allOf)) {
|
|
164
|
+
concreteSchema.allOf = [];
|
|
165
|
+
}
|
|
166
|
+
// Check if const constraint already exists for this schema
|
|
167
|
+
const constExists = concreteSchema.allOf.some((item) => item &&
|
|
168
|
+
typeof item === "object" &&
|
|
169
|
+
item.type === "object" &&
|
|
170
|
+
item.properties &&
|
|
171
|
+
item.properties[discInfo.propertyName] &&
|
|
172
|
+
item.properties[discInfo.propertyName].const === discriminatorValue);
|
|
173
|
+
// Only add const if it doesn't already exist
|
|
174
|
+
if (!constExists) {
|
|
175
|
+
// Add const as a separate allOf constraint (not merged with existing inline objects)
|
|
176
|
+
const constConstraint = {
|
|
177
|
+
type: "object",
|
|
178
|
+
properties: {
|
|
179
|
+
[discInfo.propertyName]: {
|
|
180
|
+
const: discriminatorValue
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
concreteSchema.allOf.push(constConstraint);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=allOfToOneOf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allOfToOneOf.js","sourceRoot":"","sources":["../../src/lib/allOfToOneOf.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cleans up discriminator mappings by removing entries that point to non-existent schemas.
|
|
3
|
+
*
|
|
4
|
+
* This function:
|
|
5
|
+
* 1. Iterates through all schemas looking for discriminator definitions
|
|
6
|
+
* 2. For each discriminator mapping entry, checks if the referenced schema exists
|
|
7
|
+
* 3. Removes mapping entries that reference undefined schemas
|
|
8
|
+
* 4. Returns count of cleaned mappings for reporting
|
|
9
|
+
*
|
|
10
|
+
* @param doc - OpenAPI document to clean
|
|
11
|
+
* @returns Object with cleanup statistics
|
|
12
|
+
*/
|
|
13
|
+
export declare function cleanupDiscriminatorMappings(doc: any): {
|
|
14
|
+
schemasChecked: number;
|
|
15
|
+
mappingsRemoved: number;
|
|
16
|
+
details: Array<{
|
|
17
|
+
schema: string;
|
|
18
|
+
removed: string[];
|
|
19
|
+
}>;
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=cleanupDiscriminatorMappings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanupDiscriminatorMappings.d.ts","sourceRoot":"","sources":["../../src/lib/cleanupDiscriminatorMappings.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AACH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,GAAG,GAAG;IACtD,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CACvD,CAyDA"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { refToName } from "./oasUtils.js";
|
|
2
|
+
import { updateDiscriminatorMappings } from "./schemaTransformUtils.js";
|
|
3
|
+
/**
|
|
4
|
+
* Cleans up discriminator mappings by removing entries that point to non-existent schemas.
|
|
5
|
+
*
|
|
6
|
+
* This function:
|
|
7
|
+
* 1. Iterates through all schemas looking for discriminator definitions
|
|
8
|
+
* 2. For each discriminator mapping entry, checks if the referenced schema exists
|
|
9
|
+
* 3. Removes mapping entries that reference undefined schemas
|
|
10
|
+
* 4. Returns count of cleaned mappings for reporting
|
|
11
|
+
*
|
|
12
|
+
* @param doc - OpenAPI document to clean
|
|
13
|
+
* @returns Object with cleanup statistics
|
|
14
|
+
*/
|
|
15
|
+
export function cleanupDiscriminatorMappings(doc) {
|
|
16
|
+
if (!doc || typeof doc !== "object") {
|
|
17
|
+
return { schemasChecked: 0, mappingsRemoved: 0, details: [] };
|
|
18
|
+
}
|
|
19
|
+
const schemas = doc.components?.schemas;
|
|
20
|
+
if (!schemas || typeof schemas !== "object") {
|
|
21
|
+
return { schemasChecked: 0, mappingsRemoved: 0, details: [] };
|
|
22
|
+
}
|
|
23
|
+
// Collect all existing schema names for validation
|
|
24
|
+
const existingSchemas = new Set(Object.keys(schemas));
|
|
25
|
+
let totalMappingsRemoved = 0;
|
|
26
|
+
let schemasChecked = 0;
|
|
27
|
+
const details = [];
|
|
28
|
+
// Iterate through all schemas
|
|
29
|
+
for (const [schemaName, schema] of Object.entries(schemas)) {
|
|
30
|
+
if (!schema || typeof schema !== "object")
|
|
31
|
+
continue;
|
|
32
|
+
// Check if schema has discriminator with mapping
|
|
33
|
+
if (schema.discriminator && typeof schema.discriminator === "object") {
|
|
34
|
+
const discriminator = schema.discriminator;
|
|
35
|
+
if (discriminator.mapping && typeof discriminator.mapping === "object") {
|
|
36
|
+
schemasChecked++;
|
|
37
|
+
const removedMappings = [];
|
|
38
|
+
// Update discriminator mappings, removing invalid references
|
|
39
|
+
const removed = updateDiscriminatorMappings(schema, (key, ref) => {
|
|
40
|
+
const referencedSchemaName = refToName(ref);
|
|
41
|
+
// Keep this mapping only if the referenced schema exists
|
|
42
|
+
const shouldKeep = !referencedSchemaName || existingSchemas.has(referencedSchemaName);
|
|
43
|
+
if (!shouldKeep) {
|
|
44
|
+
removedMappings.push(key);
|
|
45
|
+
}
|
|
46
|
+
return shouldKeep;
|
|
47
|
+
});
|
|
48
|
+
totalMappingsRemoved += removed;
|
|
49
|
+
if (removedMappings.length > 0) {
|
|
50
|
+
details.push({
|
|
51
|
+
schema: schemaName,
|
|
52
|
+
removed: removedMappings,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
schemasChecked,
|
|
60
|
+
mappingsRemoved: totalMappingsRemoved,
|
|
61
|
+
details,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=cleanupDiscriminatorMappings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanupDiscriminatorMappings.js","sourceRoot":"","sources":["../../src/lib/cleanupDiscriminatorMappings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAExE;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,4BAA4B,CAAC,GAAQ;IAKnD,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO,EAAE,cAAc,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAChE,CAAC;IAED,MAAM,OAAO,GAAoC,GAAG,CAAC,UAAU,EAAE,OAAO,CAAC;IACzE,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC5C,OAAO,EAAE,cAAc,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAChE,CAAC;IAED,mDAAmD;IACnD,MAAM,eAAe,GAAG,IAAI,GAAG,CAAS,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAE9D,IAAI,oBAAoB,GAAG,CAAC,CAAC;IAC7B,IAAI,cAAc,GAAG,CAAC,CAAC;IACvB,MAAM,OAAO,GAAiD,EAAE,CAAC;IAEjE,8BAA8B;IAC9B,KAAK,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3D,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,SAAS;QAEpD,iDAAiD;QACjD,IAAI,MAAM,CAAC,aAAa,IAAI,OAAO,MAAM,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;YACrE,MAAM,aAAa,GAAG,MAAM,CAAC,aAAa,CAAC;YAE3C,IAAI,aAAa,CAAC,OAAO,IAAI,OAAO,aAAa,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;gBACvE,cAAc,EAAE,CAAC;gBACjB,MAAM,eAAe,GAAa,EAAE,CAAC;gBAErC,6DAA6D;gBAC7D,MAAM,OAAO,GAAG,2BAA2B,CAAC,MAAM,EAAE,CAAC,GAAW,EAAE,GAAW,EAAE,EAAE;oBAC/E,MAAM,oBAAoB,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;oBAC5C,yDAAyD;oBACzD,MAAM,UAAU,GAAG,CAAC,oBAAoB,IAAI,eAAe,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;oBACtF,IAAI,CAAC,UAAU,EAAE,CAAC;wBAChB,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBAC5B,CAAC;oBACD,OAAO,UAAU,CAAC;gBACpB,CAAC,CAAC,CAAC;gBAEH,oBAAoB,IAAI,OAAO,CAAC;gBAEhC,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC/B,OAAO,CAAC,IAAI,CAAC;wBACX,MAAM,EAAE,UAAU;wBAClB,OAAO,EAAE,eAAe;qBACzB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,cAAc;QACd,eAAe,EAAE,oBAAoB;QACrC,OAAO;KACR,CAAC;AACJ,CAAC"}
|