@kubb/core 5.0.0-beta.60 → 5.0.0-beta.62

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.
@@ -1,5 +1,5 @@
1
1
  import { t as __name } from "./chunk-C0LytTxp.js";
2
- import { FileNode, HttpMethod, ImportNode, InputMeta, InputNode, Node, OperationNode, SchemaNode, UserFileNode, Visitor } from "@kubb/ast";
2
+ import { Enforce, FileNode, HttpMethod, ImportNode, InputMeta, InputNode, Macro, Node, OperationNode, SchemaNode, UserFileNode } from "@kubb/ast";
3
3
 
4
4
  //#region ../../internals/utils/src/asyncEventEmitter.d.ts
5
5
  /**
@@ -1137,9 +1137,14 @@ type KubbPluginSetupContext<TFactory extends PluginFactoryOptions = PluginFactor
1137
1137
  */
1138
1138
  setResolver(resolver: Partial<TFactory['resolver']>): void;
1139
1139
  /**
1140
- * Set the AST transformer to pre-process nodes before they reach generators.
1140
+ * Add a macro that rewrites AST nodes before they reach generators. Macros run in the order they
1141
+ * are added, after any macros from earlier `addMacro` calls.
1141
1142
  */
1142
- setTransformer(visitor: Visitor): void;
1143
+ addMacro(macro: Macro): void;
1144
+ /**
1145
+ * Replace this plugin's macros with `macros`.
1146
+ */
1147
+ setMacros(macros: ReadonlyArray<Macro>): void;
1143
1148
  /**
1144
1149
  * Set resolved options merged into the normalized plugin's `options`.
1145
1150
  * Call this in `kubb:plugin:setup` to provide options generators need.
@@ -1185,7 +1190,7 @@ type Plugin<TFactory extends PluginFactoryOptions = PluginFactoryOptions> = {
1185
1190
  *
1186
1191
  * Dependency constraints always take precedence over `enforce`.
1187
1192
  */
1188
- enforce?: 'pre' | 'post';
1193
+ enforce?: Enforce;
1189
1194
  /**
1190
1195
  * The options passed by the user when calling the plugin factory.
1191
1196
  */
@@ -1212,7 +1217,7 @@ type NormalizedPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptio
1212
1217
  override: Array<Override<TOptions['resolvedOptions']>>;
1213
1218
  };
1214
1219
  resolver: TOptions['resolver'];
1215
- transformer?: Visitor;
1220
+ macros?: Array<Macro>;
1216
1221
  generators?: Array<Generator$1>;
1217
1222
  apply?: (config: Config) => boolean;
1218
1223
  version?: string;
