@kubb/core 5.12.7 → 5.13.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/dist/{Hookable-BRD9qP-V.js → Hookable-BR69O7aj.js} +81 -48
- package/dist/Hookable-BR69O7aj.js.map +1 -0
- package/dist/{createAdapter-DFXvZLZC.d.ts → createAdapter-BNUEQcw9.d.ts} +11 -2
- package/dist/index.cjs +105 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -4
- package/dist/index.d.ts +9 -4
- package/dist/index.js +28 -6
- package/dist/index.js.map +1 -1
- package/dist/mocks.d.ts +1 -1
- package/dist/mocks.js +1 -1
- package/package.json +3 -4
- package/dist/Hookable-BRD9qP-V.js.map +0 -1
|
@@ -846,9 +846,13 @@ declare class FileManager {
|
|
|
846
846
|
add(...files: Array<FileNode>): Array<FileNode>;
|
|
847
847
|
upsert(...files: Array<FileNode>): Array<FileNode>;
|
|
848
848
|
/** Stores a generator result: a file array is upserted as is, an element renders through `renderer` first, falsy is a no-op. */
|
|
849
|
-
dispatch<TElement = unknown>({ result, renderer }: {
|
|
849
|
+
dispatch<TElement = unknown>({ result, renderer, pointer }: {
|
|
850
850
|
result: TElement | Array<FileNode> | undefined | null;
|
|
851
851
|
renderer?: RendererFactory<TElement> | null;
|
|
852
|
+
/**
|
|
853
|
+
* Pointer of the node the result was generated from, set on each source that carries none.
|
|
854
|
+
*/
|
|
855
|
+
pointer?: string;
|
|
852
856
|
}): Promise<void>;
|
|
853
857
|
/**
|
|
854
858
|
* Releases all stored files. Called by the core after `kubb:build:end`.
|
|
@@ -3183,6 +3187,11 @@ type Adapter<TOptions extends AdapterFactoryOptions = AdapterFactoryOptions> = {
|
|
|
3183
3187
|
validate: (input: string, options?: {
|
|
3184
3188
|
throwOnError?: boolean;
|
|
3185
3189
|
}) => Promise<void>;
|
|
3190
|
+
/**
|
|
3191
|
+
* Waits for work `parse` left running alongside generation, such as spec validation in a worker thread.
|
|
3192
|
+
* Kubb awaits it before `kubb:build:end`, inside the build's diagnostics scope. Must not reject.
|
|
3193
|
+
*/
|
|
3194
|
+
settle?: () => Promise<void>;
|
|
3186
3195
|
/**
|
|
3187
3196
|
* Zero-based UTF-16 offsets of a diagnostic in `source` for a code frame, `end` exclusive; `undefined` when it cannot be found.
|
|
3188
3197
|
*/
|
|
@@ -3223,4 +3232,4 @@ type AdapterFactory<T extends AdapterFactoryOptions = AdapterFactoryOptions> = E
|
|
|
3223
3232
|
declare function createAdapter<T extends AdapterFactoryOptions = AdapterFactoryOptions>(definition: AdapterDefinition<T>): AdapterFactory<T>;
|
|
3224
3233
|
//#endregion
|
|
3225
3234
|
export { NodeCache as $, ReporterContext as $t, PluginFactory as A, KubbInfoContext as At, ResolveImportsOptions as B, RunHookOptions as Bt, NormalizedPlugin as C, KubbGenerationEndContext as Ct, Override as D, KubbHookLineContext as Dt, OutputOptions as E, KubbHookEndContext as Et, definePlugin as F, KubbWarnContext as Ft, ResolverFile as G, createOutputManifest as Gt, ResolvePathOptions as H, KubbDriver as Ht, BannerMeta as I, PossibleConfig as It, ResolverPatch as J, createRenderer as Jt, ResolverFileParams as K, Renderer as Kt, ResolveBannerContext as L, PostGenerateCommand as Lt, PluginType as M, KubbMessageContext as Mt, ResolvePluginOptions as N, KubbPluginsEndContext as Nt, Plugin as O, KubbHookStartContext as Ot, assertPluginOption as P, KubbSuccessContext as Pt, defineGenerator as Q, Reporter as Qt, ResolveBannerFile as R, UserConfig as Rt, KubbPluginStartContext as S, KubbFilesProcessingUpdateContext as St, OutputMode as T, KubbGenerationSummaryContext as Tt, Resolver as U, Hookable as Ut, ResolveOptionsContext as V, runHook as Vt, ResolverDefault as W, OutputManifest as Wt, Generator as X, createStorage as Xt, ResolverPathParams as Y, Storage as Yt, GeneratorContext as Z, GenerationResult as Zt, Filter as _, KubbDiagnosticContext as _t, AdapterSource as a, DiagnosticFormatOptions as an, Diagnostics as at, KubbPluginEndContext as b, KubbFilesProcessingEndContext as bt, ExtensionDependency as c, ParserDefinition as cn, ProblemDiagnostic as ct, ExtensionKind as d, CLIOptions as dt, ReporterName as en, Diagnostic as et, ExtensionMeta as f, Config as ft, Exclude$1 as g, KubbBuildStartContext as gt, resolveMeta as h, KubbBuildEndContext as ht, AdapterFactoryOptions as i, logLevel as in, DiagnosticSeverity as it, PluginName as j, KubbLifecycleStartContext as jt, PluginDefinition as k, KubbHooks as kt, ExtensionDependencyRecord as l, ParserFactory as ln, UpdateDiagnostic as lt, defineExtension as m, Input as mt, AdapterDefinition as n, UserReporter as nn, DiagnosticKind as nt, createAdapter as o, SerializedDiagnostic as on, PerformanceDiagnostic as ot, checkCompatibility as p, FilesContext as pt, ResolverFilePathParams as q, RendererFactory as qt, AdapterFactory as r, createReporter as rn, DiagnosticLocation as rt, ExtensionDependencies as s, Parser as sn, ProblemCode as st, Adapter as t, ReporterPluginFiles as tn, DiagnosticDoc as tt, ExtensionFactory as u, defineParser as un, BuildOutput as ut, Group as v, KubbErrorContext as vt, Output as w, KubbGenerationStartContext as wt, KubbPluginSetupContext as x, KubbFilesProcessingStartContext as xt, Include as y, KubbFileProcessingUpdate as yt, ResolveFileOptions as z, HookResult as zt };
|
|
3226
|
-
//# sourceMappingURL=createAdapter-
|
|
3235
|
+
//# sourceMappingURL=createAdapter-BNUEQcw9.d.ts.map
|
package/dist/index.cjs
CHANGED
|
@@ -39,13 +39,10 @@ node_net = __toESM(node_net, 1);
|
|
|
39
39
|
let node_os = require("node:os");
|
|
40
40
|
let node_crypto = require("node:crypto");
|
|
41
41
|
let node_readline = require("node:readline");
|
|
42
|
-
let unstorage = require("unstorage");
|
|
43
|
-
let unstorage_drivers_fs = require("unstorage/drivers/fs");
|
|
44
|
-
unstorage_drivers_fs = __toESM(unstorage_drivers_fs, 1);
|
|
45
42
|
let node_url = require("node:url");
|
|
46
43
|
let node_module = require("node:module");
|
|
47
44
|
//#region package.json
|
|
48
|
-
var version = "5.
|
|
45
|
+
var version = "5.13.0";
|
|
49
46
|
//#endregion
|
|
50
47
|
//#region ../../internals/utils/src/casing.ts
|
|
51
48
|
/**
|
|
@@ -138,20 +135,6 @@ function isCIEnvironment() {
|
|
|
138
135
|
return !!(ci && ci !== "false" && ci !== "0" || node_process.default.env.GITHUB_ACTIONS || node_process.default.env.GITLAB_CI || node_process.default.env.BITBUCKET_BUILD_NUMBER || node_process.default.env.JENKINS_URL || node_process.default.env.CIRCLECI || node_process.default.env.TRAVIS || node_process.default.env.TEAMCITY_VERSION || node_process.default.env.BUILDKITE || node_process.default.env.TF_BUILD);
|
|
139
136
|
}
|
|
140
137
|
//#endregion
|
|
141
|
-
//#region ../../internals/utils/src/jsonPointer.ts
|
|
142
|
-
/**
|
|
143
|
-
* Escapes a single JSON pointer reference token per RFC 6901 (`~` → `~0`, `/` → `~1`), so a
|
|
144
|
-
* name holding those characters maps to a distinct pointer.
|
|
145
|
-
*
|
|
146
|
-
* @example
|
|
147
|
-
* ```ts
|
|
148
|
-
* escapePointerToken('/pets/{id}') // '~1pets~1{id}'
|
|
149
|
-
* ```
|
|
150
|
-
*/
|
|
151
|
-
function escapePointerToken(token) {
|
|
152
|
-
return token.replaceAll("~", "~0").replaceAll("/", "~1");
|
|
153
|
-
}
|
|
154
|
-
//#endregion
|
|
155
138
|
//#region ../../internals/utils/src/openInBrowser.ts
|
|
156
139
|
const ignore = () => {};
|
|
157
140
|
/**
|
|
@@ -203,6 +186,21 @@ function detect() {
|
|
|
203
186
|
//#endregion
|
|
204
187
|
//#region ../../internals/utils/src/fs.ts
|
|
205
188
|
/**
|
|
189
|
+
* Resolves to `true` when the file or directory at `path` exists.
|
|
190
|
+
* Uses `Bun.file().exists()` when running under Bun, `fs.access` otherwise.
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* ```ts
|
|
194
|
+
* if (await exists('./kubb.config.ts')) {
|
|
195
|
+
* const content = await read('./kubb.config.ts')
|
|
196
|
+
* }
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
199
|
+
async function exists(path) {
|
|
200
|
+
if (runtime.isBun) return Bun.file(path).exists();
|
|
201
|
+
return (0, node_fs_promises.access)(path).then(() => true, () => false);
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
206
204
|
* Reads the file at `path` as a UTF-8 string.
|
|
207
205
|
* Uses `Bun.file().text()` when running under Bun, `fs.readFile` otherwise.
|
|
208
206
|
*
|
|
@@ -1842,13 +1840,13 @@ var Resolver = class Resolver {
|
|
|
1842
1840
|
const resolveName = name ?? ((schemaName) => this.name(schemaName));
|
|
1843
1841
|
return (0, _kubb_ast.collectImportedRefNames)(node).map((schemaName) => _kubb_ast.ast.factory.createImport({
|
|
1844
1842
|
name: [resolveName(schemaName)],
|
|
1845
|
-
path: this
|
|
1843
|
+
path: this.#resolveFilePath({
|
|
1846
1844
|
name: schemaName,
|
|
1847
1845
|
extname,
|
|
1848
1846
|
root,
|
|
1849
1847
|
output,
|
|
1850
1848
|
group
|
|
1851
|
-
})
|
|
1849
|
+
})
|
|
1852
1850
|
}));
|
|
1853
1851
|
}
|
|
1854
1852
|
/**
|
|
@@ -2007,19 +2005,13 @@ var Resolver = class Resolver {
|
|
|
2007
2005
|
});
|
|
2008
2006
|
return resolved;
|
|
2009
2007
|
}
|
|
2010
|
-
/**
|
|
2011
|
-
|
|
2012
|
-
* path; otherwise the base name (from `#baseName`, the resolver's `file.baseName` or the
|
|
2013
|
-
* built-in `toBaseName`) is placed by the `output.path`/`group` layout. The resolved file starts
|
|
2014
|
-
* with empty `sources`, `imports`, and `exports`, which consumers populate separately.
|
|
2015
|
-
*/
|
|
2016
|
-
#resolveFile(options) {
|
|
2017
|
-
const { name, extname, tag, path: groupPath, root, output, group } = options;
|
|
2008
|
+
/** The absolute path `#resolveFile` places a file at. */
|
|
2009
|
+
#resolveFilePath({ name, extname, tag, path: groupPath, root, output, group }) {
|
|
2018
2010
|
const baseName = this.#baseName({
|
|
2019
2011
|
name,
|
|
2020
2012
|
extname
|
|
2021
2013
|
});
|
|
2022
|
-
|
|
2014
|
+
return this.#filePath ? this.#resolveOverridePath(this.#filePath({
|
|
2023
2015
|
baseName,
|
|
2024
2016
|
output
|
|
2025
2017
|
}), root) : this.#resolvePath({
|
|
@@ -2030,6 +2022,15 @@ var Resolver = class Resolver {
|
|
|
2030
2022
|
output,
|
|
2031
2023
|
group
|
|
2032
2024
|
});
|
|
2025
|
+
}
|
|
2026
|
+
/**
|
|
2027
|
+
* Builds a `FileNode`. When `#filePath` (the resolver's `file.path`) is set it owns the whole
|
|
2028
|
+
* path; otherwise the base name (from `#baseName`, the resolver's `file.baseName` or the
|
|
2029
|
+
* built-in `toBaseName`) is placed by the `output.path`/`group` layout. The resolved file starts
|
|
2030
|
+
* with empty `sources`, `imports`, and `exports`, which consumers populate separately.
|
|
2031
|
+
*/
|
|
2032
|
+
#resolveFile(options) {
|
|
2033
|
+
const filePath = this.#resolveFilePath(options);
|
|
2033
2034
|
return _kubb_ast.ast.factory.createFile({
|
|
2034
2035
|
path: filePath,
|
|
2035
2036
|
baseName: node_path.default.basename(filePath),
|
|
@@ -2301,6 +2302,17 @@ function createProgress(files, config, hooks) {
|
|
|
2301
2302
|
if (updates.length) await hooks.callHook("kubb:files:processing:update", { files: updates });
|
|
2302
2303
|
};
|
|
2303
2304
|
}
|
|
2305
|
+
/** Links each source without a pointer to the node its file was generated from. */
|
|
2306
|
+
function withPointer(files, pointer) {
|
|
2307
|
+
if (!pointer) return files;
|
|
2308
|
+
return files.map((file) => ({
|
|
2309
|
+
...file,
|
|
2310
|
+
sources: file.sources.map((source) => source.pointer ? source : {
|
|
2311
|
+
...source,
|
|
2312
|
+
pointer
|
|
2313
|
+
})
|
|
2314
|
+
}));
|
|
2315
|
+
}
|
|
2304
2316
|
/**
|
|
2305
2317
|
* In-memory file store for generated files, and the writer that turns them into source
|
|
2306
2318
|
* strings on `storage`. Files sharing a `path` are merged (sources/imports/exports
|
|
@@ -2319,6 +2331,7 @@ var FileManager = class {
|
|
|
2319
2331
|
#cache = /* @__PURE__ */ new Map();
|
|
2320
2332
|
#pending = /* @__PURE__ */ new Set();
|
|
2321
2333
|
#sorted = null;
|
|
2334
|
+
#merges = /* @__PURE__ */ new WeakSet();
|
|
2322
2335
|
add(...files) {
|
|
2323
2336
|
return this.#store(files, false);
|
|
2324
2337
|
}
|
|
@@ -2326,18 +2339,18 @@ var FileManager = class {
|
|
|
2326
2339
|
return this.#store(files, true);
|
|
2327
2340
|
}
|
|
2328
2341
|
/** Stores a generator result: a file array is upserted as is, an element renders through `renderer` first, falsy is a no-op. */
|
|
2329
|
-
async dispatch({ result, renderer }) {
|
|
2342
|
+
async dispatch({ result, renderer, pointer }) {
|
|
2330
2343
|
try {
|
|
2331
2344
|
var _usingCtx$2 = _usingCtx();
|
|
2332
2345
|
if (!result) return;
|
|
2333
2346
|
if (Array.isArray(result)) {
|
|
2334
|
-
this.#defer(result);
|
|
2347
|
+
this.#defer(withPointer(result, pointer));
|
|
2335
2348
|
return;
|
|
2336
2349
|
}
|
|
2337
2350
|
if (!renderer) return;
|
|
2338
2351
|
const instance = _usingCtx$2.u(renderer());
|
|
2339
2352
|
await instance.render(result);
|
|
2340
|
-
this.#defer(instance.files);
|
|
2353
|
+
this.#defer(withPointer(instance.files, pointer));
|
|
2341
2354
|
} catch (_) {
|
|
2342
2355
|
_usingCtx$2.e = _;
|
|
2343
2356
|
} finally {
|
|
@@ -2347,9 +2360,24 @@ var FileManager = class {
|
|
|
2347
2360
|
/** Upserts without normalizing: the raw merge waits in `#pending` until the file is read. */
|
|
2348
2361
|
#defer(files) {
|
|
2349
2362
|
for (const file of files) {
|
|
2350
|
-
const existing = this.#cache.get(file.path);
|
|
2351
|
-
this.#cache.set(file.path, existing ? mergeFile(existing, file) : file);
|
|
2352
2363
|
this.#pending.add(file.path);
|
|
2364
|
+
const existing = this.#cache.get(file.path);
|
|
2365
|
+
if (!existing) {
|
|
2366
|
+
this.#cache.set(file.path, file);
|
|
2367
|
+
continue;
|
|
2368
|
+
}
|
|
2369
|
+
if (!this.#merges.has(existing)) {
|
|
2370
|
+
const merged = mergeFile(existing, file);
|
|
2371
|
+
this.#merges.add(merged);
|
|
2372
|
+
this.#cache.set(file.path, merged);
|
|
2373
|
+
continue;
|
|
2374
|
+
}
|
|
2375
|
+
existing.banner = file.banner;
|
|
2376
|
+
existing.footer = file.footer;
|
|
2377
|
+
existing.copy = file.copy ?? existing.copy;
|
|
2378
|
+
existing.sources.push(...file.sources);
|
|
2379
|
+
existing.imports.push(...file.imports);
|
|
2380
|
+
existing.exports.push(...file.exports);
|
|
2353
2381
|
}
|
|
2354
2382
|
if (files.length > 0) this.#sorted = null;
|
|
2355
2383
|
}
|
|
@@ -2528,24 +2556,23 @@ function assertPluginEntry(entry, index) {
|
|
|
2528
2556
|
});
|
|
2529
2557
|
}
|
|
2530
2558
|
/**
|
|
2531
|
-
* Where a generator crashed: a label naming the node and, when the
|
|
2532
|
-
*
|
|
2559
|
+
* Where a generator crashed: a label naming the node and, when the adapter set one, the node's
|
|
2560
|
+
* pointer into the input.
|
|
2533
2561
|
*/
|
|
2534
2562
|
function getCrashSite(node) {
|
|
2535
|
-
if (node.kind === "Schema") return
|
|
2536
|
-
label: `schema "${node.name}"
|
|
2537
|
-
location: {
|
|
2563
|
+
if (node.kind === "Schema") return {
|
|
2564
|
+
label: node.name ? `schema "${node.name}"` : "an inline schema",
|
|
2565
|
+
location: node.pointer ? {
|
|
2538
2566
|
kind: "schema",
|
|
2539
|
-
pointer:
|
|
2540
|
-
}
|
|
2541
|
-
}
|
|
2542
|
-
if (!node.method || !node.path) return { label: `operation "${node.operationId}"` };
|
|
2567
|
+
pointer: node.pointer
|
|
2568
|
+
} : void 0
|
|
2569
|
+
};
|
|
2543
2570
|
return {
|
|
2544
|
-
label: `operation "${node.operationId}" (${node.method.toUpperCase()} ${node.path})`,
|
|
2545
|
-
location: {
|
|
2571
|
+
label: node.method && node.path ? `operation "${node.operationId}" (${node.method.toUpperCase()} ${node.path})` : `operation "${node.operationId}"`,
|
|
2572
|
+
location: node.pointer ? {
|
|
2546
2573
|
kind: "operation",
|
|
2547
|
-
pointer:
|
|
2548
|
-
}
|
|
2574
|
+
pointer: node.pointer
|
|
2575
|
+
} : void 0
|
|
2549
2576
|
};
|
|
2550
2577
|
}
|
|
2551
2578
|
var KubbDriver = class {
|
|
@@ -2833,6 +2860,7 @@ var KubbDriver = class {
|
|
|
2833
2860
|
hooks,
|
|
2834
2861
|
config
|
|
2835
2862
|
});
|
|
2863
|
+
await this.adapter?.settle?.();
|
|
2836
2864
|
await hooks.callHook("kubb:build:end", {
|
|
2837
2865
|
files: this.fileManager.files,
|
|
2838
2866
|
config,
|
|
@@ -2840,6 +2868,7 @@ var KubbDriver = class {
|
|
|
2840
2868
|
});
|
|
2841
2869
|
return { diagnostics: Diagnostics.dedupe(diagnostics) };
|
|
2842
2870
|
} catch (caughtError) {
|
|
2871
|
+
await this.adapter?.settle?.();
|
|
2843
2872
|
diagnostics.push(Diagnostics.from(caughtError));
|
|
2844
2873
|
return { diagnostics: Diagnostics.dedupe(diagnostics) };
|
|
2845
2874
|
}
|
|
@@ -3068,7 +3097,8 @@ var KubbDriver = class {
|
|
|
3068
3097
|
if (!(generator.match ? await generator.match(node, ctx) : true)) continue;
|
|
3069
3098
|
await this.fileManager.dispatch({
|
|
3070
3099
|
result: await generate(generator),
|
|
3071
|
-
renderer: generator.renderer
|
|
3100
|
+
renderer: generator.renderer,
|
|
3101
|
+
pointer: node.pointer
|
|
3072
3102
|
});
|
|
3073
3103
|
}
|
|
3074
3104
|
}
|
|
@@ -4143,8 +4173,9 @@ function resolveKubbDir(base = "") {
|
|
|
4143
4173
|
}
|
|
4144
4174
|
}
|
|
4145
4175
|
/**
|
|
4146
|
-
*
|
|
4147
|
-
*
|
|
4176
|
+
* Key-value files rooted at {@link resolveKubbDir}. Each key is a file path inside that folder.
|
|
4177
|
+
* Strings are stored as is and other values as JSON. `getItem` parses JSON and falls back to the
|
|
4178
|
+
* raw string. The 0700 folder keeps files such as a stored token private.
|
|
4148
4179
|
*
|
|
4149
4180
|
* @example
|
|
4150
4181
|
* ```ts
|
|
@@ -4153,7 +4184,30 @@ function resolveKubbDir(base = "") {
|
|
|
4153
4184
|
* ```
|
|
4154
4185
|
*/
|
|
4155
4186
|
function kubbStorage({ base } = {}) {
|
|
4156
|
-
|
|
4187
|
+
const dir = resolveKubbDir(base);
|
|
4188
|
+
const pathOf = (key) => {
|
|
4189
|
+
const path = (0, node_path.resolve)(dir, key.replaceAll(":", "/"));
|
|
4190
|
+
if (path === dir || !isPathInside(path, dir)) throw new Error(`Invalid key: ${JSON.stringify(key)}. It should not leave the storage folder`);
|
|
4191
|
+
return path;
|
|
4192
|
+
};
|
|
4193
|
+
return {
|
|
4194
|
+
async getItem(key) {
|
|
4195
|
+
const path = pathOf(key);
|
|
4196
|
+
if (!await exists(path)) return null;
|
|
4197
|
+
const raw = await read(path);
|
|
4198
|
+
try {
|
|
4199
|
+
return JSON.parse(raw);
|
|
4200
|
+
} catch {
|
|
4201
|
+
return raw;
|
|
4202
|
+
}
|
|
4203
|
+
},
|
|
4204
|
+
async setItem(key, value) {
|
|
4205
|
+
await writeRaw(pathOf(key), typeof value === "string" ? value : JSON.stringify(value));
|
|
4206
|
+
},
|
|
4207
|
+
async removeItem(key) {
|
|
4208
|
+
await (0, node_fs_promises.rm)(pathOf(key), { force: true });
|
|
4209
|
+
}
|
|
4210
|
+
};
|
|
4157
4211
|
}
|
|
4158
4212
|
//#endregion
|
|
4159
4213
|
//#region src/reporters/fileReporter.ts
|