@kubb/core 5.0.0-beta.86 → 5.0.0-beta.88

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as __name } from "./rolldown-runtime-C0LytTxp.js";
2
- import { $ as Include, A as KubbHookStartContext, At as UserReporter, B as Kubb, C as KubbFilesProcessingEndContext, Ct as createRenderer, D as KubbGenerationStartContext, Dt as Reporter, E as KubbGenerationEndContext, Et as GenerationResult, F as KubbSuccessContext, Ft as AdapterSource, G as KubbDriver, H as Generator, I as KubbWarnContext, It as createAdapter, J as Parser, K as FileManagerHooks, L as PossibleConfig, M as KubbInfoContext, Mt as logLevel, N as KubbLifecycleStartContext, Nt as Adapter, O as KubbHookEndContext, Ot as ReporterContext, P as KubbPluginsEndContext, Pt as AdapterFactoryOptions, Q as Group, R as UserConfig, S as KubbFileProcessingUpdate, St as RendererFactory, T as KubbFilesProcessingUpdateContext, Tt as createStorage, U as GeneratorContext, V as createKubb, W as defineGenerator, X as Exclude, Y as defineParser, Z as Filter, _ as InputPath, _t as ResolverDefault, a as DiagnosticLocation, at as OutputMode, b as KubbDiagnosticContext, bt as ResolverPathParams, c as PerformanceDiagnostic, ct as Plugin, d as SerializedDiagnostic, dt as BannerMeta, et as KubbPluginEndContext, f as UpdateDiagnostic, ft as ResolveBannerContext, g as InputData, gt as ResolverContext, h as Config, ht as Resolver, i as DiagnosticKind, it as Output, j as KubbHooks, jt as createReporter, k as KubbHookLineContext, kt as ReporterName, l as ProblemCode, lt as PluginFactoryOptions, m as CLIOptions, mt as ResolveOptionsContext, n as DiagnosticByCode, nt as KubbPluginStartContext, o as DiagnosticSeverity, ot as OutputOptions, p as BuildOutput, pt as ResolveBannerFile, q as Hookable, r as DiagnosticDoc, rt as NormalizedPlugin, s as Diagnostics, st as Override, t as Diagnostic, tt as KubbPluginSetupContext, u as ProblemDiagnostic, ut as definePlugin, v as KubbBuildEndContext, vt as ResolverFileParams, w as KubbFilesProcessingStartContext, wt as Storage, x as KubbErrorContext, xt as Renderer, y as KubbBuildStartContext, yt as ResolverPatch, z as CreateKubbOptions } from "./Diagnostics-aWJg-H2d.js";
2
+ import { $ as Include, A as KubbHookStartContext, At as Reporter, B as Kubb, C as KubbFilesProcessingEndContext, Ct as ResolverPathParams, D as KubbGenerationStartContext, Dt as Storage, E as KubbGenerationEndContext, Et as createRenderer, F as KubbSuccessContext, Ft as logLevel, G as KubbDriver, H as Generator, I as KubbWarnContext, It as Adapter, J as Parser, K as FileManagerHooks, L as PossibleConfig, Lt as AdapterFactoryOptions, M as KubbInfoContext, Mt as ReporterName, N as KubbLifecycleStartContext, Nt as UserReporter, O as KubbHookEndContext, Ot as createStorage, P as KubbPluginsEndContext, Pt as createReporter, Q as Group, R as UserConfig, Rt as AdapterSource, S as KubbFileProcessingUpdate, St as ResolverPatch, T as KubbFilesProcessingUpdateContext, Tt as RendererFactory, U as GeneratorContext, V as createKubb, W as defineGenerator, X as Exclude, Y as defineParser, Z as Filter, _ as InputPath, _t as Resolver, a as DiagnosticLocation, at as OutputMode, b as KubbDiagnosticContext, bt as ResolverFileParams, c as PerformanceDiagnostic, ct as Plugin, d as SerializedDiagnostic, dt as BannerMeta, et as KubbPluginEndContext, f as UpdateDiagnostic, ft as ResolveBannerContext, g as InputData, gt as ResolvePathOptions, h as Config, ht as ResolveOptionsContext, i as DiagnosticKind, it as Output, j as KubbHooks, jt as ReporterContext, k as KubbHookLineContext, kt as GenerationResult, l as ProblemCode, lt as PluginFactoryOptions, m as CLIOptions, mt as ResolveFileOptions, n as DiagnosticByCode, nt as KubbPluginStartContext, o as DiagnosticSeverity, ot as OutputOptions, p as BuildOutput, pt as ResolveBannerFile, q as Hookable, r as DiagnosticDoc, rt as NormalizedPlugin, s as Diagnostics, st as Override, t as Diagnostic, tt as KubbPluginSetupContext, u as ProblemDiagnostic, ut as definePlugin, v as KubbBuildEndContext, vt as ResolverDefault, w as KubbFilesProcessingStartContext, wt as Renderer, x as KubbErrorContext, xt as ResolverFilePathParams, y as KubbBuildStartContext, yt as ResolverFile, z as CreateKubbOptions, zt as createAdapter } from "./Diagnostics-C2HF9H7A.js";
3
3
 
