@kubb/core 5.0.0-beta.102 → 5.0.0-beta.104

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/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_usingCtx = require("./usingCtx-CZyLSqds.cjs");
2
+ const require_usingCtx = require("./usingCtx-BYOZEkiy.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");
@@ -151,7 +151,7 @@ function randomCliColor(text) {
151
151
  }
152
152
  //#endregion
153
153
  //#region package.json
154
- var version = "5.0.0-beta.102";
154
+ var version = "5.0.0-beta.104";
155
155
  //#endregion
156
156
  //#region src/constants.ts
157
157
  /**
@@ -847,28 +847,24 @@ var Resolver = class Resolver {
847
847
  * schemas (`targetName`) import the emitted name. Names and paths go through the top-level
848
848
  * `name` and `file`, so import entries follow the plugin's conventions, and a per-call
849
849
  * `name` override wins over both.
850
+ *
851
+ * The subtree scan runs through `collectImportedRefNames`, which memoizes by node identity, so a
852
+ * schema shared across the ts, zod, and faker plugins is walked once and every plugin's resolver
853
+ * reads the same ref set instead of re-scanning it per plugin.
850
854
  */
851
855
  imports(options) {
852
856
  const { node, root, output, group, extname = ".ts", name } = options;
853
857
  const resolveName = name ?? ((schemaName) => this.name(schemaName));
854
- const seen = /* @__PURE__ */ new Set();
855
- return (0, _kubb_ast.collectSync)(node, { schema: (schemaNode) => {
856
- const schemaRef = (0, _kubb_ast.narrowSchema)(schemaNode, "ref");
857
- if (!schemaRef?.ref) return null;
858
- const schemaName = (0, _kubb_ast.resolveRefName)(schemaRef);
859
- if (!schemaName || seen.has(schemaName)) return null;
860
- seen.add(schemaName);
861
- return _kubb_ast.ast.factory.createImport({
862
- name: [resolveName(schemaName)],
863
- path: this.file({
864
- name: schemaName,
865
- extname,
866
- root,
867
- output,
868
- group
869
- }).path
870
- });
871
- } });
858
+ return (0, _kubb_ast.collectImportedRefNames)(node).map((schemaName) => _kubb_ast.ast.factory.createImport({
859
+ name: [resolveName(schemaName)],
860
+ path: this.file({
861
+ name: schemaName,
862
+ extname,
863
+ root,
864
+ output,
865
+ group
866
+ }).path
867
+ }));
872
868
  }
