@speclynx/apidom-reference 4.12.1 → 4.14.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 +12 -0
- package/README.md +99 -4
- package/dist/apidom-reference.browser.js +2353 -293
- package/dist/apidom-reference.browser.min.js +1 -1
- package/package.json +33 -28
- package/src/bundle/strategies/openapi-2/index.cjs +94 -0
- package/src/bundle/strategies/openapi-2/index.mjs +81 -0
- package/src/bundle/strategies/openapi-2/visitor.cjs +559 -0
- package/src/bundle/strategies/openapi-2/visitor.mjs +551 -0
- package/src/bundle/strategies/openapi-3-0/visitor.cjs +10 -18
- package/src/bundle/strategies/openapi-3-0/visitor.mjs +10 -18
- package/src/bundle/strategies/openapi-3-1/index.cjs +59 -2
- package/src/bundle/strategies/openapi-3-1/index.mjs +54 -2
- package/src/bundle/strategies/openapi-3-1/visitor.cjs +811 -0
- package/src/bundle/strategies/openapi-3-1/visitor.mjs +803 -0
- package/src/configuration/saturated.cjs +12 -11
- package/src/configuration/saturated.mjs +2 -1
- package/src/util/url.cjs +26 -4
- package/src/util/url.mjs +23 -2
- package/types/apidom-reference.d.ts +10 -0
- package/types/bundle/strategies/openapi-2/index.d.ts +31 -0
- package/types/bundle/strategies/openapi-2/visitor.d.ts +131 -0
- package/types/bundle/strategies/openapi-3-0/visitor.d.ts +2 -2
- package/types/bundle/strategies/openapi-3-1/index.d.ts +6 -1
- package/types/bundle/strategies/openapi-3-1/visitor.d.ts +141 -0
- package/types/util/url.d.ts +8 -0
|
@@ -36,20 +36,21 @@ var _index25 = _interopRequireDefault(require("../dereference/strategies/openapi
|
|
|
36
36
|
var _index26 = _interopRequireDefault(require("../dereference/strategies/asyncapi-2/index.cjs"));
|
|
37
37
|
var _index27 = _interopRequireDefault(require("../dereference/strategies/arazzo-1/index.cjs"));
|
|
38
38
|
var _index28 = _interopRequireDefault(require("../dereference/strategies/overlay-1/index.cjs"));
|
|
39
|
-
var _index29 = _interopRequireDefault(require("../bundle/strategies/openapi-
|
|
40
|
-
var _index30 = _interopRequireDefault(require("../bundle/strategies/openapi-3-
|
|
41
|
-
var _index31 = require("../index.cjs");
|
|
42
|
-
|
|
39
|
+
var _index29 = _interopRequireDefault(require("../bundle/strategies/openapi-2/index.cjs"));
|
|
40
|
+
var _index30 = _interopRequireDefault(require("../bundle/strategies/openapi-3-0/index.cjs"));
|
|
41
|
+
var _index31 = _interopRequireDefault(require("../bundle/strategies/openapi-3-1/index.cjs"));
|
|
42
|
+
var _index32 = require("../index.cjs");
|
|
43
|
+
Object.keys(_index32).forEach(function (key) {
|
|
43
44
|
if (key === "default" || key === "__esModule") return;
|
|
44
|
-
if (key in exports && exports[key] ===
|
|
45
|
+
if (key in exports && exports[key] === _index32[key]) return;
|
|
45
46
|
Object.defineProperty(exports, key, {
|
|
46
47
|
enumerable: true,
|
|
47
48
|
get: function () {
|
|
48
|
-
return
|
|
49
|
+
return _index32[key];
|
|
49
50
|
}
|
|
50
51
|
});
|
|
51
52
|
});
|
|
52
|
-
|
|
53
|
+
_index32.options.parse.parsers = [new _index9.default({
|
|
53
54
|
allowEmpty: true,
|
|
54
55
|
sourceMap: false
|
|
55
56
|
}), new _index0.default({
|
|
@@ -97,11 +98,11 @@ _index31.options.parse.parsers = [new _index9.default({
|
|
|
97
98
|
}), new _indexNode2.default({
|
|
98
99
|
allowEmpty: true
|
|
99
100
|
})];
|
|
100
|
-
|
|
101
|
+
_index32.options.resolve.resolvers = [new _indexNode.default(), new _index.default({
|
|
101
102
|
timeout: 5000,
|
|
102
103
|
redirects: 5,
|
|
103
104
|
withCredentials: false
|
|
104
105
|
})];
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
_index32.options.resolve.strategies = [new _index2.default(), new _index3.default(), new _index4.default(), new _index5.default(), new _index6.default(), new _index7.default(), new _index8.default()];
|
|
107
|
+
_index32.options.dereference.strategies = [new _index23.default(), new _index24.default(), new _index25.default(), new _index26.default(), new _index27.default(), new _index28.default(), new _index22.default()];
|
|
108
|
+
_index32.options.bundle.strategies = [new _index29.default(), new _index30.default(), new _index31.default()];
|
|
@@ -30,6 +30,7 @@ import OpenAPI3_1DereferenceStrategy from "../dereference/strategies/openapi-3-1
|
|
|
30
30
|
import AsyncAPI2DereferenceStrategy from "../dereference/strategies/asyncapi-2/index.mjs";
|
|
31
31
|
import Arazzo1DereferenceStrategy from "../dereference/strategies/arazzo-1/index.mjs";
|
|
32
32
|
import Overlay1DereferenceStrategy from "../dereference/strategies/overlay-1/index.mjs";
|
|
33
|
+
import OpenAPI2BundleStrategy from "../bundle/strategies/openapi-2/index.mjs";
|
|
33
34
|
import OpenAPI3_0BundleStrategy from "../bundle/strategies/openapi-3-0/index.mjs";
|
|
34
35
|
import OpenAPI3_1BundleStrategy from "../bundle/strategies/openapi-3-1/index.mjs";
|
|
35
36
|
import { options } from "../index.mjs";
|
|
@@ -88,5 +89,5 @@ options.resolve.resolvers = [new FileResolver(), new HTTPResolverAxios({
|
|
|
88
89
|
})];
|
|
89
90
|
options.resolve.strategies = [new OpenAPI2ResolveStrategy(), new OpenAPI3_0ResolveStrategy(), new OpenAPI3_1ResolveStrategy(), new AsyncAPI2ResolveStrategy(), new Arazzo1ResolveStrategy(), new Overlay1ResolveStrategy(), new ApiDOMResolveStrategy()];
|
|
90
91
|
options.dereference.strategies = [new OpenAPI2DereferenceStrategy(), new OpenAPI3_0DereferenceStrategy(), new OpenAPI3_1DereferenceStrategy(), new AsyncAPI2DereferenceStrategy(), new Arazzo1DereferenceStrategy(), new Overlay1DereferenceStrategy(), new ApiDOMDereferenceStrategy()];
|
|
91
|
-
options.bundle.strategies = [new OpenAPI3_0BundleStrategy(), new OpenAPI3_1BundleStrategy()];
|
|
92
|
+
options.bundle.strategies = [new OpenAPI2BundleStrategy(), new OpenAPI3_0BundleStrategy(), new OpenAPI3_1BundleStrategy()];
|
|
92
93
|
export * from "../index.mjs";
|
package/src/util/url.cjs
CHANGED
|
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequ
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.unsanitize = exports.toFileSystemPath = exports.stripHash = exports.sanitize = exports.resolve = exports.isURI = exports.isHttpUrl = exports.isFileSystemPath = exports.hasProtocol = exports.getProtocol = exports.getHash = exports.getExtension = exports.fromFileSystemPath = exports.cwd = void 0;
|
|
7
|
+
exports.unsanitize = exports.toFileSystemPath = exports.stripHash = exports.sanitize = exports.resolve = exports.isURI = exports.isHttpUrl = exports.isFileSystemPath = exports.hasProtocol = exports.getProtocol = exports.getHash = exports.getExtension = exports.getBasename = exports.fromFileSystemPath = exports.cwd = void 0;
|
|
8
8
|
var _process = _interopRequireDefault(require("process"));
|
|
9
9
|
var _ramda = require("ramda");
|
|
10
10
|
var _ramdaAdjunct = require("ramda-adjunct");
|
|
@@ -40,25 +40,47 @@ const getProtocol = url => {
|
|
|
40
40
|
exports.getProtocol = getProtocol;
|
|
41
41
|
const hasProtocol = exports.hasProtocol = (0, _ramda.pipe)(getProtocol, _ramdaAdjunct.isNotUndefined);
|
|
42
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Returns the final path segment of the given URI (the part after the last
|
|
45
|
+
* `/`). Inputs are URIs, whose path separator is `/` — filesystem paths are
|
|
46
|
+
* forward-slashed by `sanitize` before reaching here.
|
|
47
|
+
*/
|
|
48
|
+
const getFilename = uri => uri.slice(uri.lastIndexOf('/') + 1);
|
|
49
|
+
|
|
43
50
|
/**
|
|
44
51
|
* Returns the lower-cased file extension of the given URL,
|
|
45
52
|
* or an empty string if it has no extension.
|
|
46
53
|
* @public
|
|
47
54
|
*/
|
|
48
55
|
const getExtension = url => {
|
|
49
|
-
const
|
|
56
|
+
const fileName = getFilename(url);
|
|
57
|
+
const lastDotPosition = fileName.lastIndexOf('.');
|
|
50
58
|
if (lastDotPosition >= 0) {
|
|
51
|
-
return
|
|
59
|
+
return fileName.substring(lastDotPosition).toLowerCase();
|
|
52
60
|
}
|
|
53
61
|
return '';
|
|
54
62
|
};
|
|
55
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Returns the final path segment of the given URI with its file extension
|
|
66
|
+
* removed (e.g. `./schemas/Pet.json` -> `Pet`). Returns the whole segment when
|
|
67
|
+
* there is no extension, and the whole URI when there is no path segment
|
|
68
|
+
* (e.g. a URN).
|
|
69
|
+
* @public
|
|
70
|
+
*/
|
|
71
|
+
exports.getExtension = getExtension;
|
|
72
|
+
const getBasename = uri => {
|
|
73
|
+
const fileName = getFilename(uri);
|
|
74
|
+
const extension = getExtension(uri);
|
|
75
|
+
return extension === '' ? fileName : fileName.slice(0, -extension.length);
|
|
76
|
+
};
|
|
77
|
+
|
|
56
78
|
/**
|
|
57
79
|
* Determines whether the given path is a filesystem path.
|
|
58
80
|
* This includes "file://" URLs.
|
|
59
81
|
* @public
|
|
60
82
|
*/
|
|
61
|
-
exports.
|
|
83
|
+
exports.getBasename = getBasename;
|
|
62
84
|
const isFileSystemPath = uri => {
|
|
63
85
|
const protocol = getProtocol(uri);
|
|
64
86
|
return (0, _ramdaAdjunct.isUndefined)(protocol) || protocol === 'file' || /^[a-zA-Z]$/.test(protocol);
|
package/src/util/url.mjs
CHANGED
|
@@ -33,19 +33,40 @@ export const getProtocol = url => {
|
|
|
33
33
|
*/
|
|
34
34
|
export const hasProtocol = pipe(getProtocol, isNotUndefined);
|
|
35
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Returns the final path segment of the given URI (the part after the last
|
|
38
|
+
* `/`). Inputs are URIs, whose path separator is `/` — filesystem paths are
|
|
39
|
+
* forward-slashed by `sanitize` before reaching here.
|
|
40
|
+
*/
|
|
41
|
+
const getFilename = uri => uri.slice(uri.lastIndexOf('/') + 1);
|
|
42
|
+
|
|
36
43
|
/**
|
|
37
44
|
* Returns the lower-cased file extension of the given URL,
|
|
38
45
|
* or an empty string if it has no extension.
|
|
39
46
|
* @public
|
|
40
47
|
*/
|
|
41
48
|
export const getExtension = url => {
|
|
42
|
-
const
|
|
49
|
+
const fileName = getFilename(url);
|
|
50
|
+
const lastDotPosition = fileName.lastIndexOf('.');
|
|
43
51
|
if (lastDotPosition >= 0) {
|
|
44
|
-
return
|
|
52
|
+
return fileName.substring(lastDotPosition).toLowerCase();
|
|
45
53
|
}
|
|
46
54
|
return '';
|
|
47
55
|
};
|
|
48
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Returns the final path segment of the given URI with its file extension
|
|
59
|
+
* removed (e.g. `./schemas/Pet.json` -> `Pet`). Returns the whole segment when
|
|
60
|
+
* there is no extension, and the whole URI when there is no path segment
|
|
61
|
+
* (e.g. a URN).
|
|
62
|
+
* @public
|
|
63
|
+
*/
|
|
64
|
+
export const getBasename = uri => {
|
|
65
|
+
const fileName = getFilename(uri);
|
|
66
|
+
const extension = getExtension(uri);
|
|
67
|
+
return extension === '' ? fileName : fileName.slice(0, -extension.length);
|
|
68
|
+
};
|
|
69
|
+
|
|
49
70
|
/**
|
|
50
71
|
* Determines whether the given path is a filesystem path.
|
|
51
72
|
* This includes "file://" URLs.
|
|
@@ -240,6 +240,15 @@ export declare interface FileOptions {
|
|
|
240
240
|
*/
|
|
241
241
|
declare const fromFileSystemPath: (uri: string) => string;
|
|
242
242
|
|
|
243
|
+
/**
|
|
244
|
+
* Returns the final path segment of the given URI with its file extension
|
|
245
|
+
* removed (e.g. `./schemas/Pet.json` -> `Pet`). Returns the whole segment when
|
|
246
|
+
* there is no extension, and the whole URI when there is no path segment
|
|
247
|
+
* (e.g. a URN).
|
|
248
|
+
* @public
|
|
249
|
+
*/
|
|
250
|
+
declare const getBasename: (uri: string) => string;
|
|
251
|
+
|
|
243
252
|
/**
|
|
244
253
|
* Returns the lower-cased file extension of the given URL,
|
|
245
254
|
* or an empty string if it has no extension.
|
|
@@ -627,6 +636,7 @@ declare namespace url {
|
|
|
627
636
|
getProtocol,
|
|
628
637
|
hasProtocol,
|
|
629
638
|
getExtension,
|
|
639
|
+
getBasename,
|
|
630
640
|
isFileSystemPath,
|
|
631
641
|
isHttpUrl,
|
|
632
642
|
isURI,
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ParseResultElement } from '@speclynx/apidom-datamodel';
|
|
2
|
+
import File from '../../../File.ts';
|
|
3
|
+
import BundleStrategy, { BundleStrategyOptions } from '../BundleStrategy.ts';
|
|
4
|
+
import OpenAPI2BundleVisitor from './visitor.ts';
|
|
5
|
+
import type { ReferenceOptions } from '../../../options/index.ts';
|
|
6
|
+
export type { default as DereferenceStrategy, DereferenceStrategyOptions, } from '../../../dereference/strategies/DereferenceStrategy.ts';
|
|
7
|
+
export type { default as File, FileOptions } from '../../../File.ts';
|
|
8
|
+
export type { default as Reference, ReferenceOptions } from '../../../Reference.ts';
|
|
9
|
+
export type { default as ReferenceSet, ReferenceSetOptions } from '../../../ReferenceSet.ts';
|
|
10
|
+
export type { OpenAPI2BundleVisitorOptions } from './visitor.ts';
|
|
11
|
+
export type { ReferenceOptions as ApiDOMReferenceOptions, ReferenceBundleOptions as ApiDOMReferenceBundleOptions, ReferenceDereferenceOptions as ApiDOMReferenceDereferenceOptions, ReferenceParseOptions as ApiDOMReferenceParseOptions, ReferenceResolveOptions as ApiDOMReferenceResolveOptions, } from '../../../options/index.ts';
|
|
12
|
+
export type { default as Parser, ParserOptions } from '../../../parse/parsers/Parser.ts';
|
|
13
|
+
export type { default as Resolver, ResolverOptions } from '../../../resolve/resolvers/Resolver.ts';
|
|
14
|
+
export type { default as ResolveStrategy, ResolveStrategyOptions, } from '../../../resolve/strategies/ResolveStrategy.ts';
|
|
15
|
+
export type { default as BundleStrategy, BundleStrategyOptions } from '../BundleStrategy.ts';
|
|
16
|
+
export type { ComponentNamesStrategy, ComponentNameResolver, ComponentNameResolverArgs, ComponentNameCollisionSeverity, } from '../../../options/index.ts';
|
|
17
|
+
/**
|
|
18
|
+
* @public
|
|
19
|
+
*/
|
|
20
|
+
export interface OpenAPI2BundleStrategyOptions extends Omit<BundleStrategyOptions, 'name'> {
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* @public
|
|
24
|
+
*/
|
|
25
|
+
declare class OpenAPI2BundleStrategy extends BundleStrategy {
|
|
26
|
+
constructor(options?: OpenAPI2BundleStrategyOptions);
|
|
27
|
+
canBundle(file: File): boolean;
|
|
28
|
+
bundle(file: File, options: ReferenceOptions): Promise<ParseResultElement>;
|
|
29
|
+
}
|
|
30
|
+
export { OpenAPI2BundleVisitor };
|
|
31
|
+
export default OpenAPI2BundleStrategy;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { Element, ObjectElement, ParseResultElement } from '@speclynx/apidom-datamodel';
|
|
2
|
+
import { type Path } from '@speclynx/apidom-traverse';
|
|
3
|
+
import { ReferenceElement, JSONReferenceElement, SwaggerElement } from '@speclynx/apidom-ns-openapi-2';
|
|
4
|
+
import Reference from '../../../Reference.ts';
|
|
5
|
+
import type { ReferenceOptions } from '../../../options/index.ts';
|
|
6
|
+
/**
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
export interface OpenAPI2BundleVisitorOptions {
|
|
10
|
+
readonly reference: Reference;
|
|
11
|
+
readonly options: ReferenceOptions;
|
|
12
|
+
readonly assignments?: Map<string, string>;
|
|
13
|
+
readonly reservedNames?: Map<string, Set<string>>;
|
|
14
|
+
readonly refractCache?: WeakMap<Element, Map<string, Element>>;
|
|
15
|
+
readonly inlineStack?: Set<string>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* @public
|
|
19
|
+
*/
|
|
20
|
+
declare class OpenAPI2BundleVisitor {
|
|
21
|
+
protected readonly reference: Reference;
|
|
22
|
+
protected readonly options: ReferenceOptions;
|
|
23
|
+
/**
|
|
24
|
+
* The base URI (without hash) of the entry document. A reference is
|
|
25
|
+
* considered internal when it resolves to this URI and external otherwise.
|
|
26
|
+
* Derived from the shared refSet's root reference.
|
|
27
|
+
*/
|
|
28
|
+
protected get entryURI(): string;
|
|
29
|
+
/**
|
|
30
|
+
* The entry parse result. Derived from the shared refSet's root reference.
|
|
31
|
+
*/
|
|
32
|
+
protected get entryParseResult(): ParseResultElement;
|
|
33
|
+
/**
|
|
34
|
+
* The entry document element. Hoisted external fragments are placed into its
|
|
35
|
+
* top-level definition fields. The `canBundle` guard guarantees it is a
|
|
36
|
+
* SwaggerElement.
|
|
37
|
+
*/
|
|
38
|
+
protected get entryResult(): SwaggerElement;
|
|
39
|
+
/**
|
|
40
|
+
* Shared across the entry document and every external document visitor.
|
|
41
|
+
* Guarantees each external fragment is hoisted exactly once and gives us a
|
|
42
|
+
* stable internal pointer to rewrite every referencing element to.
|
|
43
|
+
*/
|
|
44
|
+
protected readonly assignments: Map<string, string>;
|
|
45
|
+
/**
|
|
46
|
+
* Component names already reserved per definition field. Reserved before
|
|
47
|
+
* recursion so collision suffixing (`Pet`, `Pet-2`, ...) accounts for
|
|
48
|
+
* components that are still being bundled.
|
|
49
|
+
*/
|
|
50
|
+
protected readonly reservedNames: Map<string, Set<string>>;
|
|
51
|
+
/**
|
|
52
|
+
* Caches refracted fragments keyed by source element and target element type.
|
|
53
|
+
* The type is part of the key because the same source can be refracted into
|
|
54
|
+
* different semantic elements depending on the referencing context (e.g. a
|
|
55
|
+
* generic object referenced once as a Parameter and once as a Response).
|
|
56
|
+
*/
|
|
57
|
+
protected readonly refractCache: WeakMap<Element, Map<string, Element>>;
|
|
58
|
+
/**
|
|
59
|
+
* Canonical URIs of Path Item Objects currently being inlined. Path Items
|
|
60
|
+
* are not a top-level definition field in OpenAPI 2.0, so the `assignments`
|
|
61
|
+
* map can't break their cycles. This stack guards against circular external
|
|
62
|
+
* Path Item references.
|
|
63
|
+
*/
|
|
64
|
+
protected readonly inlineStack: Set<string>;
|
|
65
|
+
constructor({ reference, options, assignments, reservedNames, refractCache, inlineStack, }: OpenAPI2BundleVisitorOptions);
|
|
66
|
+
protected getRefracted(source: Element, type: string): Element | undefined;
|
|
67
|
+
protected setRefracted(source: Element, type: string, refracted: Element): void;
|
|
68
|
+
protected toBaseURI(uri: string): string;
|
|
69
|
+
protected toReference(uri: string): Promise<Reference>;
|
|
70
|
+
/**
|
|
71
|
+
* Normalizes a self-reference (e.g. `./root.json#/definitions/Pet`)
|
|
72
|
+
* to a bare fragment (`#/definitions/Pet`) so the bundled document stays
|
|
73
|
+
* transferable. Bare fragments are returned unchanged.
|
|
74
|
+
*/
|
|
75
|
+
protected normalizeSelfReference(ref: string): string;
|
|
76
|
+
/**
|
|
77
|
+
* Handles an error according to the `bundle.continueOnError` option.
|
|
78
|
+
*
|
|
79
|
+
* For new errors: wraps in UnresolvableReferenceError with structured
|
|
80
|
+
* context. For errors already wrapped by a nested visitor: prepends the
|
|
81
|
+
* current hop to the trace.
|
|
82
|
+
*
|
|
83
|
+
* Inner/intermediate visitors always throw to let the trace accumulate. Only
|
|
84
|
+
* the entry document visitor respects continueOnError (callback/swallow/throw).
|
|
85
|
+
*/
|
|
86
|
+
protected handleError(message: string, error: Error, referencingElement: Element, refFieldName: string, refFieldValue: string, visitorPath: Path<Element>): void;
|
|
87
|
+
/**
|
|
88
|
+
* Lazily creates the requested top-level definition field on the entry
|
|
89
|
+
* document, returning the field where a fragment is hoisted.
|
|
90
|
+
*/
|
|
91
|
+
protected ensureField(field: string): ObjectElement;
|
|
92
|
+
/**
|
|
93
|
+
* Derives a component name from the referenced JSON Pointer's last token,
|
|
94
|
+
* falling back to the referenced file's basename.
|
|
95
|
+
*/
|
|
96
|
+
protected basenameOf(jsonPointer: string, baseURI: string): string;
|
|
97
|
+
/**
|
|
98
|
+
* Computes the base component name (before collision suffixing) according to
|
|
99
|
+
* the configured naming strategy.
|
|
100
|
+
*/
|
|
101
|
+
protected baseName(element: Element, field: string, jsonPointer: string, baseURI: string): string;
|
|
102
|
+
/**
|
|
103
|
+
* Computes a collision-free component name within the target field. A name is
|
|
104
|
+
* taken if it's already placed in the field or reserved by a component that
|
|
105
|
+
* is still being bundled (reserved before recursion).
|
|
106
|
+
*/
|
|
107
|
+
protected uniqueName(candidate: string, field: string): string;
|
|
108
|
+
/**
|
|
109
|
+
* Bundles a Reference Object (parameters/responses) or a JSON Reference
|
|
110
|
+
* Object (schemas). The two reference flavors differ only in their predicate
|
|
111
|
+
* and refraction helpers, so the shared logic is parameterized here.
|
|
112
|
+
*/
|
|
113
|
+
protected bundleReference(path: Path<Element>, referencingElement: ReferenceElement | JSONReferenceElement, isSemanticReference: (element: Element) => boolean, isReferenceLike: (element: Element) => boolean, refractReferenceFn: (element: Element) => Element, label: string): Promise<void>;
|
|
114
|
+
/**
|
|
115
|
+
* Reference Object covers reusable Parameter and Response Objects, which are
|
|
116
|
+
* hoisted into the top-level `parameters` and `responses` fields.
|
|
117
|
+
*/
|
|
118
|
+
ReferenceElement(path: Path<Element>): Promise<void>;
|
|
119
|
+
/**
|
|
120
|
+
* JSON Reference Object covers reusable Schema Objects, which are hoisted
|
|
121
|
+
* into the top-level `definitions` field.
|
|
122
|
+
*/
|
|
123
|
+
JSONReferenceElement(path: Path<Element>): Promise<void>;
|
|
124
|
+
/**
|
|
125
|
+
* Path Item Object is not a top-level definition field in OpenAPI 2.0, so an
|
|
126
|
+
* external Path Item reference cannot be hoisted; it is inlined in place
|
|
127
|
+
* instead, after bundling its own external references.
|
|
128
|
+
*/
|
|
129
|
+
PathItemElement(path: Path<Element>): Promise<void>;
|
|
130
|
+
}
|
|
131
|
+
export default OpenAPI2BundleVisitor;
|
|
@@ -68,11 +68,11 @@ declare class OpenAPI3_0BundleVisitor {
|
|
|
68
68
|
protected toBaseURI(uri: string): string;
|
|
69
69
|
protected toReference(uri: string): Promise<Reference>;
|
|
70
70
|
/**
|
|
71
|
-
* Normalizes a self-
|
|
71
|
+
* Normalizes a self-reference (e.g. `./root.json#/components/schemas/Pet`)
|
|
72
72
|
* to a bare fragment (`#/components/schemas/Pet`) so the bundled document stays
|
|
73
73
|
* transferable. Bare fragments are returned unchanged.
|
|
74
74
|
*/
|
|
75
|
-
protected
|
|
75
|
+
protected normalizeSelfReference(ref: string): string;
|
|
76
76
|
/**
|
|
77
77
|
* Handles an error according to the `bundle.continueOnError` option.
|
|
78
78
|
*
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { ParseResultElement } from '@speclynx/apidom-datamodel';
|
|
2
2
|
import File from '../../../File.ts';
|
|
3
3
|
import BundleStrategy, { BundleStrategyOptions } from '../BundleStrategy.ts';
|
|
4
|
+
import OpenAPI3_1BundleVisitor from './visitor.ts';
|
|
5
|
+
import type { ReferenceOptions } from '../../../options/index.ts';
|
|
4
6
|
export type { default as DereferenceStrategy, DereferenceStrategyOptions, } from '../../../dereference/strategies/DereferenceStrategy.ts';
|
|
5
7
|
export type { default as File, FileOptions } from '../../../File.ts';
|
|
6
8
|
export type { default as Reference, ReferenceOptions } from '../../../Reference.ts';
|
|
7
9
|
export type { default as ReferenceSet, ReferenceSetOptions } from '../../../ReferenceSet.ts';
|
|
10
|
+
export type { OpenAPI3_1BundleVisitorOptions } from './visitor.ts';
|
|
8
11
|
export type { ReferenceOptions as ApiDOMReferenceOptions, ReferenceBundleOptions as ApiDOMReferenceBundleOptions, ReferenceDereferenceOptions as ApiDOMReferenceDereferenceOptions, ReferenceParseOptions as ApiDOMReferenceParseOptions, ReferenceResolveOptions as ApiDOMReferenceResolveOptions, } from '../../../options/index.ts';
|
|
9
12
|
export type { default as Parser, ParserOptions } from '../../../parse/parsers/Parser.ts';
|
|
10
13
|
export type { default as Resolver, ResolverOptions } from '../../../resolve/resolvers/Resolver.ts';
|
|
11
14
|
export type { default as ResolveStrategy, ResolveStrategyOptions, } from '../../../resolve/strategies/ResolveStrategy.ts';
|
|
12
15
|
export type { default as BundleStrategy, BundleStrategyOptions } from '../BundleStrategy.ts';
|
|
16
|
+
export type { ComponentNamesStrategy, ComponentNameResolver, ComponentNameResolverArgs, ComponentNameCollisionSeverity, } from '../../../options/index.ts';
|
|
13
17
|
/**
|
|
14
18
|
* @public
|
|
15
19
|
*/
|
|
@@ -21,6 +25,7 @@ export interface OpenAPI3_1BundleStrategyOptions extends Omit<BundleStrategyOpti
|
|
|
21
25
|
declare class OpenAPI3_1BundleStrategy extends BundleStrategy {
|
|
22
26
|
constructor(options?: OpenAPI3_1BundleStrategyOptions);
|
|
23
27
|
canBundle(file: File): boolean;
|
|
24
|
-
bundle(file: File): Promise<ParseResultElement>;
|
|
28
|
+
bundle(file: File, options: ReferenceOptions): Promise<ParseResultElement>;
|
|
25
29
|
}
|
|
30
|
+
export { OpenAPI3_1BundleVisitor };
|
|
26
31
|
export default OpenAPI3_1BundleStrategy;
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { Element, ObjectElement, ParseResultElement } from '@speclynx/apidom-datamodel';
|
|
2
|
+
import { type Path } from '@speclynx/apidom-traverse';
|
|
3
|
+
import { OpenApi3_1Element } from '@speclynx/apidom-ns-openapi-3-1';
|
|
4
|
+
import Reference from '../../../Reference.ts';
|
|
5
|
+
import type { ReferenceOptions } from '../../../options/index.ts';
|
|
6
|
+
/**
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
export interface OpenAPI3_1BundleVisitorOptions {
|
|
10
|
+
readonly reference: Reference;
|
|
11
|
+
readonly options: ReferenceOptions;
|
|
12
|
+
readonly assignments?: Map<string, string>;
|
|
13
|
+
readonly reservedNames?: Map<string, Set<string>>;
|
|
14
|
+
readonly refractCache?: WeakMap<Element, Map<string, Element>>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* @public
|
|
18
|
+
*/
|
|
19
|
+
declare class OpenAPI3_1BundleVisitor {
|
|
20
|
+
protected readonly reference: Reference;
|
|
21
|
+
protected readonly options: ReferenceOptions;
|
|
22
|
+
/**
|
|
23
|
+
* The base URI (without hash) of the entry document. A reference is
|
|
24
|
+
* considered internal when it resolves to this URI and external otherwise.
|
|
25
|
+
* Derived from the shared refSet's root reference.
|
|
26
|
+
*/
|
|
27
|
+
protected get entryURI(): string;
|
|
28
|
+
/**
|
|
29
|
+
* The entry parse result. Derived from the shared refSet's root reference.
|
|
30
|
+
*/
|
|
31
|
+
protected get entryParseResult(): ParseResultElement;
|
|
32
|
+
/**
|
|
33
|
+
* The entry document element. Hoisted external fragments are placed into its
|
|
34
|
+
* `components` object. The `canBundle` guard guarantees it is an
|
|
35
|
+
* OpenApi3_1Element.
|
|
36
|
+
*/
|
|
37
|
+
protected get entryResult(): OpenApi3_1Element;
|
|
38
|
+
/**
|
|
39
|
+
* Shared across the entry document and every external document visitor.
|
|
40
|
+
* Guarantees each external fragment is hoisted exactly once and gives us a
|
|
41
|
+
* stable internal pointer to rewrite every referencing element to.
|
|
42
|
+
*/
|
|
43
|
+
protected readonly assignments: Map<string, string>;
|
|
44
|
+
/**
|
|
45
|
+
* Component names already reserved per Components Object field. Reserved
|
|
46
|
+
* before recursion so collision suffixing (`Pet`, `Pet-2`, ...) accounts for
|
|
47
|
+
* components that are still being bundled.
|
|
48
|
+
*/
|
|
49
|
+
protected readonly reservedNames: Map<string, Set<string>>;
|
|
50
|
+
/**
|
|
51
|
+
* Caches refracted fragments keyed by source element and target element type.
|
|
52
|
+
* The type is part of the key because the same source can be refracted into
|
|
53
|
+
* different semantic elements depending on the referencing context (e.g. a
|
|
54
|
+
* generic object referenced once as a Parameter and once as a Response).
|
|
55
|
+
*/
|
|
56
|
+
protected readonly refractCache: WeakMap<Element, Map<string, Element>>;
|
|
57
|
+
constructor({ reference, options, assignments, reservedNames, refractCache, }: OpenAPI3_1BundleVisitorOptions);
|
|
58
|
+
protected getRefracted(source: Element, type: string): Element | undefined;
|
|
59
|
+
protected setRefracted(source: Element, type: string, refracted: Element): void;
|
|
60
|
+
protected toBaseURI(uri: string): string;
|
|
61
|
+
protected toReference(uri: string): Promise<Reference>;
|
|
62
|
+
/**
|
|
63
|
+
* Normalizes a self-reference (e.g. `./root.json#/components/schemas/Pet`)
|
|
64
|
+
* to a bare fragment (`#/components/schemas/Pet`) so the bundled document stays
|
|
65
|
+
* transferable. Bare fragments are returned unchanged.
|
|
66
|
+
*/
|
|
67
|
+
protected normalizeSelfReference(ref: string): string;
|
|
68
|
+
/**
|
|
69
|
+
* Handles an error according to the `bundle.continueOnError` option.
|
|
70
|
+
*
|
|
71
|
+
* For new errors: wraps in UnresolvableReferenceError with structured
|
|
72
|
+
* context. For errors already wrapped by a nested visitor: prepends the
|
|
73
|
+
* current hop to the trace.
|
|
74
|
+
*
|
|
75
|
+
* Inner/intermediate visitors always throw to let the trace accumulate. Only
|
|
76
|
+
* the entry document visitor respects continueOnError (callback/swallow/throw).
|
|
77
|
+
*/
|
|
78
|
+
protected handleError(message: string, error: Error, referencingElement: Element, refFieldName: string, refFieldValue: string, visitorPath: Path<Element>): void;
|
|
79
|
+
/**
|
|
80
|
+
* Lazily creates the Components Object (and the requested field within it)
|
|
81
|
+
* on the entry document, returning the field where a fragment is hoisted.
|
|
82
|
+
*/
|
|
83
|
+
protected ensureComponentsField(field: string): ObjectElement;
|
|
84
|
+
/**
|
|
85
|
+
* Derives a component name from the referenced JSON Pointer's last token,
|
|
86
|
+
* falling back to the referenced file's basename.
|
|
87
|
+
*/
|
|
88
|
+
protected basenameOf(jsonPointer: string, baseURI: string): string;
|
|
89
|
+
/**
|
|
90
|
+
* Computes the base component name (before collision suffixing) according to
|
|
91
|
+
* the configured naming strategy.
|
|
92
|
+
*/
|
|
93
|
+
protected baseName(element: Element, field: string, jsonPointer: string, baseURI: string): string;
|
|
94
|
+
/**
|
|
95
|
+
* Computes a collision-free component name within the target field. A name is
|
|
96
|
+
* taken if it's already placed in components or reserved by a component that
|
|
97
|
+
* is still being bundled (reserved before recursion).
|
|
98
|
+
*/
|
|
99
|
+
protected uniqueName(candidate: string, field: string): string;
|
|
100
|
+
/**
|
|
101
|
+
* Reports a collision-forced rename according to the configured severity.
|
|
102
|
+
* A rename means two distinct targets resolved to the same name; each keeps
|
|
103
|
+
* its own component (and origin), so report the rename per severity.
|
|
104
|
+
*/
|
|
105
|
+
protected reportNameCollision(preferredName: string, componentName: string, field: string): void;
|
|
106
|
+
ReferenceElement(path: Path<Element>): Promise<void>;
|
|
107
|
+
/**
|
|
108
|
+
* Unlike OpenAPI 3.0 (which has no `components.pathItems` field and therefore
|
|
109
|
+
* inlines external Path Items in place), OpenAPI 3.1 hoists an external Path
|
|
110
|
+
* Item Object into `components.pathItems` and rewrites the referencing `$ref`
|
|
111
|
+
* to an internal pointer — mirroring how Reference Objects are bundled.
|
|
112
|
+
* Sibling fields next to the `$ref` (e.g. `summary`, `description`) are kept
|
|
113
|
+
* on the referencing element.
|
|
114
|
+
*/
|
|
115
|
+
PathItemElement(path: Path<Element>): Promise<void>;
|
|
116
|
+
/**
|
|
117
|
+
* Schema Objects in OpenAPI 3.1 are a JSON Schema 2020-12 dialect, so they are
|
|
118
|
+
* bundled per the JSON Schema Compound Document rules: the external schema
|
|
119
|
+
* RESOURCE is embedded verbatim into `components.schemas` (carrying its `$id`),
|
|
120
|
+
* and the referencing `$ref` is left UNCHANGED — it keeps resolving against the
|
|
121
|
+
* embedded resource's `$id`. This mirrors the canonical hyperjump
|
|
122
|
+
* `json-schema-bundle` behavior (the whole resource is embedded once, keyed by
|
|
123
|
+
* its `$id`; references are not rewritten).
|
|
124
|
+
*/
|
|
125
|
+
SchemaElement(path: Path<Element>): Promise<void>;
|
|
126
|
+
/**
|
|
127
|
+
* Example Object `externalValue` points at arbitrary external content that
|
|
128
|
+
* has no place in the Components Object. The referenced value is inlined into
|
|
129
|
+
* the Example's `value` field.
|
|
130
|
+
*/
|
|
131
|
+
ExampleElement(path: Path<Element>): Promise<void>;
|
|
132
|
+
/**
|
|
133
|
+
* Link Object `operationRef` points at an Operation Object, which has no
|
|
134
|
+
* Components Object field in OpenAPI 3.1 and therefore cannot be hoisted or
|
|
135
|
+
* inlined. To keep the link resolvable from the bundled document, an external
|
|
136
|
+
* `operationRef` is rewritten to its absolute URI. Internal `operationRef`
|
|
137
|
+
* values and `operationId` links are left untouched.
|
|
138
|
+
*/
|
|
139
|
+
LinkElement(path: Path<Element>): Promise<void>;
|
|
140
|
+
}
|
|
141
|
+
export default OpenAPI3_1BundleVisitor;
|
package/types/util/url.d.ts
CHANGED
|
@@ -23,6 +23,14 @@ export declare const hasProtocol: (url: string) => boolean;
|
|
|
23
23
|
* @public
|
|
24
24
|
*/
|
|
25
25
|
export declare const getExtension: (url: string) => string;
|
|
26
|
+
/**
|
|
27
|
+
* Returns the final path segment of the given URI with its file extension
|
|
28
|
+
* removed (e.g. `./schemas/Pet.json` -> `Pet`). Returns the whole segment when
|
|
29
|
+
* there is no extension, and the whole URI when there is no path segment
|
|
30
|
+
* (e.g. a URN).
|
|
31
|
+
* @public
|
|
32
|
+
*/
|
|
33
|
+
export declare const getBasename: (uri: string) => string;
|
|
26
34
|
/**
|
|
27
35
|
* Determines whether the given path is a filesystem path.
|
|
28
36
|
* This includes "file://" URLs.
|