4
4
  //#region src/reporters/cliReporter.d.ts
5
5
  /**
@@ -40,7 +40,7 @@ declare const jsonReporter: Reporter;
40
40
  type ResolverOptions<T extends PluginFactoryOptions> = Omit<T['resolver'], keyof Resolver> & {
41
41
  pluginName: T['name'];
42
42
  name?: T['resolver']['name'];
43
- file?: T['resolver']['file'];
43
+ file?: ResolverFile;
44
44
  } & ThisType<T['resolver']>;
45
45
  /**
46
46
  * Defines a plugin resolver, the object that decides what every generated symbol and file
@@ -49,15 +49,39 @@ type ResolverOptions<T extends PluginFactoryOptions> = Omit<T['resolver'], keyof
49
49
  * (`query`, `schema`, …). Every method reaches sibling helpers and the built-in machinery
50
50
  * through `this.name`, `this.file`, and `this.default`.
51
51
  *
52
- * @example Custom identifier and file casing
52
+ * @example Custom identifier casing
53
53
  * ```ts
54
54
  * export const resolverTs = createResolver<PluginTs>({
55
55
  * pluginName: 'plugin-ts',
56
56
  * name(name) {
57
57
  * return ensureValidVarName(pascalCase(name))
58
58
  * },
59
- * file(params, context) {
60
- * return this.default.file({ ...params, resolveName: (name) => toFilePath(name, pascalCase) }, context)
59
+ * })
60
+ * ```
61
+ *
62
+ * @example Rename generated files with `file.baseName`
63
+ * ```ts
64
+ * export const resolverFaker = createResolver<PluginFaker>({
65
+ * pluginName: 'plugin-faker',
66
+ * name(name) {
67
+ * return camelCase(name, { prefix: 'create' })
68
+ * },
69
+ * file: {
70
+ * baseName({ name, extname }) {
71
+ * return `${camelCase(name, { prefix: 'create' })}${extname}`
72
+ * },
73
+ * },
74
+ * })
75
+ * ```
76
+ *
77
+ * @example Own the full path with `file.path`
78
+ * ```ts
79
+ * export const resolverFaker = createResolver<PluginFaker>({
80
+ * pluginName: 'plugin-faker',
81
+ * file: {
82
+ * path({ baseName, output }) {
83
+ * return `${output.path}/mocks/${baseName}`
84
+ * },
61
85
  * },
62
86
  * })
63
87
  * ```
@@ -116,5 +140,5 @@ declare const fsStorage: (options?: Record<string, never> | undefined) => Storag
116
140
  */
117
141
  declare const memoryStorage: (options?: Record<string, never> | undefined) => Storage;
118
142
  //#endregion
