@kubb/adapter-oas 5.0.0-beta.52 → 5.0.0-beta.54
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 +72 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +72 -13
- package/dist/index.js.map +1 -1
- package/package.json +6 -5
- package/src/bundler.ts +71 -0
- package/src/factory.ts +6 -5
- package/src/stream.ts +13 -3
- package/extension.yaml +0 -431
package/dist/index.js
CHANGED
|
@@ -2,8 +2,10 @@ import "./chunk-C0LytTxp.js";
|
|
|
2
2
|
import { Diagnostics, ast, createAdapter } from "@kubb/core";
|
|
3
3
|
import BaseOas from "oas";
|
|
4
4
|
import path from "node:path";
|
|
5
|
-
import { access } from "node:fs/promises";
|
|
5
|
+
import { access, readFile } from "node:fs/promises";
|
|
6
6
|
import OASNormalize from "oas-normalize";
|
|
7
|
+
import { bundle } from "api-ref-bundler";
|
|
8
|
+
import yaml from "js-yaml";
|
|
7
9
|
import { childName, enumPropName, extractRefName, findDiscriminator } from "@kubb/ast/utils";
|
|
8
10
|
import { isRef } from "oas/types";
|
|
9
11
|
import { matchesMimeType } from "oas/utils";
|
|
@@ -238,6 +240,19 @@ async function exists(path) {
|
|
|
238
240
|
if (isBun()) return Bun.file(path).exists();
|
|
239
241
|
return access(path).then(() => true, () => false);
|
|
240
242
|
}
|
|
243
|
+
/**
|
|
244
|
+
* Reads the file at `path` as a UTF-8 string.
|
|
245
|
+
* Uses `Bun.file().text()` when running under Bun, `fs.readFile` otherwise.
|
|
246
|
+
*
|
|
247
|
+
* @example
|
|
248
|
+
* ```ts
|
|
249
|
+
* const source = await read('./src/Pet.ts')
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
252
|
+
async function read(path) {
|
|
253
|
+
if (isBun()) return Bun.file(path).text();
|
|
254
|
+
return readFile(path, { encoding: "utf8" });
|
|
255
|
+
}
|
|
241
256
|
//#endregion
|
|
242
257
|
//#region ../../internals/utils/src/object.ts
|
|
243
258
|
/**
|
|
@@ -539,6 +554,50 @@ var URLPath = class {
|
|
|
539
554
|
}
|
|
540
555
|
};
|
|
541
556
|
//#endregion
|
|
557
|
+
//#region src/bundler.ts
|
|
558
|
+
const urlRegExp = /^https?:\/+/i;
|
|
559
|
+
async function readSource(sourcePath) {
|
|
560
|
+
if (urlRegExp.test(sourcePath)) {
|
|
561
|
+
const url = new URL(sourcePath);
|
|
562
|
+
const response = await fetch(url);
|
|
563
|
+
if (!response.ok) throw new Error(`Cannot fetch the OAS document at ${url.href} (HTTP ${response.status})`);
|
|
564
|
+
return response.text();
|
|
565
|
+
}
|
|
566
|
+
return read(sourcePath);
|
|
567
|
+
}
|
|
568
|
+
async function resolveSource(sourcePath) {
|
|
569
|
+
const data = await readSource(sourcePath);
|
|
570
|
+
if (sourcePath.toLowerCase().endsWith(".md")) return data;
|
|
571
|
+
return yaml.load(data);
|
|
572
|
+
}
|
|
573
|
+
/**
|
|
574
|
+
* Bundles a multi-file OpenAPI document into a single document via `api-ref-bundler`.
|
|
575
|
+
*
|
|
576
|
+
* External file schemas are hoisted into named `components.schemas` entries, so a property
|
|
577
|
+
* pointing at `./schemas/User.yaml` ends up referencing `#/components/schemas/User`. Generators
|
|
578
|
+
* can then emit a named type with an import instead of inlining the shape. Sources are read with
|
|
579
|
+
* the Bun-aware `read` util for local YAML and JSON files, and with `fetch` for HTTP(S) URLs.
|
|
580
|
+
*
|
|
581
|
+
* @example Local file
|
|
582
|
+
* `const document = await bundleDocument('./openapi.yaml')`
|
|
583
|
+
*
|
|
584
|
+
* @example Remote URL
|
|
585
|
+
* `const document = await bundleDocument('https://example.com/openapi.yaml')`
|
|
586
|
+
*/
|
|
587
|
+
async function bundleDocument(pathOrUrl) {
|
|
588
|
+
const cache = /* @__PURE__ */ new Map();
|
|
589
|
+
const resolver = (sourcePath) => {
|
|
590
|
+
const key = urlRegExp.test(sourcePath) ? new URL(sourcePath).href : sourcePath;
|
|
591
|
+
const cached = cache.get(key);
|
|
592
|
+
if (cached) return cached;
|
|
593
|
+
const result = resolveSource(sourcePath);
|
|
594
|
+
cache.set(key, result);
|
|
595
|
+
return result;
|
|
596
|
+
};
|
|
597
|
+
await resolver(pathOrUrl);
|
|
598
|
+
return await bundle(pathOrUrl, resolver);
|
|
599
|
+
}
|
|
600
|
+
//#endregion
|
|
542
601
|
//#region src/guards.ts
|
|
543
602
|
/**
|
|
544
603
|
* Returns `true` when `doc` is a Swagger 2.0 document (no `openapi` key).
|
|
@@ -603,8 +662,9 @@ function isDiscriminator(obj) {
|
|
|
603
662
|
/**
|
|
604
663
|
* Loads and dereferences an OpenAPI document, returning the raw `Document`.
|
|
605
664
|
*
|
|
606
|
-
* Accepts a file path string or an already-parsed document object. File paths
|
|
607
|
-
*
|
|
665
|
+
* Accepts a file path string or an already-parsed document object. File paths and URLs are
|
|
666
|
+
* bundled via `api-ref-bundler`, hoisting external file schemas into named `components.schemas`
|
|
667
|
+
* entries so generators can emit named types and imports. Swagger 2.0 documents are
|
|
608
668
|
* automatically up-converted to OpenAPI 3.0 via `swagger2openapi`.
|
|
609
669
|
*
|
|
610
670
|
* @example
|
|
@@ -614,13 +674,10 @@ function isDiscriminator(obj) {
|
|
|
614
674
|
* ```
|
|
615
675
|
*/
|
|
616
676
|
async function parseDocument(pathOrApi, { canBundle = true, enablePaths = true } = {}) {
|
|
617
|
-
if (typeof pathOrApi === "string" && canBundle) {
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
enablePaths
|
|
622
|
-
});
|
|
623
|
-
}
|
|
677
|
+
if (typeof pathOrApi === "string" && canBundle) return parseDocument(await bundleDocument(pathOrApi), {
|
|
678
|
+
canBundle: false,
|
|
679
|
+
enablePaths
|
|
680
|
+
});
|
|
624
681
|
const document = await new OASNormalize(pathOrApi, {
|
|
625
682
|
enablePaths,
|
|
626
683
|
colorizeErrors: true
|
|
@@ -2326,9 +2383,10 @@ function preScan({ schemas, parseSchema, parseOperation, baseOas, parserOptions,
|
|
|
2326
2383
|
});
|
|
2327
2384
|
for (const definition of dedupePlan.hoisted) if (definition.type === "enum" && definition.name) enumNames.push(definition.name);
|
|
2328
2385
|
}
|
|
2386
|
+
const aliasNames = dedupePlan?.aliasNames;
|
|
2329
2387
|
return {
|
|
2330
2388
|
refAliasMap,
|
|
2331
|
-
enumNames,
|
|
2389
|
+
enumNames: aliasNames && aliasNames.size > 0 ? enumNames.filter((name) => !aliasNames.has(name)) : enumNames,
|
|
2332
2390
|
circularNames,
|
|
2333
2391
|
discriminatorChildMap,
|
|
2334
2392
|
dedupePlan
|
|
@@ -2363,12 +2421,13 @@ function createInputStream({ schemas, parseSchema, parseOperation, baseOas, pars
|
|
|
2363
2421
|
description: node.description,
|
|
2364
2422
|
deprecated: node.deprecated
|
|
2365
2423
|
});
|
|
2366
|
-
return ast.applyDedupe(node, dedupePlan
|
|
2424
|
+
return ast.applyDedupe(node, dedupePlan, true);
|
|
2367
2425
|
};
|
|
2368
2426
|
const schemasIterable = { [Symbol.asyncIterator]() {
|
|
2369
2427
|
return (async function* () {
|
|
2370
2428
|
if (dedupePlan) for (const definition of dedupePlan.hoisted) yield definition;
|
|
2371
2429
|
for (const [name, schema] of Object.entries(schemas)) {
|
|
2430
|
+
if (dedupePlan?.aliasNames.has(name)) continue;
|
|
2372
2431
|
const alias = refAliasMap.get(name);
|
|
2373
2432
|
if (alias?.name && schemas[alias.name]) {
|
|
2374
2433
|
yield rewriteTopLevelSchema({
|
|
@@ -2393,7 +2452,7 @@ function createInputStream({ schemas, parseSchema, parseOperation, baseOas, pars
|
|
|
2393
2452
|
for (const methods of Object.values(baseOas.getPaths())) for (const operation of Object.values(methods)) {
|
|
2394
2453
|
if (!operation) continue;
|
|
2395
2454
|
const node = parseOperation(parserOptions, operation);
|
|
2396
|
-
if (node) yield dedupePlan ? ast.applyDedupe(node, dedupePlan
|
|
2455
|
+
if (node) yield dedupePlan ? ast.applyDedupe(node, dedupePlan) : node;
|
|
2397
2456
|
}
|
|
2398
2457
|
})();
|
|
2399
2458
|
} };
|