@@ -1339,7 +1344,7 @@ declare class KubbDriver {
1339
1344
  get hooks(): AsyncEventEmitter<KubbHooks>;
1340
1345
  /**
1341
1346
  * Emits the `kubb:plugin:setup` event so that all registered hook-style plugin listeners
1342
- * can configure generators, resolvers, transformers and renderers before `buildStart` runs.
1347
+ * can configure generators, resolvers, macros and renderers before `buildStart` runs.
1343
1348
  *
1344
1349
  * Call this once from `safeBuild` before the plugin execution loop begins.
1345
1350
  */
@@ -1497,13 +1502,6 @@ type GeneratorContext<TOptions extends PluginFactoryOptions = PluginFactoryOptio
1497
1502
  * `ctx.resolver.resolveFile({ name: 'pet', extname: '.ts' }, { root, output })`
1498
1503
  */
1499
1504
  resolver: TOptions['resolver'];
1500
- /**
1501
- * The AST visitor this plugin registered through `setTransformer` during
1502
- * `kubb:plugin:setup`, or `undefined` when it never registered one. The driver already
1503
- * applies the visitor to every schema and operation node before a generator sees it, so
1504
- * read it here only to inspect or re-run the transformation.
1505
- */
1506
- transformer: Visitor | undefined;
1507
1505
  /**
1508
1506
  * Report a warning. Collected as a `warning` diagnostic attributed to the current
1509
1507
  * plugin. It surfaces in the run summary but does not fail the build. For a structured
@@ -2903,4 +2901,4 @@ declare class Diagnostics {
2903
2901
  }
2904
2902
  //#endregion
2905
2903
  export { KubbPluginSetupContext as $, KubbHookStartContext as A, Adapter as At, ParsedFile as B, KubbFilesProcessingEndContext as C, GenerationResult as Ct, KubbGenerationStartContext as D, UserReporter as Dt, KubbGenerationEndContext as E, ReporterName as Et, KubbSuccessContext as F, Generator$1 as G, createKubb as H, KubbWarnContext as I, KubbDriver as J, GeneratorContext as K, PossibleConfig as L, KubbInfoContext as M, AdapterSource as Mt, KubbLifecycleStartContext as N, createAdapter as Nt, KubbHookEndContext as O, createReporter as Ot, KubbPluginsEndContext as P, AsyncEventEmitter as Pt, KubbPluginEndContext as Q, UserConfig as R, KubbFileProcessingUpdate as S, createStorage as St, KubbFilesProcessingUpdateContext as T, ReporterContext as Tt, Parser as U, Kubb$1 as V, defineParser as W, Group as X, Exclude$1 as Y, Include as Z, InputPath as _, defineResolver as _t, DiagnosticLocation as a, Override as at, KubbDiagnosticContext as b, createRenderer as bt, PerformanceDiagnostic as c, definePlugin as ct, SerializedDiagnostic as d, ResolveBannerFile as dt, KubbPluginStartContext as et, UpdateDiagnostic as f, ResolveOptionsContext as ft, InputData as g, ResolverPathParams as gt, Config as h, ResolverFileParams as ht, DiagnosticKind as i, OutputOptions as it, KubbHooks as j, AdapterFactoryOptions as jt, KubbHookLineContext as k, logLevel as kt, ProblemCode as l, BannerMeta as lt, CLIOptions as m, ResolverContext as mt, DiagnosticByCode as n, Output as nt, DiagnosticSeverity as o, Plugin as ot, BuildOutput as p, Resolver as pt, defineGenerator as q, DiagnosticDoc as r, OutputMode as rt, Diagnostics as s, PluginFactoryOptions as st, Diagnostic as t, NormalizedPlugin as tt, ProblemDiagnostic as u, ResolveBannerContext as ut, KubbBuildEndContext as v, Renderer as vt, KubbFilesProcessingStartContext as w, Reporter as wt, KubbErrorContext as x, Storage as xt, KubbBuildStartContext as y, RendererFactory as yt, FileProcessorHooks as z };
2906
- //# sourceMappingURL=diagnostics-B-UZnFqP.d.ts.map
2904
+ //# sourceMappingURL=diagnostics-D0G07LHG.d.ts.map
package/dist/index.cjs CHANGED
@@ -611,7 +611,7 @@ function createAdapter(build) {
611
611
  /**
612
612
  * Docs major version, derived from the package version so the link tracks the published major.
613
613
  */
614
- const docsMajor = "5.0.0-beta.60".split(".")[0] ?? "5";
614
+ const docsMajor = "5.0.0-beta.62".split(".")[0] ?? "5";
615
615
  /**
616
616
  * Narrows a {@link Diagnostic} to the variant for `code`, or `null` when it does not match.
617
617
  *
@@ -1492,45 +1492,55 @@ function defineResolver(build) {
1492
1492
  //#endregion
1493
1493
  //#region src/Transform.ts
1494
1494
  /**
1495
- * Holds one `Visitor` per plugin, keyed by plugin name. Each plugin's transformer runs in
1496
- * isolation on the original adapter node. `applyTo` is a lookup, not a chain, so plugin A's
1497
- * visitor never sees plugin B's output. When no transformer is registered, `applyTo` returns
1498
- * the original node reference, and the `@kubb/ast` `transform` primitive does the same when
1499
- * its visitor leaves the tree untouched. Callers can compare by identity to detect a no-op.
1500
- *
1501
- * Registration order matches the order setup hooks fire, which the driver has already sorted
1502
- * by `enforce` and dependency edges. The registry does not re-order anything.
1495
+ * Holds an ordered list of macros per plugin, keyed by plugin name. Each plugin's macros run in
1496
+ * isolation on the original adapter node and are composed into a single `Visitor` that the
1497
+ * `@kubb/ast` `transform` primitive applies. `applyTo` is a per-plugin lookup, not a cross-plugin
1498
+ * chain, so plugin A's macros never see plugin B's output. When a plugin has no macros, `applyTo`
1499
+ * returns the original node reference, and `transform` does the same when the composed visitor
1500
+ * leaves the tree untouched, so callers can detect a no-op by identity.
1501
+ *
1502
+ * Registration order matches the order setup hooks fire, which the driver has already sorted by
1503
+ * `enforce` and dependency edges. The registry preserves that order; macro `enforce` only reorders
1504
+ * within a single plugin's list.
1503
1505
  */
1504
1506
  var Transform = class {
1505
- #visitors = /* @__PURE__ */ new Map();
1507
+ #macros = /* @__PURE__ */ new Map();
1508
+ #composed = /* @__PURE__ */ new Map();
1506
1509
  #memo = /* @__PURE__ */ new Map();
1507
1510
  /**
1508
- * Number of plugins with a registered transformer.
1511
+ * Number of plugins with at least one registered macro.
1509
1512
  */
1510
1513
  get size() {
1511
- return this.#visitors.size;
1514
+ return this.#macros.size;
1512
1515
  }
1513
1516
  /**
1514
- * Records `visitor` as the transformer for `pluginName`. A second call for the same plugin
1515
- * replaces the first.
1517
+ * Appends `macro` to the plugin's list, after any macros already registered.
1516
1518
  */
1517
- register(pluginName, visitor) {
1518
- this.#visitors.set(pluginName, visitor);
1519
- this.#memo.delete(pluginName);
1519
+ add(pluginName, macro) {
1520
+ const list = this.#macros.get(pluginName);
1521
+ if (list) list.push(macro);
1522
+ else this.#macros.set(pluginName, [macro]);
1523
+ this.#invalidate(pluginName);
1524
+ }
1525
+ /**
1526
+ * Replaces the plugin's macro list with `macros`.
1527
+ */
1528
+ set(pluginName, macros) {
1529
+ this.#macros.set(pluginName, [...macros]);
1530
+ this.#invalidate(pluginName);
1520
1531
  }
1521
1532
  /**
1522
- * Looks up the transformer for `pluginName`. The generator context uses this so plugins can
1523
- * read their own visitor through `ctx.transformer`.
1533
+ * Looks up the composed visitor for `pluginName`, or `undefined` when the plugin has no macros.
1524
1534
  */
1525
1535
  get(pluginName) {
1526
- return this.#visitors.get(pluginName);
1536
+ return this.#visitorFor(pluginName);
1527
1537
  }
1528
1538
  /**
1529
- * Runs the plugin's transformer on `node`. Returns the original node reference when the
1530
- * plugin has no transformer, so callers can compare by identity to detect a no-op.
1539
+ * Runs the plugin's macros on `node`. Returns the original node reference when the plugin has no
1540
+ * macros, so callers can compare by identity to detect a no-op.
1531
1541
  */
1532
1542
  applyTo(pluginName, node) {
1533
- const visitor = this.#visitors.get(pluginName);
1543
+ const visitor = this.#visitorFor(pluginName);
1534
1544
  if (!visitor) return node;
1535
1545
  let memo = this.#memo.get(pluginName);
1536
1546
  if (!memo) {
@@ -1544,13 +1554,28 @@ var Transform = class {
1544
1554
  return result;
1545
1555
  }
1546
1556
  /**
1547
- * Clears every registration. Called from the driver's `dispose()` so visitors do not leak
1548
- * across builds.
1557
+ * Clears every registration. Called from the driver's `dispose()` so macros do not leak across
1558
+ * builds.
1549
1559
  */
1550
1560
  dispose() {
1551
- this.#visitors.clear();
1561
+ this.#macros.clear();
1562
+ this.#composed.clear();
1552
1563
  this.#memo.clear();
1553
1564
  }
1565
+ #invalidate(pluginName) {
1566
+ this.#composed.delete(pluginName);
1567
+ this.#memo.delete(pluginName);
1568
+ }
1569
+ #visitorFor(pluginName) {
1570
+ const macros = this.#macros.get(pluginName);
1571
+ if (!macros || macros.length === 0) return void 0;
1572
+ let composed = this.#composed.get(pluginName);
1573
+ if (!composed) {
1574
+ composed = (0, _kubb_ast.composeMacros)(macros);
1575
+ this.#composed.set(pluginName, composed);
1576
+ }
1577
+ return composed;
1578
+ }
1554
1579
  };
1555
1580
  //#endregion
1556
1581
  //#region src/KubbDriver.ts
@@ -1591,7 +1616,7 @@ var KubbDriver = class {
1591
1616
  */
1592
1617
  #listeners = [];
1593
1618
  /**
1594
- * Transform registry. Plugins populate it during `kubb:plugin:setup` via `setTransformer`,
1619
+ * Transform registry. Plugins populate it during `kubb:plugin:setup` via `addMacro`/`setMacros`,
1595
1620
  * and `#runGenerators` reads it once per `(plugin, node)` pair through `applyTo`.
1596
1621
  */
1597
1622
  #transforms = new Transform();
@@ -1674,7 +1699,7 @@ var KubbDriver = class {
1674
1699
  * Registers a hook-style plugin's lifecycle handlers on the shared `AsyncEventEmitter`.
1675
1700
  *
1676
1701
  * The `kubb:plugin:setup` listener wraps the global context in a plugin-specific one so
1677
- * `addGenerator`, `setResolver`, and `setTransformer` target the right `normalizedPlugin`.
1702
+ * `addGenerator`, `setResolver`, and `setMacros` target the right `normalizedPlugin`.
1678
1703
  * Every other `KubbHooks` event registers as a pass-through listener that external tooling
1679
1704
  * can observe via `hooks.on(...)`.
1680
1705
  *
@@ -1694,8 +1719,11 @@ var KubbDriver = class {
1694
1719
  setResolver: (resolver) => {
1695
1720
  this.setPluginResolver(plugin.name, resolver);
1696
1721
  },
1697
- setTransformer: (visitor) => {
1698
- this.#transforms.register(plugin.name, visitor);
1722
+ addMacro: (macro) => {
1723
+ this.#transforms.add(plugin.name, macro);
1724
+ },
1725
+ setMacros: (macros) => {
1726
+ this.#transforms.set(plugin.name, macros);
1699
1727
  },
1700
1728
  setOptions: (opts) => {
1701
1729
  plugin.options = {
@@ -1728,7 +1756,7 @@ var KubbDriver = class {
1728
1756
  }
1729
1757
  /**
1730
1758
  * Emits the `kubb:plugin:setup` event so that all registered hook-style plugin listeners
1731
- * can configure generators, resolvers, transformers and renderers before `buildStart` runs.
1759
+ * can configure generators, resolvers, macros and renderers before `buildStart` runs.
1732
1760
  *
1733
1761
  * Call this once from `safeBuild` before the plugin execution loop begins.
1734
1762
  */
@@ -1739,7 +1767,8 @@ var KubbDriver = class {
1739
1767
  options: {},
1740
1768
  addGenerator: noop,
1741
1769
  setResolver: noop,
1742
- setTransformer: noop,
1770
+ addMacro: noop,
1771
+ setMacros: noop,
1743
1772
  setOptions: noop,
1744
1773
  injectFile: noop,
1745
1774
  updateConfig: noop
@@ -1759,39 +1788,21 @@ var KubbDriver = class {
1759
1788
  * Call this method inside `addGenerator()` (in `kubb:plugin:setup`) to wire up a generator.
1760
1789
  */
1761
1790
  registerGenerator(pluginName, generator) {
1762
- if (generator.schema) {
1763
- const schemaHandler = async (node, ctx) => {
1791
+ const register = (event, method) => {
1792
+ if (!method) return;
1793
+ const handler = async (node, ctx) => {
1764
1794
  if (ctx.plugin.name !== pluginName) return;
1765
- const result = await generator.schema(node, ctx);
1795
+ const result = await method(node, ctx);
1766
1796
  await this.dispatch({
1767
1797
  result,
1768
1798
  renderer: generator.renderer
1769
1799
  });
1770
1800
  };
1771
- this.#trackListener("kubb:generate:schema", schemaHandler);
1772
- }
1773
- if (generator.operation) {
1774
- const operationHandler = async (node, ctx) => {
1775
- if (ctx.plugin.name !== pluginName) return;
1776
- const result = await generator.operation(node, ctx);
1777
- await this.dispatch({
1778
- result,
1779
- renderer: generator.renderer
1780
- });
1781
- };
1782
- this.#trackListener("kubb:generate:operation", operationHandler);
1783
- }
1784
- if (generator.operations) {
1785
- const operationsHandler = async (nodes, ctx) => {
1786
- if (ctx.plugin.name !== pluginName) return;
1787
- const result = await generator.operations(nodes, ctx);
1788
- await this.dispatch({
1789
- result,
1790
- renderer: generator.renderer
1791
- });
1792
- };
1793
- this.#trackListener("kubb:generate:operations", operationsHandler);
1794
- }
1801
+ this.#trackListener(event, handler);
1802
+ };
1803
+ register("kubb:generate:schema", generator.schema);
1804
+ register("kubb:generate:operation", generator.operation);
1805
+ register("kubb:generate:operations", generator.operations);
1795
1806
  this.#eventGeneratorPlugins.add(pluginName);
1796
1807
  }
1797
1808
  /**
@@ -1931,7 +1942,7 @@ var KubbDriver = class {
1931
1942
  }
1932
1943
  /**
1933
1944
  * Streams schemas and operations through every plugin's generators. Each node is run
1934
- * through the plugin's transformer (from `this.#transforms`) before the generator sees it,
1945
+ * through the plugin's macros (from `this.#transforms`) before the generator sees it,
1935
1946
  * so plugins stay isolated and the hot path stays per-node. Schemas run before operations
1936
1947
  * because the two passes share `flushPending` and the FileProcessor's event emitter.
1937
1948
  * A failing plugin contributes an error diagnostic so the rest of the build continues.
@@ -2235,9 +2246,6 @@ var KubbDriver = class {
2235
2246
  get resolver() {
2236
2247
  return driver.getResolver(plugin.name);
2237
2248
  },
2238
- get transformer() {
2239
- return driver.#transforms.get(plugin.name);
2240
- },
2241
2249
  warn(message) {
2242
2250
  report({
2243
2251
  code: Diagnostics.code.pluginWarning,