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