@kubb/agent 5.0.0-beta.19 → 5.0.0-beta.20

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.
@@ -4713,6 +4713,14 @@ async function disconnect({ sessionId, token, studioUrl }) {
4713
4713
  const visitorDepths = {
4714
4714
  deep: "deep"
4715
4715
  };
4716
+ function memoize$1(store, factory) {
4717
+ return (key) => {
4718
+ if (store.has(key)) return store.get(key);
4719
+ const value = factory(key);
4720
+ store.set(key, value);
4721
+ return value;
4722
+ };
4723
+ }
4716
4724
  function trimExtName(text) {
4717
4725
  const dotIndex = text.lastIndexOf(".");
4718
4726
  if (dotIndex > 0 && !text.includes("/", dotIndex)) return text.slice(0, dotIndex);
@@ -4727,210 +4735,131 @@ function extractRefName(ref) {
4727
4735
  var _a;
4728
4736
  return (_a = ref.split("/").at(-1)) != null ? _a : ref;
4729
4737
  }
4730
- function createLimit(concurrency) {
4731
- let active = 0;
4732
- const queue = [];
4733
- function next() {
4734
- if (active < concurrency && queue.length > 0) {
4735
- active++;
4736
- queue.shift()();
4737
- }
4738
- }
4739
- return function limit(fn) {
4740
- return new Promise((resolve, reject) => {
4741
- queue.push(() => {
4742
- Promise.resolve(fn()).then(resolve, reject).finally(() => {
4743
- active--;
4744
- next();
4745
- });
4746
- });
4747
- next();
4748
- });
4749
- };
4750
- }
4751
4738
  function* getChildren(node, recurse) {
4752
4739
  var _a;
4753
- switch (node.kind) {
4754
- case "Input":
4755
- yield* node.schemas;
4756
- yield* node.operations;
4757
- break;
4758
- case "Output":
4759
- break;
4760
- case "Operation":
4761
- yield* node.parameters;
4762
- if ((_a = node.requestBody) == null ? void 0 : _a.content) {
4763
- for (const c of node.requestBody.content) if (c.schema) yield c.schema;
4764
- }
4765
- yield* node.responses;
4766
- break;
4767
- case "Schema":
4768
- if (!recurse) break;
4769
- if ("properties" in node && node.properties.length > 0) yield* node.properties;
4770
- if ("items" in node && node.items) yield* node.items;
4771
- if ("members" in node && node.members) yield* node.members;
4772
- if ("additionalProperties" in node && node.additionalProperties && node.additionalProperties !== true) yield node.additionalProperties;
4773
- break;
4774
- case "Property":
4775
- yield node.schema;
4776
- break;
4777
- case "Parameter":
4778
- yield node.schema;
4779
- break;
4780
- case "Response":
4781
- if (node.schema) yield node.schema;
4782
- break;
4740
+ if (node.kind === "Input") {
4741
+ yield* node.schemas;
4742
+ yield* node.operations;
4743
+ return;
4783
4744
  }
4784
- }
4785
- async function walk(node, options) {
4786
- var _a, _b;
4787
- return _walk(node, options, ((_a = options.depth) != null ? _a : visitorDepths.deep) === visitorDepths.deep, createLimit((_b = options.concurrency) != null ? _b : 30), void 0);
4788
- }
4789
- async function _walk(node, visitor, recurse, limit, parent) {
4790
- switch (node.kind) {
4791
- case "Input":
4792
- await limit(() => {
4793
- var _a;
4794
- return (_a = visitor.input) == null ? void 0 : _a.call(visitor, node, { parent });
4795
- });
4796
- break;
4797
- case "Output":
4798
- await limit(() => {
4799
- var _a;
4800
- return (_a = visitor.output) == null ? void 0 : _a.call(visitor, node, { parent });
4801
- });
4802
- break;
4803
- case "Operation":
4804
- await limit(() => {
4805
- var _a;
4806
- return (_a = visitor.operation) == null ? void 0 : _a.call(visitor, node, { parent });
4807
- });
4808
- break;
4809
- case "Schema":
4810
- await limit(() => {
4811
- var _a;
4812
- return (_a = visitor.schema) == null ? void 0 : _a.call(visitor, node, { parent });
4813
- });
4814
- break;
4815
- case "Property":
4816
- await limit(() => {
4817
- var _a;
4818
- return (_a = visitor.property) == null ? void 0 : _a.call(visitor, node, { parent });
4819
- });
4820
- break;
4821
- case "Parameter":
4822
- await limit(() => {
4823
- var _a;
4824
- return (_a = visitor.parameter) == null ? void 0 : _a.call(visitor, node, { parent });
4825
- });
4826
- break;
4827
- case "Response":
4828
- await limit(() => {
4829
- var _a;
4830
- return (_a = visitor.response) == null ? void 0 : _a.call(visitor, node, { parent });
4831
- });
4832
- break;
4745
+ if (node.kind === "Output") return;
4746
+ if (node.kind === "Operation") {
4747
+ yield* node.parameters;
4748
+ if ((_a = node.requestBody) == null ? void 0 : _a.content) {
4749
+ for (const c of node.requestBody.content) if (c.schema) yield c.schema;
4750
+ }
4751
+ yield* node.responses;
4752
+ return;
4753
+ }
4754
+ if (node.kind === "Schema") {
4755
+ if (!recurse) return;
4756
+ if ("properties" in node && node.properties.length > 0) yield* node.properties;
4757
+ if ("items" in node && node.items) yield* node.items;
4758
+ if ("members" in node && node.members) yield* node.members;
4759
+ if ("additionalProperties" in node && node.additionalProperties && node.additionalProperties !== true) yield node.additionalProperties;
4760
+ return;
4761
+ }
4762
+ if (node.kind === "Property") {
4763
+ yield node.schema;
4764
+ return;
4765
+ }
4766
+ if (node.kind === "Parameter") {
4767
+ yield node.schema;
4768
+ return;
4769
+ }
4770
+ if (node.kind === "Response") {
4771
+ if (node.schema) yield node.schema;
4772
+ return;
4833
4773
  }
4834
- const children = getChildren(node, recurse);
4835
- for (const child of children) await _walk(child, visitor, recurse, limit, node);
4836
4774
  }
4837
4775
  function transform(node, options) {
4838
4776
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
4839
4777
  const { depth, parent, ...visitor } = options;
4840
4778
  const recurse = (depth != null ? depth : visitorDepths.deep) === visitorDepths.deep;
4841
- switch (node.kind) {
4842
- case "Input": {
4843
- const input = (_b = (_a = visitor.input) == null ? void 0 : _a.call(visitor, node, { parent })) != null ? _b : node;
4844
- return {
4845
- ...input,
4846
- schemas: input.schemas.map((s) => transform(s, {
4847
- ...options,
4848
- parent: input
4849
- })),
4850
- operations: input.operations.map((op) => transform(op, {
4851
- ...options,
4852
- parent: input
4853
- }))
4854
- };
4855
- }
4856
- case "Output":
4857
- return (_d = (_c = visitor.output) == null ? void 0 : _c.call(visitor, node, { parent })) != null ? _d : node;
4858
- case "Operation": {
4859
- const op = (_f = (_e = visitor.operation) == null ? void 0 : _e.call(visitor, node, { parent })) != null ? _f : node;
4860
- return {
4861
- ...op,
4862
- parameters: op.parameters.map((p) => transform(p, {
4863
- ...options,
4864
- parent: op
4865
- })),
4866
- requestBody: op.requestBody ? {
4867
- ...op.requestBody,
4868
- content: (_g = op.requestBody.content) == null ? void 0 : _g.map((c) => ({
4869
- ...c,
4870
- schema: c.schema ? transform(c.schema, {
4871
- ...options,
4872
- parent: op
4873
- }) : void 0
4874
- }))
4875
- } : void 0,
4876
- responses: op.responses.map((r) => transform(r, {
4877
- ...options,
4878
- parent: op
4779
+ if (node.kind === "Input") {
4780
+ const input = (_b = (_a = visitor.input) == null ? void 0 : _a.call(visitor, node, { parent })) != null ? _b : node;
4781
+ return {
4782
+ ...input,
4783
+ schemas: input.schemas.map((s) => transform(s, {
4784
+ ...options,
4785
+ parent: input
4786
+ })),
4787
+ operations: input.operations.map((op) => transform(op, {
4788
+ ...options,
4789
+ parent: input
4790
+ }))
4791
+ };
4792
+ }
4793
+ if (node.kind === "Output") return (_d = (_c = visitor.output) == null ? void 0 : _c.call(visitor, node, { parent })) != null ? _d : node;
4794
+ if (node.kind === "Operation") {
4795
+ const op = (_f = (_e = visitor.operation) == null ? void 0 : _e.call(visitor, node, { parent })) != null ? _f : node;
4796
+ return {
4797
+ ...op,
4798
+ parameters: op.parameters.map((p) => transform(p, {
4799
+ ...options,
4800
+ parent: op
4801
+ })),
4802
+ requestBody: op.requestBody ? {
4803
+ ...op.requestBody,
4804
+ content: (_g = op.requestBody.content) == null ? void 0 : _g.map((c) => ({
4805
+ ...c,
4806
+ schema: c.schema ? transform(c.schema, {
4807
+ ...options,
4808
+ parent: op
4809
+ }) : void 0
4879
4810
  }))
4880
- };
4881
- }
4882
- case "Schema": {
4883
- const schema = (_i = (_h = visitor.schema) == null ? void 0 : _h.call(visitor, node, { parent })) != null ? _i : node;
4884
- const childOptions = {
4811
+ } : void 0,
4812
+ responses: op.responses.map((r) => transform(r, {
4885
4813
  ...options,
4886
- parent: schema
4887
- };
4888
- return {
4889
- ...schema,
4890
- ..."properties" in schema && recurse ? { properties: schema.properties.map((p) => transform(p, childOptions)) } : {},
4891
- ..."items" in schema && recurse ? { items: (_j = schema.items) == null ? void 0 : _j.map((i) => transform(i, childOptions)) } : {},
4892
- ..."members" in schema && recurse ? { members: (_k = schema.members) == null ? void 0 : _k.map((m) => transform(m, childOptions)) } : {},
4893
- ..."additionalProperties" in schema && recurse && schema.additionalProperties && schema.additionalProperties !== true ? { additionalProperties: transform(schema.additionalProperties, childOptions) } : {}
4894
- };
4895
- }
4896
- case "Property": {
4897
- const prop = (_m = (_l = visitor.property) == null ? void 0 : _l.call(visitor, node, { parent })) != null ? _m : node;
4898
- return createProperty({
4899
- ...prop,
4900
- schema: transform(prop.schema, {
4901
- ...options,
4902
- parent: prop
4903
- })
4904
- });
4905
- }
4906
- case "Parameter": {
4907
- const param = (_o = (_n = visitor.parameter) == null ? void 0 : _n.call(visitor, node, { parent })) != null ? _o : node;
4908
- return createParameter({
4909
- ...param,
4910
- schema: transform(param.schema, {
4911
- ...options,
4912
- parent: param
4913
- })
4914
- });
4915
- }
4916
- case "Response": {
4917
- const response = (_q = (_p = visitor.response) == null ? void 0 : _p.call(visitor, node, { parent })) != null ? _q : node;
4918
- return {
4919
- ...response,
4920
- schema: transform(response.schema, {
4921
- ...options,
4922
- parent: response
4923
- })
4924
- };
4925
- }
4926
- case "FunctionParameter":
4927
- case "ParameterGroup":
4928
- case "FunctionParameters":
4929
- case "Type":
4930
- return node;
4931
- default:
4932
- return node;
4814
+ parent: op
4815
+ }))
4816
+ };
4817
+ }
4818
+ if (node.kind === "Schema") {
4819
+ const schema = (_i = (_h = visitor.schema) == null ? void 0 : _h.call(visitor, node, { parent })) != null ? _i : node;
4820
+ const childOptions = {
4821
+ ...options,
4822
+ parent: schema
4823
+ };
4824
+ return {
4825
+ ...schema,
4826
+ ..."properties" in schema && recurse ? { properties: schema.properties.map((p) => transform(p, childOptions)) } : {},
4827
+ ..."items" in schema && recurse ? { items: (_j = schema.items) == null ? void 0 : _j.map((i) => transform(i, childOptions)) } : {},
4828
+ ..."members" in schema && recurse ? { members: (_k = schema.members) == null ? void 0 : _k.map((m) => transform(m, childOptions)) } : {},
4829
+ ..."additionalProperties" in schema && recurse && schema.additionalProperties && schema.additionalProperties !== true ? { additionalProperties: transform(schema.additionalProperties, childOptions) } : {}
4830
+ };
4831
+ }
4832
+ if (node.kind === "Property") {
4833
+ const prop = (_m = (_l = visitor.property) == null ? void 0 : _l.call(visitor, node, { parent })) != null ? _m : node;
4834
+ return createProperty({
4835
+ ...prop,
4836
+ schema: transform(prop.schema, {
4837
+ ...options,
4838
+ parent: prop
4839
+ })
4840
+ });
4841
+ }
4842
+ if (node.kind === "Parameter") {
4843
+ const param = (_o = (_n = visitor.parameter) == null ? void 0 : _n.call(visitor, node, { parent })) != null ? _o : node;
4844
+ return createParameter({
4845
+ ...param,
4846
+ schema: transform(param.schema, {
4847
+ ...options,
4848
+ parent: param
4849
+ })
4850
+ });
4851
+ }
4852
+ if (node.kind === "Response") {
4853
+ const response = (_q = (_p = visitor.response) == null ? void 0 : _p.call(visitor, node, { parent })) != null ? _q : node;
4854
+ return {
4855
+ ...response,
4856
+ schema: transform(response.schema, {
4857
+ ...options,
4858
+ parent: response
4859
+ })
4860
+ };
4933
4861
  }
4862
+ return node;
4934
4863
  }
4935
4864
  function* collectLazy(node, options) {
4936
4865
  var _a, _b, _c, _d, _e, _f, _g;
@@ -5112,10 +5041,7 @@ function resolveRefName(node) {
5112
5041
  if (node.ref) return (_d = (_c = (_a = extractRefName(node.ref)) != null ? _a : node.name) != null ? _c : (_b = node.schema) == null ? void 0 : _b.name) != null ? _d : void 0;
5113
5042
  return (_g = (_f = node.name) != null ? _f : (_e = node.schema) == null ? void 0 : _e.name) != null ? _g : void 0;
5114
5043
  }
5115
- const schemaRefCache = /* @__PURE__ */ new WeakMap();
5116
- function collectSchemaRefs(node) {
5117
- const cached = schemaRefCache.get(node);
5118
- if (cached) return cached;
5044
+ const collectSchemaRefs = memoize$1(/* @__PURE__ */ new WeakMap(), (node) => {
5119
5045
  const refs = /* @__PURE__ */ new Set();
5120
5046
  collect(node, { schema(child) {
5121
5047
  if (child.type === "ref") {
@@ -5123,23 +5049,15 @@ function collectSchemaRefs(node) {
5123
5049
  if (name) refs.add(name);
5124
5050
  }
5125
5051
  } });
5126
- schemaRefCache.set(node, refs);
5127
5052
  return refs;
5128
- }
5053
+ });
5129
5054
  function collectReferencedSchemaNames(node, out = /* @__PURE__ */ new Set()) {
5130
5055
  if (!node) return out;
5131
5056
  for (const name of collectSchemaRefs(node)) out.add(name);
5132
5057
  return out;
5133
5058
  }
5134
- const usedSchemaNamesCache = /* @__PURE__ */ new WeakMap();
5135
- function collectUsedSchemaNames(operations, schemas) {
5136
- let byOps = usedSchemaNamesCache.get(operations);
5137
- if (!byOps) {
5138
- byOps = /* @__PURE__ */ new WeakMap();
5139
- usedSchemaNamesCache.set(operations, byOps);
5140
- }
5141
- const cached = byOps.get(schemas);
5142
- if (cached) return cached;
5059
+ const collectUsedSchemaNamesMemo = memoize$1(/* @__PURE__ */ new WeakMap(), (ops) => memoize$1(/* @__PURE__ */ new WeakMap(), (schemas) => computeUsedSchemaNames(ops, schemas)));
5060
+ function computeUsedSchemaNames(operations, schemas) {
5143
5061
  const schemaMap = /* @__PURE__ */ new Map();
5144
5062
  for (const schema of schemas) if (schema.name) schemaMap.set(schema.name, schema);
5145
5063
  const result = /* @__PURE__ */ new Set();
@@ -5155,9 +5073,11 @@ function collectUsedSchemaNames(operations, schemas) {
5155
5073
  depth: "shallow",
5156
5074
  schema: (node) => node
5157
5075
  })) visitSchema(schema);
5158
- byOps.set(schemas, result);
5159
5076
  return result;
5160
5077
  }
5078
+ function collectUsedSchemaNames(operations, schemas) {
5079
+ return collectUsedSchemaNamesMemo(operations)(schemas);
5080
+ }
5161
5081
  function syncOptionality(schema, required) {
5162
5082
  var _a;
5163
5083
  const nullable = (_a = schema.nullable) != null ? _a : false;
@@ -5167,6 +5087,14 @@ function syncOptionality(schema, required) {
5167
5087
  nullish: !required && nullable ? true : void 0
5168
5088
  };
5169
5089
  }
5090
+ function createStreamInput(schemas, operations, meta) {
5091
+ return {
5092
+ kind: "Input",
5093
+ schemas,
5094
+ operations,
5095
+ meta
5096
+ };
5097
+ }
5170
5098
  function createProperty(props) {
5171
5099
  var _a;
5172
5100
  const required = (_a = props.required) != null ? _a : false;
@@ -5220,9 +5148,9 @@ var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !==
5220
5148
  var __accessCheck$1 = (obj, member, msg) => member.has(obj) || __typeError$1("Cannot " + msg);
5221
5149
  var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
5222
5150
  var __privateAdd$1 = (obj, member, value) => member.has(obj) ? __typeError$1("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
5223
- var __privateSet$1 = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
5151
+ var __privateSet = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
5224
5152
  var __privateMethod$1 = (obj, member, method) => (__accessCheck$1(obj, member, "access private method"), method);
5225
- var _cache, _filesCache, _FileManager_instances, store_fn, _a$1, _studioIsOpen, _pluginsWithEventGenerators, _resolvers, _defaultResolvers, _hookListeners, _PluginDriver_instances, normalizePlugin_fn, trackHookListener_fn, createDefaultResolver_fn, _b$1;
5153
+ var _options, _URLPath_instances, transformParam_fn, eachParam_fn, _a$1, _cache, _filesCache, _FileManager_instances, store_fn, _b, _studio, _middlewareListeners, _eventGeneratorPlugins, _resolvers, _defaultResolvers, _hookListeners, _KubbDriver_instances, normalizePlugin_fn, registerAdapter_fn, registerMiddleware_fn, registerPlugin_fn, trackHookListener_fn, _getDefaultResolver, _c;
5226
5154
  function toCamelOrPascal(text, pascal) {
5227
5155
  return text.trim().replace(/([a-z\d])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/(\d)([a-z])/g, "$1 $2").split(/[\s\-_./\\:]+/).filter(Boolean).map((word, i) => {
5228
5156
  if (word.length > 1 && word === word.toUpperCase()) return word;
@@ -5248,154 +5176,411 @@ function pascalCase(text, { isFile, prefix = "", suffix = "" } = {}) {
5248
5176
  }) : camelCase(part));
5249
5177
  return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true);
5250
5178
  }
5251
- const DEFAULT_STUDIO_URL = "https://kubb.studio";
5252
- const DEFAULT_BANNER = "simple";
5253
- const DEFAULT_EXTENSION = { ".ts": ".ts" };
5254
- function getMode(fileOrFolder) {
5255
- if (!fileOrFolder) return "split";
5256
- return extname(fileOrFolder) ? "single" : "split";
5179
+ function* chunks(arr, size) {
5180
+ for (let i = 0; i < arr.length; i += size) yield arr.slice(i, i + size);
5257
5181
  }
5258
- const stringPatternCache = /* @__PURE__ */ new Map();
5259
- function testPattern(value, pattern) {
5260
- if (typeof pattern === "string") {
5261
- let regex = stringPatternCache.get(pattern);
5262
- if (!regex) {
5263
- regex = new RegExp(pattern);
5264
- stringPatternCache.set(pattern, regex);
5182
+ async function forBatches(source, process2, options) {
5183
+ const { concurrency, flush } = options;
5184
+ if (Array.isArray(source)) {
5185
+ for (const batch2 of chunks(source, concurrency)) {
5186
+ await process2(batch2);
5187
+ if (flush) await flush();
5265
5188
  }
5266
- return regex.test(value);
5267
- }
5268
- return value.match(pattern) !== null;
5269
- }
5270
- function matchesOperationPattern(node, type, pattern) {
5271
- var _a2, _b2, _c;
5272
- switch (type) {
5273
- case "tag":
5274
- return node.tags.some((tag) => testPattern(tag, pattern));
5275
- case "operationId":
5276
- return testPattern(node.operationId, pattern);
5277
- case "path":
5278
- return testPattern(node.path, pattern);
5279
- case "method":
5280
- return testPattern(node.method.toLowerCase(), pattern);
5281
- case "contentType":
5282
- return (_c = (_b2 = (_a2 = node.requestBody) == null ? void 0 : _a2.content) == null ? void 0 : _b2.some((c) => testPattern(c.contentType, pattern))) != null ? _c : false;
5283
- default:
5284
- return false;
5285
- }
5286
- }
5287
- function matchesSchemaPattern(node, type, pattern) {
5288
- switch (type) {
5289
- case "schemaName":
5290
- return node.name ? testPattern(node.name, pattern) : false;
5291
- default:
5292
- return null;
5293
- }
5294
- }
5295
- function defaultResolver(name, type) {
5296
- if (type === "file" || type === "function") return camelCase(name, { isFile: type === "file" });
5297
- if (type === "type") return pascalCase(name);
5298
- return camelCase(name);
5299
- }
5300
- const resolveOptionsCache = /* @__PURE__ */ new WeakMap();
5301
- function computeOptions(node, options, exclude, include, override) {
5302
- var _a2, _b2;
5303
- if (isOperationNode(node)) {
5304
- if (exclude.some(({ type, pattern }) => matchesOperationPattern(node, type, pattern))) return null;
5305
- if (include && !include.some(({ type, pattern }) => matchesOperationPattern(node, type, pattern))) return null;
5306
- const overrideOptions = (_a2 = override.find(({ type, pattern }) => matchesOperationPattern(node, type, pattern))) == null ? void 0 : _a2.options;
5307
- return {
5308
- ...options,
5309
- ...overrideOptions
5310
- };
5189
+ return;
5311
5190
  }
5312
- if (isSchemaNode(node)) {
5313
- if (exclude.some(({ type, pattern }) => matchesSchemaPattern(node, type, pattern) === true)) return null;
5314
- if (include) {
5315
- const applicable = include.map(({ type, pattern }) => matchesSchemaPattern(node, type, pattern)).filter((r) => r !== null);
5316
- if (applicable.length > 0 && !applicable.includes(true)) return null;
5191
+ const batch = [];
5192
+ for await (const item of source) {
5193
+ batch.push(item);
5194
+ if (batch.length >= concurrency) {
5195
+ await process2(batch.splice(0));
5196
+ if (flush) await flush();
5317
5197
  }
5318
- const overrideOptions = (_b2 = override.find(({ type, pattern }) => matchesSchemaPattern(node, type, pattern) === true)) == null ? void 0 : _b2.options;
5319
- return {
5320
- ...options,
5321
- ...overrideOptions
5322
- };
5323
5198
  }
5324
- return options;
5325
- }
5326
- function defaultResolveOptions(node, { options, exclude = [], include, override = [] }) {
5327
- const optionsKey = options;
5328
- let byOptions = resolveOptionsCache.get(optionsKey);
5329
- if (!byOptions) {
5330
- byOptions = /* @__PURE__ */ new WeakMap();
5331
- resolveOptionsCache.set(optionsKey, byOptions);
5199
+ if (batch.length > 0) {
5200
+ await process2(batch.splice(0));
5201
+ if (flush) await flush();
5332
5202
  }
5333
- const cached = byOptions.get(node);
5334
- if (cached !== void 0) return cached.value;
5335
- const result = computeOptions(node, options, exclude, include, override);
5336
- byOptions.set(node, { value: result });
5337
- return result;
5338
5203
  }
5339
- function defaultResolvePath({ baseName, pathMode, tag, path: groupPath }, { root, output, group }) {
5340
- if ((pathMode != null ? pathMode : getMode(path$1.resolve(root, output.path))) === "single") return path$1.resolve(root, output.path);
5341
- const result = (() => {
5342
- var _a2;
5343
- if (group && (groupPath || tag)) {
5344
- const groupValue = group.type === "path" ? groupPath : tag;
5345
- const defaultName = group.type === "tag" ? ({ group: g }) => `${camelCase(g)}Controller` : ({ group: g }) => {
5346
- const segment = g.split("/").filter((s) => s !== "" && s !== "." && s !== "..")[0];
5347
- return segment ? camelCase(segment) : "";
5348
- };
5349
- const resolveName = (_a2 = group.name) != null ? _a2 : defaultName;
5350
- return path$1.resolve(root, output.path, resolveName({ group: groupValue }), baseName);
5351
- }
5352
- return path$1.resolve(root, output.path, baseName);
5353
- })();
5354
- const outputDir = path$1.resolve(root, output.path);
5355
- const outputDirWithSep = outputDir.endsWith(path$1.sep) ? outputDir : `${outputDir}${path$1.sep}`;
5356
- if (result !== outputDir && !result.startsWith(outputDirWithSep)) throw new Error(`[Kubb] Resolved path "${result}" is outside the output directory "${outputDir}". This may indicate a path traversal attempt in the OpenAPI specification or a misconfigured group.name function.`);
5357
- return result;
5204
+ async function withDrain(work, flush) {
5205
+ await work(flush);
5206
+ await flush();
5358
5207
  }
5359
- function defaultResolveFile({ name, extname: extname2, tag, path: groupPath }, context) {
5360
- const pathMode = getMode(path$1.resolve(context.root, context.output.path));
5361
- const baseName = `${pathMode === "single" ? "" : this.default(name, "file")}${extname2}`;
5362
- const filePath = this.resolvePath({
5363
- baseName,
5364
- pathMode,
5365
- tag,
5366
- path: groupPath
5367
- }, context);
5368
- return createFile({
5369
- path: filePath,
5370
- baseName: path$1.basename(filePath),
5371
- meta: { pluginName: this.pluginName },
5372
- sources: [],
5373
- imports: [],
5374
- exports: []
5375
- });
5208
+ function isPromise(result) {
5209
+ return result !== null && result !== void 0 && typeof result["then"] === "function";
5376
5210
  }
5377
- function buildDefaultBanner({ title, description, version, config }) {
5378
- try {
5379
- const source = (() => {
5380
- if (Array.isArray(config.input)) {
5381
- const first = config.input[0];
5382
- if (first && "path" in first) return path$1.basename(first.path);
5383
- return "";
5384
- }
5385
- if (config.input && "path" in config.input) return path$1.basename(config.input.path);
5386
- if (config.input && "data" in config.input) return "text content";
5387
- return "";
5211
+ function memoize(store, factory) {
5212
+ return (key) => {
5213
+ if (store.has(key)) return store.get(key);
5214
+ const value = factory(key);
5215
+ store.set(key, value);
5216
+ return value;
5217
+ };
5218
+ }
5219
+ function arrayToAsyncIterable(arr) {
5220
+ return { [Symbol.asyncIterator]() {
5221
+ return (async function* () {
5222
+ yield* arr;
5388
5223
  })();
5389
- let banner = "/**\n* Generated by Kubb (https://kubb.dev/).\n* Do not edit manually.\n";
5390
- if (config.output.defaultBanner === "simple") {
5391
- banner += "*/\n";
5392
- return banner;
5393
- }
5394
- if (source) banner += `* Source: ${source}
5395
- `;
5396
- if (title) banner += `* Title: ${title}
5397
- `;
5398
- if (description) {
5224
+ } };
5225
+ }
5226
+ const reservedWords = /* @__PURE__ */ new Set([
5227
+ "abstract",
5228
+ "arguments",
5229
+ "boolean",
5230
+ "break",
5231
+ "byte",
5232
+ "case",
5233
+ "catch",
5234
+ "char",
5235
+ "class",
5236
+ "const",
5237
+ "continue",
5238
+ "debugger",
5239
+ "default",
5240
+ "delete",
5241
+ "do",
5242
+ "double",
5243
+ "else",
5244
+ "enum",
5245
+ "eval",
5246
+ "export",
5247
+ "extends",
5248
+ "false",
5249
+ "final",
5250
+ "finally",
5251
+ "float",
5252
+ "for",
5253
+ "function",
5254
+ "goto",
5255
+ "if",
5256
+ "implements",
5257
+ "import",
5258
+ "in",
5259
+ "instanceof",
5260
+ "int",
5261
+ "interface",
5262
+ "let",
5263
+ "long",
5264
+ "native",
5265
+ "new",
5266
+ "null",
5267
+ "package",
5268
+ "private",
5269
+ "protected",
5270
+ "public",
5271
+ "return",
5272
+ "short",
5273
+ "static",
5274
+ "super",
5275
+ "switch",
5276
+ "synchronized",
5277
+ "this",
5278
+ "throw",
5279
+ "throws",
5280
+ "transient",
5281
+ "true",
5282
+ "try",
5283
+ "typeof",
5284
+ "var",
5285
+ "void",
5286
+ "volatile",
5287
+ "while",
5288
+ "with",
5289
+ "yield",
5290
+ "Array",
5291
+ "Date",
5292
+ "hasOwnProperty",
5293
+ "Infinity",
5294
+ "isFinite",
5295
+ "isNaN",
5296
+ "isPrototypeOf",
5297
+ "length",
5298
+ "Math",
5299
+ "name",
5300
+ "NaN",
5301
+ "Number",
5302
+ "Object",
5303
+ "prototype",
5304
+ "String",
5305
+ "toString",
5306
+ "undefined",
5307
+ "valueOf"
5308
+ ]);
5309
+ function isValidVarName(name) {
5310
+ if (!name || reservedWords.has(name)) return false;
5311
+ return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
5312
+ }
5313
+ var URLPath = (_a$1 = class {
5314
+ constructor(path2, options = {}) {
5315
+ __privateAdd$1(this, _URLPath_instances);
5316
+ /**
5317
+ * The raw OpenAPI/Swagger path string, e.g. `/pet/{petId}`.
5318
+ */
5319
+ __publicField$1(this, "path");
5320
+ __privateAdd$1(this, _options);
5321
+ this.path = path2;
5322
+ __privateSet(this, _options, options);
5323
+ }
5324
+ /** Converts the OpenAPI path to Express-style colon syntax, e.g. `/pet/{petId}` → `/pet/:petId`.
5325
+ *
5326
+ * @example
5327
+ * ```ts
5328
+ * new URLPath('/pet/{petId}').URL // '/pet/:petId'
5329
+ * ```
5330
+ */
5331
+ get URL() {
5332
+ return this.toURLPath();
5333
+ }
5334
+ /** Returns `true` when `path` is a fully-qualified URL (e.g. starts with `https://`).
5335
+ *
5336
+ * @example
5337
+ * ```ts
5338
+ * new URLPath('https://petstore.swagger.io/v2/pet').isURL // true
5339
+ * new URLPath('/pet/{petId}').isURL // false
5340
+ * ```
5341
+ */
5342
+ get isURL() {
5343
+ try {
5344
+ return !!new URL(this.path).href;
5345
+ } catch {
5346
+ return false;
5347
+ }
5348
+ }
5349
+ /**
5350
+ * Converts the OpenAPI path to a TypeScript template literal string.
5351
+ *
5352
+ * @example
5353
+ * new URLPath('/pet/{petId}').template // '`/pet/${petId}`'
5354
+ * new URLPath('/account/monetary-accountID').template // '`/account/${monetaryAccountId}`'
5355
+ */
5356
+ get template() {
5357
+ return this.toTemplateString();
5358
+ }
5359
+ /** Returns the path and its extracted params as a structured `URLObject`, or as a stringified expression when `stringify` is set.
5360
+ *
5361
+ * @example
5362
+ * ```ts
5363
+ * new URLPath('/pet/{petId}').object
5364
+ * // { url: '/pet/:petId', params: { petId: 'petId' } }
5365
+ * ```
5366
+ */
5367
+ get object() {
5368
+ return this.toObject();
5369
+ }
5370
+ /** Returns a map of path parameter names, or `undefined` when the path has no parameters.
5371
+ *
5372
+ * @example
5373
+ * ```ts
5374
+ * new URLPath('/pet/{petId}').params // { petId: 'petId' }
5375
+ * new URLPath('/pet').params // undefined
5376
+ * ```
5377
+ */
5378
+ get params() {
5379
+ return this.getParams();
5380
+ }
5381
+ toObject({ type = "path", replacer, stringify } = {}) {
5382
+ const object = {
5383
+ url: type === "path" ? this.toURLPath() : this.toTemplateString({ replacer }),
5384
+ params: this.getParams()
5385
+ };
5386
+ if (stringify) {
5387
+ if (type === "template") return JSON.stringify(object).replaceAll("'", "").replaceAll(`"`, "");
5388
+ if (object.params) return `{ url: '${object.url}', params: ${JSON.stringify(object.params).replaceAll("'", "").replaceAll(`"`, "")} }`;
5389
+ return `{ url: '${object.url}' }`;
5390
+ }
5391
+ return object;
5392
+ }
5393
+ /**
5394
+ * Converts the OpenAPI path to a TypeScript template literal string.
5395
+ * An optional `replacer` can transform each extracted parameter name before interpolation.
5396
+ *
5397
+ * @example
5398
+ * new URLPath('/pet/{petId}').toTemplateString() // '`/pet/${petId}`'
5399
+ */
5400
+ toTemplateString({ prefix = "", replacer } = {}) {
5401
+ return `\`${prefix}${this.path.split(/\{([^}]+)\}/).map((part, i) => {
5402
+ if (i % 2 === 0) return part;
5403
+ const param = __privateMethod$1(this, _URLPath_instances, transformParam_fn).call(this, part);
5404
+ return `\${${replacer ? replacer(param) : param}}`;
5405
+ }).join("")}\``;
5406
+ }
5407
+ /**
5408
+ * Extracts all `{param}` segments from the path and returns them as a key-value map.
5409
+ * An optional `replacer` transforms each parameter name in both key and value positions.
5410
+ * Returns `undefined` when no path parameters are found.
5411
+ *
5412
+ * @example
5413
+ * ```ts
5414
+ * new URLPath('/pet/{petId}/tag/{tagId}').getParams()
5415
+ * // { petId: 'petId', tagId: 'tagId' }
5416
+ * ```
5417
+ */
5418
+ getParams(replacer) {
5419
+ const params = {};
5420
+ __privateMethod$1(this, _URLPath_instances, eachParam_fn).call(this, (_raw, param) => {
5421
+ const key = replacer ? replacer(param) : param;
5422
+ params[key] = key;
5423
+ });
5424
+ return Object.keys(params).length > 0 ? params : void 0;
5425
+ }
5426
+ /** Converts the OpenAPI path to Express-style colon syntax.
5427
+ *
5428
+ * @example
5429
+ * ```ts
5430
+ * new URLPath('/pet/{petId}').toURLPath() // '/pet/:petId'
5431
+ * ```
5432
+ */
5433
+ toURLPath() {
5434
+ return this.path.replace(/\{([^}]+)\}/g, ":$1");
5435
+ }
5436
+ }, _options = new WeakMap(), _URLPath_instances = new WeakSet(), transformParam_fn = function(raw) {
5437
+ const param = isValidVarName(raw) ? raw : camelCase(raw);
5438
+ return __privateGet$1(this, _options).casing === "camelcase" ? camelCase(param) : param;
5439
+ }, /**
5440
+ * Iterates over every `{param}` token in `path`, calling `fn` with the raw token and transformed name.
5441
+ */
5442
+ eachParam_fn = function(fn) {
5443
+ for (const match of this.path.matchAll(/\{([^}]+)\}/g)) {
5444
+ const raw = match[1];
5445
+ fn(raw, __privateMethod$1(this, _URLPath_instances, transformParam_fn).call(this, raw));
5446
+ }
5447
+ }, _a$1);
5448
+ const DEFAULT_STUDIO_URL = "https://kubb.studio";
5449
+ const DEFAULT_BANNER = "simple";
5450
+ const DEFAULT_EXTENSION = { ".ts": ".ts" };
5451
+ function getMode(fileOrFolder) {
5452
+ if (!fileOrFolder) return "split";
5453
+ return extname(fileOrFolder) ? "single" : "split";
5454
+ }
5455
+ const stringPatternCache = /* @__PURE__ */ new Map();
5456
+ function testPattern(value, pattern) {
5457
+ if (typeof pattern === "string") {
5458
+ let regex = stringPatternCache.get(pattern);
5459
+ if (!regex) {
5460
+ regex = new RegExp(pattern);
5461
+ stringPatternCache.set(pattern, regex);
5462
+ }
5463
+ return regex.test(value);
5464
+ }
5465
+ return value.match(pattern) !== null;
5466
+ }
5467
+ function matchesOperationPattern(node, type, pattern) {
5468
+ var _a2, _b2, _c2;
5469
+ if (type === "tag") return node.tags.some((tag) => testPattern(tag, pattern));
5470
+ if (type === "operationId") return testPattern(node.operationId, pattern);
5471
+ if (type === "path") return testPattern(node.path, pattern);
5472
+ if (type === "method") return testPattern(node.method.toLowerCase(), pattern);
5473
+ if (type === "contentType") return (_c2 = (_b2 = (_a2 = node.requestBody) == null ? void 0 : _a2.content) == null ? void 0 : _b2.some((c) => testPattern(c.contentType, pattern))) != null ? _c2 : false;
5474
+ return false;
5475
+ }
5476
+ function matchesSchemaPattern(node, type, pattern) {
5477
+ if (type === "schemaName") return node.name ? testPattern(node.name, pattern) : false;
5478
+ return null;
5479
+ }
5480
+ function defaultResolver(name, type) {
5481
+ if (type === "file" || type === "function") return camelCase(name, { isFile: type === "file" });
5482
+ if (type === "type") return pascalCase(name);
5483
+ return camelCase(name);
5484
+ }
5485
+ const resolveOptionsCache = /* @__PURE__ */ new WeakMap();
5486
+ function computeOptions(node, options, exclude, include, override) {
5487
+ var _a2, _b2;
5488
+ if (isOperationNode(node)) {
5489
+ if (exclude.some(({ type, pattern }) => matchesOperationPattern(node, type, pattern))) return null;
5490
+ if (include && !include.some(({ type, pattern }) => matchesOperationPattern(node, type, pattern))) return null;
5491
+ const overrideOptions = (_a2 = override.find(({ type, pattern }) => matchesOperationPattern(node, type, pattern))) == null ? void 0 : _a2.options;
5492
+ return {
5493
+ ...options,
5494
+ ...overrideOptions
5495
+ };
5496
+ }
5497
+ if (isSchemaNode(node)) {
5498
+ if (exclude.some(({ type, pattern }) => matchesSchemaPattern(node, type, pattern) === true)) return null;
5499
+ if (include) {
5500
+ const applicable = include.map(({ type, pattern }) => matchesSchemaPattern(node, type, pattern)).filter((r) => r !== null);
5501
+ if (applicable.length > 0 && !applicable.includes(true)) return null;
5502
+ }
5503
+ const overrideOptions = (_b2 = override.find(({ type, pattern }) => matchesSchemaPattern(node, type, pattern) === true)) == null ? void 0 : _b2.options;
5504
+ return {
5505
+ ...options,
5506
+ ...overrideOptions
5507
+ };
5508
+ }
5509
+ return options;
5510
+ }
5511
+ function defaultResolveOptions(node, { options, exclude = [], include, override = [] }) {
5512
+ const optionsKey = options;
5513
+ let byOptions = resolveOptionsCache.get(optionsKey);
5514
+ if (!byOptions) {
5515
+ byOptions = /* @__PURE__ */ new WeakMap();
5516
+ resolveOptionsCache.set(optionsKey, byOptions);
5517
+ }
5518
+ const cached = byOptions.get(node);
5519
+ if (cached !== void 0) return cached.value;
5520
+ const result = computeOptions(node, options, exclude, include, override);
5521
+ byOptions.set(node, { value: result });
5522
+ return result;
5523
+ }
5524
+ function defaultResolvePath({ baseName, pathMode, tag, path: groupPath }, { root, output, group }) {
5525
+ if ((pathMode != null ? pathMode : getMode(path$1.resolve(root, output.path))) === "single") return path$1.resolve(root, output.path);
5526
+ const result = (() => {
5527
+ var _a2;
5528
+ if (group && (groupPath || tag)) {
5529
+ const groupValue = group.type === "path" ? groupPath : tag;
5530
+ const defaultName = group.type === "tag" ? ({ group: g }) => `${camelCase(g)}Controller` : ({ group: g }) => {
5531
+ const segment = g.split("/").filter((s) => s !== "" && s !== "." && s !== "..")[0];
5532
+ return segment ? camelCase(segment) : "";
5533
+ };
5534
+ const resolveName = (_a2 = group.name) != null ? _a2 : defaultName;
5535
+ return path$1.resolve(root, output.path, resolveName({ group: groupValue }), baseName);
5536
+ }
5537
+ return path$1.resolve(root, output.path, baseName);
5538
+ })();
5539
+ const outputDir = path$1.resolve(root, output.path);
5540
+ const outputDirWithSep = outputDir.endsWith(path$1.sep) ? outputDir : `${outputDir}${path$1.sep}`;
5541
+ if (result !== outputDir && !result.startsWith(outputDirWithSep)) throw new Error(`[Kubb] Resolved path "${result}" is outside the output directory "${outputDir}". This may indicate a path traversal attempt in the OpenAPI specification or a misconfigured group.name function.`);
5542
+ return result;
5543
+ }
5544
+ function defaultResolveFile({ name, extname: extname2, tag, path: groupPath }, context) {
5545
+ const pathMode = getMode(path$1.resolve(context.root, context.output.path));
5546
+ const baseName = `${pathMode === "single" ? "" : this.default(name, "file")}${extname2}`;
5547
+ const filePath = this.resolvePath({
5548
+ baseName,
5549
+ pathMode,
5550
+ tag,
5551
+ path: groupPath
5552
+ }, context);
5553
+ return createFile({
5554
+ path: filePath,
5555
+ baseName: path$1.basename(filePath),
5556
+ meta: { pluginName: this.pluginName },
5557
+ sources: [],
5558
+ imports: [],
5559
+ exports: []
5560
+ });
5561
+ }
5562
+ function buildDefaultBanner({ title, description, version, config }) {
5563
+ try {
5564
+ const source = (() => {
5565
+ if (Array.isArray(config.input)) {
5566
+ const first = config.input[0];
5567
+ if (first && "path" in first) return path$1.basename(first.path);
5568
+ return "";
5569
+ }
5570
+ if (config.input && "path" in config.input) return path$1.basename(config.input.path);
5571
+ if (config.input && "data" in config.input) return "text content";
5572
+ return "";
5573
+ })();
5574
+ let banner = "/**\n* Generated by Kubb (https://kubb.dev/).\n* Do not edit manually.\n";
5575
+ if (config.output.defaultBanner === "simple") {
5576
+ banner += "*/\n";
5577
+ return banner;
5578
+ }
5579
+ if (source) banner += `* Source: ${source}
5580
+ `;
5581
+ if (title) banner += `* Title: ${title}
5582
+ `;
5583
+ if (description) {
5399
5584
  const formattedDescription = description.replace(/\n/gm, "\n* ");
5400
5585
  banner += `* Description: ${formattedDescription}
5401
5586
  `;
@@ -5408,19 +5593,18 @@ function buildDefaultBanner({ title, description, version, config }) {
5408
5593
  return "/**\n* Generated by Kubb (https://kubb.dev/).\n* Do not edit manually.\n*/";
5409
5594
  }
5410
5595
  }
5411
- function defaultResolveBanner(node, { output, config }) {
5412
- var _a2, _b2;
5413
- if (typeof (output == null ? void 0 : output.banner) === "function") return output.banner(node);
5596
+ function defaultResolveBanner(meta, { output, config }) {
5597
+ if (typeof (output == null ? void 0 : output.banner) === "function") return output.banner(meta);
5414
5598
  if (typeof (output == null ? void 0 : output.banner) === "string") return output.banner;
5415
5599
  if (config.output.defaultBanner === false) return;
5416
5600
  return buildDefaultBanner({
5417
- title: (_a2 = node == null ? void 0 : node.meta) == null ? void 0 : _a2.title,
5418
- version: (_b2 = node == null ? void 0 : node.meta) == null ? void 0 : _b2.version,
5601
+ title: meta == null ? void 0 : meta.title,
5602
+ version: meta == null ? void 0 : meta.version,
5419
5603
  config
5420
5604
  });
5421
5605
  }
5422
- function defaultResolveFooter(node, { output }) {
5423
- if (typeof (output == null ? void 0 : output.footer) === "function") return node ? output.footer(node) : void 0;
5606
+ function defaultResolveFooter(meta, { output }) {
5607
+ if (typeof (output == null ? void 0 : output.footer) === "function") return output.footer(meta);
5424
5608
  if (typeof (output == null ? void 0 : output.footer) === "string") return output.footer;
5425
5609
  }
5426
5610
  function defineResolver(build) {
@@ -5478,7 +5662,7 @@ function mergeFilesByPath(files) {
5478
5662
  }
5479
5663
  return merged;
5480
5664
  }
5481
- var FileManager = (_a$1 = class {
5665
+ var FileManager = (_b = class {
5482
5666
  constructor() {
5483
5667
  __privateAdd$1(this, _FileManager_instances);
5484
5668
  __privateAdd$1(this, _cache, /* @__PURE__ */ new Map());
@@ -5506,11 +5690,11 @@ var FileManager = (_a$1 = class {
5506
5690
  }
5507
5691
  deleteByPath(path2) {
5508
5692
  __privateGet$1(this, _cache).delete(path2);
5509
- __privateSet$1(this, _filesCache, null);
5693
+ __privateSet(this, _filesCache, null);
5510
5694
  }
5511
5695
  clear() {
5512
5696
  __privateGet$1(this, _cache).clear();
5513
- __privateSet$1(this, _filesCache, null);
5697
+ __privateSet(this, _filesCache, null);
5514
5698
  }
5515
5699
  /**
5516
5700
  * Releases all stored files. Called by the core after `kubb:build:end` to
@@ -5527,7 +5711,7 @@ var FileManager = (_a$1 = class {
5527
5711
  */
5528
5712
  get files() {
5529
5713
  if (__privateGet$1(this, _filesCache)) return __privateGet$1(this, _filesCache);
5530
- __privateSet$1(this, _filesCache, [...__privateGet$1(this, _cache).values()].sort((a, b) => {
5714
+ __privateSet(this, _filesCache, [...__privateGet$1(this, _cache).values()].sort((a, b) => {
5531
5715
  const lenDiff = a.path.length - b.path.length;
5532
5716
  if (lenDiff !== 0) return lenDiff;
5533
5717
  const aIsIndex = a.path.endsWith("/index.ts") || a.path === "index.ts";
@@ -5546,29 +5730,38 @@ var FileManager = (_a$1 = class {
5546
5730
  __privateGet$1(this, _cache).set(resolvedFile.path, resolvedFile);
5547
5731
  resolvedFiles.push(resolvedFile);
5548
5732
  }
5549
- __privateSet$1(this, _filesCache, null);
5733
+ __privateSet(this, _filesCache, null);
5550
5734
  return resolvedFiles;
5551
- }, _a$1);
5735
+ }, _b);
5552
5736
  function enforceOrder(enforce) {
5553
5737
  return enforce === "pre" ? -1 : enforce === "post" ? 1 : 0;
5554
5738
  }
5555
- var PluginDriver = (_b$1 = class {
5739
+ var KubbDriver = (_c = class {
5556
5740
  constructor(config, options) {
5557
- __privateAdd$1(this, _PluginDriver_instances);
5741
+ __privateAdd$1(this, _KubbDriver_instances);
5558
5742
  __publicField$1(this, "config");
5559
5743
  __publicField$1(this, "options");
5560
5744
  /**
5561
- * The universal `@kubb/ast` `InputNode` produced by the adapter, set by
5562
- * the build pipeline after the adapter's `parse()` resolves.
5745
+ * The streaming `InputStreamNode` produced by the adapter.
5746
+ * Always set after adapter setup — parse-only adapters are wrapped automatically.
5563
5747
  */
5564
5748
  __publicField$1(this, "inputNode");
5749
+ __publicField$1(this, "adapter");
5565
5750
  /**
5566
- * Set when the adapter returns a streaming `InputStreamNode` (large specs).
5567
- * Mutually exclusive with `inputNode` — exactly one is set after adapter setup.
5751
+ * Studio session state, kept together so `dispose()` can reset it atomically.
5752
+ *
5753
+ * - `source` holds the raw adapter source so `adapter.parse()` can be called lazily.
5754
+ * Intentionally outlives the build; cleared by `dispose()`.
5755
+ * - `isOpen` prevents opening the studio more than once per build.
5756
+ * - `inputNode` caches the parse promise so `adapter.parse()` is called at most once
5757
+ * per studio session, even when `openInStudio()` is called multiple times.
5568
5758
  */
5569
- __publicField$1(this, "inputStreamNode");
5570
- __publicField$1(this, "adapter");
5571
- __privateAdd$1(this, _studioIsOpen, false);
5759
+ __privateAdd$1(this, _studio, {
5760
+ source: void 0,
5761
+ isOpen: false,
5762
+ inputNode: void 0
5763
+ });
5764
+ __privateAdd$1(this, _middlewareListeners, []);
5572
5765
  /**
5573
5766
  * Central file store for all generated files.
5574
5767
  * Plugins should use `this.addFile()` / `this.upsertFile()` (via their context) to
@@ -5580,97 +5773,50 @@ var PluginDriver = (_b$1 = class {
5580
5773
  * Tracks which plugins have generators registered via `addGenerator()` (event-based path).
5581
5774
  * Used by the build loop to decide whether to emit generator events for a given plugin.
5582
5775
  */
5583
- __privateAdd$1(this, _pluginsWithEventGenerators, /* @__PURE__ */ new Set());
5776
+ __privateAdd$1(this, _eventGeneratorPlugins, /* @__PURE__ */ new Set());
5584
5777
  __privateAdd$1(this, _resolvers, /* @__PURE__ */ new Map());
5585
5778
  __privateAdd$1(this, _defaultResolvers, /* @__PURE__ */ new Map());
5586
5779
  __privateAdd$1(this, _hookListeners, /* @__PURE__ */ new Map());
5780
+ __privateAdd$1(this, _getDefaultResolver, memoize(__privateGet$1(this, _defaultResolvers), (pluginName) => defineResolver(() => ({
5781
+ name: "default",
5782
+ pluginName
5783
+ }))));
5587
5784
  this.config = config;
5588
5785
  this.options = options;
5589
- config.plugins.map((rawPlugin) => __privateMethod$1(this, _PluginDriver_instances, normalizePlugin_fn).call(this, rawPlugin)).filter((plugin) => {
5590
- if (typeof plugin.apply === "function") return plugin.apply(config);
5591
- return true;
5592
- }).sort((a, b) => {
5593
- var _a2, _b2;
5594
- if ((_a2 = b.dependencies) == null ? void 0 : _a2.includes(a.name)) return -1;
5595
- if ((_b2 = a.dependencies) == null ? void 0 : _b2.includes(b.name)) return 1;
5596
- return enforceOrder(a.enforce) - enforceOrder(b.enforce);
5597
- }).forEach((plugin) => {
5598
- this.plugins.set(plugin.name, plugin);
5599
- });
5786
+ this.adapter = config.adapter;
5600
5787
  }
5601
5788
  /**
5602
5789
  * Returns `'single'` when `fileOrFolder` has a file extension, `'split'` otherwise.
5603
5790
  *
5604
5791
  * @example
5605
5792
  * ```ts
5606
- * PluginDriver.getMode('src/gen/types.ts') // 'single'
5607
- * PluginDriver.getMode('src/gen/types') // 'split'
5793
+ * KubbDriver.getMode('src/gen/types.ts') // 'single'
5794
+ * KubbDriver.getMode('src/gen/types') // 'split'
5608
5795
  * ```
5609
5796
  */
5610
5797
  static getMode(fileOrFolder) {
5611
5798
  return getMode(fileOrFolder);
5612
5799
  }
5800
+ async setup() {
5801
+ const normalized = this.config.plugins.map((rawPlugin) => __privateMethod$1(this, _KubbDriver_instances, normalizePlugin_fn).call(this, rawPlugin));
5802
+ normalized.sort((a, b) => {
5803
+ var _a2, _b2;
5804
+ if ((_a2 = b.dependencies) == null ? void 0 : _a2.includes(a.name)) return -1;
5805
+ if ((_b2 = a.dependencies) == null ? void 0 : _b2.includes(b.name)) return 1;
5806
+ return enforceOrder(a.enforce) - enforceOrder(b.enforce);
5807
+ });
5808
+ for (const plugin of normalized) {
5809
+ if (plugin.apply) plugin.apply(this.config);
5810
+ __privateMethod$1(this, _KubbDriver_instances, registerPlugin_fn).call(this, plugin);
5811
+ this.plugins.set(plugin.name, plugin);
5812
+ }
5813
+ if (this.config.middleware) for (const middleware of this.config.middleware) for (const event of Object.keys(middleware.hooks)) __privateMethod$1(this, _KubbDriver_instances, registerMiddleware_fn).call(this, event, middleware.hooks);
5814
+ if (this.config.adapter) await __privateMethod$1(this, _KubbDriver_instances, registerAdapter_fn).call(this, this.config.adapter);
5815
+ }
5613
5816
  get hooks() {
5614
5817
  return this.options.hooks;
5615
5818
  }
5616
5819
  /**
5617
- * Registers a hook-style plugin's lifecycle handlers on the shared `AsyncEventEmitter`.
5618
- *
5619
- * For `kubb:plugin:setup`, the registered listener wraps the globally emitted context with a
5620
- * plugin-specific one so that `addGenerator`, `setResolver`, `setTransformer`, and
5621
- * `setRenderer` all target the correct `normalizedPlugin` entry in the plugins map.
5622
- *
5623
- * All other hooks are iterated and registered directly as pass-through listeners.
5624
- * Any event key present in the global `KubbHooks` interface can be subscribed to.
5625
- *
5626
- * External tooling can subscribe to any of these events via `hooks.on(...)` to observe
5627
- * the plugin lifecycle without modifying plugin behavior.
5628
- *
5629
- * @internal
5630
- */
5631
- registerPluginHooks(hookPlugin, normalizedPlugin) {
5632
- const { hooks } = hookPlugin;
5633
- if (!hooks) return;
5634
- if (hooks["kubb:plugin:setup"]) {
5635
- const setupHandler = (globalCtx) => {
5636
- var _a2;
5637
- const pluginCtx = {
5638
- ...globalCtx,
5639
- options: (_a2 = hookPlugin.options) != null ? _a2 : {},
5640
- addGenerator: (gen) => {
5641
- this.registerGenerator(normalizedPlugin.name, gen);
5642
- },
5643
- setResolver: (resolver) => {
5644
- this.setPluginResolver(normalizedPlugin.name, resolver);
5645
- },
5646
- setTransformer: (visitor) => {
5647
- normalizedPlugin.transformer = visitor;
5648
- },
5649
- setRenderer: (renderer) => {
5650
- normalizedPlugin.renderer = renderer;
5651
- },
5652
- setOptions: (opts) => {
5653
- normalizedPlugin.options = {
5654
- ...normalizedPlugin.options,
5655
- ...opts
5656
- };
5657
- },
5658
- injectFile: (userFileNode) => {
5659
- this.fileManager.add(createFile(userFileNode));
5660
- }
5661
- };
5662
- return hooks["kubb:plugin:setup"](pluginCtx);
5663
- };
5664
- this.hooks.on("kubb:plugin:setup", setupHandler);
5665
- __privateMethod$1(this, _PluginDriver_instances, trackHookListener_fn).call(this, "kubb:plugin:setup", setupHandler);
5666
- }
5667
- for (const [event, handler] of Object.entries(hooks)) {
5668
- if (event === "kubb:plugin:setup" || !handler) continue;
5669
- this.hooks.on(event, handler);
5670
- __privateMethod$1(this, _PluginDriver_instances, trackHookListener_fn).call(this, event, handler);
5671
- }
5672
- }
5673
- /**
5674
5820
  * Emits the `kubb:plugin:setup` event so that all registered hook-style plugin listeners
5675
5821
  * can configure generators, resolvers, transformers and renderers before `buildStart` runs.
5676
5822
  *
@@ -5721,7 +5867,7 @@ var PluginDriver = (_b$1 = class {
5721
5867
  });
5722
5868
  };
5723
5869
  this.hooks.on("kubb:generate:schema", schemaHandler);
5724
- __privateMethod$1(this, _PluginDriver_instances, trackHookListener_fn).call(this, "kubb:generate:schema", schemaHandler);
5870
+ __privateMethod$1(this, _KubbDriver_instances, trackHookListener_fn).call(this, "kubb:generate:schema", schemaHandler);
5725
5871
  }
5726
5872
  if (gen.operation) {
5727
5873
  const operationHandler = async (node, ctx) => {
@@ -5733,7 +5879,7 @@ var PluginDriver = (_b$1 = class {
5733
5879
  });
5734
5880
  };
5735
5881
  this.hooks.on("kubb:generate:operation", operationHandler);
5736
- __privateMethod$1(this, _PluginDriver_instances, trackHookListener_fn).call(this, "kubb:generate:operation", operationHandler);
5882
+ __privateMethod$1(this, _KubbDriver_instances, trackHookListener_fn).call(this, "kubb:generate:operation", operationHandler);
5737
5883
  }
5738
5884
  if (gen.operations) {
5739
5885
  const operationsHandler = async (nodes, ctx) => {
@@ -5745,9 +5891,9 @@ var PluginDriver = (_b$1 = class {
5745
5891
  });
5746
5892
  };
5747
5893
  this.hooks.on("kubb:generate:operations", operationsHandler);
5748
- __privateMethod$1(this, _PluginDriver_instances, trackHookListener_fn).call(this, "kubb:generate:operations", operationsHandler);
5894
+ __privateMethod$1(this, _KubbDriver_instances, trackHookListener_fn).call(this, "kubb:generate:operations", operationsHandler);
5749
5895
  }
5750
- __privateGet$1(this, _pluginsWithEventGenerators).add(pluginName);
5896
+ __privateGet$1(this, _eventGeneratorPlugins).add(pluginName);
5751
5897
  }
5752
5898
  /**
5753
5899
  * Returns `true` when at least one generator was registered for the given plugin
@@ -5756,8 +5902,8 @@ var PluginDriver = (_b$1 = class {
5756
5902
  * Used by the build loop to decide whether to walk the AST and emit generator events
5757
5903
  * for a plugin that has no static `plugin.generators`.
5758
5904
  */
5759
- hasRegisteredGenerators(pluginName) {
5760
- return __privateGet$1(this, _pluginsWithEventGenerators).has(pluginName);
5905
+ hasEventGenerators(pluginName) {
5906
+ return __privateGet$1(this, _eventGeneratorPlugins).has(pluginName);
5761
5907
  }
5762
5908
  /**
5763
5909
  * Unregisters all plugin lifecycle listeners from the shared event emitter.
@@ -5768,12 +5914,17 @@ var PluginDriver = (_b$1 = class {
5768
5914
  dispose() {
5769
5915
  for (const [event, handlers] of __privateGet$1(this, _hookListeners)) for (const handler of handlers) this.hooks.off(event, handler);
5770
5916
  __privateGet$1(this, _hookListeners).clear();
5771
- __privateGet$1(this, _pluginsWithEventGenerators).clear();
5917
+ __privateGet$1(this, _eventGeneratorPlugins).clear();
5772
5918
  __privateGet$1(this, _resolvers).clear();
5773
5919
  __privateGet$1(this, _defaultResolvers).clear();
5774
5920
  this.fileManager.dispose();
5775
5921
  this.inputNode = void 0;
5776
- this.inputStreamNode = void 0;
5922
+ __privateSet(this, _studio, {
5923
+ source: void 0,
5924
+ isOpen: false,
5925
+ inputNode: void 0
5926
+ });
5927
+ for (const [event, handler] of __privateGet$1(this, _middlewareListeners)) this.hooks.off(event, handler);
5777
5928
  }
5778
5929
  [Symbol.dispose]() {
5779
5930
  this.dispose();
@@ -5785,7 +5936,7 @@ var PluginDriver = (_b$1 = class {
5785
5936
  */
5786
5937
  setPluginResolver(pluginName, partial) {
5787
5938
  const merged = {
5788
- ...__privateMethod$1(this, _PluginDriver_instances, createDefaultResolver_fn).call(this, pluginName),
5939
+ ...__privateGet$1(this, _getDefaultResolver).call(this, pluginName),
5789
5940
  ...partial
5790
5941
  };
5791
5942
  __privateGet$1(this, _resolvers).set(pluginName, merged);
@@ -5793,8 +5944,8 @@ var PluginDriver = (_b$1 = class {
5793
5944
  if (plugin) plugin.resolver = merged;
5794
5945
  }
5795
5946
  getResolver(pluginName) {
5796
- var _a2, _b2, _c;
5797
- return (_c = (_b2 = __privateGet$1(this, _resolvers).get(pluginName)) != null ? _b2 : (_a2 = this.plugins.get(pluginName)) == null ? void 0 : _a2.resolver) != null ? _c : __privateMethod$1(this, _PluginDriver_instances, createDefaultResolver_fn).call(this, pluginName);
5947
+ var _a2, _b2, _c2;
5948
+ return (_c2 = (_b2 = __privateGet$1(this, _resolvers).get(pluginName)) != null ? _b2 : (_a2 = this.plugins.get(pluginName)) == null ? void 0 : _a2.resolver) != null ? _c2 : __privateGet$1(this, _getDefaultResolver).call(this, pluginName);
5798
5949
  }
5799
5950
  getContext(plugin) {
5800
5951
  const driver = this;
@@ -5804,7 +5955,7 @@ var PluginDriver = (_b$1 = class {
5804
5955
  return resolve(driver.config.root, driver.config.output.path);
5805
5956
  },
5806
5957
  getMode(output) {
5807
- return _b$1.getMode(resolve(driver.config.root, driver.config.output.path, output.path));
5958
+ return _c.getMode(resolve(driver.config.root, driver.config.output.path, output.path));
5808
5959
  },
5809
5960
  hooks: driver.hooks,
5810
5961
  plugin,
@@ -5818,14 +5969,11 @@ var PluginDriver = (_b$1 = class {
5818
5969
  upsertFile: async (...files) => {
5819
5970
  driver.fileManager.upsert(...files);
5820
5971
  },
5821
- get inputNode() {
5822
- var _a2;
5823
- if (driver.inputNode) return driver.inputNode;
5824
- return {
5825
- kind: "Input",
5826
- schemas: [],
5827
- operations: [],
5828
- meta: (_a2 = driver.inputStreamNode) == null ? void 0 : _a2.meta
5972
+ get meta() {
5973
+ var _a2, _b2;
5974
+ return (_b2 = (_a2 = driver.inputNode) == null ? void 0 : _a2.meta) != null ? _b2 : {
5975
+ circularNames: [],
5976
+ enumNames: []
5829
5977
  };
5830
5978
  },
5831
5979
  get adapter() {
@@ -5846,14 +5994,15 @@ var PluginDriver = (_b$1 = class {
5846
5994
  info(message) {
5847
5995
  driver.hooks.emit("kubb:info", { message });
5848
5996
  },
5849
- openInStudio(options) {
5850
- var _a2, _b2;
5851
- if (!driver.config.devtools || __privateGet$1(driver, _studioIsOpen)) return;
5997
+ async openInStudio(options) {
5998
+ var _a2, _b2, _c2, _d;
5999
+ if (!driver.config.devtools || __privateGet$1(driver, _studio).isOpen) return;
5852
6000
  if (typeof driver.config.devtools !== "object") throw new Error("Devtools must be an object");
5853
- if (!driver.inputNode || !driver.adapter) throw new Error("adapter is not defined, make sure you have set the parser in kubb.config.ts");
5854
- __privateSet$1(driver, _studioIsOpen, true);
6001
+ if (!driver.adapter || !__privateGet$1(driver, _studio).source) throw new Error("adapter is not defined, make sure you have set the parser in kubb.config.ts");
6002
+ __privateGet$1(driver, _studio).isOpen = true;
5855
6003
  const studioUrl = (_b2 = (_a2 = driver.config.devtools) == null ? void 0 : _a2.studioUrl) != null ? _b2 : "https://kubb.studio";
5856
- return openInStudio(driver.inputNode, studioUrl, options);
6004
+ (_d = (_c2 = __privateGet$1(driver, _studio)).inputNode) != null ? _d : _c2.inputNode = Promise.resolve(driver.adapter.parse(__privateGet$1(driver, _studio).source));
6005
+ return openInStudio(await __privateGet$1(driver, _studio).inputNode, studioUrl, options);
5857
6006
  }
5858
6007
  };
5859
6008
  }
@@ -5865,23 +6014,107 @@ var PluginDriver = (_b$1 = class {
5865
6014
  if (!plugin) throw new Error(`[kubb] Plugin "${pluginName}" is required but not found. Make sure it is included in your Kubb config.`);
5866
6015
  return plugin;
5867
6016
  }
5868
- }, _studioIsOpen = new WeakMap(), _pluginsWithEventGenerators = new WeakMap(), _resolvers = new WeakMap(), _defaultResolvers = new WeakMap(), _hookListeners = new WeakMap(), _PluginDriver_instances = new WeakSet(), /**
6017
+ }, _studio = new WeakMap(), _middlewareListeners = new WeakMap(), _eventGeneratorPlugins = new WeakMap(), _resolvers = new WeakMap(), _defaultResolvers = new WeakMap(), _hookListeners = new WeakMap(), _KubbDriver_instances = new WeakSet(), /**
5869
6018
  * Creates an `NormalizedPlugin` from a hook-style plugin and registers
5870
6019
  * its lifecycle handlers on the `AsyncEventEmitter`.
5871
6020
  */
5872
- normalizePlugin_fn = function(hookPlugin) {
5873
- const normalizedPlugin = {
5874
- name: hookPlugin.name,
5875
- dependencies: hookPlugin.dependencies,
5876
- enforce: hookPlugin.enforce,
5877
- options: {
6021
+ normalizePlugin_fn = function(plugin) {
6022
+ var _a2;
6023
+ const normalized = {
6024
+ name: plugin.name,
6025
+ dependencies: plugin.dependencies,
6026
+ enforce: plugin.enforce,
6027
+ hooks: plugin.hooks,
6028
+ options: (_a2 = plugin.options) != null ? _a2 : {
5878
6029
  output: { path: "." },
5879
6030
  exclude: [],
5880
6031
  override: []
5881
6032
  }
5882
6033
  };
5883
- this.registerPluginHooks(hookPlugin, normalizedPlugin);
5884
- return normalizedPlugin;
6034
+ if ("apply" in plugin && typeof plugin.apply === "function") normalized.apply = plugin.apply;
6035
+ return normalized;
6036
+ }, registerAdapter_fn = async function(adapter) {
6037
+ const source = inputToAdapterSource(this.config);
6038
+ __privateGet$1(this, _studio).source = source;
6039
+ if (adapter.stream) {
6040
+ this.inputNode = await adapter.stream(source);
6041
+ await this.hooks.emit("kubb:debug", {
6042
+ date: /* @__PURE__ */ new Date(),
6043
+ logs: [`\u2713 Adapter '${adapter.name}' producing input stream`]
6044
+ });
6045
+ } else {
6046
+ const inputNode = await adapter.parse(source);
6047
+ this.inputNode = createStreamInput(arrayToAsyncIterable(inputNode.schemas), arrayToAsyncIterable(inputNode.operations), inputNode.meta);
6048
+ await this.hooks.emit("kubb:debug", {
6049
+ date: /* @__PURE__ */ new Date(),
6050
+ logs: [
6051
+ `\u2713 Adapter '${adapter.name}' resolved InputNode (wrapped as stream)`,
6052
+ ` \u2022 Schemas: ${inputNode.schemas.length}`,
6053
+ ` \u2022 Operations: ${inputNode.operations.length}`
6054
+ ]
6055
+ });
6056
+ }
6057
+ }, registerMiddleware_fn = function(event, middlewareHooks) {
6058
+ const handler = middlewareHooks[event];
6059
+ if (!handler) return;
6060
+ this.hooks.on(event, handler);
6061
+ __privateGet$1(this, _middlewareListeners).push([event, handler]);
6062
+ }, /**
6063
+ * Registers a hook-style plugin's lifecycle handlers on the shared `AsyncEventEmitter`.
6064
+ *
6065
+ * For `kubb:plugin:setup`, the registered listener wraps the globally emitted context with a
6066
+ * plugin-specific one so that `addGenerator`, `setResolver`, `setTransformer`, and
6067
+ * `setRenderer` all target the correct `normalizedPlugin` entry in the plugins map.
6068
+ *
6069
+ * All other hooks are iterated and registered directly as pass-through listeners.
6070
+ * Any event key present in the global `KubbHooks` interface can be subscribed to.
6071
+ *
6072
+ * External tooling can subscribe to any of these events via `hooks.on(...)` to observe
6073
+ * the plugin lifecycle without modifying plugin behavior.
6074
+ *
6075
+ * @internal
6076
+ */
6077
+ registerPlugin_fn = function(plugin) {
6078
+ const { hooks } = plugin;
6079
+ if (!hooks) return;
6080
+ if (hooks["kubb:plugin:setup"]) {
6081
+ const setupHandler = (globalCtx) => {
6082
+ var _a2;
6083
+ const pluginCtx = {
6084
+ ...globalCtx,
6085
+ options: (_a2 = plugin.options) != null ? _a2 : {},
6086
+ addGenerator: (gen) => {
6087
+ this.registerGenerator(plugin.name, gen);
6088
+ },
6089
+ setResolver: (resolver) => {
6090
+ this.setPluginResolver(plugin.name, resolver);
6091
+ },
6092
+ setTransformer: (visitor) => {
6093
+ plugin.transformer = visitor;
6094
+ },
6095
+ setRenderer: (renderer) => {
6096
+ plugin.renderer = renderer;
6097
+ },
6098
+ setOptions: (opts) => {
6099
+ plugin.options = {
6100
+ ...plugin.options,
6101
+ ...opts
6102
+ };
6103
+ },
6104
+ injectFile: (userFileNode) => {
6105
+ this.fileManager.add(createFile(userFileNode));
6106
+ }
6107
+ };
6108
+ return hooks["kubb:plugin:setup"](pluginCtx);
6109
+ };
6110
+ this.hooks.on("kubb:plugin:setup", setupHandler);
6111
+ __privateMethod$1(this, _KubbDriver_instances, trackHookListener_fn).call(this, "kubb:plugin:setup", setupHandler);
6112
+ }
6113
+ for (const [event, handler] of Object.entries(hooks)) {
6114
+ if (event === "kubb:plugin:setup" || !handler) continue;
6115
+ this.hooks.on(event, handler);
6116
+ __privateMethod$1(this, _KubbDriver_instances, trackHookListener_fn).call(this, event, handler);
6117
+ }
5885
6118
  }, trackHookListener_fn = function(event, handler) {
5886
6119
  let handlers = __privateGet$1(this, _hookListeners).get(event);
5887
6120
  if (!handlers) {
@@ -5889,16 +6122,7 @@ normalizePlugin_fn = function(hookPlugin) {
5889
6122
  __privateGet$1(this, _hookListeners).set(event, handlers);
5890
6123
  }
5891
6124
  handlers.add(handler);
5892
- }, createDefaultResolver_fn = function(pluginName) {
5893
- const existingResolver = __privateGet$1(this, _defaultResolvers).get(pluginName);
5894
- if (existingResolver) return existingResolver;
5895
- const resolver = defineResolver(() => ({
5896
- name: "default",
5897
- pluginName
5898
- }));
5899
- __privateGet$1(this, _defaultResolvers).set(pluginName, resolver);
5900
- return resolver;
5901
- }, _b$1);
6125
+ }, _getDefaultResolver = new WeakMap(), _c);
5902
6126
  function applyHookResult({ result, driver, rendererFactory }) {
5903
6127
  if (!result) return;
5904
6128
  if (Array.isArray(result)) {
@@ -5923,6 +6147,22 @@ async function applyAsyncRender({ renderer, result, driver }) {
5923
6147
  driver.fileManager.upsert(...renderer.files);
5924
6148
  renderer.unmount();
5925
6149
  }
6150
+ function inputToAdapterSource(config) {
6151
+ const input = config.input;
6152
+ if (!input) throw new Error("[kubb] input is required when using an adapter. Provide input.path or input.data in your config.");
6153
+ if ("data" in input) return {
6154
+ type: "data",
6155
+ data: input.data
6156
+ };
6157
+ if (new URLPath(input.path).isURL) return {
6158
+ type: "path",
6159
+ path: input.path
6160
+ };
6161
+ return {
6162
+ type: "path",
6163
+ path: resolve(config.root, input.path)
6164
+ };
6165
+ }
5926
6166
 
5927
6167
  var __defProp = Object.defineProperty;
5928
6168
  var __typeError = (msg) => {
@@ -5933,9 +6173,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
5933
6173
  var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
5934
6174
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
5935
6175
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
5936
- var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
5937
6176
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
5938
- var _emitter, _AsyncEventEmitter_instances, emitAll_fn, _a, _options, _URLPath_instances, transformParam_fn, eachParam_fn, _b;
6177
+ var _emitter, _AsyncEventEmitter_instances, emitAll_fn, _a;
5939
6178
  var BuildError = class extends Error {
5940
6179
  constructor(message, options) {
5941
6180
  super(message, { cause: options.cause });
@@ -6043,283 +6282,58 @@ var AsyncEventEmitter = (_a = class {
6043
6282
  }
6044
6283
  throw new Error(`Error in async listener for "${eventName}" with eventArgs ${serializedArgs}`, { cause: toError(err) });
6045
6284
  }
6046
- }, _a);
6047
- function getElapsedMs(hrStart) {
6048
- const [seconds, nanoseconds] = process.hrtime(hrStart);
6049
- const ms = seconds * 1e3 + nanoseconds / 1e6;
6050
- return Math.round(ms * 100) / 100;
6051
- }
6052
- function formatMs(ms) {
6053
- if (ms >= 6e4) return `${Math.floor(ms / 6e4)}m ${(ms % 6e4 / 1e3).toFixed(1)}s`;
6054
- if (ms >= 1e3) return `${(ms / 1e3).toFixed(2)}s`;
6055
- return `${Math.round(ms)}ms`;
6056
- }
6057
- async function exists(path) {
6058
- if (typeof Bun !== "undefined") return Bun.file(path).exists();
6059
- return access(path).then(() => true, () => false);
6060
- }
6061
- async function write(path, data, options = {}) {
6062
- const trimmed = data.trim();
6063
- if (trimmed === "") return null;
6064
- const resolved = resolve(path);
6065
- if (typeof Bun !== "undefined") {
6066
- const file = Bun.file(resolved);
6067
- if ((await file.exists() ? await file.text() : null) === trimmed) return null;
6068
- await Bun.write(resolved, trimmed);
6069
- return trimmed;
6070
- }
6071
- try {
6072
- if (await readFile$1(resolved, { encoding: "utf-8" }) === trimmed) return null;
6073
- } catch {
6074
- }
6075
- await mkdir(dirname(resolved), { recursive: true });
6076
- await writeFile$1(resolved, trimmed, { encoding: "utf-8" });
6077
- if (options.sanity) {
6078
- const savedData = await readFile$1(resolved, { encoding: "utf-8" });
6079
- if (savedData !== trimmed) throw new Error(`Sanity check failed for ${path}
6080
-
6081
- Data[${data.length}]:
6082
- ${data}
6083
-
6084
- Saved[${savedData.length}]:
6085
- ${savedData}
6086
- `);
6087
- return savedData;
6088
- }
6089
- return trimmed;
6090
- }
6091
- async function clean(path) {
6092
- return rm(path, {
6093
- recursive: true,
6094
- force: true
6095
- });
6096
- }
6097
- function isPromise(result) {
6098
- return result !== null && result !== void 0 && typeof result["then"] === "function";
6099
- }
6100
- const reservedWords = /* @__PURE__ */ new Set([
6101
- "abstract",
6102
- "arguments",
6103
- "boolean",
6104
- "break",
6105
- "byte",
6106
- "case",
6107
- "catch",
6108
- "char",
6109
- "class",
6110
- "const",
6111
- "continue",
6112
- "debugger",
6113
- "default",
6114
- "delete",
6115
- "do",
6116
- "double",
6117
- "else",
6118
- "enum",
6119
- "eval",
6120
- "export",
6121
- "extends",
6122
- "false",
6123
- "final",
6124
- "finally",
6125
- "float",
6126
- "for",
6127
- "function",
6128
- "goto",
6129
- "if",
6130
- "implements",
6131
- "import",
6132
- "in",
6133
- "instanceof",
6134
- "int",
6135
- "interface",
6136
- "let",
6137
- "long",
6138
- "native",
6139
- "new",
6140
- "null",
6141
- "package",
6142
- "private",
6143
- "protected",
6144
- "public",
6145
- "return",
6146
- "short",
6147
- "static",
6148
- "super",
6149
- "switch",
6150
- "synchronized",
6151
- "this",
6152
- "throw",
6153
- "throws",
6154
- "transient",
6155
- "true",
6156
- "try",
6157
- "typeof",
6158
- "var",
6159
- "void",
6160
- "volatile",
6161
- "while",
6162
- "with",
6163
- "yield",
6164
- "Array",
6165
- "Date",
6166
- "hasOwnProperty",
6167
- "Infinity",
6168
- "isFinite",
6169
- "isNaN",
6170
- "isPrototypeOf",
6171
- "length",
6172
- "Math",
6173
- "name",
6174
- "NaN",
6175
- "Number",
6176
- "Object",
6177
- "prototype",
6178
- "String",
6179
- "toString",
6180
- "undefined",
6181
- "valueOf"
6182
- ]);
6183
- function isValidVarName(name) {
6184
- if (!name || reservedWords.has(name)) return false;
6185
- return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
6186
- }
6187
- var URLPath = (_b = class {
6188
- constructor(path, options = {}) {
6189
- __privateAdd(this, _URLPath_instances);
6190
- /**
6191
- * The raw OpenAPI/Swagger path string, e.g. `/pet/{petId}`.
6192
- */
6193
- __publicField(this, "path");
6194
- __privateAdd(this, _options);
6195
- this.path = path;
6196
- __privateSet(this, _options, options);
6197
- }
6198
- /** Converts the OpenAPI path to Express-style colon syntax, e.g. `/pet/{petId}` → `/pet/:petId`.
6199
- *
6200
- * @example
6201
- * ```ts
6202
- * new URLPath('/pet/{petId}').URL // '/pet/:petId'
6203
- * ```
6204
- */
6205
- get URL() {
6206
- return this.toURLPath();
6207
- }
6208
- /** Returns `true` when `path` is a fully-qualified URL (e.g. starts with `https://`).
6209
- *
6210
- * @example
6211
- * ```ts
6212
- * new URLPath('https://petstore.swagger.io/v2/pet').isURL // true
6213
- * new URLPath('/pet/{petId}').isURL // false
6214
- * ```
6215
- */
6216
- get isURL() {
6217
- try {
6218
- return !!new URL(this.path).href;
6219
- } catch {
6220
- return false;
6221
- }
6222
- }
6223
- /**
6224
- * Converts the OpenAPI path to a TypeScript template literal string.
6225
- *
6226
- * @example
6227
- * new URLPath('/pet/{petId}').template // '`/pet/${petId}`'
6228
- * new URLPath('/account/monetary-accountID').template // '`/account/${monetaryAccountId}`'
6229
- */
6230
- get template() {
6231
- return this.toTemplateString();
6232
- }
6233
- /** Returns the path and its extracted params as a structured `URLObject`, or as a stringified expression when `stringify` is set.
6234
- *
6235
- * @example
6236
- * ```ts
6237
- * new URLPath('/pet/{petId}').object
6238
- * // { url: '/pet/:petId', params: { petId: 'petId' } }
6239
- * ```
6240
- */
6241
- get object() {
6242
- return this.toObject();
6243
- }
6244
- /** Returns a map of path parameter names, or `undefined` when the path has no parameters.
6245
- *
6246
- * @example
6247
- * ```ts
6248
- * new URLPath('/pet/{petId}').params // { petId: 'petId' }
6249
- * new URLPath('/pet').params // undefined
6250
- * ```
6251
- */
6252
- get params() {
6253
- return this.getParams();
6254
- }
6255
- toObject({ type = "path", replacer, stringify } = {}) {
6256
- const object = {
6257
- url: type === "path" ? this.toURLPath() : this.toTemplateString({ replacer }),
6258
- params: this.getParams()
6259
- };
6260
- if (stringify) {
6261
- if (type === "template") return JSON.stringify(object).replaceAll("'", "").replaceAll(`"`, "");
6262
- if (object.params) return `{ url: '${object.url}', params: ${JSON.stringify(object.params).replaceAll("'", "").replaceAll(`"`, "")} }`;
6263
- return `{ url: '${object.url}' }`;
6264
- }
6265
- return object;
6266
- }
6267
- /**
6268
- * Converts the OpenAPI path to a TypeScript template literal string.
6269
- * An optional `replacer` can transform each extracted parameter name before interpolation.
6270
- *
6271
- * @example
6272
- * new URLPath('/pet/{petId}').toTemplateString() // '`/pet/${petId}`'
6273
- */
6274
- toTemplateString({ prefix = "", replacer } = {}) {
6275
- return `\`${prefix}${this.path.split(/\{([^}]+)\}/).map((part, i) => {
6276
- if (i % 2 === 0) return part;
6277
- const param = __privateMethod(this, _URLPath_instances, transformParam_fn).call(this, part);
6278
- return `\${${replacer ? replacer(param) : param}}`;
6279
- }).join("")}\``;
6280
- }
6281
- /**
6282
- * Extracts all `{param}` segments from the path and returns them as a key-value map.
6283
- * An optional `replacer` transforms each parameter name in both key and value positions.
6284
- * Returns `undefined` when no path parameters are found.
6285
- *
6286
- * @example
6287
- * ```ts
6288
- * new URLPath('/pet/{petId}/tag/{tagId}').getParams()
6289
- * // { petId: 'petId', tagId: 'tagId' }
6290
- * ```
6291
- */
6292
- getParams(replacer) {
6293
- const params = {};
6294
- __privateMethod(this, _URLPath_instances, eachParam_fn).call(this, (_raw, param) => {
6295
- const key = replacer ? replacer(param) : param;
6296
- params[key] = key;
6297
- });
6298
- return Object.keys(params).length > 0 ? params : void 0;
6299
- }
6300
- /** Converts the OpenAPI path to Express-style colon syntax.
6301
- *
6302
- * @example
6303
- * ```ts
6304
- * new URLPath('/pet/{petId}').toURLPath() // '/pet/:petId'
6305
- * ```
6306
- */
6307
- toURLPath() {
6308
- return this.path.replace(/\{([^}]+)\}/g, ":$1");
6285
+ }, _a);
6286
+ function getElapsedMs(hrStart) {
6287
+ const [seconds, nanoseconds] = process.hrtime(hrStart);
6288
+ const ms = seconds * 1e3 + nanoseconds / 1e6;
6289
+ return Math.round(ms * 100) / 100;
6290
+ }
6291
+ function formatMs(ms) {
6292
+ if (ms >= 6e4) return `${Math.floor(ms / 6e4)}m ${(ms % 6e4 / 1e3).toFixed(1)}s`;
6293
+ if (ms >= 1e3) return `${(ms / 1e3).toFixed(2)}s`;
6294
+ return `${Math.round(ms)}ms`;
6295
+ }
6296
+ async function exists(path) {
6297
+ if (typeof Bun !== "undefined") return Bun.file(path).exists();
6298
+ return access(path).then(() => true, () => false);
6299
+ }
6300
+ async function write(path, data, options = {}) {
6301
+ const trimmed = data.trim();
6302
+ if (trimmed === "") return null;
6303
+ const resolved = resolve(path);
6304
+ if (typeof Bun !== "undefined") {
6305
+ const file = Bun.file(resolved);
6306
+ if ((await file.exists() ? await file.text() : null) === trimmed) return null;
6307
+ await Bun.write(resolved, trimmed);
6308
+ return trimmed;
6309
6309
  }
6310
- }, _options = new WeakMap(), _URLPath_instances = new WeakSet(), transformParam_fn = function(raw) {
6311
- const param = isValidVarName(raw) ? raw : camelCase(raw);
6312
- return __privateGet(this, _options).casing === "camelcase" ? camelCase(param) : param;
6313
- }, /**
6314
- * Iterates over every `{param}` token in `path`, calling `fn` with the raw token and transformed name.
6315
- */
6316
- eachParam_fn = function(fn) {
6317
- for (const match of this.path.matchAll(/\{([^}]+)\}/g)) {
6318
- const raw = match[1];
6319
- fn(raw, __privateMethod(this, _URLPath_instances, transformParam_fn).call(this, raw));
6310
+ try {
6311
+ if (await readFile$1(resolved, { encoding: "utf-8" }) === trimmed) return null;
6312
+ } catch {
6320
6313
  }
6321
- }, _b);
6322
- var version$1 = "5.0.0-beta.19";
6314
+ await mkdir(dirname(resolved), { recursive: true });
6315
+ await writeFile$1(resolved, trimmed, { encoding: "utf-8" });
6316
+ if (options.sanity) {
6317
+ const savedData = await readFile$1(resolved, { encoding: "utf-8" });
6318
+ if (savedData !== trimmed) throw new Error(`Sanity check failed for ${path}
6319
+
6320
+ Data[${data.length}]:
6321
+ ${data}
6322
+
6323
+ Saved[${savedData.length}]:
6324
+ ${savedData}
6325
+ `);
6326
+ return savedData;
6327
+ }
6328
+ return trimmed;
6329
+ }
6330
+ async function clean(path) {
6331
+ return rm(path, {
6332
+ recursive: true,
6333
+ force: true
6334
+ });
6335
+ }
6336
+ var version$1 = "5.0.0-beta.20";
6323
6337
  function createStorage(build2) {
6324
6338
  return (options) => build2(options != null ? options : {});
6325
6339
  }
@@ -6398,7 +6412,7 @@ const fsStorage = createStorage(() => ({
6398
6412
  },
6399
6413
  async getKeys(base) {
6400
6414
  const resolvedBase = resolve(base != null ? base : process.cwd());
6401
- async function* walk2(dir, prefix) {
6415
+ async function* walk(dir, prefix) {
6402
6416
  let entries;
6403
6417
  try {
6404
6418
  entries = await readdir$1(dir, { withFileTypes: true });
@@ -6407,12 +6421,12 @@ const fsStorage = createStorage(() => ({
6407
6421
  }
6408
6422
  for (const entry of entries) {
6409
6423
  const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
6410
- if (entry.isDirectory()) yield* walk2(join(dir, entry.name), rel);
6424
+ if (entry.isDirectory()) yield* walk(join(dir, entry.name), rel);
6411
6425
  else yield rel;
6412
6426
  }
6413
6427
  }
6414
6428
  const keys = [];
6415
- for await (const key of walk2(resolvedBase, "")) keys.push(key);
6429
+ for await (const key of walk(resolvedBase, "")) keys.push(key);
6416
6430
  return keys;
6417
6431
  },
6418
6432
  async clear(base) {
@@ -6509,13 +6523,12 @@ function createSourcesView(storage) {
6509
6523
  }))();
6510
6524
  }
6511
6525
  async function setup(userConfig, options = {}) {
6512
- var _a2, _b2, _c, _d, _e, _f, _g, _h, _i;
6526
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i;
6513
6527
  const hooks = (_a2 = options.hooks) != null ? _a2 : new AsyncEventEmitter();
6514
6528
  const config = {
6515
6529
  ...userConfig,
6516
6530
  root: userConfig.root || process.cwd(),
6517
- parsers: (_b2 = userConfig.parsers) != null ? _b2 : [],
6518
- adapter: userConfig.adapter,
6531
+ parsers: (_b = userConfig.parsers) != null ? _b : [],
6519
6532
  output: {
6520
6533
  format: false,
6521
6534
  lint: false,
@@ -6530,7 +6543,7 @@ async function setup(userConfig, options = {}) {
6530
6543
  } : void 0,
6531
6544
  plugins: (_d = userConfig.plugins) != null ? _d : []
6532
6545
  };
6533
- const driver = new PluginDriver(config, { hooks });
6546
+ const driver = new KubbDriver(config, { hooks });
6534
6547
  const storage = createSourcesView(config.storage);
6535
6548
  const diagnosticInfo = getDiagnosticInfo();
6536
6549
  await hooks.emit("kubb:debug", {
@@ -6545,6 +6558,7 @@ async function setup(userConfig, options = {}) {
6545
6558
  ` \u2022 Storage: ${config.storage.name}`,
6546
6559
  ` \u2022 Formatter: ${((_g = userConfig.output) == null ? void 0 : _g.format) || "none"}`,
6547
6560
  ` \u2022 Linter: ${((_h = userConfig.output) == null ? void 0 : _h.lint) || "none"}`,
6561
+ `Running adapter: ${((_i = config.adapter) == null ? void 0 : _i.name) || "none"}`,
6548
6562
  "Environment:",
6549
6563
  Object.entries(diagnosticInfo).map(([key, value]) => ` \u2022 ${key}: ${value}`).join("\n")
6550
6564
  ]
@@ -6570,48 +6584,7 @@ async function setup(userConfig, options = {}) {
6570
6584
  });
6571
6585
  await config.storage.clear(resolve(config.root, config.output.path));
6572
6586
  }
6573
- const middlewareListeners = [];
6574
- function registerMiddlewareHook(event, middlewareHooks) {
6575
- const handler = middlewareHooks[event];
6576
- if (handler) {
6577
- hooks.on(event, handler);
6578
- middlewareListeners.push([event, handler]);
6579
- }
6580
- }
6581
- for (const middleware of (_i = config.middleware) != null ? _i : []) for (const event of Object.keys(middleware.hooks)) registerMiddlewareHook(event, middleware.hooks);
6582
- if (config.adapter) {
6583
- const source = inputToAdapterSource(config);
6584
- await hooks.emit("kubb:debug", {
6585
- date: /* @__PURE__ */ new Date(),
6586
- logs: [`Running adapter: ${config.adapter.name}`]
6587
- });
6588
- driver.adapter = config.adapter;
6589
- if (config.adapter.count && config.adapter.stream) {
6590
- const { schemas: schemaCount, operations: operationCount } = await config.adapter.count(source);
6591
- if (schemaCount > 100) {
6592
- driver.inputStreamNode = await config.adapter.stream(source);
6593
- await hooks.emit("kubb:debug", {
6594
- date: /* @__PURE__ */ new Date(),
6595
- logs: [
6596
- `\u2713 Adapter '${config.adapter.name}' streaming InputStreamNode`,
6597
- ` \u2022 Schemas: ${schemaCount} (threshold: 100)`,
6598
- ` \u2022 Operations: ${operationCount}`
6599
- ]
6600
- });
6601
- }
6602
- }
6603
- if (!driver.inputStreamNode) {
6604
- driver.inputNode = await config.adapter.parse(source);
6605
- await hooks.emit("kubb:debug", {
6606
- date: /* @__PURE__ */ new Date(),
6607
- logs: [
6608
- `\u2713 Adapter '${config.adapter.name}' resolved InputNode`,
6609
- ` \u2022 Schemas: ${driver.inputNode.schemas.length}`,
6610
- ` \u2022 Operations: ${driver.inputNode.operations.length}`
6611
- ]
6612
- });
6613
- }
6614
- }
6587
+ await driver.setup();
6615
6588
  return {
6616
6589
  config,
6617
6590
  hooks,
@@ -6622,249 +6595,10 @@ async function setup(userConfig, options = {}) {
6622
6595
  };
6623
6596
  function dispose() {
6624
6597
  driver.dispose();
6625
- for (const [event, handler] of middlewareListeners) hooks.off(event, handler);
6626
- }
6627
- }
6628
- async function runPluginStreamHooks({ entries, driver, pluginTimings, failedPlugins }) {
6629
- const inputStreamNode = driver.inputStreamNode;
6630
- function resolveRendererFor(gen, state) {
6631
- var _a2, _b2;
6632
- return gen.renderer === null ? void 0 : (_b2 = (_a2 = gen.renderer) != null ? _a2 : state.plugin.renderer) != null ? _b2 : state.generatorContext.config.renderer;
6633
- }
6634
- const states = entries.map(({ plugin, context, hrStart }) => {
6635
- var _a2;
6636
- const { exclude, include, override } = plugin.options;
6637
- const hasExclude = Array.isArray(exclude) && exclude.length > 0;
6638
- const hasInclude = Array.isArray(include) && include.length > 0;
6639
- const hasOverride = Array.isArray(override) && override.length > 0;
6640
- return {
6641
- plugin,
6642
- generatorContext: {
6643
- ...context,
6644
- resolver: driver.getResolver(plugin.name)
6645
- },
6646
- generators: (_a2 = plugin.generators) != null ? _a2 : [],
6647
- hrStart,
6648
- failed: false,
6649
- error: void 0,
6650
- optionsAreStatic: !hasExclude && !hasInclude && !hasOverride
6651
- };
6652
- });
6653
- async function dispatchSchema(state, node) {
6654
- if (state.failed) return;
6655
- try {
6656
- const { plugin, generatorContext, generators } = state;
6657
- const transformedNode = plugin.transformer ? transform(node, plugin.transformer) : node;
6658
- const { exclude, include, override } = plugin.options;
6659
- const options = state.optionsAreStatic ? plugin.options : generatorContext.resolver.resolveOptions(transformedNode, {
6660
- options: plugin.options,
6661
- exclude,
6662
- include,
6663
- override
6664
- });
6665
- if (options === null) return;
6666
- const ctx = {
6667
- ...generatorContext,
6668
- options
6669
- };
6670
- for (const gen of generators) {
6671
- if (!gen.schema) continue;
6672
- const raw = gen.schema(transformedNode, ctx);
6673
- const applied = applyHookResult({
6674
- result: isPromise(raw) ? await raw : raw,
6675
- driver,
6676
- rendererFactory: resolveRendererFor(gen, state)
6677
- });
6678
- if (isPromise(applied)) await applied;
6679
- }
6680
- await driver.hooks.emit("kubb:generate:schema", transformedNode, ctx);
6681
- } catch (caughtError) {
6682
- state.failed = true;
6683
- state.error = caughtError;
6684
- }
6685
- }
6686
- async function dispatchOperation(state, node) {
6687
- if (state.failed) return;
6688
- try {
6689
- const { plugin, generatorContext, generators } = state;
6690
- const transformedNode = plugin.transformer ? transform(node, plugin.transformer) : node;
6691
- const { exclude, include, override } = plugin.options;
6692
- const options = state.optionsAreStatic ? plugin.options : generatorContext.resolver.resolveOptions(transformedNode, {
6693
- options: plugin.options,
6694
- exclude,
6695
- include,
6696
- override
6697
- });
6698
- if (options === null) return;
6699
- const ctx = {
6700
- ...generatorContext,
6701
- options
6702
- };
6703
- for (const gen of generators) {
6704
- if (!gen.operation) continue;
6705
- const raw = gen.operation(transformedNode, ctx);
6706
- const applied = applyHookResult({
6707
- result: isPromise(raw) ? await raw : raw,
6708
- driver,
6709
- rendererFactory: resolveRendererFor(gen, state)
6710
- });
6711
- if (isPromise(applied)) await applied;
6712
- }
6713
- await driver.hooks.emit("kubb:generate:operation", transformedNode, ctx);
6714
- } catch (caughtError) {
6715
- state.failed = true;
6716
- state.error = caughtError;
6717
- }
6718
- }
6719
- for await (const node of inputStreamNode.schemas) await Promise.all(states.map((state) => dispatchSchema(state, node)));
6720
- const collectedOperations = [];
6721
- for await (const node of inputStreamNode.operations) {
6722
- collectedOperations.push(node);
6723
- await Promise.all(states.map((state) => dispatchOperation(state, node)));
6724
- }
6725
- for (const state of states) {
6726
- if (!state.failed) try {
6727
- const { plugin, generatorContext, generators } = state;
6728
- const ctx = {
6729
- ...generatorContext,
6730
- options: plugin.options
6731
- };
6732
- for (const gen of generators) {
6733
- if (!gen.operations) continue;
6734
- await applyHookResult({
6735
- result: await gen.operations(collectedOperations, ctx),
6736
- driver,
6737
- rendererFactory: resolveRendererFor(gen, state)
6738
- });
6739
- }
6740
- await driver.hooks.emit("kubb:generate:operations", collectedOperations, ctx);
6741
- } catch (caughtError) {
6742
- state.failed = true;
6743
- state.error = caughtError;
6744
- }
6745
- const duration = getElapsedMs(state.hrStart);
6746
- pluginTimings.set(state.plugin.name, duration);
6747
- await driver.hooks.emit("kubb:plugin:end", {
6748
- plugin: state.plugin,
6749
- duration,
6750
- success: !state.failed,
6751
- ...state.failed && state.error ? { error: state.error } : {},
6752
- config: driver.config,
6753
- get files() {
6754
- return driver.fileManager.files;
6755
- },
6756
- upsertFile: (...files) => driver.fileManager.upsert(...files)
6757
- });
6758
- if (state.failed && state.error) failedPlugins.add({
6759
- plugin: state.plugin,
6760
- error: state.error
6761
- });
6762
- await driver.hooks.emit("kubb:debug", {
6763
- date: /* @__PURE__ */ new Date(),
6764
- logs: [state.failed ? "\u2717 Plugin start failed" : `\u2713 Plugin started successfully (${formatMs(duration)})`]
6765
- });
6766
- }
6767
- }
6768
- async function runPluginAstHooks(plugin, context) {
6769
- var _a2, _b2, _c;
6770
- const { adapter, inputNode, resolver, driver } = context;
6771
- const { exclude, include, override } = plugin.options;
6772
- if (!adapter || !inputNode) throw new Error(`[${plugin.name}] No adapter found. Add an OAS adapter (e.g. adapterOas()) before this plugin in your Kubb config.`);
6773
- function resolveRenderer(gen) {
6774
- var _a3, _b3;
6775
- return gen.renderer === null ? void 0 : (_b3 = (_a3 = gen.renderer) != null ? _a3 : plugin.renderer) != null ? _b3 : context.config.renderer;
6776
- }
6777
- const generators = (_a2 = plugin.generators) != null ? _a2 : [];
6778
- const collectedOperations = [];
6779
- const generatorContext = {
6780
- ...context,
6781
- resolver: driver.getResolver(plugin.name)
6782
- };
6783
- const operationFilterTypes = /* @__PURE__ */ new Set([
6784
- "tag",
6785
- "operationId",
6786
- "path",
6787
- "method",
6788
- "contentType"
6789
- ]);
6790
- const hasOperationBasedIncludes = (_b2 = include == null ? void 0 : include.some(({ type }) => operationFilterTypes.has(type))) != null ? _b2 : false;
6791
- const hasSchemaNameIncludes = (_c = include == null ? void 0 : include.some(({ type }) => type === "schemaName")) != null ? _c : false;
6792
- const allowedSchemaNames = (() => {
6793
- if (!hasOperationBasedIncludes || hasSchemaNameIncludes) return void 0;
6794
- return collectUsedSchemaNames(inputNode.operations.filter((op) => resolver.resolveOptions(op, {
6795
- options: plugin.options,
6796
- exclude,
6797
- include,
6798
- override
6799
- }) !== null), inputNode.schemas);
6800
- })();
6801
- await walk(inputNode, {
6802
- depth: "shallow",
6803
- async schema(node) {
6804
- const transformedNode = plugin.transformer ? transform(node, plugin.transformer) : node;
6805
- if (allowedSchemaNames !== void 0 && transformedNode.name && !allowedSchemaNames.has(transformedNode.name)) return;
6806
- const options = resolver.resolveOptions(transformedNode, {
6807
- options: plugin.options,
6808
- exclude,
6809
- include,
6810
- override
6811
- });
6812
- if (options === null) return;
6813
- const ctx = {
6814
- ...generatorContext,
6815
- options
6816
- };
6817
- await Promise.all(generators.filter((gen) => gen.schema).map(async (gen) => {
6818
- return applyHookResult({
6819
- result: await gen.schema(transformedNode, ctx),
6820
- driver,
6821
- rendererFactory: resolveRenderer(gen)
6822
- });
6823
- }));
6824
- await driver.hooks.emit("kubb:generate:schema", transformedNode, ctx);
6825
- },
6826
- async operation(node) {
6827
- const transformedNode = plugin.transformer ? transform(node, plugin.transformer) : node;
6828
- const options = resolver.resolveOptions(transformedNode, {
6829
- options: plugin.options,
6830
- exclude,
6831
- include,
6832
- override
6833
- });
6834
- if (options === null) return;
6835
- collectedOperations.push(transformedNode);
6836
- const ctx = {
6837
- ...generatorContext,
6838
- options
6839
- };
6840
- await Promise.all(generators.filter((gen) => gen.operation).map(async (gen) => {
6841
- return applyHookResult({
6842
- result: await gen.operation(transformedNode, ctx),
6843
- driver,
6844
- rendererFactory: resolveRenderer(gen)
6845
- });
6846
- }));
6847
- await driver.hooks.emit("kubb:generate:operation", transformedNode, ctx);
6848
- }
6849
- });
6850
- if (collectedOperations.length > 0) {
6851
- const ctx = {
6852
- ...generatorContext,
6853
- options: plugin.options
6854
- };
6855
- for (const gen of generators) {
6856
- if (!gen.operations) continue;
6857
- await applyHookResult({
6858
- result: await gen.operations(collectedOperations, ctx),
6859
- driver,
6860
- rendererFactory: resolveRenderer(gen)
6861
- });
6862
- }
6863
- await driver.hooks.emit("kubb:generate:operations", collectedOperations, ctx);
6864
6598
  }
6865
6599
  }
6866
6600
  async function safeBuild(setupResult) {
6867
- var _a2, _b2, _c, _d;
6601
+ var _a2;
6868
6602
  try {
6869
6603
  var _usingCtx$1 = _usingCtx();
6870
6604
  _usingCtx$1.u(setupResult);
@@ -6874,8 +6608,8 @@ async function safeBuild(setupResult) {
6874
6608
  const config = driver.config;
6875
6609
  const writtenPaths = /* @__PURE__ */ new Set();
6876
6610
  const parsersMap = /* @__PURE__ */ new Map();
6877
- for (const parser of config.parsers) if (parser.extNames) for (const extname of parser.extNames) parsersMap.set(extname, parser);
6878
6611
  const fileProcessor = new FileProcessor();
6612
+ for (const parser of config.parsers) if (parser.extNames) for (const extname of parser.extNames) parsersMap.set(extname, parser);
6879
6613
  async function flushPendingFiles() {
6880
6614
  const files = driver.fileManager.files.filter((f) => !writtenPaths.has(f.path));
6881
6615
  if (files.length === 0) return;
@@ -6888,119 +6622,236 @@ async function safeBuild(setupResult) {
6888
6622
  parsers: parsersMap,
6889
6623
  extension: config.output.extension
6890
6624
  });
6625
+ const queue = [];
6891
6626
  for (const { file, source, processed, total, percentage } of stream) {
6892
- await hooks.emit("kubb:file:processing:update", {
6893
- file,
6894
- source,
6895
- processed,
6896
- total,
6897
- percentage,
6898
- config
6899
- });
6900
- if (source) await storage.setItem(file.path, source);
6901
6627
  writtenPaths.add(file.path);
6628
+ queue.push((async () => {
6629
+ await hooks.emit("kubb:file:processing:update", {
6630
+ file,
6631
+ source,
6632
+ processed,
6633
+ total,
6634
+ percentage,
6635
+ config
6636
+ });
6637
+ if (source) await storage.setItem(file.path, source);
6638
+ })());
6639
+ if (queue.length >= 50) await Promise.all(queue.splice(0));
6902
6640
  }
6641
+ await Promise.all(queue);
6903
6642
  await hooks.emit("kubb:files:processing:end", { files });
6904
6643
  await hooks.emit("kubb:debug", {
6905
6644
  date: /* @__PURE__ */ new Date(),
6906
6645
  logs: [`\u2713 File write process completed for ${files.length} files`]
6907
6646
  });
6908
6647
  }
6648
+ async function dispatchOperationsToGenerators(generators, collectedOperations, ctx, rendererFor) {
6649
+ for (const gen of generators) {
6650
+ if (!gen.operations) continue;
6651
+ await applyHookResult({
6652
+ result: await gen.operations(collectedOperations, ctx),
6653
+ driver,
6654
+ rendererFactory: rendererFor(gen)
6655
+ });
6656
+ }
6657
+ await driver.hooks.emit("kubb:generate:operations", collectedOperations, ctx);
6658
+ }
6659
+ async function runPlugins(entries) {
6660
+ var _a3, _b;
6661
+ const { schemas, operations } = driver.inputNode;
6662
+ const operationFilterTypes = /* @__PURE__ */ new Set([
6663
+ "tag",
6664
+ "operationId",
6665
+ "path",
6666
+ "method",
6667
+ "contentType"
6668
+ ]);
6669
+ const states = entries.map(({ plugin, context, hrStart }) => {
6670
+ var _a4;
6671
+ const { exclude, include, override } = plugin.options;
6672
+ const hasExclude = Array.isArray(exclude) && exclude.length > 0;
6673
+ const hasInclude = Array.isArray(include) && include.length > 0;
6674
+ const hasOverride = Array.isArray(override) && override.length > 0;
6675
+ return {
6676
+ plugin,
6677
+ generatorContext: {
6678
+ ...context,
6679
+ resolver: driver.getResolver(plugin.name)
6680
+ },
6681
+ generators: (_a4 = plugin.generators) != null ? _a4 : [],
6682
+ hrStart,
6683
+ failed: false,
6684
+ error: void 0,
6685
+ optionsAreStatic: !hasExclude && !hasInclude && !hasOverride,
6686
+ allowedSchemaNames: void 0
6687
+ };
6688
+ });
6689
+ const pruningStates = states.filter(({ plugin }) => {
6690
+ var _a4, _b2;
6691
+ const { include } = plugin.options;
6692
+ return ((_a4 = include == null ? void 0 : include.some(({ type }) => operationFilterTypes.has(type))) != null ? _a4 : false) && !((_b2 = include == null ? void 0 : include.some(({ type }) => type === "schemaName")) != null ? _b2 : false);
6693
+ });
6694
+ if (pruningStates.length > 0) {
6695
+ const allSchemas = [];
6696
+ for await (const schema of schemas) allSchemas.push(schema);
6697
+ const includedOpsByState = new Map(pruningStates.map((s) => [s, []]));
6698
+ for await (const operation of operations) for (const state of pruningStates) {
6699
+ const { exclude, include, override } = state.plugin.options;
6700
+ if (state.generatorContext.resolver.resolveOptions(operation, {
6701
+ options: state.plugin.options,
6702
+ exclude,
6703
+ include,
6704
+ override
6705
+ }) !== null) (_a3 = includedOpsByState.get(state)) == null ? void 0 : _a3.push(operation);
6706
+ }
6707
+ for (const state of pruningStates) state.allowedSchemaNames = collectUsedSchemaNames((_b = includedOpsByState.get(state)) != null ? _b : [], allSchemas);
6708
+ }
6709
+ function resolveRendererFor(gen, state) {
6710
+ var _a4, _b2;
6711
+ return gen.renderer === null ? void 0 : (_b2 = (_a4 = gen.renderer) != null ? _a4 : state.plugin.renderer) != null ? _b2 : state.generatorContext.config.renderer;
6712
+ }
6713
+ async function dispatchSchema(state, node) {
6714
+ if (state.failed) return;
6715
+ try {
6716
+ const { plugin, generatorContext, generators } = state;
6717
+ const transformedNode = plugin.transformer ? transform(node, plugin.transformer) : node;
6718
+ if (state.allowedSchemaNames !== void 0 && transformedNode.name && !state.allowedSchemaNames.has(transformedNode.name)) return;
6719
+ const { exclude, include, override } = plugin.options;
6720
+ const options = state.optionsAreStatic ? plugin.options : generatorContext.resolver.resolveOptions(transformedNode, {
6721
+ options: plugin.options,
6722
+ exclude,
6723
+ include,
6724
+ override
6725
+ });
6726
+ if (options === null) return;
6727
+ const ctx = {
6728
+ ...generatorContext,
6729
+ options
6730
+ };
6731
+ for (const gen of generators) {
6732
+ if (!gen.schema) continue;
6733
+ const raw = gen.schema(transformedNode, ctx);
6734
+ const applied = applyHookResult({
6735
+ result: isPromise(raw) ? await raw : raw,
6736
+ driver,
6737
+ rendererFactory: resolveRendererFor(gen, state)
6738
+ });
6739
+ if (isPromise(applied)) await applied;
6740
+ }
6741
+ await driver.hooks.emit("kubb:generate:schema", transformedNode, ctx);
6742
+ } catch (caughtError) {
6743
+ state.failed = true;
6744
+ state.error = caughtError;
6745
+ }
6746
+ }
6747
+ async function dispatchOperation(state, node) {
6748
+ if (state.failed) return;
6749
+ try {
6750
+ const { plugin, generatorContext, generators } = state;
6751
+ const transformedNode = plugin.transformer ? transform(node, plugin.transformer) : node;
6752
+ const { exclude, include, override } = plugin.options;
6753
+ const options = state.optionsAreStatic ? plugin.options : generatorContext.resolver.resolveOptions(transformedNode, {
6754
+ options: plugin.options,
6755
+ exclude,
6756
+ include,
6757
+ override
6758
+ });
6759
+ if (options === null) return;
6760
+ const ctx = {
6761
+ ...generatorContext,
6762
+ options
6763
+ };
6764
+ for (const gen of generators) {
6765
+ if (!gen.operation) continue;
6766
+ const raw = gen.operation(transformedNode, ctx);
6767
+ const applied = applyHookResult({
6768
+ result: isPromise(raw) ? await raw : raw,
6769
+ driver,
6770
+ rendererFactory: resolveRendererFor(gen, state)
6771
+ });
6772
+ if (isPromise(applied)) await applied;
6773
+ }
6774
+ await driver.hooks.emit("kubb:generate:operation", transformedNode, ctx);
6775
+ } catch (caughtError) {
6776
+ state.failed = true;
6777
+ state.error = caughtError;
6778
+ }
6779
+ }
6780
+ await forBatches(schemas, (nodes) => Promise.all(nodes.flatMap((n) => states.map((state) => dispatchSchema(state, n)))), {
6781
+ concurrency: 8,
6782
+ flush: flushPendingFiles
6783
+ });
6784
+ const collectedOperations = [];
6785
+ await forBatches(operations, (nodes) => {
6786
+ collectedOperations.push(...nodes);
6787
+ return Promise.all(nodes.flatMap((n) => states.map((state) => dispatchOperation(state, n))));
6788
+ }, {
6789
+ concurrency: 8,
6790
+ flush: flushPendingFiles
6791
+ });
6792
+ for (const state of states) {
6793
+ if (!state.failed) try {
6794
+ const { plugin, generatorContext, generators } = state;
6795
+ await dispatchOperationsToGenerators(generators, collectedOperations, {
6796
+ ...generatorContext,
6797
+ options: plugin.options
6798
+ }, (gen) => resolveRendererFor(gen, state));
6799
+ } catch (caughtError) {
6800
+ state.failed = true;
6801
+ state.error = caughtError;
6802
+ }
6803
+ const duration = getElapsedMs(state.hrStart);
6804
+ pluginTimings.set(state.plugin.name, duration);
6805
+ await driver.hooks.emit("kubb:plugin:end", {
6806
+ plugin: state.plugin,
6807
+ duration,
6808
+ success: !state.failed,
6809
+ ...state.failed && state.error ? { error: state.error } : {},
6810
+ config: driver.config,
6811
+ get files() {
6812
+ return driver.fileManager.files;
6813
+ },
6814
+ upsertFile: (...files) => driver.fileManager.upsert(...files)
6815
+ });
6816
+ if (state.failed && state.error) failedPlugins.add({
6817
+ plugin: state.plugin,
6818
+ error: state.error
6819
+ });
6820
+ await driver.hooks.emit("kubb:debug", {
6821
+ date: /* @__PURE__ */ new Date(),
6822
+ logs: [state.failed ? "\u2717 Plugin start failed" : `\u2713 Plugin started successfully (${formatMs(duration)})`]
6823
+ });
6824
+ }
6825
+ }
6909
6826
  try {
6910
6827
  await driver.emitSetupHooks();
6911
- if (driver.adapter && (driver.inputNode || driver.inputStreamNode)) await hooks.emit("kubb:build:start", {
6828
+ if (driver.adapter && driver.inputNode) await hooks.emit("kubb:build:start", {
6912
6829
  config,
6913
6830
  adapter: driver.adapter,
6914
- inputNode: (_b2 = driver.inputNode) != null ? _b2 : {
6915
- kind: "Input",
6916
- schemas: [],
6917
- operations: [],
6918
- meta: (_a2 = driver.inputStreamNode) == null ? void 0 : _a2.meta
6919
- },
6831
+ meta: driver.inputNode.meta,
6920
6832
  getPlugin: driver.getPlugin.bind(driver),
6921
6833
  get files() {
6922
6834
  return driver.fileManager.files;
6923
6835
  },
6924
6836
  upsertFile: (...files2) => driver.fileManager.upsert(...files2)
6925
6837
  });
6926
- if (driver.inputStreamNode) {
6927
- const streamPluginEntries = [];
6928
- for (const plugin of driver.plugins.values()) {
6929
- const context = driver.getContext(plugin);
6930
- const hrStart = process.hrtime();
6931
- await hooks.emit("kubb:plugin:start", { plugin });
6932
- await hooks.emit("kubb:debug", {
6933
- date: /* @__PURE__ */ new Date(),
6934
- logs: ["Starting plugin...", ` \u2022 Plugin Name: ${plugin.name}`]
6935
- });
6936
- if (((_c = plugin.generators) == null ? void 0 : _c.length) || driver.hasRegisteredGenerators(plugin.name)) {
6937
- streamPluginEntries.push({
6938
- plugin,
6939
- context,
6940
- hrStart
6941
- });
6942
- continue;
6943
- }
6944
- const duration = getElapsedMs(hrStart);
6945
- pluginTimings.set(plugin.name, duration);
6946
- await hooks.emit("kubb:plugin:end", {
6947
- plugin,
6948
- duration,
6949
- success: true,
6950
- config,
6951
- get files() {
6952
- return driver.fileManager.files;
6953
- },
6954
- upsertFile: (...files2) => driver.fileManager.upsert(...files2)
6955
- });
6956
- await hooks.emit("kubb:debug", {
6957
- date: /* @__PURE__ */ new Date(),
6958
- logs: [`\u2713 Plugin started successfully (${formatMs(duration)})`]
6959
- });
6960
- }
6961
- if (streamPluginEntries.length > 0) {
6962
- await runPluginStreamHooks({
6963
- entries: streamPluginEntries,
6964
- driver,
6965
- pluginTimings,
6966
- failedPlugins
6967
- });
6968
- await flushPendingFiles();
6969
- }
6970
- } else for (const plugin of driver.plugins.values()) {
6838
+ const generatorPlugins = [];
6839
+ for (const plugin of driver.plugins.values()) {
6971
6840
  const context = driver.getContext(plugin);
6972
6841
  const hrStart = process.hrtime();
6973
6842
  try {
6974
- const timestamp = /* @__PURE__ */ new Date();
6975
6843
  await hooks.emit("kubb:plugin:start", { plugin });
6976
- await hooks.emit("kubb:debug", {
6977
- date: timestamp,
6978
- logs: ["Starting plugin...", ` \u2022 Plugin Name: ${plugin.name}`]
6979
- });
6980
- if (((_d = plugin.generators) == null ? void 0 : _d.length) || driver.hasRegisteredGenerators(plugin.name)) await runPluginAstHooks(plugin, context);
6981
- const duration = getElapsedMs(hrStart);
6982
- pluginTimings.set(plugin.name, duration);
6983
- await hooks.emit("kubb:plugin:end", {
6984
- plugin,
6985
- duration,
6986
- success: true,
6987
- config,
6988
- get files() {
6989
- return driver.fileManager.files;
6990
- },
6991
- upsertFile: (...files2) => driver.fileManager.upsert(...files2)
6992
- });
6993
6844
  await hooks.emit("kubb:debug", {
6994
6845
  date: /* @__PURE__ */ new Date(),
6995
- logs: [`\u2713 Plugin started successfully (${formatMs(duration)})`]
6846
+ logs: ["Starting plugin...", ` \u2022 Plugin Name: ${plugin.name}`]
6996
6847
  });
6997
6848
  } catch (caughtError) {
6998
6849
  const error = caughtError;
6999
- const errorTimestamp = /* @__PURE__ */ new Date();
7000
- const duration = getElapsedMs(hrStart);
6850
+ const duration2 = getElapsedMs(hrStart);
6851
+ pluginTimings.set(plugin.name, duration2);
7001
6852
  await hooks.emit("kubb:plugin:end", {
7002
6853
  plugin,
7003
- duration,
6854
+ duration: duration2,
7004
6855
  success: false,
7005
6856
  error,
7006
6857
  config,
@@ -7009,22 +6860,51 @@ async function safeBuild(setupResult) {
7009
6860
  },
7010
6861
  upsertFile: (...files2) => driver.fileManager.upsert(...files2)
7011
6862
  });
7012
- await hooks.emit("kubb:debug", {
7013
- date: errorTimestamp,
7014
- logs: [
7015
- "\u2717 Plugin start failed",
7016
- ` \u2022 Plugin Name: ${plugin.name}`,
7017
- ` \u2022 Error: ${error.constructor.name} - ${error.message}`,
7018
- " \u2022 Stack Trace:",
7019
- error.stack || "No stack trace available"
7020
- ]
7021
- });
7022
6863
  failedPlugins.add({
7023
6864
  plugin,
7024
6865
  error
7025
6866
  });
6867
+ continue;
6868
+ }
6869
+ if (((_a2 = plugin.generators) == null ? void 0 : _a2.length) || driver.hasEventGenerators(plugin.name)) {
6870
+ generatorPlugins.push({
6871
+ plugin,
6872
+ context,
6873
+ hrStart
6874
+ });
6875
+ continue;
7026
6876
  }
7027
- await flushPendingFiles();
6877
+ const duration = getElapsedMs(hrStart);
6878
+ pluginTimings.set(plugin.name, duration);
6879
+ await hooks.emit("kubb:plugin:end", {
6880
+ plugin,
6881
+ duration,
6882
+ success: true,
6883
+ config,
6884
+ get files() {
6885
+ return driver.fileManager.files;
6886
+ },
6887
+ upsertFile: (...files2) => driver.fileManager.upsert(...files2)
6888
+ });
6889
+ await hooks.emit("kubb:debug", {
6890
+ date: /* @__PURE__ */ new Date(),
6891
+ logs: [`\u2713 Plugin started successfully (${formatMs(duration)})`]
6892
+ });
6893
+ }
6894
+ if (generatorPlugins.length > 0) if (driver.inputNode) await withDrain(() => runPlugins(generatorPlugins), flushPendingFiles);
6895
+ else for (const { plugin, hrStart } of generatorPlugins) {
6896
+ const duration = getElapsedMs(hrStart);
6897
+ pluginTimings.set(plugin.name, duration);
6898
+ await hooks.emit("kubb:plugin:end", {
6899
+ plugin,
6900
+ duration,
6901
+ success: true,
6902
+ config,
6903
+ get files() {
6904
+ return driver.fileManager.files;
6905
+ },
6906
+ upsertFile: (...files2) => driver.fileManager.upsert(...files2)
6907
+ });
7028
6908
  }
7029
6909
  await hooks.emit("kubb:plugins:end", {
7030
6910
  config,
@@ -7091,22 +6971,6 @@ function getDiagnosticInfo() {
7091
6971
  function isInputPath(config) {
7092
6972
  return typeof (config == null ? void 0 : config.input) === "object" && config.input !== null && "path" in config.input;
7093
6973
  }
7094
- function inputToAdapterSource(config) {
7095
- const input = config.input;
7096
- if (!input) throw new Error("[kubb] input is required when using an adapter. Provide input.path or input.data in your config.");
7097
- if ("data" in input) return {
7098
- type: "data",
7099
- data: input.data
7100
- };
7101
- if (new URLPath(input.path).isURL) return {
7102
- type: "path",
7103
- path: input.path
7104
- };
7105
- return {
7106
- type: "path",
7107
- path: resolve(config.root, input.path)
7108
- };
7109
- }
7110
6974
  function createKubb(userConfig, options = {}) {
7111
6975
  var _a2;
7112
6976
  const hooks = (_a2 = options.hooks) != null ? _a2 : new AsyncEventEmitter();
@@ -7172,7 +7036,7 @@ const memoryStorage = createStorage(() => {
7172
7036
  };
7173
7037
  });
7174
7038
 
7175
- var version = "5.0.0-beta.19";
7039
+ var version = "5.0.0-beta.20";
7176
7040
 
7177
7041
  function isCommandMessage(msg) {
7178
7042
  return msg.type === "command";