@amartus/oas-utils 0.5.2 → 0.7.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 +50 -9
- package/dist/cli.js +19 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/allOfToOneOfInterface.d.ts +36 -0
- package/dist/lib/allOfToOneOfInterface.d.ts.map +1 -0
- package/dist/lib/allOfToOneOfInterface.js +5 -0
- package/dist/lib/allOfToOneOfInterface.js.map +1 -0
- package/dist/lib/allOfToOneOfJsonPath.d.ts +60 -0
- package/dist/lib/allOfToOneOfJsonPath.d.ts.map +1 -0
- package/dist/lib/allOfToOneOfJsonPath.js +539 -0
- package/dist/lib/allOfToOneOfJsonPath.js.map +1 -0
- package/dist/lib/cleanupDiscriminatorMappings.d.ts +14 -2
- package/dist/lib/cleanupDiscriminatorMappings.d.ts.map +1 -1
- package/dist/lib/cleanupDiscriminatorMappings.js +30 -5
- package/dist/lib/cleanupDiscriminatorMappings.js.map +1 -1
- package/dist/lib/cliActions.d.ts +15 -0
- package/dist/lib/cliActions.d.ts.map +1 -1
- package/dist/lib/cliActions.js +32 -2
- package/dist/lib/cliActions.js.map +1 -1
- package/dist/lib/optimizeAllOfComposition.d.ts.map +1 -1
- package/dist/lib/optimizeAllOfComposition.js +1 -9
- package/dist/lib/optimizeAllOfComposition.js.map +1 -1
- package/dist/lib/removeSingleComposition.d.ts +24 -0
- package/dist/lib/removeSingleComposition.d.ts.map +1 -0
- package/dist/lib/removeSingleComposition.js +121 -0
- package/dist/lib/removeSingleComposition.js.map +1 -0
- package/dist/redocly/allof-to-oneof-decorator.js +1 -1
- package/dist/redocly/allof-to-oneof-decorator.js.map +1 -1
- package/dist/redocly/cleanup-discriminator-decorator.d.ts +2 -1
- package/dist/redocly/cleanup-discriminator-decorator.d.ts.map +1 -1
- package/dist/redocly/cleanup-discriminator-decorator.js +5 -2
- package/dist/redocly/cleanup-discriminator-decorator.js.map +1 -1
- package/dist/redocly/plugin.d.ts +3 -0
- package/dist/redocly/plugin.d.ts.map +1 -1
- package/dist/redocly/plugin.js +3 -0
- package/dist/redocly/plugin.js.map +1 -1
- package/dist/redocly/remove-single-composition-decorator.d.ts +6 -0
- package/dist/redocly/remove-single-composition-decorator.d.ts.map +1 -0
- package/dist/redocly/remove-single-composition-decorator.js +14 -0
- package/dist/redocly/remove-single-composition-decorator.js.map +1 -0
- package/package.json +1 -1
- package/dist/lib/allOfToOneOf.d.ts +0 -23
- package/dist/lib/allOfToOneOf.d.ts.map +0 -1
- package/dist/lib/allOfToOneOf.js +0 -413
- package/dist/lib/allOfToOneOf.js.map +0 -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, remove entries from oneOf, optimize allOf composition, convert allOf + discriminator patterns to oneOf + discriminator, clean up discriminator mappings,
|
|
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, clean up discriminator mappings, remove dangling `$ref` targets, and remove single-composition wrapper schemas. Use them as a CLI or as Redocly decorators.
|
|
4
4
|
|
|
5
5
|
## Definition of "unused schema"
|
|
6
6
|
|
|
@@ -76,23 +76,25 @@ Specifically, it:
|
|
|
76
76
|
2. Finds concrete schemas that extend the base via allOf
|
|
77
77
|
3. Optionally adds a const property to each concrete schema matching its discriminator value (enabled by default)
|
|
78
78
|
4. Creates a new oneOf wrapper schema containing all concrete types
|
|
79
|
-
5. Replaces references to the base schema with the wrapper schema (
|
|
79
|
+
5. Replaces references to the base schema with the wrapper schema (outside of allOf composition contexts)
|
|
80
|
+
6. Removes discriminators from base schemas that received wrappers
|
|
81
|
+
7. Optionally merges nested oneOf schemas by inlining references to schemas that only contain oneOf
|
|
80
82
|
|
|
81
83
|
```
|
|
82
84
|
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
85
|
# Optionally skip adding const to specialization schemas
|
|
86
86
|
oas-utils allof-to-oneof <input.yaml> -o output.yaml --no-add-discriminator-const
|
|
87
87
|
# Optionally skip transformation if only one specialization is found
|
|
88
88
|
oas-utils allof-to-oneof <input.yaml> -o output.yaml --ignore-single-specialization
|
|
89
|
+
# Optionally merge nested oneOf schemas
|
|
90
|
+
oas-utils allof-to-oneof <input.yaml> -o output.yaml --merge-nested-oneof
|
|
89
91
|
```
|
|
90
92
|
|
|
91
93
|
Options:
|
|
92
94
|
- -o, --output: write result to this file (defaults to stdout).
|
|
93
|
-
- --remove-discriminator-from-base: remove the discriminator from base schemas after conversion.
|
|
94
95
|
- --no-add-discriminator-const: do not add const property with discriminator value to specialization schemas.
|
|
95
96
|
- --ignore-single-specialization: skip oneOf transformation if only one specialization is found (useful for bases with only one concrete implementation).
|
|
97
|
+
- --merge-nested-oneof: merge nested oneOf schemas by inlining references to schemas that only contain oneOf.
|
|
96
98
|
|
|
97
99
|
Example transformation (with addDiscriminatorConst enabled, the default):
|
|
98
100
|
- Base schema `Animal` with discriminator `type` and mapping `{Cat: ..., Dog: ...}`
|
|
@@ -103,22 +105,43 @@ Example transformation (with addDiscriminatorConst enabled, the default):
|
|
|
103
105
|
|
|
104
106
|
### cleanup-discriminators
|
|
105
107
|
|
|
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.
|
|
108
|
+
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. Optionally, remove entire discriminators from schemas matching specified patterns.
|
|
107
109
|
|
|
108
110
|
```
|
|
109
111
|
oas-utils cleanup-discriminators <input.yaml> -o output.yaml
|
|
110
112
|
# Read from stdin and write to stdout
|
|
111
113
|
cat openapi.yaml | oas-utils cleanup-discriminators > cleaned.yaml
|
|
114
|
+
# Remove discriminators from schemas matching patterns
|
|
115
|
+
oas-utils cleanup-discriminators spec.yaml --remove-patterns "*_RES" "*Response" -o output.yaml
|
|
112
116
|
```
|
|
113
117
|
|
|
114
118
|
Options:
|
|
115
119
|
- -o, --output: write result to this file (defaults to stdout).
|
|
120
|
+
- --remove-patterns: schema name patterns for which discriminators should be removed entirely (supports glob-style wildcards like `*`).
|
|
116
121
|
|
|
117
122
|
Example:
|
|
118
123
|
- Original discriminator mapping: `{cat: '#/components/schemas/Cat', dog: '#/components/schemas/Dog', bird: '#/components/schemas/Bird'}`
|
|
119
124
|
- After removing `Bird` schema: mapping entries `bird` is invalid
|
|
120
125
|
- After cleanup: `{cat: '#/components/schemas/Cat', dog: '#/components/schemas/Dog'}`
|
|
121
126
|
|
|
127
|
+
### remove-single-composition
|
|
128
|
+
|
|
129
|
+
Remove single-composition wrapper schemas. A single-composition schema is one whose only content is a single `allOf`, `anyOf`, or `oneOf` containing exactly one `$ref`. Such schemas add indirection without semantic value and are replaced by their target reference.
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
oas-utils remove-single-composition <input.yaml> -o output.yaml
|
|
133
|
+
# Read from stdin and write to stdout
|
|
134
|
+
cat openapi.yaml | oas-utils remove-single-composition > cleaned.yaml
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Options:
|
|
138
|
+
- -o, --output: write result to this file (defaults to stdout).
|
|
139
|
+
|
|
140
|
+
Example:
|
|
141
|
+
- Schema `Foo` with `allOf: [{$ref: '#/components/schemas/Bar'}]`
|
|
142
|
+
- `Foo` is removed and all references to `Foo` are replaced with `Bar`
|
|
143
|
+
- Transitive chains are resolved: if `A`→`B`→`C` are all single-composition, both `A` and `B` are removed and references point to `C`
|
|
144
|
+
|
|
122
145
|
### seal-schema
|
|
123
146
|
|
|
124
147
|
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`.
|
|
@@ -195,16 +218,22 @@ decorators:
|
|
|
195
218
|
|
|
196
219
|
# Convert allOf + discriminator to oneOf + discriminator
|
|
197
220
|
oas-utils/allof-to-oneof:
|
|
198
|
-
removeDiscriminatorFromBase: false
|
|
199
221
|
addDiscriminatorConst: true
|
|
200
222
|
ignoreSingleSpecialization: false
|
|
201
223
|
|
|
202
224
|
# Clean up discriminator mappings
|
|
203
|
-
oas-utils/cleanup-discriminators:
|
|
225
|
+
oas-utils/cleanup-discriminators:
|
|
226
|
+
# Optional: remove discriminators from schemas matching these patterns
|
|
227
|
+
# removeDiscriminatorPatterns:
|
|
228
|
+
# - '*_RES'
|
|
229
|
+
# - '*Response'
|
|
204
230
|
|
|
205
231
|
# Remove dangling $ref entries that point to missing component schemas
|
|
206
232
|
oas-utils/remove-dangling-refs: {}
|
|
207
233
|
|
|
234
|
+
# Remove single-composition wrapper schemas
|
|
235
|
+
oas-utils/remove-single-composition: {}
|
|
236
|
+
|
|
208
237
|
# Seal object schemas
|
|
209
238
|
oas-utils/seal-schema:
|
|
210
239
|
useUnevaluatedProperties: true
|
|
@@ -224,6 +253,7 @@ Notes:
|
|
|
224
253
|
import {
|
|
225
254
|
cleanupDiscriminatorMappings,
|
|
226
255
|
removeDanglingRefs,
|
|
256
|
+
removeSingleComposition,
|
|
227
257
|
removeUnusedSchemas,
|
|
228
258
|
allOfToOneOf,
|
|
229
259
|
sealSchema,
|
|
@@ -233,18 +263,29 @@ import {
|
|
|
233
263
|
removeUnusedSchemas(doc, { keep: ['CommonError'], aggressive: true });
|
|
234
264
|
|
|
235
265
|
// Convert allOf + discriminator to oneOf + discriminator
|
|
236
|
-
allOfToOneOf(doc, {
|
|
266
|
+
allOfToOneOf(doc, { addDiscriminatorConst: true, mergeNestedOneOf: false });
|
|
237
267
|
|
|
238
268
|
// Clean up discriminator mappings
|
|
239
269
|
const result = cleanupDiscriminatorMappings(doc);
|
|
240
270
|
console.log(`Removed ${result.mappingsRemoved} invalid mappings from ${result.schemasChecked} schemas`);
|
|
241
271
|
|
|
272
|
+
// Clean up discriminator mappings and remove discriminators from schemas matching patterns
|
|
273
|
+
const resultWithPatterns = cleanupDiscriminatorMappings(doc, {
|
|
274
|
+
removeDiscriminatorPatterns: ['*_RES', '*Response']
|
|
275
|
+
});
|
|
276
|
+
console.log(`Removed ${resultWithPatterns.discriminatorsRemoved} discriminator(s) from matching schemas`);
|
|
277
|
+
console.log(`Removed schemas: ${resultWithPatterns.removedDiscriminators.join(', ')}`);
|
|
278
|
+
|
|
242
279
|
// Seal object schemas
|
|
243
280
|
sealSchema(doc, { useUnevaluatedProperties: true, uplift: true });
|
|
244
281
|
|
|
245
282
|
// Remove dangling refs (aggressive mode prunes external URIs too)
|
|
246
283
|
const dangling = removeDanglingRefs(doc, { aggressive: true });
|
|
247
284
|
console.log(`Removed ${dangling.removed} dangling $ref(s)`);
|
|
285
|
+
|
|
286
|
+
// Remove single-composition wrapper schemas
|
|
287
|
+
const single = removeSingleComposition(doc);
|
|
288
|
+
console.log(`Removed ${single.schemasRemoved} single-composition schema(s)`);
|
|
248
289
|
```
|
|
249
290
|
|
|
250
291
|
## 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, runAllOfToOneOf, runSealSchema, runCleanupDiscriminators } from "./lib/cliActions.js";
|
|
4
|
+
import { runRemoveUnused, runRemoveOneOf, optimizeAllOf, runAllOfToOneOf, runSealSchema, runCleanupDiscriminators, runRemoveSingleComposition } from "./lib/cliActions.js";
|
|
5
5
|
import YAML from "yaml";
|
|
6
6
|
import { dropNulls } from "./lib/utils.js";
|
|
7
7
|
import { createRequire } from "node:module";
|
|
@@ -60,9 +60,9 @@ program
|
|
|
60
60
|
.description("Convert allOf + discriminator patterns to oneOf + discriminator")
|
|
61
61
|
.argument("[input]", "Path to input OpenAPI file (YAML or JSON). If omitted, reads from stdin")
|
|
62
62
|
.option("-o, --output <file>", "Write result to this file (defaults to stdout)")
|
|
63
|
-
.option("--remove-discriminator-from-base", "Remove discriminator from base schemas after conversion", false)
|
|
64
63
|
.option("--no-add-discriminator-const", "Do not add const property with discriminator value to specialization schemas", true)
|
|
65
64
|
.option("--ignore-single-specialization", "Skip oneOf transformation if only one specialization is found", false)
|
|
65
|
+
.option("--merge-nested-oneof", "Merge nested oneOf schemas by inlining references to schemas that only contain oneOf", false)
|
|
66
66
|
.action(async (input, opts) => {
|
|
67
67
|
try {
|
|
68
68
|
await runAllOfToOneOf(opts, format, () => reader(input));
|
|
@@ -97,6 +97,7 @@ program
|
|
|
97
97
|
.description("Clean up discriminator mappings by removing references to non-existent schemas")
|
|
98
98
|
.argument("[input]", "Path to input OpenAPI file (YAML or JSON). If omitted, reads from stdin")
|
|
99
99
|
.option("-o, --output <file>", "Write result to this file (defaults to stdout)")
|
|
100
|
+
.option("--remove-patterns <patterns...>", "Schema name patterns for which discriminators should be removed entirely (e.g., *_RES)", [])
|
|
100
101
|
.action(async (input, opts) => {
|
|
101
102
|
try {
|
|
102
103
|
await runCleanupDiscriminators(opts, format, () => reader(input));
|
|
@@ -106,6 +107,22 @@ program
|
|
|
106
107
|
process.exitCode = 1;
|
|
107
108
|
}
|
|
108
109
|
});
|
|
110
|
+
program
|
|
111
|
+
.command("remove-single-composition")
|
|
112
|
+
.showHelpAfterError()
|
|
113
|
+
.description("Remove single-composition wrapper schemas (allOf/anyOf/oneOf with a single $ref)")
|
|
114
|
+
.argument("[input]", "Path to input OpenAPI file (YAML or JSON). If omitted, reads from stdin")
|
|
115
|
+
.option("-o, --output <file>", "Write result to this file (defaults to stdout)")
|
|
116
|
+
.option("--aggressive", "Also remove schemas with extra keywords (e.g. description, discriminator) alongside the composition keyword, unless properties is present", false)
|
|
117
|
+
.action(async (input, opts) => {
|
|
118
|
+
try {
|
|
119
|
+
await runRemoveSingleComposition(opts, format, () => reader(input));
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
console.error(`Error: ${err?.message || String(err)}`);
|
|
123
|
+
process.exitCode = 1;
|
|
124
|
+
}
|
|
125
|
+
});
|
|
109
126
|
if (process.argv.length <= 2) {
|
|
110
127
|
program.help();
|
|
111
128
|
}
|
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,eAAe,EAAE,aAAa,EAAE,wBAAwB,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,10 +1,11 @@
|
|
|
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/
|
|
4
|
+
export * from './lib/allOfToOneOfJsonPath.js';
|
|
5
5
|
export * from './lib/sealSchema.js';
|
|
6
6
|
export * from './lib/oasUtils.js';
|
|
7
7
|
export * from './lib/cleanupDiscriminatorMappings.js';
|
|
8
8
|
export * from './lib/schemaTransformUtils.js';
|
|
9
9
|
export * from './lib/removeDanglingRefs.js';
|
|
10
|
+
export * from './lib/removeSingleComposition.js';
|
|
10
11
|
//# 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;AAClD,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,+BAA+B,CAAC;AAC9C,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kCAAkC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
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/
|
|
4
|
+
export * from './lib/allOfToOneOfJsonPath.js';
|
|
5
5
|
export * from './lib/sealSchema.js';
|
|
6
6
|
export * from './lib/oasUtils.js';
|
|
7
7
|
export * from './lib/cleanupDiscriminatorMappings.js';
|
|
8
8
|
export * from './lib/schemaTransformUtils.js';
|
|
9
9
|
export * from './lib/removeDanglingRefs.js';
|
|
10
|
+
export * from './lib/removeSingleComposition.js';
|
|
10
11
|
//# 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;AAClD,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,+BAA+B,CAAC;AAC9C,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kCAAkC,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common interface for allOf to oneOf transformation implementations
|
|
3
|
+
*/
|
|
4
|
+
export interface AllOfToOneOfOptions {
|
|
5
|
+
/** If true, add const property with discriminator value to specialization schemas (default: true) */
|
|
6
|
+
addDiscriminatorConst?: boolean;
|
|
7
|
+
/** If true, skip oneOf transformation if only one specialization is found (default: false) */
|
|
8
|
+
ignoreSingleSpecialization?: boolean;
|
|
9
|
+
/** If true, merge nested oneOf schemas by inlining references to schemas that only contain oneOf (default: false) */
|
|
10
|
+
mergeNestedOneOf?: boolean;
|
|
11
|
+
/** Optional callback to receive warnings during transformation. If not provided, warnings are silently ignored. */
|
|
12
|
+
onWarning?: (message: string) => void;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Transforms allOf + discriminator patterns to oneOf + discriminator in OpenAPI documents.
|
|
16
|
+
*
|
|
17
|
+
* @param doc - The OpenAPI document to transform (will be modified in-place)
|
|
18
|
+
* @param opts - Optional configuration for the transformation
|
|
19
|
+
* @returns The transformed document (same reference as input)
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* import { allOfToOneOf } from "./lib/allOfToOneOfJsonPath.js";
|
|
24
|
+
*
|
|
25
|
+
* const doc = { ... }; // OpenAPI document
|
|
26
|
+
* const transformed = allOfToOneOf(doc, {
|
|
27
|
+
* addDiscriminatorConst: true,
|
|
28
|
+
* ignoreSingleSpecialization: false,
|
|
29
|
+
* mergeNestedOneOf: false
|
|
30
|
+
* });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export interface AllOfToOneOfTransform {
|
|
34
|
+
(doc: any, opts?: AllOfToOneOfOptions): any;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=allOfToOneOfInterface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allOfToOneOfInterface.d.ts","sourceRoot":"","sources":["../../src/lib/allOfToOneOfInterface.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,MAAM,WAAW,mBAAmB;IAClC,qGAAqG;IACrG,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,8FAA8F;IAC9F,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,qHAAqH;IACrH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,mHAAmH;IACnH,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,qBAAqB;IACpC,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,mBAAmB,GAAG,GAAG,CAAC;CAC7C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allOfToOneOfInterface.js","sourceRoot":"","sources":["../../src/lib/allOfToOneOfInterface.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { AllOfToOneOfOptions } from './allOfToOneOfInterface.js';
|
|
2
|
+
/**
|
|
3
|
+
* Third implementation of allOfToOneOf using JSONPath library.
|
|
4
|
+
*
|
|
5
|
+
* This implementation focuses on using JSONPath queries for:
|
|
6
|
+
* - Finding all allOf relationships
|
|
7
|
+
* - Locating references to schemas
|
|
8
|
+
* - Replacing references throughout the document
|
|
9
|
+
*
|
|
10
|
+
* Algorithm:
|
|
11
|
+
* 1. Find discriminator parents (schemas with discriminator.mapping with >1 entry)
|
|
12
|
+
* 2. Build inheritance graph using JSONPath to find allOf relationships
|
|
13
|
+
* 3. For each discriminator parent:
|
|
14
|
+
* - Find all references using JSONPath
|
|
15
|
+
* - Check if referenced outside composition contexts
|
|
16
|
+
* - If yes, create polymorphic wrapper
|
|
17
|
+
* 4. Rewire references using JSONPath
|
|
18
|
+
* 5. Remove discriminators from parents
|
|
19
|
+
* 6. Optionally add const constraints to children
|
|
20
|
+
* 7. Handle nested hierarchies (chain wrappers)
|
|
21
|
+
*/
|
|
22
|
+
interface SchemaReference {
|
|
23
|
+
$ref: string;
|
|
24
|
+
}
|
|
25
|
+
interface DiscriminatorObject {
|
|
26
|
+
propertyName: string;
|
|
27
|
+
mapping: Record<string, string>;
|
|
28
|
+
}
|
|
29
|
+
interface SchemaObject {
|
|
30
|
+
type?: string;
|
|
31
|
+
properties?: Record<string, unknown>;
|
|
32
|
+
allOf?: Array<SchemaReference | SchemaObject>;
|
|
33
|
+
oneOf?: Array<SchemaReference | SchemaObject>;
|
|
34
|
+
anyOf?: Array<SchemaReference | SchemaObject>;
|
|
35
|
+
discriminator?: Partial<DiscriminatorObject>;
|
|
36
|
+
[key: string]: unknown;
|
|
37
|
+
}
|
|
38
|
+
interface ComponentsObject {
|
|
39
|
+
schemas?: Record<string, SchemaObject>;
|
|
40
|
+
requestBodies?: Record<string, unknown>;
|
|
41
|
+
responses?: Record<string, unknown>;
|
|
42
|
+
parameters?: Record<string, unknown>;
|
|
43
|
+
callbacks?: Record<string, unknown>;
|
|
44
|
+
links?: Record<string, unknown>;
|
|
45
|
+
headers?: Record<string, unknown>;
|
|
46
|
+
}
|
|
47
|
+
interface OpenAPIDocument {
|
|
48
|
+
openapi?: string;
|
|
49
|
+
components?: ComponentsObject;
|
|
50
|
+
paths?: Record<string, unknown>;
|
|
51
|
+
webhooks?: Record<string, unknown>;
|
|
52
|
+
[key: string]: unknown;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Main transformation function.
|
|
56
|
+
* Converts allOf + discriminator patterns to oneOf wrappers using JSONPath.
|
|
57
|
+
*/
|
|
58
|
+
export declare function allOfToOneOf(doc: OpenAPIDocument, opts?: AllOfToOneOfOptions): OpenAPIDocument;
|
|
59
|
+
export {};
|
|
60
|
+
//# sourceMappingURL=allOfToOneOfJsonPath.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allOfToOneOfJsonPath.d.ts","sourceRoot":"","sources":["../../src/lib/allOfToOneOfJsonPath.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAGjE;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,mBAAmB;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,UAAU,YAAY;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,KAAK,CAAC,EAAE,KAAK,CAAC,eAAe,GAAG,YAAY,CAAC,CAAC;IAC9C,KAAK,CAAC,EAAE,KAAK,CAAC,eAAe,GAAG,YAAY,CAAC,CAAC;IAC9C,KAAK,CAAC,EAAE,KAAK,CAAC,eAAe,GAAG,YAAY,CAAC,CAAC;IAC9C,aAAa,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC7C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,UAAU,gBAAgB;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACvC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,UAAU,eAAe;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAqpBD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,GAAE,mBAAwB,GAAG,eAAe,CA4BlG"}
|