@dudousxd/nestjs-codegen 0.26.0 → 0.27.1

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/cli/main.js CHANGED
@@ -83,12 +83,33 @@ function validateUserConfig(userConfig) {
83
83
  "validation adapter is required \u2014 install @dudousxd/nestjs-codegen-zod and pass zodAdapter, or use @dudousxd/nestjs-codegen-valibot / -arktype"
84
84
  );
85
85
  }
86
- if (userConfig.pages && typeof userConfig.pages.glob !== "string") {
86
+ if (userConfig.pages && !isGlobInput(userConfig.pages.glob)) {
87
87
  throw new ConfigError(
88
- "Config validation failed: `pages.glob` must be a string when `pages` is set"
88
+ "Config validation failed: `pages.glob` must be a string or a non-empty array of strings when `pages` is set"
89
+ );
90
+ }
91
+ for (const [scope, scopeConfig] of Object.entries(userConfig.pages?.scopes ?? {})) {
92
+ if (scope === "default") {
93
+ throw new ConfigError(
94
+ 'Config validation failed: `pages.scopes` cannot declare "default" \u2014 the default app is `pages.glob` (InertiaModule.forRoot).'
95
+ );
96
+ }
97
+ if (!isGlobInput(scopeConfig?.glob)) {
98
+ throw new ConfigError(
99
+ `Config validation failed: \`pages.scopes.${scope}.glob\` must be a string or a non-empty array of strings`
100
+ );
101
+ }
102
+ }
103
+ if (userConfig.scopes && Object.keys(userConfig.scopes).length > 0) {
104
+ console.warn(
105
+ "[nestjs-codegen] The top-level `scopes` option has no effect and is deprecated. For several Inertia apps use `pages.scopes` (one entry per InertiaModule.forFeature scope); for several controller sets use one `contracts.glob` (e.g. a brace glob)."
89
106
  );
90
107
  }
91
108
  }