119
- export { type Adapter, type AdapterFactoryOptions, type AdapterSource, type BannerMeta, BuildOutput, CLIOptions, Config, type CreateKubbOptions, type Diagnostic, type DiagnosticByCode, type DiagnosticDoc, type DiagnosticKind, type DiagnosticLocation, type DiagnosticSeverity, Diagnostics, type Exclude, type FileManagerHooks, type Filter, type GenerationResult, type Generator, type GeneratorContext, type Group, Hookable, type Include, InputData, InputPath, type Kubb, KubbBuildEndContext, KubbBuildStartContext, KubbDiagnosticContext, KubbDriver, KubbErrorContext, KubbFileProcessingUpdate, KubbFilesProcessingEndContext, KubbFilesProcessingStartContext, KubbFilesProcessingUpdateContext, KubbGenerationEndContext, KubbGenerationStartContext, KubbHookEndContext, KubbHookLineContext, KubbHookStartContext, KubbHooks, KubbInfoContext, KubbLifecycleStartContext, type KubbPluginEndContext, type KubbPluginSetupContext, type KubbPluginStartContext, KubbPluginsEndContext, KubbSuccessContext, KubbWarnContext, type NormalizedPlugin, type Output, type OutputMode, type OutputOptions, type Override, type Parser, type PerformanceDiagnostic, type Plugin, type PluginFactoryOptions, PossibleConfig, type ProblemCode, type ProblemDiagnostic, type Renderer, type RendererFactory, type Reporter, type ReporterContext, type ReporterName, type ResolveBannerContext, type ResolveBannerFile, type ResolveOptionsContext, Resolver, type ResolverContext, type ResolverDefault, type ResolverFileParams, type ResolverPatch, type ResolverPathParams, type SerializedDiagnostic, type Storage, type UpdateDiagnostic, UserConfig, type UserReporter, cliReporter, createAdapter, createKubb, createRenderer, createReporter, createResolver, createStorage, defineGenerator, defineParser, definePlugin, fileReporter, fsStorage, jsonReporter, logLevel, memoryStorage };
143
+ export { type Adapter, type AdapterFactoryOptions, type AdapterSource, type BannerMeta, BuildOutput, CLIOptions, Config, type CreateKubbOptions, type Diagnostic, type DiagnosticByCode, type DiagnosticDoc, type DiagnosticKind, type DiagnosticLocation, type DiagnosticSeverity, Diagnostics, type Exclude, type FileManagerHooks, type Filter, type GenerationResult, type Generator, type GeneratorContext, type Group, Hookable, type Include, InputData, InputPath, type Kubb, KubbBuildEndContext, KubbBuildStartContext, KubbDiagnosticContext, KubbDriver, KubbErrorContext, KubbFileProcessingUpdate, KubbFilesProcessingEndContext, KubbFilesProcessingStartContext, KubbFilesProcessingUpdateContext, KubbGenerationEndContext, KubbGenerationStartContext, KubbHookEndContext, KubbHookLineContext, KubbHookStartContext, KubbHooks, KubbInfoContext, KubbLifecycleStartContext, type KubbPluginEndContext, type KubbPluginSetupContext, type KubbPluginStartContext, KubbPluginsEndContext, KubbSuccessContext, KubbWarnContext, type NormalizedPlugin, type Output, type OutputMode, type OutputOptions, type Override, type Parser, type PerformanceDiagnostic, type Plugin, type PluginFactoryOptions, PossibleConfig, type ProblemCode, type ProblemDiagnostic, type Renderer, type RendererFactory, type Reporter, type ReporterContext, type ReporterName, type ResolveBannerContext, type ResolveBannerFile, type ResolveFileOptions, type ResolveOptionsContext, type ResolvePathOptions, Resolver, type ResolverDefault, type ResolverFile, type ResolverFileParams, type ResolverFilePathParams, type ResolverPatch, type ResolverPathParams, type SerializedDiagnostic, type Storage, type UpdateDiagnostic, UserConfig, type UserReporter, cliReporter, createAdapter, createKubb, createRenderer, createReporter, createResolver, createStorage, defineGenerator, defineParser, definePlugin, fileReporter, fsStorage, jsonReporter, logLevel, memoryStorage };
120
144
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -170,7 +170,7 @@ function memoize(store, factory) {
170
170
  }
171
171
  //#endregion
172
172
  //#region package.json
173
- var version = "5.0.0-beta.86";
173
+ var version = "5.0.0-beta.88";
174
174
  //#endregion
175
175
  //#region src/constants.ts
176
176
  /**
@@ -745,6 +745,12 @@ function isNamespace(value) {
745
745
  return typeof value === "object" && value !== null && !Array.isArray(value);
746
746
  }
747
747
  /**
748
+ * Built-in `file.baseName`: casts the identifier with `toFilePath` and appends the extension.
749
+ */
750
+ function toBaseName({ name, extname }) {
751
+ return `${toFilePath(name)}${extname}`;
752
+ }
753
+ /**
748
754
  * Base constraint for all plugin resolver objects.
749
755
  *
750
756
  * The built-in machinery lives under `default`. Generators call the top-level `name` and
@@ -773,9 +779,13 @@ var Resolver = class Resolver {
773
779
  static #optionsCache = /* @__PURE__ */ new WeakMap();
774
780
  pluginName;
775
781
  #options;
782
+ #baseName;
783
+ #filePath;
776
784
  constructor(options) {
777
785
  this.pluginName = options.pluginName;
778
786
  this.#options = options;
787
+ this.#baseName = options.file?.baseName ? options.file.baseName.bind(this) : toBaseName;
788
+ this.#filePath = options.file?.path ? options.file.path.bind(this) : void 0;
779
789
  this.#apply(options);
780
790
  }
