@dudousxd/nestjs-codegen 0.26.0 → 0.27.0
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/CHANGELOG.md +32 -0
- package/README.md +2 -2
- package/dist/cli/main.cjs +201 -63
- package/dist/cli/main.cjs.map +1 -1
- package/dist/cli/main.js +202 -64
- package/dist/cli/main.js.map +1 -1
- package/dist/extension/index.d.cts +1 -1
- package/dist/extension/index.d.ts +1 -1
- package/dist/{index-Bbw73Kkb.d.cts → index-Dc4s883u.d.cts} +41 -4
- package/dist/{index-Bbw73Kkb.d.ts → index-Dc4s883u.d.ts} +41 -4
- package/dist/index.cjs +201 -63
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +202 -64
- package/dist/index.js.map +1 -1
- package/dist/nest/index.cjs +205 -67
- package/dist/nest/index.cjs.map +1 -1
- package/dist/nest/index.d.cts +1 -1
- package/dist/nest/index.d.ts +1 -1
- package/dist/nest/index.js +206 -68
- package/dist/nest/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { U as UserConfig, R as ResolvedConfig, a as RouteDescriptor, S as SchemaNode, b as RenderContext, c as SchemaModule, d as RenderedModule, e as ResolvedFormsConfig, V as ValidationAdapter, C as CodegenExtension, E as ExtensionContext, f as SerializationMode } from './index-
|
|
2
|
-
export { A as AdapterUsage, g as ContractDescriptor, h as ContractSource, i as ControllerRef, N as NumberCheck, j as ScopeConfig, k as StringCheck, T as TypeRef, l as ValidationOption, r as resolveAdapter } from './index-
|
|
1
|
+
import { U as UserConfig, R as ResolvedConfig, a as RouteDescriptor, S as SchemaNode, b as RenderContext, c as SchemaModule, d as RenderedModule, e as ResolvedFormsConfig, V as ValidationAdapter, C as CodegenExtension, E as ExtensionContext, f as SerializationMode } from './index-Dc4s883u.cjs';
|
|
2
|
+
export { A as AdapterUsage, g as ContractDescriptor, h as ContractSource, i as ControllerRef, N as NumberCheck, j as ScopeConfig, k as StringCheck, T as TypeRef, l as ValidationOption, r as resolveAdapter } from './index-Dc4s883u.cjs';
|
|
3
3
|
import { ClassDeclaration, SourceFile, Project } from 'ts-morph';
|
|
4
4
|
|
|
5
5
|
declare function defineConfig(c: UserConfig): UserConfig;
|
|
@@ -382,6 +382,6 @@ interface FastDiscoveryOptions {
|
|
|
382
382
|
}
|
|
383
383
|
declare function discoverContractsFast(opts: FastDiscoveryOptions): Promise<RouteDescriptor[]>;
|
|
384
384
|
|
|
385
|
-
declare const VERSION = "0.
|
|
385
|
+
declare const VERSION = "0.27.0";
|
|
386
386
|
|
|
387
387
|
export { type ChainModuleRendererOptions, CodegenError, type CodegenManifest, ConfigError, DriftGuardError, type EntryPoint, type FastDiscoveryOptions, type JsonSchema, type MocksEmitOptions, type OpenApiDocument, type OpenApiEmitOptions, type OpenApiInfo, RenderContext, RenderedModule, ResolvedConfig, RouteDescriptor, SchemaModule, SchemaNode, type TsTypeContext, UserConfig, VERSION, ValidationAdapter, type WatchOptions, type Watcher, acquireLock, buildMocksFile, buildOpenApiSpec, createChainModuleRenderer, defineConfig, discoverContractsFast, emitApi, emitForms, emitMocks, emitOpenApi, emitRoutes, extractSchemaFromDto, generate, loadConfig, renderTsType, resolveConfig, schemaModuleToJsonSchema, schemaNodeToJsonSchema, toObjectKey, typeNameFor, watch };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { U as UserConfig, R as ResolvedConfig, a as RouteDescriptor, S as SchemaNode, b as RenderContext, c as SchemaModule, d as RenderedModule, e as ResolvedFormsConfig, V as ValidationAdapter, C as CodegenExtension, E as ExtensionContext, f as SerializationMode } from './index-
|
|
2
|
-
export { A as AdapterUsage, g as ContractDescriptor, h as ContractSource, i as ControllerRef, N as NumberCheck, j as ScopeConfig, k as StringCheck, T as TypeRef, l as ValidationOption, r as resolveAdapter } from './index-
|
|
1
|
+
import { U as UserConfig, R as ResolvedConfig, a as RouteDescriptor, S as SchemaNode, b as RenderContext, c as SchemaModule, d as RenderedModule, e as ResolvedFormsConfig, V as ValidationAdapter, C as CodegenExtension, E as ExtensionContext, f as SerializationMode } from './index-Dc4s883u.js';
|
|
2
|
+
export { A as AdapterUsage, g as ContractDescriptor, h as ContractSource, i as ControllerRef, N as NumberCheck, j as ScopeConfig, k as StringCheck, T as TypeRef, l as ValidationOption, r as resolveAdapter } from './index-Dc4s883u.js';
|
|
3
3
|
import { ClassDeclaration, SourceFile, Project } from 'ts-morph';
|
|
4
4
|
|
|
5
5
|
declare function defineConfig(c: UserConfig): UserConfig;
|
|
@@ -382,6 +382,6 @@ interface FastDiscoveryOptions {
|
|
|
382
382
|
}
|
|
383
383
|
declare function discoverContractsFast(opts: FastDiscoveryOptions): Promise<RouteDescriptor[]>;
|
|
384
384
|
|
|
385
|
-
declare const VERSION = "0.
|
|
385
|
+
declare const VERSION = "0.27.0";
|
|
386
386
|
|
|
387
387
|
export { type ChainModuleRendererOptions, CodegenError, type CodegenManifest, ConfigError, DriftGuardError, type EntryPoint, type FastDiscoveryOptions, type JsonSchema, type MocksEmitOptions, type OpenApiDocument, type OpenApiEmitOptions, type OpenApiInfo, RenderContext, RenderedModule, ResolvedConfig, RouteDescriptor, SchemaModule, SchemaNode, type TsTypeContext, UserConfig, VERSION, ValidationAdapter, type WatchOptions, type Watcher, acquireLock, buildMocksFile, buildOpenApiSpec, createChainModuleRenderer, defineConfig, discoverContractsFast, emitApi, emitForms, emitMocks, emitOpenApi, emitRoutes, extractSchemaFromDto, generate, loadConfig, renderTsType, resolveConfig, schemaModuleToJsonSchema, schemaNodeToJsonSchema, toObjectKey, typeNameFor, watch };
|
package/dist/index.js
CHANGED
|
@@ -88,11 +88,32 @@ function validateUserConfig(userConfig) {
|
|
|
88
88
|
"validation adapter is required \u2014 install @dudousxd/nestjs-codegen-zod and pass zodAdapter, or use @dudousxd/nestjs-codegen-valibot / -arktype"
|
|
89
89
|
);
|
|
90
90
|
}
|
|
91
|
-
if (userConfig.pages &&
|
|
91
|
+
if (userConfig.pages && !isGlobInput(userConfig.pages.glob)) {
|
|
92
92
|
throw new ConfigError(
|
|
93
|
-
"Config validation failed: `pages.glob` must be a string when `pages` is set"
|
|
93
|
+
"Config validation failed: `pages.glob` must be a string or a non-empty array of strings when `pages` is set"
|
|
94
94
|
);
|
|
95
95
|
}
|
|
96
|
+
for (const [scope, scopeConfig] of Object.entries(userConfig.pages?.scopes ?? {})) {
|
|
97
|
+
if (scope === "default") {
|
|
98
|
+
throw new ConfigError(
|
|
99
|
+
'Config validation failed: `pages.scopes` cannot declare "default" \u2014 the default app is `pages.glob` (InertiaModule.forRoot).'
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
if (!isGlobInput(scopeConfig?.glob)) {
|
|
103
|
+
throw new ConfigError(
|
|
104
|
+
`Config validation failed: \`pages.scopes.${scope}.glob\` must be a string or a non-empty array of strings`
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (userConfig.scopes && Object.keys(userConfig.scopes).length > 0) {
|
|
109
|
+
console.warn(
|
|
110
|
+
"[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)."
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function isGlobInput(value) {
|
|
115
|
+
if (typeof value === "string") return true;
|
|
116
|
+
return Array.isArray(value) && value.length > 0 && value.every((glob) => typeof glob === "string");
|
|
96
117
|
}
|
|
97
118
|
function applyDefaults(userConfig, cwd) {
|
|
98
119
|
validateUserConfig(userConfig);
|
|
@@ -120,7 +141,17 @@ function applyDefaults(userConfig, cwd) {
|
|
|
120
141
|
pages: userConfig.pages ? {
|
|
121
142
|
glob: userConfig.pages.glob,
|
|
122
143
|
propsExport: userConfig.pages.propsExport ?? "ComponentProps",
|
|
123
|
-
componentNameStrategy: userConfig.pages.componentNameStrategy ?? "relative-no-ext"
|
|
144
|
+
componentNameStrategy: userConfig.pages.componentNameStrategy ?? "relative-no-ext",
|
|
145
|
+
scopes: Object.fromEntries(
|
|
146
|
+
Object.entries(userConfig.pages.scopes ?? {}).map(([scope, scopeConfig]) => [
|
|
147
|
+
scope,
|
|
148
|
+
{
|
|
149
|
+
glob: scopeConfig.glob,
|
|
150
|
+
prefix: scopeConfig.prefix ?? `${scope}/`,
|
|
151
|
+
componentNameStrategy: scopeConfig.componentNameStrategy ?? userConfig.pages?.componentNameStrategy ?? "relative-no-ext"
|
|
152
|
+
}
|
|
153
|
+
])
|
|
154
|
+
)
|
|
124
155
|
} : null,
|
|
125
156
|
contracts: {
|
|
126
157
|
glob: userConfig.contracts?.glob ?? "src/**/*.controller.ts",
|
|
@@ -194,26 +225,84 @@ import { dirname as dirname4, join as join14 } from "path";
|
|
|
194
225
|
|
|
195
226
|
// src/discovery/pages.ts
|
|
196
227
|
import { readFile } from "fs/promises";
|
|
197
|
-
import { join as join2, relative as relative2 } from "path";
|
|
228
|
+
import { join as join2, relative as relative2, sep as sep2 } from "path";
|
|
198
229
|
import fg from "fast-glob";
|
|
199
230
|
var NON_PAGE_FILE_RE = /\.(?:test|spec|stories|story)\.(?:tsx?|jsx?|vue|svelte)$/i;
|
|
231
|
+
var MAGIC_SEGMENT_RE = /[*?{}[\]()!]/;
|
|
232
|
+
function globStaticBase(glob) {
|
|
233
|
+
const segments = glob.split("/");
|
|
234
|
+
const staticSegments = [];
|
|
235
|
+
for (const segment of segments.slice(0, -1)) {
|
|
236
|
+
if (MAGIC_SEGMENT_RE.test(segment)) break;
|
|
237
|
+
staticSegments.push(segment);
|
|
238
|
+
}
|
|
239
|
+
return staticSegments.join("/");
|
|
240
|
+
}
|
|
200
241
|
async function discoverPages(opts) {
|
|
201
|
-
const
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
const
|
|
205
|
-
const pagesBase = join2(opts.cwd, globStatic);
|
|
242
|
+
const globs = typeof opts.glob === "string" ? [opts.glob] : opts.glob;
|
|
243
|
+
const prefix = opts.prefix ?? "";
|
|
244
|
+
const scope = opts.scope ?? "default";
|
|
245
|
+
const seenFiles = /* @__PURE__ */ new Set();
|
|
206
246
|
const out = [];
|
|
207
|
-
for (const
|
|
208
|
-
const
|
|
209
|
-
const
|
|
210
|
-
const
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
247
|
+
for (const glob of globs) {
|
|
248
|
+
const files = (await fg(glob, { cwd: opts.cwd, absolute: true })).filter((f) => !NON_PAGE_FILE_RE.test(f) && !seenFiles.has(f)).sort();
|
|
249
|
+
const pagesBase = join2(opts.cwd, globStaticBase(glob));
|
|
250
|
+
for (const file of files) {
|
|
251
|
+
seenFiles.add(file);
|
|
252
|
+
const rel = relative2(opts.cwd, file);
|
|
253
|
+
const nameRel = relative2(pagesBase, file).split(sep2).join("/");
|
|
254
|
+
const name = `${prefix}${computeName(nameRel, opts.componentNameStrategy)}`;
|
|
255
|
+
const source = await readFile(file, "utf8");
|
|
256
|
+
const propsSource = extractPropsSource(source, opts.propsExport);
|
|
257
|
+
out.push({ name, absolutePath: file, relativePath: rel, propsSource, scope });
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
assertUniqueNames(out);
|
|
261
|
+
return out;
|
|
262
|
+
}
|
|
263
|
+
async function discoverPageScopes(config) {
|
|
264
|
+
const pages = config.pages;
|
|
265
|
+
if (!pages) return [];
|
|
266
|
+
const common = { cwd: config.codegen.cwd, propsExport: pages.propsExport };
|
|
267
|
+
const out = await discoverPages({
|
|
268
|
+
...common,
|
|
269
|
+
glob: pages.glob,
|
|
270
|
+
componentNameStrategy: pages.componentNameStrategy
|
|
271
|
+
});
|
|
272
|
+
for (const [scope, scopeConfig] of Object.entries(pages.scopes ?? {})) {
|
|
273
|
+
out.push(
|
|
274
|
+
...await discoverPages({
|
|
275
|
+
...common,
|
|
276
|
+
glob: scopeConfig.glob,
|
|
277
|
+
componentNameStrategy: scopeConfig.componentNameStrategy,
|
|
278
|
+
prefix: scopeConfig.prefix,
|
|
279
|
+
scope
|
|
280
|
+
})
|
|
281
|
+
);
|
|
214
282
|
}
|
|
283
|
+
assertUniqueNames(out);
|
|
215
284
|
return out;
|
|
216
285
|
}
|
|
286
|
+
function allPageGlobs(config) {
|
|
287
|
+
if (!config.pages) return [];
|
|
288
|
+
const asList = (glob) => typeof glob === "string" ? [glob] : glob;
|
|
289
|
+
return [
|
|
290
|
+
...asList(config.pages.glob),
|
|
291
|
+
...Object.values(config.pages.scopes ?? {}).flatMap((scope) => asList(scope.glob))
|
|
292
|
+
];
|
|
293
|
+
}
|
|
294
|
+
function assertUniqueNames(pages) {
|
|
295
|
+
const byName = /* @__PURE__ */ new Map();
|
|
296
|
+
for (const page of pages) {
|
|
297
|
+
const previous = byName.get(page.name);
|
|
298
|
+
if (previous) {
|
|
299
|
+
throw new Error(
|
|
300
|
+
`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.`
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
byName.set(page.name, page);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
217
306
|
function computeName(rel, strat) {
|
|
218
307
|
if (typeof strat === "function") return strat(rel);
|
|
219
308
|
const noExt = rel.replace(/\.(tsx?|vue|svelte)$/, "");
|
|
@@ -4102,28 +4191,28 @@ function renderFetcherRequest(req, binaryResponse) {
|
|
|
4102
4191
|
}
|
|
4103
4192
|
function emitReqHelper() {
|
|
4104
4193
|
return [
|
|
4105
|
-
"/**
|
|
4106
|
-
"type
|
|
4107
|
-
"
|
|
4194
|
+
"/** An awaitable request handle: a lazy, memoized `Promise` that also carries `fetch()` and the members extensions add. */",
|
|
4195
|
+
"export type RequestHandle<R, M = {}> = Promise<R> & { fetch(): Promise<R> } & M;",
|
|
4196
|
+
"class __Request<R> extends Promise<R> {",
|
|
4197
|
+
" static override get [Symbol.species](): PromiseConstructor {",
|
|
4198
|
+
" return Promise;",
|
|
4199
|
+
" }",
|
|
4200
|
+
" private __run: () => Promise<R>;",
|
|
4201
|
+
" private __p: Promise<R> | undefined;",
|
|
4202
|
+
" constructor(run: () => Promise<R>) {",
|
|
4203
|
+
" super(() => {});",
|
|
4204
|
+
" this.__run = run;",
|
|
4205
|
+
" }",
|
|
4206
|
+
" override then<T1 = R, T2 = never>(",
|
|
4108
4207
|
" onfulfilled?: ((value: R) => T1 | PromiseLike<T1>) | null,",
|
|
4109
4208
|
" onrejected?: ((reason: unknown) => T2 | PromiseLike<T2>) | null,",
|
|
4110
|
-
" ): Promise<T1 | T2
|
|
4111
|
-
"
|
|
4112
|
-
"
|
|
4113
|
-
"
|
|
4114
|
-
"}
|
|
4115
|
-
"function __req<R>(run: () => Promise<R
|
|
4116
|
-
"
|
|
4117
|
-
" const __promise = () => {",
|
|
4118
|
-
" __p ??= run();",
|
|
4119
|
-
" return __p;",
|
|
4120
|
-
" };",
|
|
4121
|
-
" return {",
|
|
4122
|
-
" then: (onfulfilled, onrejected) => __promise().then(onfulfilled, onrejected),",
|
|
4123
|
-
" catch: (onrejected) => __promise().catch(onrejected),",
|
|
4124
|
-
" finally: (onfinally) => __promise().finally(onfinally),",
|
|
4125
|
-
" fetch: run,",
|
|
4126
|
-
" };",
|
|
4209
|
+
" ): Promise<T1 | T2> {",
|
|
4210
|
+
" this.__p ??= this.__run();",
|
|
4211
|
+
" return this.__p.then(onfulfilled, onrejected);",
|
|
4212
|
+
" }",
|
|
4213
|
+
"}",
|
|
4214
|
+
"function __req<R, M extends object = {}>(run: () => Promise<R>, members?: M): RequestHandle<R, M> {",
|
|
4215
|
+
" return Object.assign(new __Request<R>(run), { fetch: run }, members) as RequestHandle<R, M>;",
|
|
4127
4216
|
"}",
|
|
4128
4217
|
""
|
|
4129
4218
|
];
|
|
@@ -4141,18 +4230,26 @@ function emitFilterFieldGuard() {
|
|
|
4141
4230
|
];
|
|
4142
4231
|
}
|
|
4143
4232
|
function renderLeaf(pad, objKey, req, requestExpr, members, streamExpr) {
|
|
4144
|
-
const
|
|
4145
|
-
lines.push(`${pad} ...__req<${req.responseType}>(() => ${requestExpr}),`);
|
|
4233
|
+
const memberLines = [];
|
|
4146
4234
|
if (req.filterFieldsExpr) {
|
|
4147
|
-
|
|
4235
|
+
memberLines.push(`${pad} filterFields: ${req.filterFieldsExpr},`);
|
|
4148
4236
|
}
|
|
4149
4237
|
if (streamExpr) {
|
|
4150
|
-
|
|
4238
|
+
memberLines.push(`${pad} stream: () => ${streamExpr},`);
|
|
4151
4239
|
}
|
|
4152
4240
|
for (const [name, value] of Object.entries(members)) {
|
|
4153
|
-
|
|
4154
|
-
}
|
|
4155
|
-
|
|
4241
|
+
memberLines.push(`${pad} ${name}: ${value},`);
|
|
4242
|
+
}
|
|
4243
|
+
const body = [requestExpr, ...memberLines].join("\n");
|
|
4244
|
+
const param = /\binput\b/.test(body) ? `input?: ${req.inputType}` : "";
|
|
4245
|
+
const lines = [`${pad}${objKey}: (${param}) =>`];
|
|
4246
|
+
if (memberLines.length === 0) {
|
|
4247
|
+
lines.push(`${pad} __req<${req.responseType}>(() => ${requestExpr}),`);
|
|
4248
|
+
return lines;
|
|
4249
|
+
}
|
|
4250
|
+
lines.push(`${pad} __req(() => ${requestExpr}, {`);
|
|
4251
|
+
lines.push(...memberLines);
|
|
4252
|
+
lines.push(`${pad} }),`);
|
|
4156
4253
|
return lines;
|
|
4157
4254
|
}
|
|
4158
4255
|
function renderStreamExpr(req) {
|
|
@@ -4286,6 +4383,23 @@ var EMPTY_PATH_NAMESPACE = [
|
|
|
4286
4383
|
function isClientCallable(route) {
|
|
4287
4384
|
return route.method.toUpperCase() !== "ALL";
|
|
4288
4385
|
}
|
|
4386
|
+
var ROUTES_IMPORT_PLACEHOLDER = "/* @@routes-import@@ */";
|
|
4387
|
+
var ROUTES_EXPORTS = [
|
|
4388
|
+
// Called, never mentioned in prose: match the call so a comment saying "route" doesn't count.
|
|
4389
|
+
{ name: "route", typeOnly: false },
|
|
4390
|
+
{ name: "ROUTES", typeOnly: false },
|
|
4391
|
+
{ name: "RouteName", typeOnly: true },
|
|
4392
|
+
{ name: "ExtractParams", typeOnly: true },
|
|
4393
|
+
{ name: "RouteParams", typeOnly: true }
|
|
4394
|
+
];
|
|
4395
|
+
function finishRoutesImport(lines) {
|
|
4396
|
+
const body = lines.filter((l) => l !== ROUTES_IMPORT_PLACEHOLDER).join("\n");
|
|
4397
|
+
const used = ROUTES_EXPORTS.filter(
|
|
4398
|
+
({ name }) => new RegExp(name === "route" ? "\\broute\\(" : `\\b${name}\\b`).test(body)
|
|
4399
|
+
).map(({ name, typeOnly }) => typeOnly ? `type ${name}` : name);
|
|
4400
|
+
const importLine = used.length ? `import { ${used.join(", ")} } from './routes.js';` : null;
|
|
4401
|
+
return lines.flatMap((l) => l === ROUTES_IMPORT_PLACEHOLDER ? importLine ? [importLine] : [] : [l]).join("\n");
|
|
4402
|
+
}
|
|
4289
4403
|
function buildApiFile(routes, outDir, opts = {}) {
|
|
4290
4404
|
const fetcherImportPath = opts.fetcherImportPath;
|
|
4291
4405
|
const serialization = opts.serialization ?? "json";
|
|
@@ -4345,9 +4459,7 @@ function buildApiFile(routes, outDir, opts = {}) {
|
|
|
4345
4459
|
for (const imp of ext.apiHeader?.(ctx)?.imports ?? []) pushImport(imp);
|
|
4346
4460
|
}
|
|
4347
4461
|
lines.push(...extImports);
|
|
4348
|
-
lines.push(
|
|
4349
|
-
"import { route, ROUTES, type RouteName, type ExtractParams, type RouteParams } from './routes.js';"
|
|
4350
|
-
);
|
|
4462
|
+
lines.push(ROUTES_IMPORT_PLACEHOLDER);
|
|
4351
4463
|
const runtimeImport = fetcherImportPath ?? "@dudousxd/nestjs-client";
|
|
4352
4464
|
lines.push(`import type { Fetcher } from '${runtimeImport}';`);
|
|
4353
4465
|
if (serialization === "json" && contracted.length > 0) {
|
|
@@ -4398,7 +4510,7 @@ function buildApiFile(routes, outDir, opts = {}) {
|
|
|
4398
4510
|
lines.push(...statements, "");
|
|
4399
4511
|
}
|
|
4400
4512
|
}
|
|
4401
|
-
return lines
|
|
4513
|
+
return finishRoutesImport(lines);
|
|
4402
4514
|
}
|
|
4403
4515
|
const tree = /* @__PURE__ */ new Map();
|
|
4404
4516
|
for (const r of contracted) {
|
|
@@ -4451,7 +4563,7 @@ function buildApiFile(routes, outDir, opts = {}) {
|
|
|
4451
4563
|
lines.push(...statements, "");
|
|
4452
4564
|
}
|
|
4453
4565
|
}
|
|
4454
|
-
return lines
|
|
4566
|
+
return finishRoutesImport(lines);
|
|
4455
4567
|
}
|
|
4456
4568
|
|
|
4457
4569
|
// src/emit/emit-cache.ts
|
|
@@ -4464,6 +4576,7 @@ async function emitCache(pages, outDir) {
|
|
|
4464
4576
|
const s = await stat(p.absolutePath);
|
|
4465
4577
|
return {
|
|
4466
4578
|
name: p.name,
|
|
4579
|
+
scope: p.scope ?? "default",
|
|
4467
4580
|
relativePath: p.relativePath,
|
|
4468
4581
|
mtime: s.mtime.toISOString()
|
|
4469
4582
|
};
|
|
@@ -5258,10 +5371,11 @@ async function emitPages(pages, outDir, _options = {}) {
|
|
|
5258
5371
|
}).join("\n");
|
|
5259
5372
|
const propsHelper = "\nexport type InertiaProps<K extends InertiaPageName> = import('@dudousxd/nestjs-inertia').InertiaPages[K];\n";
|
|
5260
5373
|
const sharedPropsBlock = buildSharedPropsBlock(_options.sharedProps ?? null);
|
|
5374
|
+
const scopesBlock = buildScopesBlock(pages);
|
|
5261
5375
|
const content = `// Generated by @dudousxd/nestjs-codegen. Do not edit.
|
|
5262
5376
|
|
|
5263
5377
|
export type InertiaPageName = ${pageNameUnion};
|
|
5264
|
-
${propsHelper}
|
|
5378
|
+
${propsHelper}${scopesBlock}
|
|
5265
5379
|
declare module '@dudousxd/nestjs-inertia' {
|
|
5266
5380
|
interface InertiaPages {
|
|
5267
5381
|
${augBody}
|
|
@@ -5270,6 +5384,31 @@ ${sharedPropsBlock}}
|
|
|
5270
5384
|
`;
|
|
5271
5385
|
await writeFile7(join11(outDir, "pages.d.ts"), content, "utf8");
|
|
5272
5386
|
}
|
|
5387
|
+
function buildScopesBlock(pages) {
|
|
5388
|
+
const byScope = /* @__PURE__ */ new Map();
|
|
5389
|
+
for (const page of pages) {
|
|
5390
|
+
const scope = page.scope ?? "default";
|
|
5391
|
+
const names = byScope.get(scope) ?? [];
|
|
5392
|
+
names.push(JSON.stringify(page.name));
|
|
5393
|
+
byScope.set(scope, names);
|
|
5394
|
+
}
|
|
5395
|
+
if (![...byScope.keys()].some((scope) => scope !== "default")) return "";
|
|
5396
|
+
if (!byScope.has("default")) byScope.set("default", []);
|
|
5397
|
+
const scopes = ["default", ...[...byScope.keys()].filter((s) => s !== "default")];
|
|
5398
|
+
const body = scopes.map((scope) => {
|
|
5399
|
+
const key = needsQuotes(scope) ? JSON.stringify(scope) : scope;
|
|
5400
|
+
const names = byScope.get(scope) ?? [];
|
|
5401
|
+
return ` ${key}: ${names.length ? names.join(" | ") : "never"};`;
|
|
5402
|
+
}).join("\n");
|
|
5403
|
+
return `
|
|
5404
|
+
/** The page names of each Inertia app: \`default\` (forRoot) and every \`pages.scopes\` entry. */
|
|
5405
|
+
export interface InertiaScopePages {
|
|
5406
|
+
${body}
|
|
5407
|
+
}
|
|
5408
|
+
|
|
5409
|
+
export type InertiaScopePageName<S extends keyof InertiaScopePages> = InertiaScopePages[S];
|
|
5410
|
+
`;
|
|
5411
|
+
}
|
|
5273
5412
|
function buildSharedPropsBlock(sharedProps) {
|
|
5274
5413
|
if (!sharedProps) return "";
|
|
5275
5414
|
if (sharedProps.isImportRef) {
|
|
@@ -5477,8 +5616,7 @@ function diffConfigKeyHashes(previous, current) {
|
|
|
5477
5616
|
return [...keys].filter((key) => previous[key] !== current[key]).sort();
|
|
5478
5617
|
}
|
|
5479
5618
|
async function discoverInputFiles(config) {
|
|
5480
|
-
const globs = [config.contracts.glob, config.forms.watch];
|
|
5481
|
-
if (config.pages) globs.push(config.pages.glob);
|
|
5619
|
+
const globs = [config.contracts.glob, config.forms.watch, ...allPageGlobs(config)];
|
|
5482
5620
|
const cwd = config.codegen.cwd;
|
|
5483
5621
|
const matched = await fg3(globs, { cwd, absolute: true, onlyFiles: true });
|
|
5484
5622
|
return [...new Set(matched)].sort();
|
|
@@ -5609,12 +5747,7 @@ async function generate(config, inputRoutes = [], entryPoint = "cli") {
|
|
|
5609
5747
|
}
|
|
5610
5748
|
if (config.pages) {
|
|
5611
5749
|
const pagesConfig = config.pages;
|
|
5612
|
-
const pages = await
|
|
5613
|
-
glob: pagesConfig.glob,
|
|
5614
|
-
cwd: config.codegen.cwd,
|
|
5615
|
-
propsExport: pagesConfig.propsExport,
|
|
5616
|
-
componentNameStrategy: pagesConfig.componentNameStrategy
|
|
5617
|
-
});
|
|
5750
|
+
const pages = await discoverPageScopes(config);
|
|
5618
5751
|
const sharedProps = discoverSharedPropsFromConfig(config);
|
|
5619
5752
|
await emitPages(pages, config.codegen.outDir, {
|
|
5620
5753
|
propsExport: pagesConfig.propsExport,
|
|
@@ -5789,12 +5922,17 @@ async function watch(config, onChange, options = {}) {
|
|
|
5789
5922
|
await runInitialPass();
|
|
5790
5923
|
}
|
|
5791
5924
|
let pagesDebounceTimer;
|
|
5792
|
-
const
|
|
5793
|
-
const pagesWatcher = chokidar.watch(
|
|
5794
|
-
|
|
5795
|
-
|
|
5796
|
-
|
|
5797
|
-
|
|
5925
|
+
const pageGlobs = allPageGlobs(config);
|
|
5926
|
+
const pagesWatcher = chokidar.watch(
|
|
5927
|
+
(pageGlobs.length ? pageGlobs : [".nestjs-codegen-no-pages"]).map(
|
|
5928
|
+
(glob) => join16(config.codegen.cwd, glob)
|
|
5929
|
+
),
|
|
5930
|
+
{
|
|
5931
|
+
ignoreInitial: true,
|
|
5932
|
+
persistent: true,
|
|
5933
|
+
awaitWriteFinish: { stabilityThreshold: 80, pollInterval: 20 }
|
|
5934
|
+
}
|
|
5935
|
+
);
|
|
5798
5936
|
function schedulePagesRegenerate() {
|
|
5799
5937
|
if (pagesDebounceTimer !== void 0) {
|
|
5800
5938
|
clearTimeout(pagesDebounceTimer);
|
|
@@ -5957,7 +6095,7 @@ function createChainModuleRenderer(opts) {
|
|
|
5957
6095
|
}
|
|
5958
6096
|
|
|
5959
6097
|
// src/index.ts
|
|
5960
|
-
var VERSION = "0.
|
|
6098
|
+
var VERSION = "0.27.0";
|
|
5961
6099
|
export {
|
|
5962
6100
|
CodegenError,
|
|
5963
6101
|
ConfigError,
|