@speclynx/apidom-ns-openapi-3-0 4.1.0 → 4.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/CHANGELOG.md +11 -0
- package/README.md +177 -0
- package/dist/apidom-ns-openapi-3-0.browser.js +759 -222
- package/dist/apidom-ns-openapi-3-0.browser.min.js +1 -1
- package/package.json +8 -7
- package/src/index.cjs +10 -2
- package/src/index.mjs +4 -0
- package/src/refractor/plugins/normalize-parameters.cjs +107 -0
- package/src/refractor/plugins/normalize-parameters.mjs +101 -0
- package/src/refractor/plugins/normalize-security-requirements.cjs +89 -0
- package/src/refractor/plugins/normalize-security-requirements.mjs +83 -0
- package/src/refractor/plugins/normalize-servers.cjs +149 -0
- package/src/refractor/plugins/normalize-servers.mjs +143 -0
- package/src/refractor/plugins/normalize-storage/index.cjs +38 -0
- package/src/refractor/plugins/normalize-storage/index.mjs +34 -0
- package/src/refractor/toolbox.cjs +6 -1
- package/src/refractor/toolbox.mjs +7 -2
- package/types/apidom-ns-openapi-3-0.d.ts +110 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { isArrayElement } from '@speclynx/apidom-datamodel';
|
|
2
|
+
import ServersElement from "../../elements/nces/Servers.mjs";
|
|
3
|
+
import PathItemServersElement from "../../elements/nces/PathItemServers.mjs";
|
|
4
|
+
import OperationServersElement from "../../elements/nces/OperationServers.mjs";
|
|
5
|
+
import NormalizeStorage from "./normalize-storage/index.mjs";
|
|
6
|
+
import { refractServer } from "../index.mjs";
|
|
7
|
+
/**
|
|
8
|
+
* Override of Server Objects.
|
|
9
|
+
*
|
|
10
|
+
* List of Server Objects can be defined in OpenAPI 3.0 on multiple levels:
|
|
11
|
+
*
|
|
12
|
+
* - OpenAPI.servers
|
|
13
|
+
* - PathItem.servers
|
|
14
|
+
* - Operation.servers
|
|
15
|
+
*
|
|
16
|
+
* If a servers array is specified at the OpenAPI Object level, it will be overridden by `PathItem`.servers.
|
|
17
|
+
* If a servers array is specified at the Path Item Object or OpenAPI Object level, it will be overridden by Operation.servers.
|
|
18
|
+
* @public
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Ensures the OpenAPI document has at least one server defined.
|
|
22
|
+
* If `servers` is missing or empty, adds a default server with `url: "/"`.
|
|
23
|
+
* @public
|
|
24
|
+
*/
|
|
25
|
+
const ensureDefaultServer = openapiElement => {
|
|
26
|
+
const isServersUndefined = typeof openapiElement.servers === 'undefined';
|
|
27
|
+
const isServersArray = isArrayElement(openapiElement.servers);
|
|
28
|
+
const isServersEmpty = isServersArray && openapiElement.servers.length === 0;
|
|
29
|
+
const defaultServer = refractServer({
|
|
30
|
+
url: '/'
|
|
31
|
+
});
|
|
32
|
+
if (isServersUndefined || !isServersArray) {
|
|
33
|
+
openapiElement.servers = new ServersElement([defaultServer]);
|
|
34
|
+
} else if (isServersArray && isServersEmpty) {
|
|
35
|
+
openapiElement.servers.push(defaultServer);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Inherits servers from the OpenAPI root into a PathItem element.
|
|
41
|
+
* If PathItem.servers is missing or empty, copies from OpenAPI.servers.
|
|
42
|
+
* @public
|
|
43
|
+
*/
|
|
44
|
+
const inheritServersToPathItem = (pathItemElement, openapiElement) => {
|
|
45
|
+
const isServersUndefined = typeof pathItemElement.servers === 'undefined';
|
|
46
|
+
const isServersArray = isArrayElement(pathItemElement.servers);
|
|
47
|
+
const isServersEmpty = isServersArray && pathItemElement.servers.length === 0;
|
|
48
|
+
const openapiServers = [...(openapiElement.servers ?? [])];
|
|
49
|
+
if (isServersUndefined || !isServersArray) {
|
|
50
|
+
pathItemElement.servers = new PathItemServersElement(openapiServers);
|
|
51
|
+
} else if (isServersArray && isServersEmpty) {
|
|
52
|
+
openapiServers.forEach(server => {
|
|
53
|
+
pathItemElement.servers.push(server);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Inherits servers from a PathItem into an Operation element.
|
|
60
|
+
* If Operation.servers is missing or empty, copies from PathItem.servers.
|
|
61
|
+
* @public
|
|
62
|
+
*/
|
|
63
|
+
const inheritServersToOperation = (operationElement, pathItemElement) => {
|
|
64
|
+
const isServersUndefined = typeof operationElement.servers === 'undefined';
|
|
65
|
+
const isServersArray = isArrayElement(operationElement.servers);
|
|
66
|
+
const isServersEmpty = isServersArray && operationElement.servers.length === 0;
|
|
67
|
+
const pathItemServers = [...(pathItemElement.servers ?? [])];
|
|
68
|
+
if (isServersUndefined || !isServersArray) {
|
|
69
|
+
operationElement.servers = new OperationServersElement(pathItemServers);
|
|
70
|
+
} else if (isServersArray && isServersEmpty) {
|
|
71
|
+
pathItemServers.forEach(server => {
|
|
72
|
+
operationElement.servers.push(server);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* @public
|
|
79
|
+
*/
|
|
80
|
+
const plugin = ({
|
|
81
|
+
storageField = 'x-normalized'
|
|
82
|
+
} = {}) => toolbox => {
|
|
83
|
+
const {
|
|
84
|
+
predicates
|
|
85
|
+
} = toolbox;
|
|
86
|
+
let storage;
|
|
87
|
+
return {
|
|
88
|
+
visitor: {
|
|
89
|
+
OpenApi3_0Element: {
|
|
90
|
+
enter(path) {
|
|
91
|
+
const openapiElement = path.node;
|
|
92
|
+
ensureDefaultServer(openapiElement);
|
|
93
|
+
storage = new NormalizeStorage(openapiElement, storageField, 'servers');
|
|
94
|
+
},
|
|
95
|
+
leave() {
|
|
96
|
+
storage = undefined;
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
PathItemElement(path) {
|
|
100
|
+
const pathItemElement = path.node;
|
|
101
|
+
const ancestors = path.getAncestorNodes(); // parent to root order
|
|
102
|
+
|
|
103
|
+
// skip visiting this Path Item
|
|
104
|
+
if (ancestors.some(predicates.isComponentsElement)) return;
|
|
105
|
+
if (!ancestors.some(predicates.isOpenApi3_0Element)) return;
|
|
106
|
+
const pathItemJSONPointer = path.formatPath();
|
|
107
|
+
|
|
108
|
+
// skip visiting this Path Item Object if it's already normalized
|
|
109
|
+
if (storage.includes(pathItemJSONPointer)) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const parentOpenapiElement = ancestors.find(predicates.isOpenApi3_0Element);
|
|
113
|
+
if (predicates.isOpenApi3_0Element(parentOpenapiElement)) {
|
|
114
|
+
inheritServersToPathItem(pathItemElement, parentOpenapiElement);
|
|
115
|
+
storage.append(pathItemJSONPointer);
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
OperationElement(path) {
|
|
119
|
+
const operationElement = path.node;
|
|
120
|
+
const ancestors = path.getAncestorNodes(); // parent to root order
|
|
121
|
+
|
|
122
|
+
// skip visiting this Operation
|
|
123
|
+
if (ancestors.some(predicates.isComponentsElement)) return;
|
|
124
|
+
if (!ancestors.some(predicates.isOpenApi3_0Element)) return;
|
|
125
|
+
const operationJSONPointer = path.formatPath();
|
|
126
|
+
|
|
127
|
+
// skip visiting this Operation Object if it's already normalized
|
|
128
|
+
if (storage.includes(operationJSONPointer)) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const parentPathItemElement = ancestors.find(predicates.isPathItemElement);
|
|
132
|
+
if (predicates.isPathItemElement(parentPathItemElement)) {
|
|
133
|
+
inheritServersToOperation(operationElement, parentPathItemElement);
|
|
134
|
+
storage.append(operationJSONPointer);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
};
|
|
140
|
+
plugin.ensureDefaultServer = ensureDefaultServer;
|
|
141
|
+
plugin.inheritServersToPathItem = inheritServersToPathItem;
|
|
142
|
+
plugin.inheritServersToOperation = inheritServersToOperation;
|
|
143
|
+
export default plugin;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.default = void 0;
|
|
5
|
+
var _apidomDatamodel = require("@speclynx/apidom-datamodel");
|
|
6
|
+
class NormalizeStorage {
|
|
7
|
+
internalStore;
|
|
8
|
+
constructor(storageElement, storageField, storageSubField) {
|
|
9
|
+
this.storageElement = storageElement;
|
|
10
|
+
this.storageField = storageField;
|
|
11
|
+
this.storageSubField = storageSubField;
|
|
12
|
+
}
|
|
13
|
+
get store() {
|
|
14
|
+
if (this.internalStore === undefined) {
|
|
15
|
+
let rootStore = this.storageElement.get(this.storageField);
|
|
16
|
+
if (!(0, _apidomDatamodel.isObjectElement)(rootStore)) {
|
|
17
|
+
rootStore = new _apidomDatamodel.ObjectElement();
|
|
18
|
+
this.storageElement.set(this.storageField, rootStore);
|
|
19
|
+
}
|
|
20
|
+
let store = rootStore.get(this.storageSubField);
|
|
21
|
+
if (!(0, _apidomDatamodel.isArrayElement)(store)) {
|
|
22
|
+
store = new _apidomDatamodel.ArrayElement();
|
|
23
|
+
rootStore.set(this.storageSubField, store);
|
|
24
|
+
}
|
|
25
|
+
this.internalStore = store;
|
|
26
|
+
}
|
|
27
|
+
return this.internalStore;
|
|
28
|
+
}
|
|
29
|
+
append(pointer) {
|
|
30
|
+
if (!this.includes(pointer)) {
|
|
31
|
+
this.store.push(pointer);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
includes(pointer) {
|
|
35
|
+
return this.store.includes(pointer);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
var _default = exports.default = NormalizeStorage;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ArrayElement, ObjectElement, isObjectElement, isArrayElement } from '@speclynx/apidom-datamodel';
|
|
2
|
+
class NormalizeStorage {
|
|
3
|
+
internalStore;
|
|
4
|
+
constructor(storageElement, storageField, storageSubField) {
|
|
5
|
+
this.storageElement = storageElement;
|
|
6
|
+
this.storageField = storageField;
|
|
7
|
+
this.storageSubField = storageSubField;
|
|
8
|
+
}
|
|
9
|
+
get store() {
|
|
10
|
+
if (this.internalStore === undefined) {
|
|
11
|
+
let rootStore = this.storageElement.get(this.storageField);
|
|
12
|
+
if (!isObjectElement(rootStore)) {
|
|
13
|
+
rootStore = new ObjectElement();
|
|
14
|
+
this.storageElement.set(this.storageField, rootStore);
|
|
15
|
+
}
|
|
16
|
+
let store = rootStore.get(this.storageSubField);
|
|
17
|
+
if (!isArrayElement(store)) {
|
|
18
|
+
store = new ArrayElement();
|
|
19
|
+
rootStore.set(this.storageSubField, store);
|
|
20
|
+
}
|
|
21
|
+
this.internalStore = store;
|
|
22
|
+
}
|
|
23
|
+
return this.internalStore;
|
|
24
|
+
}
|
|
25
|
+
append(pointer) {
|
|
26
|
+
if (!this.includes(pointer)) {
|
|
27
|
+
this.store.push(pointer);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
includes(pointer) {
|
|
31
|
+
return this.store.includes(pointer);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export default NormalizeStorage;
|
|
@@ -12,12 +12,17 @@ var _namespace = _interopRequireDefault(require("../namespace.cjs"));
|
|
|
12
12
|
* @public
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
15
18
|
const createToolbox = () => {
|
|
16
19
|
const namespace = new _apidomDatamodel.Namespace();
|
|
17
20
|
const predicates = {
|
|
18
21
|
...refractorPredicates,
|
|
19
22
|
...openApi3_0Predicates,
|
|
20
|
-
isStringElement: _apidomDatamodel.isStringElement
|
|
23
|
+
isStringElement: _apidomDatamodel.isStringElement,
|
|
24
|
+
isArrayElement: _apidomDatamodel.isArrayElement,
|
|
25
|
+
isObjectElement: _apidomDatamodel.isObjectElement
|
|
21
26
|
};
|
|
22
27
|
namespace.use(_namespace.default);
|
|
23
28
|
return {
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import { isStringElement, Namespace } from '@speclynx/apidom-datamodel';
|
|
1
|
+
import { isStringElement, isArrayElement, isObjectElement, Namespace } from '@speclynx/apidom-datamodel';
|
|
2
2
|
import * as openApi3_0Predicates from "../predicates.mjs";
|
|
3
3
|
import * as refractorPredicates from "./predicates.mjs";
|
|
4
4
|
import openApi3_0Namespace from "../namespace.mjs";
|
|
5
|
+
/**
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
5
8
|
/**
|
|
6
9
|
* @public
|
|
7
10
|
*/
|
|
@@ -10,7 +13,9 @@ const createToolbox = () => {
|
|
|
10
13
|
const predicates = {
|
|
11
14
|
...refractorPredicates,
|
|
12
15
|
...openApi3_0Predicates,
|
|
13
|
-
isStringElement
|
|
16
|
+
isStringElement,
|
|
17
|
+
isArrayElement,
|
|
18
|
+
isObjectElement
|
|
14
19
|
};
|
|
15
20
|
namespace.use(openApi3_0Namespace);
|
|
16
21
|
return {
|
|
@@ -488,6 +488,11 @@ export declare class ContentVisitor extends BaseMapVisitor {
|
|
|
488
488
|
constructor(options: BaseMapVisitorOptions);
|
|
489
489
|
}
|
|
490
490
|
|
|
491
|
+
/**
|
|
492
|
+
* @public
|
|
493
|
+
*/
|
|
494
|
+
export declare const createToolbox: () => Toolbox;
|
|
495
|
+
|
|
491
496
|
/**
|
|
492
497
|
* @public
|
|
493
498
|
*/
|
|
@@ -1815,6 +1820,111 @@ export declare type RefractorPlugin = (toolbox: Toolbox) => {
|
|
|
1815
1820
|
post?: () => void;
|
|
1816
1821
|
};
|
|
1817
1822
|
|
|
1823
|
+
/**
|
|
1824
|
+
* @public
|
|
1825
|
+
*/
|
|
1826
|
+
export declare const refractorPluginNormalizeParameters: {
|
|
1827
|
+
({ storageField }?: RefractorPluginNormalizeParametersOptions): (toolbox: Toolbox) => {
|
|
1828
|
+
visitor: {
|
|
1829
|
+
OpenApi3_0Element: {
|
|
1830
|
+
enter(path: Path<OpenApi3_0Element>): void;
|
|
1831
|
+
leave(): void;
|
|
1832
|
+
};
|
|
1833
|
+
OperationElement: {
|
|
1834
|
+
leave(path: Path<OperationElement>): void;
|
|
1835
|
+
};
|
|
1836
|
+
};
|
|
1837
|
+
};
|
|
1838
|
+
inheritParametersToOperation: (operationElement: OperationElement, pathItemElement: PathItemElement) => void;
|
|
1839
|
+
};
|
|
1840
|
+
|
|
1841
|
+
/**
|
|
1842
|
+
* Inheritance of Parameter Objects.
|
|
1843
|
+
*
|
|
1844
|
+
* OpenAPI 3.0 specification excerpt that defines the inheritance behavior:
|
|
1845
|
+
*
|
|
1846
|
+
* A list of parameters that are applicable for this operation. If a parameter is already defined at the Path Item,
|
|
1847
|
+
* the new definition will override it but can never remove it. The list MUST NOT include duplicated parameters.
|
|
1848
|
+
* A unique parameter is defined by a combination of a name and location.
|
|
1849
|
+
*
|
|
1850
|
+
* NOTE: this plugin is idempotent
|
|
1851
|
+
* @public
|
|
1852
|
+
*/
|
|
1853
|
+
export declare interface RefractorPluginNormalizeParametersOptions {
|
|
1854
|
+
storageField?: string;
|
|
1855
|
+
}
|
|
1856
|
+
|
|
1857
|
+
/**
|
|
1858
|
+
* @public
|
|
1859
|
+
*/
|
|
1860
|
+
export declare const refractorPluginNormalizeSecurityRequirements: {
|
|
1861
|
+
({ storageField }?: RefractorPluginNormalizeSecurityRequirementsOptions): (toolbox: Toolbox) => {
|
|
1862
|
+
visitor: {
|
|
1863
|
+
OpenApi3_0Element: {
|
|
1864
|
+
enter(path: Path<OpenApi3_0Element>): void;
|
|
1865
|
+
leave(): void;
|
|
1866
|
+
};
|
|
1867
|
+
OperationElement: {
|
|
1868
|
+
leave(path: Path<OperationElement>): void;
|
|
1869
|
+
};
|
|
1870
|
+
};
|
|
1871
|
+
};
|
|
1872
|
+
inheritSecurityToOperation: (operationElement: OperationElement, openapiElement: OpenApi3_0Element) => void;
|
|
1873
|
+
};
|
|
1874
|
+
|
|
1875
|
+
/**
|
|
1876
|
+
* Override of Security Requirement Objects.
|
|
1877
|
+
*
|
|
1878
|
+
* OpenAPI 3.0 specification excerpt that defines the override behavior:
|
|
1879
|
+
*
|
|
1880
|
+
* Operation.security definition overrides any declared top-level security.
|
|
1881
|
+
* To remove a top-level security declaration, an empty array can be used.
|
|
1882
|
+
* When a list of Security Requirement Objects is defined on the OpenAPI Object or Operation Object,
|
|
1883
|
+
* only one of the Security Requirement Objects in the list needs to be satisfied to authorize the request.
|
|
1884
|
+
*
|
|
1885
|
+
* NOTE: this plugin is idempotent
|
|
1886
|
+
* @public
|
|
1887
|
+
*/
|
|
1888
|
+
export declare interface RefractorPluginNormalizeSecurityRequirementsOptions {
|
|
1889
|
+
storageField?: string;
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1892
|
+
/**
|
|
1893
|
+
* @public
|
|
1894
|
+
*/
|
|
1895
|
+
export declare const refractorPluginNormalizeServers: {
|
|
1896
|
+
({ storageField }?: RefractorPluginNormalizeServersOptions): (toolbox: Toolbox) => {
|
|
1897
|
+
visitor: {
|
|
1898
|
+
OpenApi3_0Element: {
|
|
1899
|
+
enter(path: Path<OpenApi3_0Element>): void;
|
|
1900
|
+
leave(): void;
|
|
1901
|
+
};
|
|
1902
|
+
PathItemElement(path: Path<PathItemElement>): void;
|
|
1903
|
+
OperationElement(path: Path<OperationElement>): void;
|
|
1904
|
+
};
|
|
1905
|
+
};
|
|
1906
|
+
ensureDefaultServer: (openapiElement: OpenApi3_0Element) => void;
|
|
1907
|
+
inheritServersToPathItem: (pathItemElement: PathItemElement, openapiElement: OpenApi3_0Element) => void;
|
|
1908
|
+
inheritServersToOperation: (operationElement: OperationElement, pathItemElement: PathItemElement) => void;
|
|
1909
|
+
};
|
|
1910
|
+
|
|
1911
|
+
/**
|
|
1912
|
+
* Override of Server Objects.
|
|
1913
|
+
*
|
|
1914
|
+
* List of Server Objects can be defined in OpenAPI 3.0 on multiple levels:
|
|
1915
|
+
*
|
|
1916
|
+
* - OpenAPI.servers
|
|
1917
|
+
* - PathItem.servers
|
|
1918
|
+
* - Operation.servers
|
|
1919
|
+
*
|
|
1920
|
+
* If a servers array is specified at the OpenAPI Object level, it will be overridden by `PathItem`.servers.
|
|
1921
|
+
* If a servers array is specified at the Path Item Object or OpenAPI Object level, it will be overridden by Operation.servers.
|
|
1922
|
+
* @public
|
|
1923
|
+
*/
|
|
1924
|
+
export declare interface RefractorPluginNormalizeServersOptions {
|
|
1925
|
+
storageField?: string;
|
|
1926
|
+
}
|
|
1927
|
+
|
|
1818
1928
|
/**
|
|
1819
1929
|
* @public
|
|
1820
1930
|
*/
|