@scalar/openapi-parser 0.9.0 → 0.10.1
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 +16 -0
- package/dist/utils/details.d.ts +3 -2
- package/dist/utils/details.d.ts.map +1 -1
- package/dist/utils/details.js +7 -0
- package/dist/utils/normalize.d.ts +3 -2
- package/dist/utils/normalize.d.ts.map +1 -1
- package/dist/utils/normalize.js +8 -2
- package/dist/utils/resolveReferences.d.ts.map +1 -1
- package/dist/utils/resolveReferences.js +40 -44
- package/dist/utils/upgrade.d.ts.map +1 -1
- package/dist/utils/upgrade.js +6 -0
- package/dist/utils/upgradeFromThreeToThreeOne.d.ts +24 -3
- package/dist/utils/upgradeFromThreeToThreeOne.d.ts.map +1 -1
- package/dist/utils/upgradeFromThreeToThreeOne.js +4 -2
- package/dist/utils/upgradeFromTwoToThree.d.ts +3 -2
- package/dist/utils/upgradeFromTwoToThree.d.ts.map +1 -1
- package/dist/utils/upgradeFromTwoToThree.js +24 -18
- package/package.json +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @scalar/openapi-parser
|
|
2
2
|
|
|
3
|
+
## 0.10.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- c263aaf: feat: better deal with empty OpenAPI documents
|
|
8
|
+
|
|
9
|
+
## 0.10.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- fbef0c3: fix(openapi-parser): improve performance
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- fbef0c3: fix: doesn’t validate files with external references
|
|
18
|
+
|
|
3
19
|
## 0.9.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
package/dist/utils/details.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { UnknownObject } from '@scalar/types/utils';
|
|
2
|
+
import type { DetailsResult } from '../types';
|
|
2
3
|
/**
|
|
3
4
|
* Get versions of the OpenAPI document.
|
|
4
5
|
*/
|
|
5
|
-
export declare function details(specification:
|
|
6
|
+
export declare function details(specification: UnknownObject): DetailsResult;
|
|
6
7
|
//# sourceMappingURL=details.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"details.d.ts","sourceRoot":"","sources":["../../src/utils/details.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"details.d.ts","sourceRoot":"","sources":["../../src/utils/details.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAGxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAE7C;;GAEG;AACH,wBAAgB,OAAO,CAAC,aAAa,EAAE,aAAa,GAAG,aAAa,CA2BnE"}
|
package/dist/utils/details.js
CHANGED
|
@@ -4,6 +4,13 @@ import { OpenApiVersions } from '../configuration/index.js';
|
|
|
4
4
|
* Get versions of the OpenAPI document.
|
|
5
5
|
*/
|
|
6
6
|
function details(specification) {
|
|
7
|
+
if (specification === null) {
|
|
8
|
+
return {
|
|
9
|
+
version: undefined,
|
|
10
|
+
specificationType: undefined,
|
|
11
|
+
specificationVersion: undefined,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
7
14
|
for (const version of new Set(OpenApiVersions)) {
|
|
8
15
|
const specificationType = version === '2.0' ? 'swagger' : 'openapi';
|
|
9
16
|
const value = specification[specificationType];
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { UnknownObject } from '@scalar/types/utils';
|
|
2
|
+
import type { Filesystem } from '../types';
|
|
2
3
|
/**
|
|
3
4
|
* Normalize the OpenAPI document (YAML, JSON, object) to a JavaScript object.
|
|
4
5
|
*
|
|
5
6
|
* Doesn’t modify the object if it’s a `Filesystem` (multiple files) already.
|
|
6
7
|
*/
|
|
7
|
-
export declare function normalize(specification: string |
|
|
8
|
+
export declare function normalize(specification: string | UnknownObject | Filesystem): UnknownObject | Filesystem;
|
|
8
9
|
//# sourceMappingURL=normalize.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/utils/normalize.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/utils/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAGxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAG1C;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,aAAa,EAAE,MAAM,GAAG,aAAa,GAAG,UAAU,GACjD,aAAa,GAAG,UAAU,CAwB5B"}
|
package/dist/utils/normalize.js
CHANGED
|
@@ -7,10 +7,13 @@ import { isFilesystem } from './isFilesystem.js';
|
|
|
7
7
|
* Doesn’t modify the object if it’s a `Filesystem` (multiple files) already.
|
|
8
8
|
*/
|
|
9
9
|
function normalize(specification) {
|
|
10
|
-
if (
|
|
11
|
-
return
|
|
10
|
+
if (specification === null) {
|
|
11
|
+
return {};
|
|
12
12
|
}
|
|
13
13
|
if (typeof specification === 'string') {
|
|
14
|
+
if (specification.trim() === '') {
|
|
15
|
+
return {};
|
|
16
|
+
}
|
|
14
17
|
try {
|
|
15
18
|
return JSON.parse(specification);
|
|
16
19
|
}
|
|
@@ -20,6 +23,9 @@ function normalize(specification) {
|
|
|
20
23
|
});
|
|
21
24
|
}
|
|
22
25
|
}
|
|
26
|
+
if (isFilesystem(specification)) {
|
|
27
|
+
return specification;
|
|
28
|
+
}
|
|
23
29
|
return specification;
|
|
24
30
|
}
|
|
25
31
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveReferences.d.ts","sourceRoot":"","sources":["../../src/utils/resolveReferences.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAGpD,OAAO,KAAK,EACV,SAAS,EACT,WAAW,EACX,UAAU,EACV,eAAe,EACf,kBAAkB,EACnB,MAAM,UAAU,CAAA;AAejB,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,OAAO,CAAA;IACd,MAAM,EAAE,WAAW,EAAE,CAAA;IACrB,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG,kBAAkB,GAAG;IAC1D,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,SAAS,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;CACnE,CAAA;AAOD;;GAEG;AACH,wBAAgB,iBAAiB,CAE/B,KAAK,EAAE,SAAS,GAAG,UAAU,EAE7B,OAAO,CAAC,EAAE,wBAAwB,EAElC,IAAI,CAAC,EAAE,eAAe,EAEtB,MAAM,CAAC,EAAE,WAAW,EAAE,GACrB,uBAAuB,
|
|
1
|
+
{"version":3,"file":"resolveReferences.d.ts","sourceRoot":"","sources":["../../src/utils/resolveReferences.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAGpD,OAAO,KAAK,EACV,SAAS,EACT,WAAW,EACX,UAAU,EACV,eAAe,EACf,kBAAkB,EACnB,MAAM,UAAU,CAAA;AAejB,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,OAAO,CAAA;IACd,MAAM,EAAE,WAAW,EAAE,CAAA;IACrB,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG,kBAAkB,GAAG;IAC1D,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,SAAS,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;CACnE,CAAA;AAOD;;GAEG;AACH,wBAAgB,iBAAiB,CAE/B,KAAK,EAAE,SAAS,GAAG,UAAU,EAE7B,OAAO,CAAC,EAAE,wBAAwB,EAElC,IAAI,CAAC,EAAE,eAAe,EAEtB,MAAM,CAAC,EAAE,WAAW,EAAE,GACrB,uBAAuB,CAqGzB"}
|
|
@@ -26,10 +26,7 @@ errors) {
|
|
|
26
26
|
// Get the main file
|
|
27
27
|
const entrypoint = getEntrypoint(filesystem);
|
|
28
28
|
// Recursively resolve all references
|
|
29
|
-
resolve(file?.specification ?? entrypoint.specification, filesystem, file ?? entrypoint
|
|
30
|
-
// If we replace references with content, that includes a reference, we can’t deal with that right-away.
|
|
31
|
-
// That’s why we need a second run.
|
|
32
|
-
resolve(file?.specification ?? entrypoint.specification, filesystem, file ?? entrypoint, options?.onDereference);
|
|
29
|
+
resolve(file?.specification ?? entrypoint.specification, filesystem, file ?? entrypoint);
|
|
33
30
|
// Remove duplicats (according to message) from errors
|
|
34
31
|
errors = errors.filter((error, index, self) => index ===
|
|
35
32
|
self.findIndex((t) => t.message === error.message && t.code === error.code));
|
|
@@ -43,49 +40,46 @@ errors) {
|
|
|
43
40
|
/**
|
|
44
41
|
* Resolves the circular reference to an object and deletes the $ref properties.
|
|
45
42
|
*/
|
|
46
|
-
function resolve(schema, resolveFilesystem, resolveFile,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
43
|
+
function resolve(schema, resolveFilesystem, resolveFile,
|
|
44
|
+
// references to resolved object
|
|
45
|
+
resolved = new WeakSet()) {
|
|
46
|
+
let result = { errors: [] };
|
|
47
|
+
if (schema === null || resolved.has(schema))
|
|
48
|
+
return result;
|
|
49
|
+
resolved.add(schema);
|
|
50
|
+
function resolveExternal(externalFile) {
|
|
51
|
+
resolve(externalFile.specification, resolveFilesystem, externalFile, resolved);
|
|
52
|
+
return externalFile;
|
|
53
|
+
}
|
|
54
|
+
// Ignore parts without a reference
|
|
55
|
+
while (schema.$ref !== undefined) {
|
|
56
|
+
// Find the referenced content
|
|
57
|
+
const target = resolveUri(schema.$ref, options, resolveFile, resolveFilesystem, resolveExternal, errors);
|
|
58
|
+
// invalid
|
|
59
|
+
if (typeof target !== 'object' || target === null)
|
|
60
|
+
break;
|
|
61
|
+
options?.onDereference?.({ schema, ref: schema.$ref });
|
|
62
|
+
// Get rid of the reference
|
|
63
|
+
delete schema.$ref;
|
|
64
|
+
for (const key of Object.keys(target)) {
|
|
65
|
+
if (schema[key] === undefined) {
|
|
66
|
+
schema[key] = target[key];
|
|
66
67
|
}
|
|
67
68
|
}
|
|
68
|
-
|
|
69
|
-
|
|
69
|
+
}
|
|
70
|
+
// Iterate over the whole object
|
|
71
|
+
for (const value of Object.values(schema)) {
|
|
72
|
+
if (typeof value === 'object' && value !== null) {
|
|
73
|
+
result = resolve(value, resolveFilesystem, resolveFile, resolved);
|
|
70
74
|
}
|
|
71
|
-
}
|
|
72
|
-
return
|
|
73
|
-
errors: result?.errors ?? [],
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
// TODO: Is there a better way? :D
|
|
78
|
-
function isCircular(schema) {
|
|
79
|
-
try {
|
|
80
|
-
JSON.stringify(schema);
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
|
-
catch (error) {
|
|
84
|
-
return true;
|
|
75
|
+
}
|
|
76
|
+
return result;
|
|
85
77
|
}
|
|
86
78
|
}
|
|
87
79
|
/**
|
|
88
80
|
* Resolves a URI to a part of the specification
|
|
81
|
+
*
|
|
82
|
+
* The output is not necessarily dereferenced
|
|
89
83
|
*/
|
|
90
84
|
function resolveUri(
|
|
91
85
|
// 'foobar.json#/foo/bar'
|
|
@@ -93,7 +87,9 @@ uri, options,
|
|
|
93
87
|
// { filename: './foobar.json '}
|
|
94
88
|
file,
|
|
95
89
|
// [ { filename: './foobar.json '} ]
|
|
96
|
-
filesystem,
|
|
90
|
+
filesystem,
|
|
91
|
+
// a function to resolve references in external file
|
|
92
|
+
resolve, errors) {
|
|
97
93
|
// Ignore invalid URIs
|
|
98
94
|
if (typeof uri !== 'string') {
|
|
99
95
|
if (options?.throwOnError) {
|
|
@@ -124,13 +120,13 @@ filesystem, errors) {
|
|
|
124
120
|
});
|
|
125
121
|
return;
|
|
126
122
|
}
|
|
127
|
-
const result = resolveReferences(filesystem, options, externalReference, errors);
|
|
128
123
|
// $ref: 'other-file.yaml'
|
|
129
124
|
if (path === undefined) {
|
|
130
|
-
return
|
|
125
|
+
return externalReference.specification;
|
|
131
126
|
}
|
|
132
127
|
// $ref: 'other-file.yaml#/foo/bar'
|
|
133
|
-
|
|
128
|
+
// resolve refs first before accessing properties directly
|
|
129
|
+
return resolveUri(`#${path}`, options, resolve(externalReference), filesystem, resolve, errors);
|
|
134
130
|
}
|
|
135
131
|
// Pointers
|
|
136
132
|
const segments = getSegmentsFromPath(path);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/utils/upgrade.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAMpE;;GAEG;AACH,wBAAgB,OAAO,CACrB,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GACrC,aAAa,CAAC,WAAW,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/utils/upgrade.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAMpE;;GAEG;AACH,wBAAgB,OAAO,CACrB,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GACrC,aAAa,CAAC,WAAW,CAAC,QAAQ,CAAC,CAoBrC"}
|
package/dist/utils/upgrade.js
CHANGED
|
@@ -7,6 +7,12 @@ import { upgradeFromTwoToThree } from './upgradeFromTwoToThree.js';
|
|
|
7
7
|
* Upgrade specification to OpenAPI 3.1.0
|
|
8
8
|
*/
|
|
9
9
|
function upgrade(value) {
|
|
10
|
+
if (!value) {
|
|
11
|
+
return {
|
|
12
|
+
specification: null,
|
|
13
|
+
version: '3.1',
|
|
14
|
+
};
|
|
15
|
+
}
|
|
10
16
|
const upgraders = [upgradeFromTwoToThree, upgradeFromThreeToThreeOne];
|
|
11
17
|
// TODO: Run upgrade over the whole filesystem
|
|
12
18
|
const result = upgraders.reduce((currentSpecification, upgrader) => upgrader(currentSpecification), getEntrypoint(makeFilesystem(value)).specification);
|
|
@@ -1,10 +1,31 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { OpenAPIV3_1 } from '@scalar/openapi-types';
|
|
2
|
+
import type { UnknownObject } from '@scalar/types/utils';
|
|
2
3
|
/**
|
|
3
|
-
* Upgrade from OpenAPI 3.0.x to 3.1.
|
|
4
|
+
* Upgrade from OpenAPI 3.0.x to 3.1.1
|
|
4
5
|
*
|
|
5
6
|
* https://www.openapis.org/blog/2021/02/16/migrating-from-openapi-3-0-to-3-1-0
|
|
6
7
|
*/
|
|
7
|
-
export declare function upgradeFromThreeToThreeOne(originalSpecification:
|
|
8
|
+
export declare function upgradeFromThreeToThreeOne(originalSpecification: UnknownObject): (Omit<Omit<import("@scalar/openapi-types").OpenAPIV3.Document<{}>, "paths" | "components">, keyof {
|
|
9
|
+
[customExtension: `x-${string}`]: any;
|
|
10
|
+
[key: string]: any;
|
|
11
|
+
}> & {
|
|
12
|
+
openapi?: "3.1.0" | "3.1.1";
|
|
13
|
+
swagger?: undefined;
|
|
14
|
+
info?: OpenAPIV3_1.InfoObject;
|
|
15
|
+
jsonSchemaDialect?: string;
|
|
16
|
+
servers?: OpenAPIV3_1.ServerObject[];
|
|
17
|
+
} & Pick<{
|
|
18
|
+
paths?: OpenAPIV3_1.PathsObject<{}, {}>;
|
|
19
|
+
webhooks?: Record<string, OpenAPIV3_1.PathItemObject | OpenAPIV3_1.ReferenceObject>;
|
|
20
|
+
components?: OpenAPIV3_1.ComponentsObject;
|
|
21
|
+
}, "paths"> & Omit<Partial<{
|
|
22
|
+
paths?: OpenAPIV3_1.PathsObject<{}, {}>;
|
|
23
|
+
webhooks?: Record<string, OpenAPIV3_1.PathItemObject | OpenAPIV3_1.ReferenceObject>;
|
|
24
|
+
components?: OpenAPIV3_1.ComponentsObject;
|
|
25
|
+
}>, "paths"> & {
|
|
26
|
+
[customExtension: `x-${string}`]: any;
|
|
27
|
+
[key: string]: any;
|
|
28
|
+
}) | UnknownObject;
|
|
8
29
|
/** Determine if the current path is within a schema */
|
|
9
30
|
export declare function isSchemaPath(path: string[]): boolean;
|
|
10
31
|
//# sourceMappingURL=upgradeFromThreeToThreeOne.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgradeFromThreeToThreeOne.d.ts","sourceRoot":"","sources":["../../src/utils/upgradeFromThreeToThreeOne.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"upgradeFromThreeToThreeOne.d.ts","sourceRoot":"","sources":["../../src/utils/upgradeFromThreeToThreeOne.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAIxD;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,qBAAqB,EAAE,aAAa;;;;;;;;;;;;;;;;;;;;mBAkHrC;AAED,uDAAuD;AACvD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAsBpD"}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { traverse } from './traverse.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Upgrade from OpenAPI 3.0.x to 3.1.
|
|
4
|
+
* Upgrade from OpenAPI 3.0.x to 3.1.1
|
|
5
5
|
*
|
|
6
6
|
* https://www.openapis.org/blog/2021/02/16/migrating-from-openapi-3-0-to-3-1-0
|
|
7
7
|
*/
|
|
8
8
|
function upgradeFromThreeToThreeOne(originalSpecification) {
|
|
9
9
|
let specification = originalSpecification;
|
|
10
10
|
// Version
|
|
11
|
-
if (specification
|
|
11
|
+
if (specification !== null &&
|
|
12
|
+
typeof specification.openapi === 'string' &&
|
|
13
|
+
specification.openapi.startsWith('3.0')) {
|
|
12
14
|
specification.openapi = '3.1.1';
|
|
13
15
|
}
|
|
14
16
|
else {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { OpenAPIV3 } from '@scalar/openapi-types';
|
|
2
|
+
import type { UnknownObject } from '@scalar/types/utils';
|
|
2
3
|
/**
|
|
3
4
|
* Upgrade Swagger 2.0 to OpenAPI 3.0
|
|
4
5
|
*
|
|
5
6
|
* https://swagger.io/blog/news/whats-new-in-openapi-3-0/
|
|
6
7
|
*/
|
|
7
|
-
export declare function upgradeFromTwoToThree(
|
|
8
|
+
export declare function upgradeFromTwoToThree(originalSpecification: UnknownObject): OpenAPIV3.Document<{}> | UnknownObject;
|
|
8
9
|
//# sourceMappingURL=upgradeFromTwoToThree.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgradeFromTwoToThree.d.ts","sourceRoot":"","sources":["../../src/utils/upgradeFromTwoToThree.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"upgradeFromTwoToThree.d.ts","sourceRoot":"","sources":["../../src/utils/upgradeFromTwoToThree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAIxD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,qBAAqB,EAAE,aAAa,0CAkQzE"}
|
|
@@ -5,9 +5,12 @@ import { traverse } from './traverse.js';
|
|
|
5
5
|
*
|
|
6
6
|
* https://swagger.io/blog/news/whats-new-in-openapi-3-0/
|
|
7
7
|
*/
|
|
8
|
-
function upgradeFromTwoToThree(
|
|
8
|
+
function upgradeFromTwoToThree(originalSpecification) {
|
|
9
|
+
let specification = originalSpecification;
|
|
9
10
|
// Version
|
|
10
|
-
if (specification
|
|
11
|
+
if (specification !== null &&
|
|
12
|
+
typeof specification.swagger === 'string' &&
|
|
13
|
+
specification.swagger?.startsWith('2.0')) {
|
|
11
14
|
specification.openapi = '3.0.4';
|
|
12
15
|
delete specification.swagger;
|
|
13
16
|
}
|
|
@@ -18,7 +21,7 @@ function upgradeFromTwoToThree(specification) {
|
|
|
18
21
|
console.warn(`[upgradeFromTwoToThree] The upgrade from Swagger 2.0 to OpenAPI 3.0 documents is experimental and lacks features.`);
|
|
19
22
|
// Servers
|
|
20
23
|
if (specification.host) {
|
|
21
|
-
const schemes = specification.schemes?.length
|
|
24
|
+
const schemes = Array.isArray(specification.schemes) && specification.schemes?.length
|
|
22
25
|
? specification.schemes
|
|
23
26
|
: ['http'];
|
|
24
27
|
specification.servers = schemes.map((scheme) => ({
|
|
@@ -30,10 +33,9 @@ function upgradeFromTwoToThree(specification) {
|
|
|
30
33
|
}
|
|
31
34
|
// Schemas
|
|
32
35
|
if (specification.definitions) {
|
|
33
|
-
|
|
34
|
-
specification.
|
|
35
|
-
}
|
|
36
|
-
specification.components.schemas = specification.definitions;
|
|
36
|
+
specification.components = Object.assign({}, specification.components, {
|
|
37
|
+
schemas: specification.definitions,
|
|
38
|
+
});
|
|
37
39
|
delete specification.definitions;
|
|
38
40
|
// Rewrite $refs to definitions
|
|
39
41
|
specification = traverse(specification, (schema) => {
|
|
@@ -44,7 +46,7 @@ function upgradeFromTwoToThree(specification) {
|
|
|
44
46
|
});
|
|
45
47
|
}
|
|
46
48
|
// Paths
|
|
47
|
-
if (specification.paths) {
|
|
49
|
+
if (typeof specification.paths === 'object') {
|
|
48
50
|
for (const path in specification.paths) {
|
|
49
51
|
if (Object.hasOwn(specification.paths, path)) {
|
|
50
52
|
const pathItem = specification.paths[path];
|
|
@@ -145,24 +147,28 @@ function upgradeFromTwoToThree(specification) {
|
|
|
145
147
|
if (typeof specification.components !== 'object') {
|
|
146
148
|
specification.components = {};
|
|
147
149
|
}
|
|
148
|
-
|
|
150
|
+
// Assert that components is of type OpenAPIV3.ComponentsObject
|
|
151
|
+
specification.components =
|
|
152
|
+
specification.components;
|
|
153
|
+
Object.assign(specification.components, { securitySchemes: {} });
|
|
149
154
|
for (const [key, securityScheme] of Object.entries(specification.securityDefinitions)) {
|
|
150
155
|
if (typeof securityScheme === 'object') {
|
|
151
156
|
if ('type' in securityScheme && securityScheme.type === 'oauth2') {
|
|
152
157
|
const { flow, authorizationUrl, tokenUrl, scopes } = securityScheme;
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
158
|
+
// Assert that securitySchemes is of type OpenAPIV3.SecuritySchemeObject
|
|
159
|
+
Object.assign(specification.components
|
|
160
|
+
.securitySchemes, {
|
|
161
|
+
[key]: {
|
|
162
|
+
type: 'oauth2',
|
|
163
|
+
flows: {
|
|
164
|
+
[flow]: Object.assign({}, authorizationUrl && { authorizationUrl }, tokenUrl && { tokenUrl }, scopes && { scopes }),
|
|
160
165
|
},
|
|
161
166
|
},
|
|
162
|
-
};
|
|
167
|
+
});
|
|
163
168
|
}
|
|
164
169
|
else {
|
|
165
|
-
specification.components
|
|
170
|
+
Object.assign(specification.components
|
|
171
|
+
.securitySchemes, { [key]: securityScheme });
|
|
166
172
|
}
|
|
167
173
|
}
|
|
168
174
|
}
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"bugs": "https://github.com/scalar/scalar/issues/new/choose",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "https://github.com/scalar/scalar.git",
|
|
10
|
+
"url": "git+https://github.com/scalar/scalar.git",
|
|
11
11
|
"directory": "packages/openapi-parser"
|
|
12
12
|
},
|
|
13
13
|
"keywords": [
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"parser",
|
|
18
18
|
"typescript"
|
|
19
19
|
],
|
|
20
|
-
"version": "0.
|
|
20
|
+
"version": "0.10.1",
|
|
21
21
|
"engines": {
|
|
22
22
|
"node": ">=18"
|
|
23
23
|
},
|
|
@@ -65,7 +65,8 @@
|
|
|
65
65
|
"just-diff": "^6.0.2",
|
|
66
66
|
"tinybench": "^2.8.0",
|
|
67
67
|
"@scalar/build-tooling": "0.1.12",
|
|
68
|
-
"@scalar/openapi-types": "0.1.5"
|
|
68
|
+
"@scalar/openapi-types": "0.1.5",
|
|
69
|
+
"@scalar/types": "0.0.25"
|
|
69
70
|
},
|
|
70
71
|
"scripts": {
|
|
71
72
|
"build": "scalar-build-rollup",
|