873
869
  /**
874
870
  * Folds each `override` over `base`, left to right, and returns a new resolver with helpers
@@ -1483,6 +1479,7 @@ var KubbDriver = class {
1483
1479
  updateBuffer.push(item);
1484
1480
  },
1485
1481
  end: async (files) => {
1482
+ updateBuffer.sort((a, b) => a.processed - b.processed);
1486
1483
  await hooks.callHook("kubb:files:processing:update", { files: updateBuffer.map((item) => ({
1487
1484
  ...item,
1488
1485
  config
@@ -1591,16 +1588,20 @@ var KubbDriver = class {
1591
1588
  }));
1592
1589
  }
1593
1590
  /**
1594
- * Runs schemas and operations through every plugin's generators. Each node is run
1595
- * through the plugin's macros (from `this.#transforms`) before the generator sees it,
1596
- * so plugins stay isolated and the hot path stays per-node. Schemas run before operations
1597
- * so file output stays deterministic across runs.
1598
- * A failing plugin contributes an error diagnostic so the rest of the build continues.
1599
- * Every plugin also contributes a `timing` diagnostic.
1591
+ * Runs schemas and operations through every plugin's generators. The walk is node-outer: each
1592
+ * schema is visited once and each operation once, and the node fans out to the matching
1593
+ * generators of every plugin in dependency order. A per-node cache (`createNodeCache`) is created
1594
+ * once per node and shared by all of that node's plugins, so node-derived work is computed once
1595
+ * and reused instead of recomputed per plugin. Each node still runs through the plugin's macros
1596
+ * (from `this.#transforms`) and its exclude/include/override filters before that plugin's
1597
+ * generator sees it, so plugins stay isolated. Schemas run before operations so file output
1598
+ * stays deterministic across runs. A generator with a `match` predicate that resolves `false`
1599
+ * for a node is skipped for that node, without calling `schema`/`operation`.
1600
1600
  *
1601
- * Plugins are processed one at a time, in full, so `kubb:plugin:end` fires as each one
1602
- * completes rather than all at once at the end. That ordering drives the CLI's
1603
- * `Plugins N/M` counter.
1601
+ * A failing plugin is dropped from the remaining walk, contributes an error diagnostic, and no
1602
+ * longer aborts the other plugins. `kubb:plugin:end` and each plugin's `timing` diagnostic fire
1603
+ * in dependency order once the walk finishes, driving the CLI's `Plugins N/M` counter. The
1604
+ * `operations` batch fires once per plugin after the single operation walk.
1604
1605
  *
1605
1606
  * When `this.inputNode` is `null`, every entry still gets a `kubb:plugin:end` so
1606
1607
  * post-plugin listeners (the barrel writer and friends) complete.
@@ -1638,105 +1639,133 @@ var KubbDriver = class {
1638
1639
  }) !== null);
1639
1640
  allowedSchemaNamesByPlugin.set(plugin.name, (0, _kubb_ast.collectUsedSchemaNames)(includedOps, schemas));
1640
1641
  }
1641
- for (const { plugin, context, hrStart } of entries) {
1642
+ const states = entries.map(({ plugin, context, hrStart }) => {
1642
1643
  const generatorContext = {
1643
1644
  ...context,
1644
1645
  resolver: this.getResolver(plugin.name)
1645
1646
  };
1646
1647
  const { exclude, include, override } = plugin.options;
1647
- const optionsAreStatic = !exclude?.length && !include?.length && !override?.length;
1648
- const allowedSchemaNames = allowedSchemaNamesByPlugin.get(plugin.name) ?? null;
1649
1648
  const generators = plugin.generators ?? [];
1650
- const schemaGenerators = generators.filter((generator) => generator.schema);
1651
- const operationGenerators = generators.filter((generator) => generator.operation);
1652
- const operationsGenerators = generators.filter((generator) => generator.operations);
1653
- let error = null;
1654
- const resolveForPlugin = (node) => {
1655
- const transformedNode = transforms.applyTo(plugin.name, node);
1656
- if (optionsAreStatic) return {
1657
- transformedNode,
1658
- options: plugin.options
1659
- };
1660
- const options = generatorContext.resolver.default.options(transformedNode, {
1661
- options: plugin.options,
1662
- exclude,
1663
- include,
1664
- override
1665
- });
1666
- if (options === null) return null;
1667
- return {
1668
- transformedNode,
1669
- options
1670
- };
1649
+ return {
1650
+ plugin,
1651
+ hrStart,
1652
+ generatorContext,
1653
+ exclude,
1654
+ include,
1655
+ override,
1656
+ optionsAreStatic: !exclude?.length && !include?.length && !override?.length,
1657
+ allowedSchemaNames: allowedSchemaNamesByPlugin.get(plugin.name) ?? null,
1658
+ schemaGenerators: generators.filter((generator) => generator.schema),
1659
+ operationGenerators: generators.filter((generator) => generator.operation),
1660
+ operationsGenerators: generators.filter((generator) => generator.operations),
1661
+ pluginOperations: [],
1662
+ error: null
1671
1663
  };
1672
- if (schemaGenerators.length) for (const node of schemas) {
1673
- if (error) break;
1664
+ });
1665
+ const resolveForPlugin = (state, node) => {
1666
+ const transformedNode = transforms.applyTo(state.plugin.name, node);
1667
+ if (state.optionsAreStatic) return {
1668
+ transformedNode,
1669
+ options: state.plugin.options
1670
+ };
1671
+ const options = state.generatorContext.resolver.default.options(transformedNode, {
1672
+ options: state.plugin.options,
1673
+ exclude: state.exclude,
1674
+ include: state.include,
1675
+ override: state.override
1676
+ });
1677
+ if (options === null) return null;
1678
+ return {
1679
+ transformedNode,
1680
+ options
1681
+ };
1682
+ };
1683
+ for (const node of schemas) {
1684
+ const cache = require_usingCtx.createNodeCache();
1685
+ for (const state of states) {
1686
+ if (state.error || !state.schemaGenerators.length) continue;
1674
1687
  try {
1675
- const resolved = resolveForPlugin(node);
1688
+ const resolved = resolveForPlugin(state, node);
1676
1689
  if (!resolved) continue;
1677
1690
  const { transformedNode, options } = resolved;
1678
- if (allowedSchemaNames !== null && transformedNode.name && !allowedSchemaNames.has(transformedNode.name)) continue;
1691
+ if (state.allowedSchemaNames !== null && transformedNode.name && !state.allowedSchemaNames.has(transformedNode.name)) continue;
1679
1692
  const ctx = {
1680
- ...generatorContext,
1681
- options
1693
+ ...state.generatorContext,
1694
+ options,
1695
+ cache
1682
1696
  };
1683
- for (const generator of schemaGenerators) await this.dispatch({
1684
- result: await generator.schema(transformedNode, ctx),
1685
- renderer: generator.renderer
1686
- });
1697
+ for (const generator of state.schemaGenerators) {
1698
+ if (!(generator.match ? await generator.match(transformedNode, ctx) : true)) continue;
1699
+ await this.dispatch({
1700
+ result: await generator.schema(transformedNode, ctx),
1701
+ renderer: generator.renderer
1702
+ });
1703
+ }
1687
1704
  await this.hooks.callHook("kubb:generate:schema", transformedNode, ctx);
1688
1705
  } catch (caughtError) {
1689
- error = require_usingCtx.toError(caughtError);
1706
+ state.error = require_usingCtx.toError(caughtError);
1690
1707
  }
1691
1708
  }
1692
- const pluginOperations = [];
1693
- if (operationGenerators.length || operationsGenerators.length) for (const node of operations) {
1694
- if (error) break;
1709
+ }
1710
+ for (const node of operations) {
1711
+ const cache = require_usingCtx.createNodeCache();
1712
+ for (const state of states) {
1713
+ if (state.error || !state.operationGenerators.length && !state.operationsGenerators.length) continue;
1695
1714
  try {
1696
- const resolved = resolveForPlugin(node);
1715
+ const resolved = resolveForPlugin(state, node);
1697
1716
  if (!resolved) continue;
1698
- pluginOperations.push(resolved.transformedNode);
1699
- if (operationGenerators.length) {
1717
+ state.pluginOperations.push(resolved.transformedNode);
1718
+ if (state.operationGenerators.length) {
1700
1719
  const ctx = {
1701
- ...generatorContext,
1702
- options: resolved.options
1720
+ ...state.generatorContext,
1721
+ options: resolved.options,
1722
+ cache
1703
1723
  };
1704
- for (const generator of operationGenerators) await this.dispatch({
1705
- result: await generator.operation(resolved.transformedNode, ctx),
1706
- renderer: generator.renderer
1707
- });
1724
+ for (const generator of state.operationGenerators) {
1725
+ if (!(generator.match ? await generator.match(resolved.transformedNode, ctx) : true)) continue;
1726
+ await this.dispatch({
1727
+ result: await generator.operation(resolved.transformedNode, ctx),
1728
+ renderer: generator.renderer
1729
+ });
1730
+ }
1708
1731
  await this.hooks.callHook("kubb:generate:operation", resolved.transformedNode, ctx);
1709
1732
  }
1710
1733
  } catch (caughtError) {
1711
- error = require_usingCtx.toError(caughtError);
1734
+ state.error = require_usingCtx.toError(caughtError);
1712
1735
  }
1713
1736
  }
1714
- if (!error && operationsGenerators.length) try {
1737
+ }
1738
+ for (const state of states) {
1739
+ if (state.error || !state.operationsGenerators.length) continue;
1740
+ try {
1715
1741
  const ctx = {
1716
- ...generatorContext,
1717
- options: plugin.options
1742
+ ...state.generatorContext,
1743
+ options: state.plugin.options,
1744
+ cache: require_usingCtx.createNodeCache()
1718
1745
  };
1719
- for (const generator of operationsGenerators) await this.dispatch({
1720
- result: await generator.operations(pluginOperations, ctx),
1746
+ for (const generator of state.operationsGenerators) await this.dispatch({
1747
+ result: await generator.operations(state.pluginOperations, ctx),
1721
1748
  renderer: generator.renderer
1722
1749
  });
1723
- await this.hooks.callHook("kubb:generate:operations", pluginOperations, ctx);
1750
+ await this.hooks.callHook("kubb:generate:operations", state.pluginOperations, ctx);
1724
1751
  } catch (caughtError) {
1725
- error = require_usingCtx.toError(caughtError);
1752
+ state.error = require_usingCtx.toError(caughtError);
1726
1753
  }
1727
- const duration = getElapsedMs(hrStart);
1754
+ }
1755
+ for (const state of states) {
1756
+ const duration = getElapsedMs(state.hrStart);
1728
1757
  await this.#emitPluginEnd({
1729
- plugin,
1758
+ plugin: state.plugin,
1730
1759
  duration,
1731
- success: !error,
1732
- error: error ?? void 0
1760
+ success: !state.error,
1761
+ error: state.error ?? void 0
1733
1762
  });
1734
- if (error) diagnostics.push({
1735
- ...Diagnostics.from(error),
1736
- plugin: plugin.name
1763
+ if (state.error) diagnostics.push({
1764
+ ...Diagnostics.from(state.error),
1765
+ plugin: state.plugin.name
1737
1766
  });
1738
1767
  diagnostics.push(Diagnostics.performance({
1739
- plugin: plugin.name,
1768
+ plugin: state.plugin.name,
1740
1769
  duration
1741
1770
  }));
1742
1771
  }