@kubb/core 5.11.4 → 5.11.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/{Hookable-C2bwJUE5.js → Hookable-CvStaYYq.js} +95 -73
- package/dist/Hookable-CvStaYYq.js.map +1 -0
- package/dist/{createAdapter-D6osJ_0O.d.ts → createAdapter-DtX_MKL-.d.ts} +77 -14
- package/dist/index.cjs +148 -107
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +77 -16
- package/dist/index.d.ts +3 -5
- package/dist/index.js +56 -38
- package/dist/index.js.map +1 -1
- package/dist/mocks.d.ts +1 -1
- package/dist/mocks.js +1 -1
- package/package.json +2 -2
- package/dist/Hookable-C2bwJUE5.js.map +0 -1
|
@@ -14,7 +14,7 @@ var __name = (target, value) => __defProp(target, "name", {
|
|
|
14
14
|
});
|
|
15
15
|
//#endregion
|
|
16
16
|
//#region package.json
|
|
17
|
-
var version = "5.11.
|
|
17
|
+
var version = "5.11.6";
|
|
18
18
|
//#endregion
|
|
19
19
|
//#region ../../internals/utils/src/casing.ts
|
|
20
20
|
/**
|
|
@@ -614,13 +614,15 @@ function serialize(diagnostic) {
|
|
|
614
614
|
* with `at`, `fix`, the first cause, and `Learn more` for an error, and one row for a warning.
|
|
615
615
|
* `verbose` adds the full stack.
|
|
616
616
|
*/
|
|
617
|
-
function format(diagnostic, { audience = "agent", verbose = false, width = 0 } = {}) {
|
|
617
|
+
function format(diagnostic, { audience = "agent", verbose = false, width = 0, position } = {}) {
|
|
618
618
|
const { code, severity, message } = diagnostic;
|
|
619
619
|
const problem = Diagnostics.isProblem(diagnostic) ? diagnostic : void 0;
|
|
620
620
|
const human = audience === "human";
|
|
621
621
|
const paint = human ? styleText : (_format, text) => text;
|
|
622
622
|
const [firstLine = "", ...rest] = message.split("\n");
|
|
623
623
|
const pointer = problem?.location && "pointer" in problem.location ? problem.location.pointer : void 0;
|
|
624
|
+
const at = position ? `${position.file}:${position.line}:${position.column}` : void 0;
|
|
625
|
+
const where = at ?? pointer;
|
|
624
626
|
const help = problem ? getHelp(problem) : void 0;
|
|
625
627
|
const causes = problem ? getCauses(problem) : [];
|
|
626
628
|
const crash = problem ? crashCodes.has(problem.code) : false;
|
|
@@ -630,7 +632,7 @@ function format(diagnostic, { audience = "agent", verbose = false, width = 0 } =
|
|
|
630
632
|
const row = (label, value) => {
|
|
631
633
|
if (value) details.push(` ${label}: ${value}`);
|
|
632
634
|
};
|
|
633
|
-
row("at", pointer);
|
|
635
|
+
row("at", at && pointer ? `${at} (${pointer})` : pointer);
|
|
634
636
|
if (problem && severity !== "info") row("why", Diagnostics.explain(problem.code).cause);
|
|
635
637
|
row("fix", help);
|
|
636
638
|
for (const cause of causes) row("caused by", cause);
|
|
@@ -640,24 +642,25 @@ function format(diagnostic, { audience = "agent", verbose = false, width = 0 } =
|
|
|
640
642
|
return [`${severity} ${code}${problem?.plugin ? ` [${problem.plugin}]` : ""}: ${firstLine}`, ...details];
|
|
641
643
|
}
|
|
642
644
|
const left = `${paint(severityStyle[severity], severityIcon[severity])} ${paint("bold", firstLine)}`;
|
|
643
|
-
const gap =
|
|
644
|
-
const headline = `${left}${" ".repeat(gap)}${paint("dim", code)}
|
|
645
|
+
const gap = width - stripVTControlCharacters(left).length - code.length;
|
|
646
|
+
const headline = width && gap < 2 ? [left, `${" ".repeat(Math.max(0, width - code.length))}${paint("dim", code)}`] : [`${left}${" ".repeat(Math.max(2, gap))}${paint("dim", code)}`];
|
|
645
647
|
const frame = rest.filter((line) => line.trim()).map((line) => ` ${paint("dim", line)}`);
|
|
646
648
|
const label = (name) => paint("dim", name.length < 4 ? name.padEnd(4) : `${name} `);
|
|
647
|
-
const rows = [["at",
|
|
649
|
+
const rows = [["at", where && paint("cyan", where)], ["fix", help]];
|
|
648
650
|
if (severity !== "error") {
|
|
649
651
|
const first = rows.find(([, value]) => value);
|
|
650
652
|
return [
|
|
651
|
-
headline,
|
|
653
|
+
...headline,
|
|
652
654
|
...frame,
|
|
653
655
|
...first ? [` ${label(first[0])} ${first[1]}`] : []
|
|
654
656
|
];
|
|
655
657
|
}
|
|
656
658
|
rows.push(["caused by", causes[0]], ["report", problem?.issues && paint("cyan", problem.issues)]);
|
|
657
|
-
const
|
|
659
|
+
const codeFrame = (position?.frame ?? []).map((line) => ` ${line}`);
|
|
660
|
+
const details = [...frame, ...rows.flatMap(([name, value]) => value ? [` ${label(name)} ${value}`, ...name === "at" ? codeFrame : []] : [])];
|
|
658
661
|
if (frames?.length) details.push(` ${paint("dim", "stack")}`, ...frames);
|
|
659
662
|
if (code !== diagnosticCode.unknown) details.push(` ${paint("dim", "↳ Learn more")} ${paint("cyan", Diagnostics.docsUrl(code).replace(/^https:\/\//, ""))}`);
|
|
660
|
-
return [headline, ...details];
|
|
663
|
+
return [...headline, ...details];
|
|
661
664
|
}
|
|
662
665
|
//#endregion
|
|
663
666
|
//#region src/Diagnostics.ts
|
|
@@ -709,6 +712,7 @@ const failedCode = {
|
|
|
709
712
|
parser: diagnosticCode.parserFailed
|
|
710
713
|
};
|
|
711
714
|
const docsByCode = new Map(Object.values(diagnosticCatalog).map((doc) => [doc.code, doc]));
|
|
715
|
+
const reporterKey = Symbol.for("kubb.diagnostics.reporter");
|
|
712
716
|
const countKey = {
|
|
713
717
|
error: "errors",
|
|
714
718
|
warning: "warnings",
|
|
@@ -718,13 +722,13 @@ const countKey = {
|
|
|
718
722
|
* Static helpers for working with {@link Diagnostic}s, plus the run-scoped sink
|
|
719
723
|
* that lets deep code report a diagnostic without threading a callback.
|
|
720
724
|
*
|
|
721
|
-
* The sink lives in a single `AsyncLocalStorage`
|
|
725
|
+
* The sink lives in a single `AsyncLocalStorage` on `globalThis`, shared by every copy of `@kubb/core`.
|
|
722
726
|
* `Diagnostics.scope` activates it for a run, so anything inside that run (the
|
|
723
727
|
* adapter parse, a generator) reports through `Diagnostics.report` and lands
|
|
724
728
|
* in the same run.
|
|
725
729
|
*/
|
|
726
730
|
var Diagnostics = class Diagnostics {
|
|
727
|
-
static #reporterStorage = new AsyncLocalStorage();
|
|
731
|
+
static #reporterStorage = globalThis[reporterKey] ??= new AsyncLocalStorage();
|
|
728
732
|
/**
|
|
729
733
|
* The diagnostic code catalog, exposed as `Diagnostics.code` (e.g. `Diagnostics.code.refNotFound`).
|
|
730
734
|
*/
|
|
@@ -1067,7 +1071,7 @@ function defineExtension(definition) {
|
|
|
1067
1071
|
return Object.assign(build(options), {
|
|
1068
1072
|
name: meta.name,
|
|
1069
1073
|
meta,
|
|
1070
|
-
options
|
|
1074
|
+
options: raw
|
|
1071
1075
|
});
|
|
1072
1076
|
}
|
|
1073
1077
|
});
|
|
@@ -1562,7 +1566,8 @@ var Resolver = class Resolver {
|
|
|
1562
1566
|
#resolvePath({ baseName, tag, path: groupPath, root, output, group }) {
|
|
1563
1567
|
if (output.mode !== "directory") return path.resolve(root, output.path);
|
|
1564
1568
|
const outputDir = path.resolve(root, output.path);
|
|
1565
|
-
const
|
|
1569
|
+
const groupValue = group?.type === "path" ? groupPath : tag;
|
|
1570
|
+
const result = group && groupValue ? path.resolve(outputDir, Resolver.#resolveGroupDir(group, groupValue), baseName) : path.resolve(outputDir, baseName);
|
|
1566
1571
|
assertInside({
|
|
1567
1572
|
target: result,
|
|
1568
1573
|
parent: outputDir,
|
|
@@ -1803,10 +1808,7 @@ function runParser(parser, print) {
|
|
|
1803
1808
|
* Reads a `copy` file and prints it through the parser's `copy` hook, or verbatim with `banner`/`footer` when there is none.
|
|
1804
1809
|
*/
|
|
1805
1810
|
async function parseCopy(file, parser) {
|
|
1806
|
-
|
|
1807
|
-
try {
|
|
1808
|
-
content = await readFile(file.copy, "utf8");
|
|
1809
|
-
} catch (err) {
|
|
1811
|
+
const content = await readFile(file.copy, "utf8").catch((err) => {
|
|
1810
1812
|
throw new Diagnostics.Error({
|
|
1811
1813
|
code: Diagnostics.code.pluginFailed,
|
|
1812
1814
|
severity: "error",
|
|
@@ -1814,7 +1816,7 @@ async function parseCopy(file, parser) {
|
|
|
1814
1816
|
help: "Check that the file a plugin copies into the output exists and is readable.",
|
|
1815
1817
|
cause: toError(err)
|
|
1816
1818
|
});
|
|
1817
|
-
}
|
|
1819
|
+
});
|
|
1818
1820
|
if (parser?.copy) return runParser(parser, () => parser.parse(ast.factory.createFile(parser.copy(file, content))));
|
|
1819
1821
|
return [
|
|
1820
1822
|
file.banner,
|
|
@@ -1828,9 +1830,9 @@ function mergeFile(a, b) {
|
|
|
1828
1830
|
banner: b.banner,
|
|
1829
1831
|
footer: b.footer,
|
|
1830
1832
|
copy: b.copy ?? a.copy,
|
|
1831
|
-
sources:
|
|
1832
|
-
imports:
|
|
1833
|
-
exports:
|
|
1833
|
+
sources: [...a.sources, ...b.sources],
|
|
1834
|
+
imports: [...a.imports, ...b.imports],
|
|
1835
|
+
exports: [...a.exports, ...b.exports]
|
|
1834
1836
|
};
|
|
1835
1837
|
}
|
|
1836
1838
|
function isIndexPath(path) {
|
|
@@ -1839,17 +1841,49 @@ function isIndexPath(path) {
|
|
|
1839
1841
|
function compareFiles(a, b) {
|
|
1840
1842
|
return a.path.length - b.path.length || Number(isIndexPath(a.path)) - Number(isIndexPath(b.path));
|
|
1841
1843
|
}
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1844
|
+
/**
|
|
1845
|
+
* Writes `source` to `file.path` unless the storage already holds it, either verbatim or, per the
|
|
1846
|
+
* manifest, as what the output passes make of it. Checking here rather than in a driver gives a
|
|
1847
|
+
* storage writing to S3 or a database the same guarantee `fsStorage` has. `false` when skipped.
|
|
1848
|
+
*/
|
|
1849
|
+
async function writeChanged({ storage, manifest, file, source, signal }) {
|
|
1850
|
+
signal?.throwIfAborted();
|
|
1851
|
+
const stored = await storage.readItem(file.path);
|
|
1852
|
+
if (stored !== null && (matchesStored({
|
|
1845
1853
|
stored,
|
|
1846
1854
|
source
|
|
1847
|
-
})
|
|
1848
|
-
|
|
1849
|
-
key,
|
|
1855
|
+
}) || manifest?.isUpToDate({
|
|
1856
|
+
key: file.path,
|
|
1850
1857
|
source,
|
|
1851
1858
|
disk: stored
|
|
1852
|
-
})
|
|
1859
|
+
}))) return false;
|
|
1860
|
+
signal?.throwIfAborted();
|
|
1861
|
+
await storage.writeItem(file.path, source, { stored });
|
|
1862
|
+
manifest?.track({
|
|
1863
|
+
key: file.path,
|
|
1864
|
+
source
|
|
1865
|
+
});
|
|
1866
|
+
return true;
|
|
1867
|
+
}
|
|
1868
|
+
/** Reports finished files in input order: each finished file flushes the run of finished files ahead of it as one update. */
|
|
1869
|
+
function createProgress(files, config, hooks) {
|
|
1870
|
+
const finished = [];
|
|
1871
|
+
let flushed = 0;
|
|
1872
|
+
return async (index) => {
|
|
1873
|
+
finished[index] = true;
|
|
1874
|
+
const updates = [];
|
|
1875
|
+
while (finished[flushed]) {
|
|
1876
|
+
flushed++;
|
|
1877
|
+
updates.push({
|
|
1878
|
+
file: files[flushed - 1],
|
|
1879
|
+
processed: flushed,
|
|
1880
|
+
total: files.length,
|
|
1881
|
+
percentage: flushed / files.length * 100,
|
|
1882
|
+
config
|
|
1883
|
+
});
|
|
1884
|
+
}
|
|
1885
|
+
if (updates.length) await hooks.callHook("kubb:files:processing:update", { files: updates });
|
|
1886
|
+
};
|
|
1853
1887
|
}
|
|
1854
1888
|
/**
|
|
1855
1889
|
* In-memory file store for generated files, and the writer that turns them into source
|
|
@@ -1894,25 +1928,17 @@ var FileManager = class {
|
|
|
1894
1928
|
}
|
|
1895
1929
|
}
|
|
1896
1930
|
#store(files, mergeExisting) {
|
|
1897
|
-
const batch =
|
|
1898
|
-
const resolved =
|
|
1899
|
-
for (const file of batch) {
|
|
1931
|
+
const batch = /* @__PURE__ */ new Set();
|
|
1932
|
+
const resolved = files.map((file) => {
|
|
1900
1933
|
const existing = this.#cache.get(file.path);
|
|
1901
|
-
const merged = existing && mergeExisting
|
|
1934
|
+
const merged = ast.factory.createFile(existing && (mergeExisting || batch.has(file.path)) ? mergeFile(existing, file) : file);
|
|
1902
1935
|
this.#cache.set(merged.path, merged);
|
|
1903
|
-
|
|
1904
|
-
|
|
1936
|
+
batch.add(merged.path);
|
|
1937
|
+
return merged;
|
|
1938
|
+
});
|
|
1905
1939
|
if (resolved.length > 0) this.#sorted = null;
|
|
1906
1940
|
return resolved;
|
|
1907
1941
|
}
|
|
1908
|
-
#dedupe(files) {
|
|
1909
|
-
const seen = /* @__PURE__ */ new Map();
|
|
1910
|
-
for (const file of files) {
|
|
1911
|
-
const prev = seen.get(file.path);
|
|
1912
|
-
seen.set(file.path, prev ? mergeFile(prev, file) : file);
|
|
1913
|
-
}
|
|
1914
|
-
return [...seen.values()];
|
|
1915
|
-
}
|
|
1916
1942
|
/**
|
|
1917
1943
|
* Releases all stored files. Called by the core after `kubb:build:end`.
|
|
1918
1944
|
*/
|
|
@@ -1940,50 +1966,38 @@ var FileManager = class {
|
|
|
1940
1966
|
* Parses and writes every file through a bounded pool of workers. A small spec runs all its files
|
|
1941
1967
|
* at once; a spec with thousands of files keeps at most {@link FILE_CONCURRENCY} parsed sources in
|
|
1942
1968
|
* memory rather than holding every source, while still overlapping each file's write with the
|
|
1943
|
-
* next file's parse. Files finish in whatever order they parse, so
|
|
1944
|
-
*
|
|
1969
|
+
* next file's parse. Files finish in whatever order they parse, so each finished file flushes the
|
|
1970
|
+
* run of finished files ahead of it as one `kubb:files:processing:update`, keeping rows in input order.
|
|
1945
1971
|
*
|
|
1946
1972
|
* A file the storage already holds is skipped, so a rebuild that generates identical output
|
|
1947
|
-
* writes nothing and leaves every mtime where it was.
|
|
1973
|
+
* writes nothing and leaves every mtime where it was. `kubb:files:processing:end` lists the
|
|
1974
|
+
* skipped paths as `unchanged`.
|
|
1948
1975
|
*/
|
|
1949
1976
|
async write(files, { storage, parsers, manifest, signal, hooks, config }) {
|
|
1950
1977
|
if (files.length === 0) return;
|
|
1951
1978
|
await hooks?.callHook("kubb:files:processing:start", { files });
|
|
1952
|
-
const
|
|
1953
|
-
const
|
|
1979
|
+
const unchanged = [];
|
|
1980
|
+
const progress = hooks && config ? createProgress(files, config, hooks) : void 0;
|
|
1954
1981
|
await inParallel({
|
|
1955
1982
|
items: files,
|
|
1956
1983
|
limit: 50,
|
|
1957
1984
|
run: async (file, index) => {
|
|
1958
1985
|
signal?.throwIfAborted();
|
|
1959
1986
|
const source = await this.parse(file, { parsers });
|
|
1960
|
-
if (
|
|
1987
|
+
if (source && !await writeChanged({
|
|
1988
|
+
storage,
|
|
1989
|
+
manifest,
|
|
1961
1990
|
file,
|
|
1962
|
-
processed: index + 1,
|
|
1963
|
-
total,
|
|
1964
|
-
percentage: (index + 1) / total * 100,
|
|
1965
|
-
config
|
|
1966
|
-
});
|
|
1967
|
-
if (!source) return;
|
|
1968
|
-
signal?.throwIfAborted();
|
|
1969
|
-
const stored = await storage.readItem(file.path);
|
|
1970
|
-
if (isUnchanged({
|
|
1971
|
-
stored,
|
|
1972
1991
|
source,
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
signal?.throwIfAborted();
|
|
1977
|
-
await storage.writeItem(file.path, source, { stored });
|
|
1978
|
-
manifest?.track({
|
|
1979
|
-
key: file.path,
|
|
1980
|
-
source
|
|
1981
|
-
});
|
|
1992
|
+
signal
|
|
1993
|
+
})) unchanged.push(file.path);
|
|
1994
|
+
await progress?.(index);
|
|
1982
1995
|
}
|
|
1983
1996
|
});
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1997
|
+
await hooks?.callHook("kubb:files:processing:end", {
|
|
1998
|
+
files,
|
|
1999
|
+
unchanged
|
|
2000
|
+
});
|
|
1987
2001
|
}
|
|
1988
2002
|
};
|
|
1989
2003
|
//#endregion
|
|
@@ -2311,10 +2325,15 @@ var KubbDriver = class {
|
|
|
2311
2325
|
plugin.options = normalizePluginOptions(plugin.options, plugin.name);
|
|
2312
2326
|
}
|
|
2313
2327
|
if (this.adapter && this.inputNode) {
|
|
2328
|
+
const { meta, schemas, operations } = this.inputNode;
|
|
2314
2329
|
const buildStartContext = this.#withFiles({
|
|
2315
2330
|
config,
|
|
2316
2331
|
adapter: this.adapter,
|
|
2317
|
-
meta
|
|
2332
|
+
meta,
|
|
2333
|
+
nodeCounts: {
|
|
2334
|
+
schemas: schemas.length,
|
|
2335
|
+
operations: operations.length
|
|
2336
|
+
},
|
|
2318
2337
|
getPlugin: this.getPlugin.bind(this)
|
|
2319
2338
|
});
|
|
2320
2339
|
await hooks.callHook("kubb:build:start", buildStartContext);
|
|
@@ -2599,7 +2618,10 @@ var KubbDriver = class {
|
|
|
2599
2618
|
}
|
|
2600
2619
|
return diagnostics;
|
|
2601
2620
|
}
|
|
2602
|
-
/**
|
|
2621
|
+
/**
|
|
2622
|
+
* Runs `node` through the generators whose `match` accepts it; `generate` picks the method for the
|
|
2623
|
+
* node kind.
|
|
2624
|
+
*/
|
|
2603
2625
|
async #dispatchNode({ generators, node, ctx, generate }) {
|
|
2604
2626
|
for (const generator of generators) {
|
|
2605
2627
|
if (!(generator.match ? await generator.match(node, ctx) : true)) continue;
|
|
@@ -2836,4 +2858,4 @@ var Hookable = class {
|
|
|
2836
2858
|
//#endregion
|
|
2837
2859
|
export { inParallel as A, __name as B, useOptions as C, Diagnostics as D, resolveMeta as E, rm as F, write as I, writeRaw as L, isPathInside as M, listFiles as N, formatMs as O, read as P, toError as R, useKubb as S, defineExtension as T, setMacros as _, FileManager as a, tryUseKubb as b, Resolver as c, definePlugin as d, addGenerator as f, requirePlugin as g, kubbContext as h, createNodeCache as i, existsSync$1 as j, getElapsedMs as k, getInputKind as l, injectFile as m, KubbDriver as n, _usingCtx as o, addMacro as p, pluginNotFoundError as r, createResolver as s, Hookable as t, assertPluginOption as u, setOptions as v, checkCompatibility as w, useConfig as x, setResolver as y, camelCase as z };
|
|
2838
2860
|
|
|
2839
|
-
//# sourceMappingURL=Hookable-
|
|
2861
|
+
//# sourceMappingURL=Hookable-CvStaYYq.js.map
|