@kubb/core 5.0.0-beta.85 → 5.0.0-beta.86
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/{Diagnostics-PnPLU3kj.d.ts → Diagnostics-aWJg-H2d.d.ts} +90 -98
- package/dist/index.cjs +170 -198
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +36 -3
- package/dist/index.js +170 -198
- package/dist/index.js.map +1 -1
- package/dist/mocks.cjs +1 -1
- package/dist/mocks.d.ts +1 -1
- package/dist/mocks.js +1 -1
- package/dist/{usingCtx-fxRpJw0P.cjs → usingCtx-BN2OKJRx.cjs} +72 -48
- package/dist/usingCtx-BN2OKJRx.cjs.map +1 -0
- package/dist/{usingCtx-BABTfo1g.js → usingCtx-Cnrm3TcM.js} +61 -43
- package/dist/usingCtx-Cnrm3TcM.js.map +1 -0
- package/package.json +2 -2
- package/dist/usingCtx-BABTfo1g.js.map +0 -1
- package/dist/usingCtx-fxRpJw0P.cjs.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "./rolldown-runtime-C0LytTxp.js";
|
|
2
|
-
import { a as toFilePath, c as BuildError, i as clean, l as getErrorMessage, n as FileManager, o as toPosixPath, r as
|
|
2
|
+
import { a as toFilePath, c as BuildError, d as camelCase, i as clean, l as getErrorMessage, n as FileManager, o as toPosixPath, r as Hookable, s as write, t as _usingCtx, u as toError } from "./usingCtx-Cnrm3TcM.js";
|
|
3
3
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
4
4
|
import { stripVTControlCharacters, styleText } from "node:util";
|
|
5
5
|
import { hash } from "node:crypto";
|
|
@@ -170,7 +170,7 @@ function memoize(store, factory) {
|
|
|
170
170
|
}
|
|
171
171
|
//#endregion
|
|
172
172
|
//#region package.json
|
|
173
|
-
var version = "5.0.0-beta.
|
|
173
|
+
var version = "5.0.0-beta.86";
|
|
174
174
|
//#endregion
|
|
175
175
|
//#region src/constants.ts
|
|
176
176
|
/**
|
|
@@ -517,12 +517,12 @@ var Diagnostics = class Diagnostics {
|
|
|
517
517
|
return true;
|
|
518
518
|
}
|
|
519
519
|
/**
|
|
520
|
-
* Emits a diagnostic on the run's `kubb:diagnostic`
|
|
521
|
-
* Use it instead of calling `hooks.
|
|
520
|
+
* Emits a diagnostic on the run's `kubb:diagnostic` hook so the loggers render it live.
|
|
521
|
+
* Use it instead of calling `hooks.callHook('kubb:diagnostic', ...)` directly. To collect a
|
|
522
522
|
* diagnostic into the build result from deep in a run, use {@link Diagnostics.report} instead.
|
|
523
523
|
*/
|
|
524
524
|
static async emit(hooks, diagnostic) {
|
|
525
|
-
await hooks.
|
|
525
|
+
await hooks.callHook("kubb:diagnostic", { diagnostic });
|
|
526
526
|
}
|
|
527
527
|
/**
|
|
528
528
|
* Coerces any thrown value into a {@link ProblemDiagnostic}. A {@link Diagnostics.Error}
|
|
@@ -740,7 +740,7 @@ function definePlugin(factory) {
|
|
|
740
740
|
return (options) => factory(options ?? {});
|
|
741
741
|
}
|
|
742
742
|
//#endregion
|
|
743
|
-
//#region src/
|
|
743
|
+
//#region src/Resolver.ts
|
|
744
744
|
function isNamespace(value) {
|
|
745
745
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
746
746
|
}
|
|
@@ -804,7 +804,7 @@ var Resolver = class Resolver {
|
|
|
804
804
|
*/
|
|
805
805
|
static merge(base, override) {
|
|
806
806
|
const patch = override instanceof Resolver ? override.#options : override;
|
|
807
|
-
return
|
|
807
|
+
return new Resolver({
|
|
808
808
|
...base.#options,
|
|
809
809
|
...patch
|
|
810
810
|
});
|
|
@@ -996,6 +996,8 @@ var Resolver = class Resolver {
|
|
|
996
996
|
return Resolver.#resolveUserText(output?.footer, meta, file) ?? null;
|
|
997
997
|
}
|
|
998
998
|
};
|
|
999
|
+
//#endregion
|
|
1000
|
+
//#region src/createResolver.ts
|
|
999
1001
|
/**
|
|
1000
1002
|
* Defines a plugin resolver, the object that decides what every generated symbol and file
|
|
1001
1003
|
* path is called. Override the top-level `name` and `file` to set the plugin's conventions,
|
|
@@ -1101,35 +1103,7 @@ const ENFORCE_ORDER = {
|
|
|
1101
1103
|
pre: -1,
|
|
1102
1104
|
post: 1
|
|
1103
1105
|
};
|
|
1104
|
-
|
|
1105
|
-
* Orders plugins so every dependency runs before its dependents (Kahn's algorithm), with
|
|
1106
|
-
* `enforce` (`'pre'` before normal before `'post'`) and declaration order as tiebreaks.
|
|
1107
|
-
* A pairwise `Array.sort` comparator cannot do this: dependency relations are not transitive
|
|
1108
|
-
* at the comparator level, so a chain where A depends on B and B depends on C could come out
|
|
1109
|
-
* wrong when A and C are never compared directly. Dependencies on plugins missing from the
|
|
1110
|
-
* config are ignored here and surface later through `requirePlugin`.
|
|
1111
|
-
*/
|
|
1112
|
-
function sortPlugins(plugins) {
|
|
1113
|
-
const queue = [...plugins].sort((a, b) => (a.enforce ? ENFORCE_ORDER[a.enforce] : 0) - (b.enforce ? ENFORCE_ORDER[b.enforce] : 0));
|
|
1114
|
-
const names = new Set(queue.map((plugin) => plugin.name));
|
|
1115
|
-
const blockedBy = new Map(queue.map((plugin) => [plugin.name, new Set(plugin.dependencies?.filter((name) => names.has(name) && name !== plugin.name))]));
|
|
1116
|
-
const sorted = [];
|
|
1117
|
-
while (queue.length > 0) {
|
|
1118
|
-
const index = queue.findIndex((plugin) => blockedBy.get(plugin.name)?.size === 0);
|
|
1119
|
-
if (index === -1) throw new Diagnostics.Error({
|
|
1120
|
-
code: Diagnostics.code.invalidPluginOptions,
|
|
1121
|
-
severity: "error",
|
|
1122
|
-
message: `Plugin dependencies form a cycle: ${queue.map((plugin) => plugin.name).join(" → ")}.`,
|
|
1123
|
-
help: "Remove one of the `dependencies` entries so the plugins can be ordered.",
|
|
1124
|
-
location: { kind: "config" }
|
|
1125
|
-
});
|
|
1126
|
-
const [plugin] = queue.splice(index, 1);
|
|
1127
|
-
if (!plugin) break;
|
|
1128
|
-
sorted.push(plugin);
|
|
1129
|
-
for (const blockers of blockedBy.values()) blockers.delete(plugin.name);
|
|
1130
|
-
}
|
|
1131
|
-
return sorted;
|
|
1132
|
-
}
|
|
1106
|
+
const enforceWeight = (plugin) => plugin.enforce ? ENFORCE_ORDER[plugin.enforce] : 0;
|
|
1133
1107
|
var KubbDriver = class {
|
|
1134
1108
|
config;
|
|
1135
1109
|
options;
|
|
@@ -1151,17 +1125,17 @@ var KubbDriver = class {
|
|
|
1151
1125
|
fileManager = new FileManager();
|
|
1152
1126
|
plugins = /* @__PURE__ */ new Map();
|
|
1153
1127
|
/**
|
|
1154
|
-
* Tracks which plugins have generators registered via `addGenerator()` (
|
|
1155
|
-
* Used by the build loop to decide whether to emit generator
|
|
1128
|
+
* Tracks which plugins have generators registered via `addGenerator()` (hook-based path).
|
|
1129
|
+
* Used by the build loop to decide whether to emit generator hooks for a given plugin.
|
|
1156
1130
|
*/
|
|
1157
|
-
#
|
|
1131
|
+
#hookGeneratorPlugins = /* @__PURE__ */ new Set();
|
|
1158
1132
|
#resolvers = /* @__PURE__ */ new Map();
|
|
1159
1133
|
#defaultResolvers = /* @__PURE__ */ new Map();
|
|
1160
1134
|
/**
|
|
1161
|
-
*
|
|
1162
|
-
* in one pass. External `hooks.
|
|
1135
|
+
* Removers for every listener the driver added (plugin, generator) so `dispose()` can detach
|
|
1136
|
+
* them in one pass. External `hooks.hook(...)` listeners are not tracked.
|
|
1163
1137
|
*/
|
|
1164
|
-
#
|
|
1138
|
+
#unhooks = [];
|
|
1165
1139
|
/**
|
|
1166
1140
|
* Transform registry. Plugins populate it during `kubb:plugin:setup` via `addMacro`/`setMacros`,
|
|
1167
1141
|
* and `#runGenerators` reads it once per `(plugin, node)` pair through `applyTo`.
|
|
@@ -1173,52 +1147,67 @@ var KubbDriver = class {
|
|
|
1173
1147
|
this.adapter = config.adapter ?? null;
|
|
1174
1148
|
}
|
|
1175
1149
|
/**
|
|
1176
|
-
* Attaches a listener to the shared emitter and tracks it so `dispose()` can remove it later.
|
|
1177
|
-
* Listeners attached directly via `hooks.on(...)` are not tracked and survive disposal.
|
|
1178
|
-
*/
|
|
1179
|
-
#trackListener(event, handler) {
|
|
1180
|
-
this.hooks.on(event, handler);
|
|
1181
|
-
this.#listeners.push([event, handler]);
|
|
1182
|
-
}
|
|
1183
|
-
/**
|
|
1184
1150
|
* Normalizes every configured plugin, orders them, and registers their lifecycle handlers.
|
|
1185
1151
|
* A plugin that another lists as a dependency runs first, then `enforce: 'pre'` before
|
|
1186
1152
|
* `'post'`. When the config has an adapter, the adapter source is resolved from the input
|
|
1187
1153
|
* so `run` can parse it later.
|
|
1188
1154
|
*/
|
|
1189
1155
|
async setup() {
|
|
1190
|
-
const normalized = sortPlugins(this.config.plugins.map((rawPlugin) =>
|
|
1156
|
+
const normalized = this.#sortPlugins(this.config.plugins.map((rawPlugin) => {
|
|
1157
|
+
return {
|
|
1158
|
+
name: rawPlugin.name,
|
|
1159
|
+
dependencies: rawPlugin.dependencies,
|
|
1160
|
+
enforce: rawPlugin.enforce,
|
|
1161
|
+
hooks: rawPlugin.hooks,
|
|
1162
|
+
options: rawPlugin.options ?? {
|
|
1163
|
+
output: {
|
|
1164
|
+
path: ".",
|
|
1165
|
+
mode: "directory"
|
|
1166
|
+
},
|
|
1167
|
+
exclude: [],
|
|
1168
|
+
override: []
|
|
1169
|
+
}
|
|
1170
|
+
};
|
|
1171
|
+
}));
|
|
1191
1172
|
for (const plugin of normalized) {
|
|
1192
1173
|
this.#registerPlugin(plugin);
|
|
1193
1174
|
this.plugins.set(plugin.name, plugin);
|
|
1194
1175
|
}
|
|
1195
1176
|
if (this.config.adapter) this.#adapterSource = inputToAdapterSource(this.config);
|
|
1196
1177
|
}
|
|
1178
|
+
/**
|
|
1179
|
+
* Orders plugins so every dependency runs before its dependents (Kahn's algorithm), with
|
|
1180
|
+
* `enforce` (`'pre'` before normal before `'post'`) and declaration order as tiebreaks.
|
|
1181
|
+
* A pairwise `Array.sort` comparator cannot do this: dependency relations are not transitive
|
|
1182
|
+
* at the comparator level, so a chain where A depends on B and B depends on C could come out
|
|
1183
|
+
* wrong when A and C are never compared directly. Dependencies on plugins missing from the
|
|
1184
|
+
* config are ignored here and surface later through `requirePlugin`.
|
|
1185
|
+
*/
|
|
1186
|
+
#sortPlugins(plugins) {
|
|
1187
|
+
const queue = [...plugins].sort((a, b) => enforceWeight(a) - enforceWeight(b));
|
|
1188
|
+
const names = new Set(queue.map((plugin) => plugin.name));
|
|
1189
|
+
const blockedBy = new Map(queue.map((plugin) => [plugin.name, new Set(plugin.dependencies?.filter((name) => names.has(name) && name !== plugin.name))]));
|
|
1190
|
+
const sorted = [];
|
|
1191
|
+
for (const _ of plugins) {
|
|
1192
|
+
const index = queue.findIndex((plugin) => blockedBy.get(plugin.name)?.size === 0);
|
|
1193
|
+
if (index === -1) throw new Diagnostics.Error({
|
|
1194
|
+
code: Diagnostics.code.invalidPluginOptions,
|
|
1195
|
+
severity: "error",
|
|
1196
|
+
message: `Plugin dependencies form a cycle: ${queue.map((plugin) => plugin.name).join(" → ")}.`,
|
|
1197
|
+
help: "Remove one of the `dependencies` entries so the plugins can be ordered.",
|
|
1198
|
+
location: { kind: "config" }
|
|
1199
|
+
});
|
|
1200
|
+
const [plugin] = queue.splice(index, 1);
|
|
1201
|
+
if (!plugin) break;
|
|
1202
|
+
sorted.push(plugin);
|
|
1203
|
+
for (const blockers of blockedBy.values()) blockers.delete(plugin.name);
|
|
1204
|
+
}
|
|
1205
|
+
return sorted;
|
|
1206
|
+
}
|
|
1197
1207
|
get hooks() {
|
|
1198
1208
|
return this.options.hooks;
|
|
1199
1209
|
}
|
|
1200
1210
|
/**
|
|
1201
|
-
* Builds a `NormalizedPlugin` from a hook-style plugin, filling in default
|
|
1202
|
-
* options. Registering its lifecycle handlers on the `AsyncEventEmitter` is
|
|
1203
|
-
* done separately by `#registerPlugin`.
|
|
1204
|
-
*/
|
|
1205
|
-
#normalizePlugin(plugin) {
|
|
1206
|
-
return {
|
|
1207
|
-
name: plugin.name,
|
|
1208
|
-
dependencies: plugin.dependencies,
|
|
1209
|
-
enforce: plugin.enforce,
|
|
1210
|
-
hooks: plugin.hooks,
|
|
1211
|
-
options: plugin.options ?? {
|
|
1212
|
-
output: {
|
|
1213
|
-
path: ".",
|
|
1214
|
-
mode: "directory"
|
|
1215
|
-
},
|
|
1216
|
-
exclude: [],
|
|
1217
|
-
override: []
|
|
1218
|
-
}
|
|
1219
|
-
};
|
|
1220
|
-
}
|
|
1221
|
-
/**
|
|
1222
1211
|
* Parses the adapter source into `this.inputNode`. Idempotent, so repeated calls from
|
|
1223
1212
|
* `run` do not re-parse.
|
|
1224
1213
|
*/
|
|
@@ -1227,86 +1216,68 @@ var KubbDriver = class {
|
|
|
1227
1216
|
this.inputNode = await this.adapter.parse(this.#adapterSource);
|
|
1228
1217
|
}
|
|
1229
1218
|
/**
|
|
1230
|
-
* Registers a
|
|
1231
|
-
*
|
|
1232
|
-
*
|
|
1233
|
-
*
|
|
1234
|
-
* Every other `KubbHooks` event registers as a pass-through listener that external tooling
|
|
1235
|
-
* can observe via `hooks.on(...)`.
|
|
1219
|
+
* Registers a plugin's lifecycle hooks on the shared `Hookable` as pass-through listeners that
|
|
1220
|
+
* external tooling can observe via `hooks.hook(...)`. The returned remover is tracked for
|
|
1221
|
+
* `dispose`. `kubb:plugin:setup` is skipped here; `setupHooks` invokes it directly with a
|
|
1222
|
+
* plugin-scoped context.
|
|
1236
1223
|
*
|
|
1237
1224
|
* @internal
|
|
1238
1225
|
*/
|
|
1239
1226
|
#registerPlugin(plugin) {
|
|
1240
1227
|
const { hooks } = plugin;
|
|
1241
1228
|
if (!hooks) return;
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
const pluginCtx = {
|
|
1245
|
-
...globalCtx,
|
|
1246
|
-
options: plugin.options ?? {},
|
|
1247
|
-
addGenerator: (...generators) => {
|
|
1248
|
-
for (const generator of generators.flat()) this.registerGenerator(plugin.name, generator);
|
|
1249
|
-
},
|
|
1250
|
-
setResolver: (resolver) => {
|
|
1251
|
-
this.setPluginResolver(plugin.name, resolver);
|
|
1252
|
-
},
|
|
1253
|
-
addMacro: (macro) => {
|
|
1254
|
-
this.#transforms.add(plugin.name, macro);
|
|
1255
|
-
},
|
|
1256
|
-
setMacros: (macros) => {
|
|
1257
|
-
this.#transforms.set(plugin.name, macros);
|
|
1258
|
-
},
|
|
1259
|
-
setOptions: (opts) => {
|
|
1260
|
-
plugin.options = {
|
|
1261
|
-
...plugin.options,
|
|
1262
|
-
...opts
|
|
1263
|
-
};
|
|
1264
|
-
if (plugin.options.output) {
|
|
1265
|
-
const group = "group" in plugin.options ? plugin.options.group : void 0;
|
|
1266
|
-
plugin.options.output = normalizeOutput({
|
|
1267
|
-
output: plugin.options.output,
|
|
1268
|
-
group,
|
|
1269
|
-
pluginName: plugin.name
|
|
1270
|
-
});
|
|
1271
|
-
}
|
|
1272
|
-
},
|
|
1273
|
-
injectFile: (userFileNode) => {
|
|
1274
|
-
this.fileManager.add(ast.factory.createFile(userFileNode));
|
|
1275
|
-
}
|
|
1276
|
-
};
|
|
1277
|
-
return hooks["kubb:plugin:setup"](pluginCtx);
|
|
1278
|
-
};
|
|
1279
|
-
this.#trackListener("kubb:plugin:setup", setupHandler);
|
|
1280
|
-
}
|
|
1281
|
-
for (const event of Object.keys(hooks)) {
|
|
1282
|
-
if (event === "kubb:plugin:setup") continue;
|
|
1283
|
-
const handler = hooks[event];
|
|
1284
|
-
if (!handler) continue;
|
|
1285
|
-
this.#trackListener(event, handler);
|
|
1286
|
-
}
|
|
1229
|
+
const { "kubb:plugin:setup": _setup, ...configHooks } = hooks;
|
|
1230
|
+
this.#unhooks.push(this.hooks.addHooks(configHooks));
|
|
1287
1231
|
}
|
|
1288
1232
|
/**
|
|
1289
|
-
*
|
|
1290
|
-
*
|
|
1291
|
-
*
|
|
1292
|
-
*
|
|
1233
|
+
* Runs each plugin's `kubb:plugin:setup` handler, in plugin order, with a context scoped to that
|
|
1234
|
+
* plugin so `addGenerator`, `setResolver`, `addMacro`, `setMacros`, and `setOptions` target its
|
|
1235
|
+
* `NormalizedPlugin` entry. Called once from `run` before the plugin execution loop begins, so
|
|
1236
|
+
* plugins can configure generators, resolvers, macros, and options before `buildStart`.
|
|
1293
1237
|
*/
|
|
1294
|
-
async
|
|
1238
|
+
async setupHooks() {
|
|
1295
1239
|
const noop = () => {};
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1240
|
+
for (const plugin of this.plugins.values()) {
|
|
1241
|
+
const setup = plugin.hooks?.["kubb:plugin:setup"];
|
|
1242
|
+
if (!setup) continue;
|
|
1243
|
+
await setup({
|
|
1244
|
+
config: this.config,
|
|
1245
|
+
options: plugin.options ?? {},
|
|
1246
|
+
updateConfig: noop,
|
|
1247
|
+
addGenerator: (...generators) => {
|
|
1248
|
+
for (const generator of generators) this.registerGenerator(plugin.name, generator);
|
|
1249
|
+
},
|
|
1250
|
+
setResolver: (resolver) => {
|
|
1251
|
+
this.setPluginResolver(plugin.name, resolver);
|
|
1252
|
+
},
|
|
1253
|
+
addMacro: (macro) => {
|
|
1254
|
+
this.#transforms.add(plugin.name, macro);
|
|
1255
|
+
},
|
|
1256
|
+
setMacros: (macros) => {
|
|
1257
|
+
this.#transforms.set(plugin.name, macros);
|
|
1258
|
+
},
|
|
1259
|
+
setOptions: (opts) => {
|
|
1260
|
+
plugin.options = {
|
|
1261
|
+
...plugin.options,
|
|
1262
|
+
...opts
|
|
1263
|
+
};
|
|
1264
|
+
if (plugin.options.output) {
|
|
1265
|
+
const group = "group" in plugin.options ? plugin.options.group : void 0;
|
|
1266
|
+
plugin.options.output = normalizeOutput({
|
|
1267
|
+
output: plugin.options.output,
|
|
1268
|
+
group,
|
|
1269
|
+
pluginName: plugin.name
|
|
1270
|
+
});
|
|
1271
|
+
}
|
|
1272
|
+
},
|
|
1273
|
+
injectFile: (userFileNode) => {
|
|
1274
|
+
this.fileManager.add(ast.factory.createFile(userFileNode));
|
|
1275
|
+
}
|
|
1276
|
+
});
|
|
1277
|
+
}
|
|
1307
1278
|
}
|
|
1308
1279
|
/**
|
|
1309
|
-
* Registers a generator for the given plugin on the shared
|
|
1280
|
+
* Registers a generator for the given plugin on the shared hook emitter.
|
|
1310
1281
|
*
|
|
1311
1282
|
* The generator's `schema`, `operation`, and `operations` methods are registered as
|
|
1312
1283
|
* listeners on `kubb:generate:schema`, `kubb:generate:operation`, and `kubb:generate:operations`
|
|
@@ -1319,9 +1290,9 @@ var KubbDriver = class {
|
|
|
1319
1290
|
* Call this method inside `addGenerator()` (in `kubb:plugin:setup`) to wire up a generator.
|
|
1320
1291
|
*/
|
|
1321
1292
|
registerGenerator(pluginName, generator) {
|
|
1322
|
-
const
|
|
1323
|
-
if (!method) return;
|
|
1324
|
-
|
|
1293
|
+
const wrap = (method) => {
|
|
1294
|
+
if (!method) return void 0;
|
|
1295
|
+
return async (node, ctx) => {
|
|
1325
1296
|
if (ctx.plugin.name !== pluginName) return;
|
|
1326
1297
|
const result = await method(node, ctx);
|
|
1327
1298
|
await this.dispatch({
|
|
@@ -1329,22 +1300,23 @@ var KubbDriver = class {
|
|
|
1329
1300
|
renderer: generator.renderer
|
|
1330
1301
|
});
|
|
1331
1302
|
};
|
|
1332
|
-
this.#trackListener(event, handler);
|
|
1333
1303
|
};
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1304
|
+
this.#unhooks.push(this.hooks.addHooks({
|
|
1305
|
+
"kubb:generate:schema": wrap(generator.schema),
|
|
1306
|
+
"kubb:generate:operation": wrap(generator.operation),
|
|
1307
|
+
"kubb:generate:operations": wrap(generator.operations)
|
|
1308
|
+
}));
|
|
1309
|
+
this.#hookGeneratorPlugins.add(pluginName);
|
|
1338
1310
|
}
|
|
1339
1311
|
/**
|
|
1340
1312
|
* Returns `true` when at least one generator was registered for the given plugin
|
|
1341
1313
|
* via `addGenerator()` in `kubb:plugin:setup`.
|
|
1342
1314
|
*
|
|
1343
|
-
* Used by the build loop to decide whether to walk the AST and emit generator
|
|
1315
|
+
* Used by the build loop to decide whether to walk the AST and emit generator hooks
|
|
1344
1316
|
* for a plugin.
|
|
1345
1317
|
*/
|
|
1346
|
-
|
|
1347
|
-
return this.#
|
|
1318
|
+
hasHookGenerators(pluginName) {
|
|
1319
|
+
return this.#hookGeneratorPlugins.has(pluginName);
|
|
1348
1320
|
}
|
|
1349
1321
|
/**
|
|
1350
1322
|
* Runs the full plugin pipeline. Returns the diagnostics collected so far even
|
|
@@ -1358,29 +1330,31 @@ var KubbDriver = class {
|
|
|
1358
1330
|
const parsersMap = /* @__PURE__ */ new Map();
|
|
1359
1331
|
for (const parser of config.parsers) if (parser.extNames) for (const ext of parser.extNames) parsersMap.set(ext, parser);
|
|
1360
1332
|
const onWriteStart = async (files) => {
|
|
1361
|
-
await hooks.
|
|
1333
|
+
await hooks.callHook("kubb:files:processing:start", { files });
|
|
1362
1334
|
};
|
|
1363
1335
|
const updateBuffer = [];
|
|
1364
1336
|
const onWriteUpdate = (item) => {
|
|
1365
1337
|
updateBuffer.push(item);
|
|
1366
1338
|
};
|
|
1367
1339
|
const onWriteEnd = async (files) => {
|
|
1368
|
-
await hooks.
|
|
1340
|
+
await hooks.callHook("kubb:files:processing:update", { files: updateBuffer.map((item) => ({
|
|
1369
1341
|
...item,
|
|
1370
1342
|
config
|
|
1371
1343
|
})) });
|
|
1372
1344
|
updateBuffer.length = 0;
|
|
1373
|
-
await hooks.
|
|
1345
|
+
await hooks.callHook("kubb:files:processing:end", { files });
|
|
1374
1346
|
};
|
|
1375
|
-
fileManager.hooks.
|
|
1376
|
-
|
|
1377
|
-
|
|
1347
|
+
const unhookWrites = fileManager.hooks.addHooks({
|
|
1348
|
+
start: onWriteStart,
|
|
1349
|
+
update: onWriteUpdate,
|
|
1350
|
+
end: onWriteEnd
|
|
1351
|
+
});
|
|
1378
1352
|
return Diagnostics.scope((diagnostic) => diagnostics.push(diagnostic), async () => {
|
|
1379
1353
|
try {
|
|
1380
1354
|
const outputRoot = resolve(config.root, config.output.path);
|
|
1381
1355
|
await this.#parseInput();
|
|
1382
|
-
await this.
|
|
1383
|
-
if (this.adapter && this.inputNode) await hooks.
|
|
1356
|
+
await this.setupHooks();
|
|
1357
|
+
if (this.adapter && this.inputNode) await hooks.callHook("kubb:build:start", Object.assign({
|
|
1384
1358
|
config,
|
|
1385
1359
|
adapter: this.adapter,
|
|
1386
1360
|
meta: this.inputNode.meta,
|
|
@@ -1391,9 +1365,9 @@ var KubbDriver = class {
|
|
|
1391
1365
|
const context = this.getContext(plugin);
|
|
1392
1366
|
const hrStart = process.hrtime();
|
|
1393
1367
|
try {
|
|
1394
|
-
await hooks.
|
|
1368
|
+
await hooks.callHook("kubb:plugin:start", { plugin });
|
|
1395
1369
|
} catch (caughtError) {
|
|
1396
|
-
const error = caughtError;
|
|
1370
|
+
const error = toError(caughtError);
|
|
1397
1371
|
const duration = getElapsedMs(hrStart);
|
|
1398
1372
|
await this.#emitPluginEnd({
|
|
1399
1373
|
plugin,
|
|
@@ -1410,7 +1384,7 @@ var KubbDriver = class {
|
|
|
1410
1384
|
}));
|
|
1411
1385
|
continue;
|
|
1412
1386
|
}
|
|
1413
|
-
if (this.
|
|
1387
|
+
if (this.hasHookGenerators(plugin.name)) {
|
|
1414
1388
|
generatorPlugins.push({
|
|
1415
1389
|
plugin,
|
|
1416
1390
|
context,
|
|
@@ -1430,13 +1404,13 @@ var KubbDriver = class {
|
|
|
1430
1404
|
});
|
|
1431
1405
|
}
|
|
1432
1406
|
diagnostics.push(...await this.#runGenerators(generatorPlugins));
|
|
1433
|
-
await hooks.
|
|
1407
|
+
await hooks.callHook("kubb:plugins:end", Object.assign({ config }, this.#filesPayload()));
|
|
1434
1408
|
await fileManager.write(fileManager.files, {
|
|
1435
1409
|
storage,
|
|
1436
1410
|
parsers: parsersMap,
|
|
1437
1411
|
extension: config.output.extension
|
|
1438
1412
|
});
|
|
1439
|
-
await hooks.
|
|
1413
|
+
await hooks.callHook("kubb:build:end", {
|
|
1440
1414
|
files: this.fileManager.files,
|
|
1441
1415
|
config,
|
|
1442
1416
|
outputDir: outputRoot
|
|
@@ -1446,9 +1420,7 @@ var KubbDriver = class {
|
|
|
1446
1420
|
diagnostics.push(Diagnostics.from(caughtError));
|
|
1447
1421
|
return { diagnostics: Diagnostics.dedupe(diagnostics) };
|
|
1448
1422
|
} finally {
|
|
1449
|
-
|
|
1450
|
-
fileManager.hooks.off("update", onWriteUpdate);
|
|
1451
|
-
fileManager.hooks.off("end", onWriteEnd);
|
|
1423
|
+
unhookWrites();
|
|
1452
1424
|
}
|
|
1453
1425
|
});
|
|
1454
1426
|
}
|
|
@@ -1462,7 +1434,7 @@ var KubbDriver = class {
|
|
|
1462
1434
|
};
|
|
1463
1435
|
}
|
|
1464
1436
|
#emitPluginEnd({ plugin, duration, success, error }) {
|
|
1465
|
-
return this.hooks.
|
|
1437
|
+
return this.hooks.callHook("kubb:plugin:end", Object.assign({
|
|
1466
1438
|
plugin,
|
|
1467
1439
|
duration,
|
|
1468
1440
|
success,
|
|
@@ -1555,12 +1527,12 @@ var KubbDriver = class {
|
|
|
1555
1527
|
if (!resolved) continue;
|
|
1556
1528
|
const { transformedNode, options } = resolved;
|
|
1557
1529
|
if (allowedSchemaNames !== null && transformedNode.name && !allowedSchemaNames.has(transformedNode.name)) continue;
|
|
1558
|
-
await this.hooks.
|
|
1530
|
+
await this.hooks.callHook("kubb:generate:schema", transformedNode, {
|
|
1559
1531
|
...generatorContext,
|
|
1560
1532
|
options
|
|
1561
1533
|
});
|
|
1562
1534
|
} catch (caughtError) {
|
|
1563
|
-
error = caughtError;
|
|
1535
|
+
error = toError(caughtError);
|
|
1564
1536
|
}
|
|
1565
1537
|
}
|
|
1566
1538
|
if (emitsOperationHook) for (const node of operations) {
|
|
@@ -1568,12 +1540,12 @@ var KubbDriver = class {
|
|
|
1568
1540
|
try {
|
|
1569
1541
|
const resolved = resolveForPlugin(node);
|
|
1570
1542
|
if (!resolved) continue;
|
|
1571
|
-
await this.hooks.
|
|
1543
|
+
await this.hooks.callHook("kubb:generate:operation", resolved.transformedNode, {
|
|
1572
1544
|
...generatorContext,
|
|
1573
1545
|
options: resolved.options
|
|
1574
1546
|
});
|
|
1575
1547
|
} catch (caughtError) {
|
|
1576
|
-
error = caughtError;
|
|
1548
|
+
error = toError(caughtError);
|
|
1577
1549
|
}
|
|
1578
1550
|
}
|
|
1579
1551
|
if (!error && emitsOperationsHook) try {
|
|
@@ -1586,9 +1558,9 @@ var KubbDriver = class {
|
|
|
1586
1558
|
if (resolved) acc.push(resolved.transformedNode);
|
|
1587
1559
|
return acc;
|
|
1588
1560
|
}, []);
|
|
1589
|
-
await this.hooks.
|
|
1561
|
+
await this.hooks.callHook("kubb:generate:operations", pluginOperations, ctx);
|
|
1590
1562
|
} catch (caughtError) {
|
|
1591
|
-
error = caughtError;
|
|
1563
|
+
error = toError(caughtError);
|
|
1592
1564
|
}
|
|
1593
1565
|
const duration = getElapsedMs(hrStart);
|
|
1594
1566
|
await this.#emitPluginEnd({
|
|
@@ -1645,9 +1617,9 @@ var KubbDriver = class {
|
|
|
1645
1617
|
* @internal
|
|
1646
1618
|
*/
|
|
1647
1619
|
dispose() {
|
|
1648
|
-
for (const
|
|
1649
|
-
this.#
|
|
1650
|
-
this.#
|
|
1620
|
+
for (const unhook of this.#unhooks) unhook();
|
|
1621
|
+
this.#unhooks.length = 0;
|
|
1622
|
+
this.#hookGeneratorPlugins.clear();
|
|
1651
1623
|
this.#transforms.dispose();
|
|
1652
1624
|
this.#resolvers.clear();
|
|
1653
1625
|
this.#defaultResolvers.clear();
|
|
@@ -1740,18 +1712,18 @@ var KubbDriver = class {
|
|
|
1740
1712
|
return this.plugins.get(pluginName);
|
|
1741
1713
|
}
|
|
1742
1714
|
requirePlugin(pluginName, context) {
|
|
1743
|
-
const plugin = this.
|
|
1744
|
-
if (
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
}
|
|
1753
|
-
|
|
1754
|
-
|
|
1715
|
+
const plugin = this.getPlugin(pluginName);
|
|
1716
|
+
if (plugin) return plugin;
|
|
1717
|
+
const requiredBy = context?.requiredBy;
|
|
1718
|
+
const by = requiredBy ? ` by "${requiredBy}"` : "";
|
|
1719
|
+
const help = requiredBy ? ` (required by "${requiredBy}")` : "";
|
|
1720
|
+
throw new Diagnostics.Error({
|
|
1721
|
+
code: Diagnostics.code.pluginNotFound,
|
|
1722
|
+
severity: "error",
|
|
1723
|
+
message: `Plugin "${pluginName}" is required${by} but not found. Make sure it is included in your Kubb config.`,
|
|
1724
|
+
help: `Add "${pluginName}" to the \`plugins\` array in kubb.config.ts${help}, or remove the dependency on it.`,
|
|
1725
|
+
location: { kind: "config" }
|
|
1726
|
+
});
|
|
1755
1727
|
}
|
|
1756
1728
|
};
|
|
1757
1729
|
function inputToAdapterSource(config) {
|
|
@@ -1940,12 +1912,12 @@ function resolveConfig(userConfig) {
|
|
|
1940
1912
|
* `createKubb` takes a plain config object (the shape `defineConfig` produces),
|
|
1941
1913
|
* not a fluent builder.
|
|
1942
1914
|
*
|
|
1943
|
-
* Attach
|
|
1915
|
+
* Attach hook listeners to `.hooks` before calling `setup()` or `build()`.
|
|
1944
1916
|
*
|
|
1945
1917
|
* @example
|
|
1946
1918
|
* ```ts
|
|
1947
1919
|
* const kubb = createKubb(userConfig)
|
|
1948
|
-
* kubb.hooks.
|
|
1920
|
+
* kubb.hooks.hook('kubb:plugin:end', ({ plugin, duration }) => console.log(plugin.name, duration))
|
|
1949
1921
|
* const { files, diagnostics } = await kubb.safeBuild()
|
|
1950
1922
|
* ```
|
|
1951
1923
|
*/
|
|
@@ -1956,7 +1928,7 @@ var Kubb = class {
|
|
|
1956
1928
|
#storage = null;
|
|
1957
1929
|
constructor(userConfig, options = {}) {
|
|
1958
1930
|
this.config = resolveConfig(userConfig);
|
|
1959
|
-
this.hooks = options.hooks ?? new
|
|
1931
|
+
this.hooks = options.hooks ?? new Hookable();
|
|
1960
1932
|
}
|
|
1961
1933
|
get storage() {
|
|
1962
1934
|
if (!this.#storage) throw new Error("[kubb] setup() must be called before accessing storage");
|
|
@@ -1999,9 +1971,9 @@ var Kubb = class {
|
|
|
1999
1971
|
try {
|
|
2000
1972
|
var _usingCtx$1 = _usingCtx();
|
|
2001
1973
|
if (!this.#driver) await this.setup();
|
|
2002
|
-
const
|
|
2003
|
-
const driver =
|
|
2004
|
-
const storage =
|
|
1974
|
+
const self = _usingCtx$1.u(this);
|
|
1975
|
+
const driver = self.driver;
|
|
1976
|
+
const storage = self.storage;
|
|
2005
1977
|
const { diagnostics } = await driver.run({ storage });
|
|
2006
1978
|
return {
|
|
2007
1979
|
diagnostics,
|
|
@@ -2062,7 +2034,7 @@ const logLevel = {
|
|
|
2062
2034
|
/**
|
|
2063
2035
|
* Defines a reporter. When the definition has a `drain`, the returned reporter buffers each value
|
|
2064
2036
|
* `report` returns and hands the array to `drain` once, then clears it. Without a `drain`, nothing
|
|
2065
|
-
* is buffered. Wiring the reporter onto the run's
|
|
2037
|
+
* is buffered. Wiring the reporter onto the run's hooks is the host's job, so the reporter only
|
|
2066
2038
|
* ever deals with a {@link GenerationResult}.
|
|
2067
2039
|
*
|
|
2068
2040
|
* @example
|
|
@@ -2246,7 +2218,7 @@ function buildTimingSection(report) {
|
|
|
2246
2218
|
* `## Timings` section. Selected with `--reporter file` (or `reporters: ['file']`).
|
|
2247
2219
|
*
|
|
2248
2220
|
* @note It captures the collected diagnostics once a config finishes, not the live
|
|
2249
|
-
* `kubb:info`/`kubb:plugin`
|
|
2221
|
+
* `kubb:info`/`kubb:plugin` hook stream. Color is stripped so the file stays plain text even when
|
|
2250
2222
|
* the run is attached to a TTY.
|
|
2251
2223
|
*/
|
|
2252
2224
|
const fileReporter = createReporter({
|
|
@@ -2434,6 +2406,6 @@ const memoryStorage = createStorage(() => {
|
|
|
2434
2406
|
};
|
|
2435
2407
|
});
|
|
2436
2408
|
//#endregion
|
|
2437
|
-
export {
|
|
2409
|
+
export { Diagnostics, Hookable, KubbDriver, Resolver, cliReporter, createAdapter, createKubb, createRenderer, createReporter, createResolver, createStorage, defineGenerator, defineParser, definePlugin, fileReporter, fsStorage, jsonReporter, logLevel, memoryStorage };
|
|
2438
2410
|
|
|
2439
2411
|
//# sourceMappingURL=index.js.map
|