781
791
  /**
@@ -795,19 +805,26 @@ var Resolver = class Resolver {
795
805
  name(name) {
796
806
  return this.default.name(name);
797
807
  }
798
- file(params, context) {
799
- return this.default.file(params, context);
808
+ file(options) {
809
+ return this.#resolveFile(options);
800
810
  }
801
811
  /**
802
- * Merges `override` over `base` and returns a new resolver with helpers re-bound.
803
- * Each key is replaced wholesale. Used when applying `setResolver` partial overrides.
812
+ * Merges `override` over `base` and returns a new resolver with helpers re-bound. Top-level
813
+ * keys replace, and a namespace (or `file`) merges per method, so overriding `query.name`
814
+ * keeps the base `query.keyName`. Used when applying `setResolver` partial overrides.
804
815
  */
805
816
  static merge(base, override) {
806
817
  const patch = override instanceof Resolver ? override.#options : override;
807
- return new Resolver({
808
- ...base.#options,
809
- ...patch
810
- });
818
+ const merged = { ...base.#options };
819
+ for (const [key, value] of Object.entries(patch)) {
820
+ if (value === void 0) continue;
821
+ const current = merged[key];
822
+ merged[key] = isNamespace(value) && isNamespace(current) ? {
823
+ ...current,
824
+ ...value
825
+ } : value;
826
+ }
827
+ return new Resolver(merged);
811
828
  }
812
829
  /**
813
830
  * Binds each entry of `options` onto the resolver, so `this.name`, `this.default`, and
@@ -818,7 +835,7 @@ var Resolver = class Resolver {
818
835
  const root = this;
819
836
  const bind = (value) => typeof value === "function" ? value.bind(root) : value;
820
837
  for (const [key, value] of Object.entries(options)) {
821
- if (key === "pluginName" || key === "default" || value === void 0) continue;
838
+ if (key === "pluginName" || key === "default" || key === "file" || value === void 0) continue;
822
839
  root[key] = isNamespace(value) ? Object.fromEntries(Object.entries(value).map(([method, member]) => [method, bind(member)])) : bind(value);
823
840
  }
824
841
  }
@@ -903,7 +920,7 @@ var Resolver = class Resolver {
903
920
  * to `output.path/{baseName}`, or into a subdirectory when `group` and a `tag`/`path` value
904
921
  * are provided.
905
922
  */
906
- #resolvePath({ baseName, tag, path: groupPath }, { root, output, group }) {
923
+ #resolvePath({ baseName, tag, path: groupPath, root, output, group }) {
907
924
  if (output.mode === "file") return path.resolve(root, output.path);
908
925
  const outputDir = path.resolve(root, output.path);
909
926
  const result = group && (groupPath || tag) ? path.resolve(outputDir, Resolver.#resolveGroupDir(group, group.type === "path" ? groupPath : tag), baseName) : path.resolve(outputDir, baseName);
@@ -918,17 +935,45 @@ var Resolver = class Resolver {
918
935
  return result;
919
936
  }
920
937
  /**
921
- * Builds a `FileNode` by combining file-name casing (`params.resolveName`) with path
922
- * resolution. The resolved file starts with empty `sources`, `imports`, and `exports`,
923
- * which consumers populate separately.
938
+ * Resolves a resolver-supplied full path (`file.path`) against `root`, bypassing `output.path`
939
+ * and `group`. The path may not escape `root`, which keeps a `file.path` that interpolates
940
+ * spec-derived values from writing outside the project.
941
+ */
942
+ #resolveOverridePath(filePath, root) {
943
+ const resolved = path.resolve(root, filePath);
944
+ const rootWithSep = root.endsWith(path.sep) ? root : `${root}${path.sep}`;
945
+ if (resolved !== root && !resolved.startsWith(rootWithSep)) throw new Diagnostics.Error({
946
+ code: Diagnostics.code.pathTraversal,
947
+ severity: "error",
948
+ message: `Resolved path "${resolved}" is outside the project root "${root}".`,
949
+ help: "A resolver `file.path` must return a path inside the project root.",
950
+ location: { kind: "config" }
951
+ });
952
+ return resolved;
953
+ }
954
+ /**
955
+ * Builds a `FileNode`. When `#filePath` (the resolver's `file.path`) is set it owns the whole
956
+ * path; otherwise the base name (from `#baseName`, the resolver's `file.baseName` or the
957
+ * built-in `toBaseName`) is placed by the `output.path`/`group` layout. The resolved file starts
958
+ * with empty `sources`, `imports`, and `exports`, which consumers populate separately.
924
959
  */
925
- #resolveFile({ name, extname, tag, path: groupPath, resolveName = toFilePath }, context) {
926
- const resolvedName = context.output.mode === "file" ? "" : resolveName(name);
927
- const filePath = this.#resolvePath({
928
- baseName: `${resolvedName}${extname}`,
960
+ #resolveFile(options) {
961
+ const { name, extname, tag, path: groupPath, root, output, group } = options;
962
+ const baseName = this.#baseName({
963
+ name,
964
+ extname
965
+ });
966
+ const filePath = this.#filePath ? this.#resolveOverridePath(this.#filePath({
967
+ baseName,
968
+ output
969
+ }), root) : this.#resolvePath({
970
+ baseName,
929
971
  tag,
