@kubb/adapter-oas 5.14.4 → 5.14.6
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/dist/index.cjs +79 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +79 -14
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -23,6 +23,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
23
23
|
//#endregion
|
|
24
24
|
let _kubb_core = require("@kubb/core");
|
|
25
25
|
let _kubb_kit = require("@kubb/kit");
|
|
26
|
+
let node_path = require("node:path");
|
|
26
27
|
let node_fs_promises = require("node:fs/promises");
|
|
27
28
|
let _scalar_openapi_upgrader = require("@scalar/openapi-upgrader");
|
|
28
29
|
let api_ref_bundler = require("api-ref-bundler");
|
|
@@ -36,7 +37,7 @@ var compatibility = {
|
|
|
36
37
|
};
|
|
37
38
|
//#endregion
|
|
38
39
|
//#region package.json
|
|
39
|
-
var version = "5.14.
|
|
40
|
+
var version = "5.14.6";
|
|
40
41
|
//#endregion
|
|
41
42
|
//#region src/constants.ts
|
|
42
43
|
/**
|
|
@@ -714,6 +715,30 @@ function inlinePathRefs(node, resolve, visiting = []) {
|
|
|
714
715
|
for (const [key, value] of Object.entries(node)) node[key] = inlinePathRefs(value, resolve, visiting);
|
|
715
716
|
return node;
|
|
716
717
|
}
|
|
718
|
+
const namedEntryKeys = /* @__PURE__ */ new Set([
|
|
719
|
+
"properties",
|
|
720
|
+
"patternProperties",
|
|
721
|
+
"headers",
|
|
722
|
+
"schemas",
|
|
723
|
+
"responses",
|
|
724
|
+
"parameters",
|
|
725
|
+
"requestBodies",
|
|
726
|
+
"examples",
|
|
727
|
+
"links",
|
|
728
|
+
"callbacks",
|
|
729
|
+
"securitySchemes",
|
|
730
|
+
"securityDefinitions",
|
|
731
|
+
"pathItems",
|
|
732
|
+
"definitions",
|
|
733
|
+
"$defs"
|
|
734
|
+
]);
|
|
735
|
+
/**
|
|
736
|
+
* True when `path` runs through an `x-` vendor extension. Kubb never reads an extension, so a `$ref`
|
|
737
|
+
* Kubb cannot read inside one cannot change the output.
|
|
738
|
+
*/
|
|
739
|
+
function isExtensionPath(path) {
|
|
740
|
+
return path.some((token, index) => String(token).startsWith("x-") && !namedEntryKeys.has(String(path[index - 1])));
|
|
741
|
+
}
|
|
717
742
|
/**
|
|
718
743
|
* Bundles a multi-file OpenAPI document into a single document via `api-ref-bundler`.
|
|
719
744
|
*
|
|
@@ -727,33 +752,55 @@ function inlinePathRefs(node, resolve, visiting = []) {
|
|
|
727
752
|
* all-internal document it is a no-op that still walks the whole tree to confirm that, which
|
|
728
753
|
* costs real time on a large spec.
|
|
729
754
|
*
|
|
755
|
+
* `document` stands in for the file at `pathOrUrl`, such as inline input. Every other file or URL
|
|
756
|
+
* read, including one that fails, lands in `sources`. A `$ref` that cannot be read reports
|
|
757
|
+
* `KUBB_REF_NOT_FOUND` at the key that holds it, as a warning when it sits inside an `x-` extension.
|
|
758
|
+
*
|
|
730
759
|
* @example Local file
|
|
731
760
|
* `const document = await bundleDocument('./openapi.yaml')`
|
|
732
761
|
*
|
|
733
762
|
* @example Remote URL
|
|
734
763
|
* `const document = await bundleDocument('https://example.com/openapi.yaml')`
|
|
735
764
|
*/
|
|
736
|
-
async function bundleDocument(pathOrUrl) {
|
|
765
|
+
async function bundleDocument(pathOrUrl, { document, sources = [] } = {}) {
|
|
737
766
|
const cache = /* @__PURE__ */ new Map();
|
|
767
|
+
const toKey = (sourcePath) => urlRegExp.test(sourcePath) ? new URL(sourcePath).href : sourcePath;
|
|
738
768
|
const resolver = (sourcePath) => {
|
|
739
|
-
|
|
769
|
+
if (document && sourcePath === pathOrUrl) return Promise.resolve(document);
|
|
770
|
+
const key = toKey(sourcePath);
|
|
740
771
|
const cached = cache.get(key);
|
|
741
772
|
if (cached) return cached;
|
|
773
|
+
sources.push(key);
|
|
742
774
|
const result = resolveSource(sourcePath);
|
|
743
775
|
cache.set(key, result);
|
|
744
776
|
return result;
|
|
745
777
|
};
|
|
746
778
|
const root = await resolver(pathOrUrl);
|
|
747
779
|
if (typeof root === "object" && root !== null && !hasExternalRef(root)) return root;
|
|
748
|
-
return await (0, api_ref_bundler.bundle)(pathOrUrl, resolver)
|
|
780
|
+
return await (0, api_ref_bundler.bundle)(pathOrUrl, resolver, { hooks: { onError: (message, { path, state }) => {
|
|
781
|
+
const pointer = toKey(state.baseFile) === toKey(pathOrUrl) ? `#/${path.map((token) => escapePointerToken(String(token))).join("/")}` : void 0;
|
|
782
|
+
const diagnostic = {
|
|
783
|
+
code: _kubb_kit.Diagnostics.code.refNotFound,
|
|
784
|
+
severity: isExtensionPath(path) ? "warning" : "error",
|
|
785
|
+
message: `Could not bundle an external \`$ref\`. ${message}.`,
|
|
786
|
+
help: "Check that the file or URL the `$ref` points at exists and is readable, or fix the `$ref`.",
|
|
787
|
+
...pointer && { location: {
|
|
788
|
+
kind: "schema",
|
|
789
|
+
pointer
|
|
790
|
+
} }
|
|
791
|
+
};
|
|
792
|
+
if (!_kubb_kit.Diagnostics.report(diagnostic) && diagnostic.severity === "error") throw new _kubb_kit.Diagnostics.Error(diagnostic);
|
|
793
|
+
} } });
|
|
749
794
|
}
|
|
795
|
+
const inlineInputName = "<inline input>";
|
|
750
796
|
/**
|
|
751
797
|
* Creates a `Document` from an `AdapterSource`.
|
|
752
798
|
*
|
|
753
799
|
* - `{ type: 'path' }` bundles an absolute file path (core resolves `input`) or remote URL via
|
|
754
800
|
* `api-ref-bundler`, hoisting external file schemas into named `components.schemas` entries so
|
|
755
801
|
* generators can emit named types and imports.
|
|
756
|
-
* - `{ type: 'data' }` parses an inline string (YAML/JSON) or raw object
|
|
802
|
+
* - `{ type: 'data' }` parses an inline string (YAML/JSON) or raw object, then bundles its
|
|
803
|
+
* external `$ref`s from `root` when it has any. Each file or URL read lands in `sources`.
|
|
757
804
|
*
|
|
758
805
|
* Swagger 2.0 and OpenAPI 3.0 documents are up-converted to OpenAPI 3.1 via `@scalar/openapi-upgrader`.
|
|
759
806
|
*
|
|
@@ -763,14 +810,20 @@ async function bundleDocument(pathOrUrl) {
|
|
|
763
810
|
* const document = await parseFromConfig({ type: 'data', data: '{"openapi":"3.0.0",...}' })
|
|
764
811
|
* ```
|
|
765
812
|
*/
|
|
766
|
-
async function parseFromConfig(source) {
|
|
813
|
+
async function parseFromConfig(source, sources = []) {
|
|
767
814
|
const raw = await (async () => {
|
|
768
|
-
if (source.type === "data")
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
815
|
+
if (source.type === "data") {
|
|
816
|
+
const data = typeof source.data === "string" ? parseYaml(source.data, {
|
|
817
|
+
origin: "the inline `input` string",
|
|
818
|
+
help: "Fix the syntax at the reported line. Kubb reads `input` as an inline spec, not a file path, because it starts with `{`, `[`, `openapi:`, or `swagger:`, or spans several lines."
|
|
819
|
+
}) : structuredClone(source.data);
|
|
820
|
+
return source.root && hasExternalRef(data) ? bundleDocument((0, node_path.join)(source.root, inlineInputName), {
|
|
821
|
+
document: data,
|
|
822
|
+
sources
|
|
823
|
+
}) : data;
|
|
824
|
+
}
|
|
772
825
|
await assertInputExists(source.path);
|
|
773
|
-
return bundleDocument(source.path);
|
|
826
|
+
return bundleDocument(source.path, { sources });
|
|
774
827
|
})();
|
|
775
828
|
if (raw && typeof raw === "object") {
|
|
776
829
|
const document = raw;
|
|
@@ -2905,6 +2958,7 @@ const adapterOas = (0, _kubb_core.defineExtension)({
|
|
|
2905
2958
|
}),
|
|
2906
2959
|
build({ validate, contentType, server, discriminator, enums, ...parserOptions }) {
|
|
2907
2960
|
let parsedDocument = null;
|
|
2961
|
+
let sources = [];
|
|
2908
2962
|
const pendingValidations = [];
|
|
2909
2963
|
const inputCache = /* @__PURE__ */ new WeakMap();
|
|
2910
2964
|
/**
|
|
@@ -3038,6 +3092,9 @@ const adapterOas = (0, _kubb_core.defineExtension)({
|
|
|
3038
3092
|
get document() {
|
|
3039
3093
|
return parsedDocument;
|
|
3040
3094
|
},
|
|
3095
|
+
get sources() {
|
|
3096
|
+
return sources;
|
|
3097
|
+
},
|
|
3041
3098
|
locate,
|
|
3042
3099
|
async validate(input, options) {
|
|
3043
3100
|
const document = await parseFromConfig({
|
|
@@ -3053,9 +3110,14 @@ const adapterOas = (0, _kubb_core.defineExtension)({
|
|
|
3053
3110
|
async parse(source, { signal } = {}) {
|
|
3054
3111
|
signal?.throwIfAborted();
|
|
3055
3112
|
const cached = inputCache.get(source);
|
|
3056
|
-
if (cached)
|
|
3113
|
+
if (cached) {
|
|
3114
|
+
sources = cached.sources;
|
|
3115
|
+
return cached.promise;
|
|
3116
|
+
}
|
|
3117
|
+
const read = [];
|
|
3118
|
+
sources = read;
|
|
3057
3119
|
const promise = (async () => {
|
|
3058
|
-
const document = await parseFromConfig(source);
|
|
3120
|
+
const document = await parseFromConfig(source, read);
|
|
3059
3121
|
signal?.throwIfAborted();
|
|
3060
3122
|
assertDocument(document);
|
|
3061
3123
|
if (validate) pendingValidations.push(validateDocumentInWorker(document));
|
|
@@ -3075,7 +3137,10 @@ const adapterOas = (0, _kubb_core.defineExtension)({
|
|
|
3075
3137
|
})
|
|
3076
3138
|
});
|
|
3077
3139
|
})();
|
|
3078
|
-
inputCache.set(source,
|
|
3140
|
+
inputCache.set(source, {
|
|
3141
|
+
promise,
|
|
3142
|
+
sources: read
|
|
3143
|
+
});
|
|
3079
3144
|
return promise.catch((error) => {
|
|
3080
3145
|
if (signal?.aborted) inputCache.delete(source);
|
|
3081
3146
|
throw error;
|