109
+ function isGlobInput(value) {
110
+ if (typeof value === "string") return true;
111
+ return Array.isArray(value) && value.length > 0 && value.every((glob) => typeof glob === "string");
112
+ }
92
113
  function applyDefaults(userConfig, cwd) {
93
114
  validateUserConfig(userConfig);
94
115
  const outDir = userConfig.codegen?.outDir ? resolveAbsolute(cwd, userConfig.codegen.outDir) : join(cwd, ".nestjs-codegen");
@@ -115,7 +136,17 @@ function applyDefaults(userConfig, cwd) {
115
136
  pages: userConfig.pages ? {
116
137
  glob: userConfig.pages.glob,
117
138
  propsExport: userConfig.pages.propsExport ?? "ComponentProps",
118
- componentNameStrategy: userConfig.pages.componentNameStrategy ?? "relative-no-ext"
139
+ componentNameStrategy: userConfig.pages.componentNameStrategy ?? "relative-no-ext",
140
+ scopes: Object.fromEntries(
141
+ Object.entries(userConfig.pages.scopes ?? {}).map(([scope, scopeConfig]) => [
142
+ scope,
143
+ {
144
+ glob: scopeConfig.glob,
145
+ prefix: scopeConfig.prefix ?? `${scope}/`,
146
+ componentNameStrategy: scopeConfig.componentNameStrategy ?? userConfig.pages?.componentNameStrategy ?? "relative-no-ext"
147
+ }
148
+ ])
149
+ )
119
150
  } : null,
120
151
  contracts: {
121
152
  glob: userConfig.contracts?.glob ?? "src/**/*.controller.ts",
@@ -189,26 +220,84 @@ import { dirname as dirname4, join as join14 } from "path";
189
220
 
190
221
  // src/discovery/pages.ts
191
222
  import { readFile } from "fs/promises";
192
- import { join as join2, relative as relative2 } from "path";
223
+ import { join as join2, relative as relative2, sep as sep2 } from "path";
193
224
  import fg from "fast-glob";
194
225
  var NON_PAGE_FILE_RE = /\.(?:test|spec|stories|story)\.(?:tsx?|jsx?|vue|svelte)$/i;
226
+ var MAGIC_SEGMENT_RE = /[*?{}[\]()!]/;
227
+ function globStaticBase(glob) {
228
+ const segments = glob.split("/");
229
+ const staticSegments = [];
230
+ for (const segment of segments.slice(0, -1)) {
231
+ if (MAGIC_SEGMENT_RE.test(segment)) break;
232
+ staticSegments.push(segment);
233
+ }
234
+ return staticSegments.join("/");
235
+ }
195
236
  async function discoverPages(opts) {
196
- const allFiles = await fg(opts.glob, { cwd: opts.cwd, absolute: true });
197
- const files = allFiles.filter((f) => !NON_PAGE_FILE_RE.test(f));
198
- files.sort();
199
- const globStatic = opts.glob.split("*")[0]?.replace(/\/$/, "") ?? "";
200
- const pagesBase = join2(opts.cwd, globStatic);
237
+ const globs = typeof opts.glob === "string" ? [opts.glob] : opts.glob;
238
+ const prefix = opts.prefix ?? "";
239
+ const scope = opts.scope ?? "default";
240
+ const seenFiles = /* @__PURE__ */ new Set();
201
241
  const out = [];
202
- for (const file of files) {
203
- const rel = relative2(opts.cwd, file);
204
- const nameRel = relative2(pagesBase, file);
205
- const name = computeName(nameRel, opts.componentNameStrategy);
206
- const source = await readFile(file, "utf8");
207
- const propsSource = extractPropsSource(source, opts.propsExport);
208
- out.push({ name, absolutePath: file, relativePath: rel, propsSource });
242
+ for (const glob of globs) {
243
+ const files = (await fg(glob, { cwd: opts.cwd, absolute: true })).filter((f) => !NON_PAGE_FILE_RE.test(f) && !seenFiles.has(f)).sort();
244
+ const pagesBase = join2(opts.cwd, globStaticBase(glob));
245
+ for (const file of files) {
246
+ seenFiles.add(file);
247
+ const rel = relative2(opts.cwd, file);
248
+ const nameRel = relative2(pagesBase, file).split(sep2).join("/");
249
+ const name = `${prefix}${computeName(nameRel, opts.componentNameStrategy)}`;
250
+ const source = await readFile(file, "utf8");
251
+ const propsSource = extractPropsSource(source, opts.propsExport);
252
+ out.push({ name, absolutePath: file, relativePath: rel, propsSource, scope });
253
+ }
254
+ }
255
+ assertUniqueNames(out);
256
+ return out;
257
+ }
258
+ async function discoverPageScopes(config) {
259
+ const pages = config.pages;
260
+ if (!pages) return [];
261
+ const common = { cwd: config.codegen.cwd, propsExport: pages.propsExport };
262
+ const out = await discoverPages({
263
+ ...common,
264
+ glob: pages.glob,
265
+ componentNameStrategy: pages.componentNameStrategy
266
+ });
267
+ for (const [scope, scopeConfig] of Object.entries(pages.scopes ?? {})) {
268
+ out.push(
269
+ ...await discoverPages({
270
+ ...common,
271
+ glob: scopeConfig.glob,
272
+ componentNameStrategy: scopeConfig.componentNameStrategy,
273
+ prefix: scopeConfig.prefix,
274
+ scope
275
+ })
276
+ );
209
277
  }
278
+ assertUniqueNames(out);
210
279
  return out;
211
280
  }
281
+ function allPageGlobs(config) {
282
+ if (!config.pages) return [];
283
+ const asList = (glob) => typeof glob === "string" ? [glob] : glob;
284
+ return [
285
+ ...asList(config.pages.glob),
286
+ ...Object.values(config.pages.scopes ?? {}).flatMap((scope) => asList(scope.glob))
287
+ ];
288
+ }
289
+ function assertUniqueNames(pages) {
290
+ const byName = /* @__PURE__ */ new Map();
291
+ for (const page of pages) {
292
+ const previous = byName.get(page.name);
293
+ if (previous) {
294
+ throw new Error(
295
+ `Two Inertia pages resolve to the component name "${page.name}": ${previous.relativePath} (scope "${previous.scope}") and ${page.relativePath} (scope "${page.scope}"). Give one of them another name, directory or scope prefix.`
296
+ );
297
+ }
298
+ byName.set(page.name, page);
299
+ }
300
+ }
212
301
  function computeName(rel, strat) {
213
302
  if (typeof strat === "function") return strat(rel);
214
303
  const noExt = rel.replace(/\.(tsx?|vue|svelte)$/, "");
@@ -631,10 +720,11 @@ function resolveModuleSpecifier(moduleSpecifier, sourceFile, project) {
631
720
  }
632
721
  return [];
633
722
  }
634
- function resolveImportedType(name, sourceFile, project) {
723
+ function resolveImportedType(name, sourceFile, project, seen = /* @__PURE__ */ new Set()) {
635
724
  for (const importDecl of sourceFile.getImportDeclarations()) {
636
- const namedImport = importDecl.getNamedImports().find((n) => n.getName() === name);
725
+ const namedImport = importDecl.getNamedImports().find((n) => (n.getAliasNode()?.getText() ?? n.getName()) === name);
637
726
  if (!namedImport) continue;
727
+ const sourceName = namedImport.getName();
638
728
  const moduleSpecifier = importDecl.getModuleSpecifierValue();
639
729
  const candidates = resolveModuleSpecifier(moduleSpecifier, sourceFile, project);
640
730
  for (const candidate of candidates) {
@@ -646,17 +736,17 @@ function resolveImportedType(name, sourceFile, project) {
646
736
  continue;
647
737
  }
648
738
  }
649
- const result = findTypeInFile(name, importedFile);
739
+ const result = findTypeInFile(sourceName, importedFile);
650
740
  if (result) return result;
651
- const viaReExport = resolveReExportedType(name, importedFile, project, /* @__PURE__ */ new Set());
741
+ const viaReExport = resolveReExportedType(sourceName, importedFile, project, /* @__PURE__ */ new Set());
652
742
  if (viaReExport) return viaReExport;
653
743
  }
654
744
  if (candidates.length === 0) {
655
- const viaCompiler = resolveBareSpecifierType(name, importDecl, project);
745
+ const viaCompiler = resolveBareSpecifierType(sourceName, importDecl, project);
656
746
  if (viaCompiler) return viaCompiler;
657
747
  }
658
748
  }
659
- return resolveReExportedType(name, sourceFile, project, /* @__PURE__ */ new Set());
749
+ return resolveReExportedType(name, sourceFile, project, seen);
660
750
  }
661
751
  function resolveBareSpecifierType(name, importDecl, project) {
662
752
  let target;
@@ -671,9 +761,9 @@ function resolveBareSpecifierType(name, importDecl, project) {
671
761
  return resolveReExportedType(name, target, project, /* @__PURE__ */ new Set());
672
762
  }
673
763
  function resolveReExportedType(name, file, project, seen) {
674
- const filePath = file.getFilePath();
675
- if (seen.has(filePath)) return null;
676
- seen.add(filePath);
764
+ const visit = `${file.getFilePath()}#${name}`;
765
+ if (seen.has(visit)) return null;
766
+ seen.add(visit);
677
767
  for (const exportDecl of file.getExportDeclarations()) {
678
768
  const moduleSpecifier = exportDecl.getModuleSpecifierValue();
679
769
  const namedExports = exportDecl.getNamedExports();
@@ -695,7 +785,7 @@ function resolveReExportedType(name, file, project, seen) {
695
785
  const sourceName = namedExports.find((n) => (n.getAliasNode()?.getText() ?? n.getName()) === name)?.getName() ?? name;
696
786
  const local = findTypeInFile(sourceName, file);
697
787
  if (local) return local;
698
- const imported = resolveImportedType(sourceName, file, project);
788
+ const imported = resolveImportedType(sourceName, file, project, seen);
699
789
  if (imported) return imported;
700
790
  }
701
791
  return null;
@@ -4097,28 +4187,28 @@ function renderFetcherRequest(req, binaryResponse) {
4097
4187
  }
4098
4188
  function emitReqHelper() {
4099
4189
  return [
4100
- "/** Awaitable request handle. `await api.x.y({...})` runs the fetch; extensions add query/mutation helpers. */",
4101
- "type __Req<R> = {",
4102
- " then<T1 = R, T2 = never>(",
4190
+ "/** An awaitable request handle: a lazy, memoized `Promise` that also carries `fetch()` and the members extensions add. */",
4191
+ "export type RequestHandle<R, M = {}> = Promise<R> & { fetch(): Promise<R> } & M;",
4192
+ "class __Request<R> extends Promise<R> {",
4193
+ " static override get [Symbol.species](): PromiseConstructor {",
4194
+ " return Promise;",
4195
+ " }",
4196
+ " private __run: () => Promise<R>;",
4197
+ " private __p: Promise<R> | undefined;",
4198
+ " constructor(run: () => Promise<R>) {",
4199
+ " super(() => {});",
4200
+ " this.__run = run;",
4201
+ " }",
4202
+ " override then<T1 = R, T2 = never>(",
4103
4203
  " onfulfilled?: ((value: R) => T1 | PromiseLike<T1>) | null,",
4104
4204
  " onrejected?: ((reason: unknown) => T2 | PromiseLike<T2>) | null,",
4105
- " ): Promise<T1 | T2>;",
4106
- " catch<T = never>(onrejected?: ((reason: unknown) => T | PromiseLike<T>) | null): Promise<R | T>;",
4107
- " finally(onfinally?: (() => void) | null): Promise<R>;",
4108
- " fetch(): Promise<R>;",
4109
- "};",
4110
- "function __req<R>(run: () => Promise<R>): __Req<R> {",
4111
- " let __p: Promise<R> | undefined;",
4112
- " const __promise = () => {",
4113
- " __p ??= run();",
4114
- " return __p;",
4115
- " };",
4116
- " return {",
4117
- " then: (onfulfilled, onrejected) => __promise().then(onfulfilled, onrejected),",
4118
- " catch: (onrejected) => __promise().catch(onrejected),",
4119
- " finally: (onfinally) => __promise().finally(onfinally),",
4120
- " fetch: run,",
4121
- " };",
4205
+ " ): Promise<T1 | T2> {",
4206
+ " this.__p ??= this.__run();",
4207
+ " return this.__p.then(onfulfilled, onrejected);",
4208
+ " }",
4209
+ "}",
4210
+ "function __req<R, M extends object = {}>(run: () => Promise<R>, members?: M): RequestHandle<R, M> {",
4211
+ " return Object.assign(new __Request<R>(run), { fetch: run }, members) as RequestHandle<R, M>;",
4122
4212
  "}",
4123
4213
  ""
4124
4214
  ];
@@ -4136,18 +4226,26 @@ function emitFilterFieldGuard() {
4136
4226
  ];
4137
4227
  }
4138
4228
  function renderLeaf(pad, objKey, req, requestExpr, members, streamExpr) {
4139
- const lines = [`${pad}${objKey}: (input?: ${req.inputType}) => ({`];
4140
- lines.push(`${pad} ...__req<${req.responseType}>(() => ${requestExpr}),`);
4229
+ const memberLines = [];
4141
4230
  if (req.filterFieldsExpr) {
4142
- lines.push(`${pad} filterFields: ${req.filterFieldsExpr},`);
4231
+ memberLines.push(`${pad} filterFields: ${req.filterFieldsExpr},`);
4143
4232
  }
4144
4233
  if (streamExpr) {
4145
- lines.push(`${pad} stream: () => ${streamExpr},`);
4234
+ memberLines.push(`${pad} stream: () => ${streamExpr},`);
4146
4235
  }
4147
4236
  for (const [name, value] of Object.entries(members)) {
4148
- lines.push(`${pad} ${name}: ${value},`);
4149
- }
4150
- lines.push(`${pad}}),`);
4237
+ memberLines.push(`${pad} ${name}: ${value},`);
4238
+ }
4239
+ const body = [requestExpr, ...memberLines].join("\n");
4240
+ const param = /\binput\b/.test(body) ? `input?: ${req.inputType}` : "";
4241
+ const lines = [`${pad}${objKey}: (${param}) =>`];
4242
+ if (memberLines.length === 0) {
4243
+ lines.push(`${pad} __req<${req.responseType}>(() => ${requestExpr}),`);
4244
+ return lines;
4245
+ }
4246
+ lines.push(`${pad} __req(() => ${requestExpr}, {`);
4247
+ lines.push(...memberLines);
4248
+ lines.push(`${pad} }),`);
4151
4249
  return lines;
4152
4250
  }
4153
4251
  function renderStreamExpr(req) {
@@ -4281,6 +4379,23 @@ var EMPTY_PATH_NAMESPACE = [
4281
4379
  function isClientCallable(route) {
4282
4380
  return route.method.toUpperCase() !== "ALL";
4283
4381
  }
4382
+ var ROUTES_IMPORT_PLACEHOLDER = "/* @@routes-import@@ */";
4383
+ var ROUTES_EXPORTS = [
4384
+ // Called, never mentioned in prose: match the call so a comment saying "route" doesn't count.
4385
+ { name: "route", typeOnly: false },
4386
+ { name: "ROUTES", typeOnly: false },
4387
+ { name: "RouteName", typeOnly: true },
4388
+ { name: "ExtractParams", typeOnly: true },
4389
+ { name: "RouteParams", typeOnly: true }
4390
+ ];
4391
+ function finishRoutesImport(lines) {
4392
+ const body = lines.filter((l) => l !== ROUTES_IMPORT_PLACEHOLDER).join("\n");
4393
+ const used = ROUTES_EXPORTS.filter(
4394
+ ({ name }) => new RegExp(name === "route" ? "\\broute\\(" : `\\b${name}\\b`).test(body)
4395
+ ).map(({ name, typeOnly }) => typeOnly ? `type ${name}` : name);
4396
+ const importLine = used.length ? `import { ${used.join(", ")} } from './routes.js';` : null;
4397
+ return lines.flatMap((l) => l === ROUTES_IMPORT_PLACEHOLDER ? importLine ? [importLine] : [] : [l]).join("\n");
4398
+ }
4284
4399
  function buildApiFile(routes, outDir, opts = {}) {
4285
4400
  const fetcherImportPath = opts.fetcherImportPath;
4286
4401
  const serialization = opts.serialization ?? "json";
@@ -4340,9 +4455,7 @@ function buildApiFile(routes, outDir, opts = {}) {
4340
4455
  for (const imp of ext.apiHeader?.(ctx)?.imports ?? []) pushImport(imp);
4341
4456
  }
4342
4457
  lines.push(...extImports);
4343
- lines.push(
4344
- "import { route, ROUTES, type RouteName, type ExtractParams, type RouteParams } from './routes.js';"
4345
- );
4458
+ lines.push(ROUTES_IMPORT_PLACEHOLDER);
4346
4459
  const runtimeImport = fetcherImportPath ?? "@dudousxd/nestjs-client";
4347
4460
  lines.push(`import type { Fetcher } from '${runtimeImport}';`);
4348
4461
  if (serialization === "json" && contracted.length > 0) {
@@ -4393,7 +4506,7 @@ function buildApiFile(routes, outDir, opts = {}) {
4393
4506
  lines.push(...statements, "");
4394
4507
  }
4395
4508
  }
4396
- return lines.join("\n");
4509
+ return finishRoutesImport(lines);
4397
4510
  }
4398
4511
  const tree = /* @__PURE__ */ new Map();
4399
4512
  for (const r of contracted) {
@@ -4446,7 +4559,7 @@ function buildApiFile(routes, outDir, opts = {}) {
4446
4559
  lines.push(...statements, "");
4447
4560
  }
4448
4561
  }
4449
- return lines.join("\n");
4562
+ return finishRoutesImport(lines);
4450
4563
  }
4451
4564
 
4452
4565
  // src/emit/emit-cache.ts
@@ -4459,6 +4572,7 @@ async function emitCache(pages, outDir) {
4459
4572
  const s = await stat(p.absolutePath);
4460
4573
  return {
4461
4574
  name: p.name,
4575
+ scope: p.scope ?? "default",
4462
4576
  relativePath: p.relativePath,
4463
4577
  mtime: s.mtime.toISOString()
4464
4578
  };
@@ -5250,10 +5364,11 @@ async function emitPages(pages, outDir, _options = {}) {
5250
5364
  }).join("\n");
5251
5365
  const propsHelper = "\nexport type InertiaProps<K extends InertiaPageName> = import('@dudousxd/nestjs-inertia').InertiaPages[K];\n";
5252
5366
  const sharedPropsBlock = buildSharedPropsBlock(_options.sharedProps ?? null);
5367
+ const scopesBlock = buildScopesBlock(pages);
5253
5368
  const content = `// Generated by @dudousxd/nestjs-codegen. Do not edit.
5254
5369
 
5255
5370
  export type InertiaPageName = ${pageNameUnion};
5256
- ${propsHelper}
5371
+ ${propsHelper}${scopesBlock}
5257
5372
  declare module '@dudousxd/nestjs-inertia' {
5258
5373
  interface InertiaPages {
5259
5374
  ${augBody}
@@ -5262,6 +5377,31 @@ ${sharedPropsBlock}}
5262
5377
  `;
5263
5378
  await writeFile7(join11(outDir, "pages.d.ts"), content, "utf8");
5264
5379
  }
5380
+ function buildScopesBlock(pages) {
5381
+ const byScope = /* @__PURE__ */ new Map();
5382
+ for (const page of pages) {
5383
+ const scope = page.scope ?? "default";
5384
+ const names = byScope.get(scope) ?? [];
5385
+ names.push(JSON.stringify(page.name));
5386
+ byScope.set(scope, names);
5387
+ }
5388
+ if (![...byScope.keys()].some((scope) => scope !== "default")) return "";
5389
+ if (!byScope.has("default")) byScope.set("default", []);
5390
+ const scopes = ["default", ...[...byScope.keys()].filter((s) => s !== "default")];
5391
+ const body = scopes.map((scope) => {
5392
+ const key = needsQuotes(scope) ? JSON.stringify(scope) : scope;
5393
+ const names = byScope.get(scope) ?? [];
5394
+ return ` ${key}: ${names.length ? names.join(" | ") : "never"};`;
5395
+ }).join("\n");
5396
+ return `
5397
+ /** The page names of each Inertia app: \`default\` (forRoot) and every \`pages.scopes\` entry. */
5398
+ export interface InertiaScopePages {
5399
+ ${body}
5400
+ }
5401
+
5402
+ export type InertiaScopePageName<S extends keyof InertiaScopePages> = InertiaScopePages[S];
5403
+ `;
5404
+ }
5265
5405
  function buildSharedPropsBlock(sharedProps) {
5266
5406
  if (!sharedProps) return "";
5267
5407
  if (sharedProps.isImportRef) {
@@ -5469,8 +5609,7 @@ function diffConfigKeyHashes(previous, current) {
5469
5609
  return [...keys].filter((key) => previous[key] !== current[key]).sort();
5470
5610
  }
5471
5611
  async function discoverInputFiles(config) {
5472
- const globs = [config.contracts.glob, config.forms.watch];
5473
- if (config.pages) globs.push(config.pages.glob);
5612
+ const globs = [config.contracts.glob, config.forms.watch, ...allPageGlobs(config)];
5474
5613
  const cwd = config.codegen.cwd;
5475
5614
  const matched = await fg3(globs, { cwd, absolute: true, onlyFiles: true });
5476
5615
  return [...new Set(matched)].sort();
@@ -5601,12 +5740,7 @@ async function generate(config, inputRoutes = [], entryPoint = "cli") {
5601
5740
  }
5602
5741
  if (config.pages) {
5603
5742
  const pagesConfig = config.pages;
5604
- const pages = await discoverPages({
5605
- glob: pagesConfig.glob,
5606
- cwd: config.codegen.cwd,
5607
- propsExport: pagesConfig.propsExport,
5608
- componentNameStrategy: pagesConfig.componentNameStrategy
5609
- });
5743
+ const pages = await discoverPageScopes(config);
5610
5744
  const sharedProps = discoverSharedPropsFromConfig(config);
5611
5745
  await emitPages(pages, config.codegen.outDir, {
5612
5746
  propsExport: pagesConfig.propsExport,
@@ -5781,12 +5915,17 @@ async function watch(config, onChange, options = {}) {
5781
5915
  await runInitialPass();
5782
5916
  }
5783
5917
  let pagesDebounceTimer;
5784
- const pagesGlob = config.pages?.glob ?? ".nestjs-codegen-no-pages";
5785
- const pagesWatcher = chokidar.watch(join16(config.codegen.cwd, pagesGlob), {
5786
- ignoreInitial: true,
5787
- persistent: true,
5788
- awaitWriteFinish: { stabilityThreshold: 80, pollInterval: 20 }
5789
- });
5918
+ const pageGlobs = allPageGlobs(config);
5919
+ const pagesWatcher = chokidar.watch(
5920
+ (pageGlobs.length ? pageGlobs : [".nestjs-codegen-no-pages"]).map(
5921
+ (glob) => join16(config.codegen.cwd, glob)
5922
+ ),
5923
+ {
5924
+ ignoreInitial: true,
5925
+ persistent: true,
5926
+ awaitWriteFinish: { stabilityThreshold: 80, pollInterval: 20 }
5927
+ }
5928
+ );
5790
5929
  function schedulePagesRegenerate() {
5791
5930
  if (pagesDebounceTimer !== void 0) {
5792
5931
  clearTimeout(pagesDebounceTimer);
@@ -5866,7 +6005,7 @@ async function watch(config, onChange, options = {}) {
5866
6005
  }
5867
6006
 
5868
6007
  // src/index.ts
5869
- var VERSION = "0.26.0";
6008
+ var VERSION = "0.27.1";
5870
6009
 
5871
6010
  // src/cli/codegen.ts
5872
6011
  async function runCodegen(opts = {}) {