930
- path: groupPath
931
- }, context);
972
+ path: groupPath,
973
+ root,
974
+ output,
975
+ group
976
+ });
932
977
  return ast.factory.createFile({
933
978
  path: filePath,
934
979
  baseName: path.basename(filePath),
@@ -1005,15 +1050,39 @@ var Resolver = class Resolver {
1005
1050
  * (`query`, `schema`, …). Every method reaches sibling helpers and the built-in machinery
1006
1051
  * through `this.name`, `this.file`, and `this.default`.
1007
1052
  *
1008
- * @example Custom identifier and file casing
1053
+ * @example Custom identifier casing
1009
1054
  * ```ts
1010
1055
  * export const resolverTs = createResolver<PluginTs>({
1011
1056
  * pluginName: 'plugin-ts',
1012
1057
  * name(name) {
1013
1058
  * return ensureValidVarName(pascalCase(name))
1014
1059
  * },
1015
- * file(params, context) {
1016
- * return this.default.file({ ...params, resolveName: (name) => toFilePath(name, pascalCase) }, context)
1060
+ * })
1061
+ * ```
1062
+ *
1063
+ * @example Rename generated files with `file.baseName`
1064
+ * ```ts
1065
+ * export const resolverFaker = createResolver<PluginFaker>({
1066
+ * pluginName: 'plugin-faker',
1067
+ * name(name) {
1068
+ * return camelCase(name, { prefix: 'create' })
1069
+ * },
1070
+ * file: {
1071
+ * baseName({ name, extname }) {
1072
+ * return `${camelCase(name, { prefix: 'create' })}${extname}`
1073
+ * },
1074
+ * },
1075
+ * })
1076
+ * ```
1077
+ *
1078
+ * @example Own the full path with `file.path`
1079
+ * ```ts
1080
+ * export const resolverFaker = createResolver<PluginFaker>({
1081
+ * pluginName: 'plugin-faker',
1082
+ * file: {
1083
+ * path({ baseName, output }) {
1084
+ * return `${output.path}/mocks/${baseName}`
1085
+ * },
1017
1086
  * },
1018
1087
  * })
1019
1088
  * ```
@@ -1324,7 +1393,7 @@ var KubbDriver = class {
1324
1393
  * the failure as a {@link Diagnostic} instead of propagating. Each plugin also
1325
1394
  * contributes a `timing` diagnostic for the run summary.
1326
1395
  */
1327
- async run({ storage }) {
1396
+ async run() {
1328
1397
  const { hooks, config, fileManager } = this;
1329
1398
  const diagnostics = [];
1330
1399
  const parsersMap = /* @__PURE__ */ new Map();
@@ -1406,7 +1475,7 @@ var KubbDriver = class {
1406
1475
  diagnostics.push(...await this.#runGenerators(generatorPlugins));
1407
1476
  await hooks.callHook("kubb:plugins:end", Object.assign({ config }, this.#filesPayload()));
1408
1477
  await fileManager.write(fileManager.files, {
1409
- storage,
1478
+ storage: config.storage,
1410
1479
  parsers: parsersMap,
1411
1480
  extension: config.output.extension
1412
1481
  });
@@ -1974,7 +2043,7 @@ var Kubb = class {
1974
2043
  const self = _usingCtx$1.u(this);
1975
2044
  const driver = self.driver;
1976
2045
  const storage = self.storage;
1977
- const { diagnostics } = await driver.run({ storage });
2046
+ const { diagnostics } = await driver.run();
1978
2047
  return {
1979
2048
  diagnostics,
1980
2049
  files: driver.fileManager.files,