@dudousxd/nestjs-codegen 0.11.0 → 0.12.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 +28 -0
- package/dist/cli/main.cjs +204 -88
- package/dist/cli/main.cjs.map +1 -1
- package/dist/cli/main.js +188 -72
- package/dist/cli/main.js.map +1 -1
- package/dist/index.cjs +162 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -3
- package/dist/index.d.ts +29 -3
- package/dist/index.js +149 -33
- package/dist/index.js.map +1 -1
- package/dist/nest/index.cjs +207 -72
- package/dist/nest/index.cjs.map +1 -1
- package/dist/nest/index.d.cts +15 -4
- package/dist/nest/index.d.ts +15 -4
- package/dist/nest/index.js +207 -72
- package/dist/nest/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/main.js
CHANGED
|
@@ -183,8 +183,8 @@ Run \`nestjs-codegen init\` to create a starter config.`
|
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
// src/generate.ts
|
|
186
|
-
import { mkdir as mkdir9, writeFile as
|
|
187
|
-
import { dirname as dirname2, join as
|
|
186
|
+
import { mkdir as mkdir9, writeFile as writeFile10 } from "fs/promises";
|
|
187
|
+
import { dirname as dirname2, join as join13 } from "path";
|
|
188
188
|
|
|
189
189
|
// src/discovery/pages.ts
|
|
190
190
|
import { readFile } from "fs/promises";
|
|
@@ -2079,6 +2079,99 @@ function buildEmpty() {
|
|
|
2079
2079
|
].join("\n");
|
|
2080
2080
|
}
|
|
2081
2081
|
|
|
2082
|
+
// src/generate-manifest.ts
|
|
2083
|
+
import { createHash } from "crypto";
|
|
2084
|
+
import { readFile as readFile2, readdir, writeFile as writeFile9 } from "fs/promises";
|
|
2085
|
+
import { join as join12, relative as relative6 } from "path";
|
|
2086
|
+
import fg2 from "fast-glob";
|
|
2087
|
+
var MANIFEST_FILE = ".codegen-manifest.json";
|
|
2088
|
+
var LOCK_FILE = ".watcher.lock";
|
|
2089
|
+
function isManifestShape(value) {
|
|
2090
|
+
if (typeof value !== "object" || value === null) return false;
|
|
2091
|
+
const candidate = value;
|
|
2092
|
+
if (typeof candidate.version !== "string") return false;
|
|
2093
|
+
if (typeof candidate.hash !== "string") return false;
|
|
2094
|
+
if (!Array.isArray(candidate.files)) return false;
|
|
2095
|
+
return candidate.files.every((entry) => typeof entry === "string");
|
|
2096
|
+
}
|
|
2097
|
+
function serializeConfig(config) {
|
|
2098
|
+
try {
|
|
2099
|
+
return JSON.stringify(config, (_key, value) => {
|
|
2100
|
+
if (typeof value === "function") return `[fn:${value.name}]${value.toString()}`;
|
|
2101
|
+
return value;
|
|
2102
|
+
});
|
|
2103
|
+
} catch {
|
|
2104
|
+
return `unserializable:${config.codegen.outDir}:${config.contracts.glob}`;
|
|
2105
|
+
}
|
|
2106
|
+
}
|
|
2107
|
+
async function discoverInputFiles(config) {
|
|
2108
|
+
const globs = [config.contracts.glob, config.forms.watch];
|
|
2109
|
+
if (config.pages) globs.push(config.pages.glob);
|
|
2110
|
+
const cwd = config.codegen.cwd;
|
|
2111
|
+
const matched = await fg2(globs, { cwd, absolute: true, onlyFiles: true });
|
|
2112
|
+
return [...new Set(matched)].sort();
|
|
2113
|
+
}
|
|
2114
|
+
async function computeInputsHash(config) {
|
|
2115
|
+
const hash = createHash("sha256");
|
|
2116
|
+
hash.update(`version:${VERSION}
|
|
2117
|
+
`);
|
|
2118
|
+
hash.update(`config:${serializeConfig(config)}
|
|
2119
|
+
`);
|
|
2120
|
+
const inputFiles = await discoverInputFiles(config);
|
|
2121
|
+
const cwd = config.codegen.cwd;
|
|
2122
|
+
for (const file of inputFiles) {
|
|
2123
|
+
const contents = await readFile2(file, "utf8");
|
|
2124
|
+
hash.update(`file:${relative6(cwd, file)}
|
|
2125
|
+
`);
|
|
2126
|
+
hash.update(contents);
|
|
2127
|
+
hash.update("\n");
|
|
2128
|
+
}
|
|
2129
|
+
return hash.digest("hex");
|
|
2130
|
+
}
|
|
2131
|
+
async function readManifest(outDir) {
|
|
2132
|
+
try {
|
|
2133
|
+
const raw = await readFile2(join12(outDir, MANIFEST_FILE), "utf8");
|
|
2134
|
+
const parsed = JSON.parse(raw);
|
|
2135
|
+
if (!isManifestShape(parsed)) return null;
|
|
2136
|
+
return { version: parsed.version, hash: parsed.hash, files: parsed.files };
|
|
2137
|
+
} catch {
|
|
2138
|
+
return null;
|
|
2139
|
+
}
|
|
2140
|
+
}
|
|
2141
|
+
async function writeManifest(outDir, manifest) {
|
|
2142
|
+
await writeFile9(join12(outDir, MANIFEST_FILE), `${JSON.stringify(manifest, null, 2)}
|
|
2143
|
+
`, "utf8");
|
|
2144
|
+
}
|
|
2145
|
+
async function listOutputFiles(outDir) {
|
|
2146
|
+
const found = [];
|
|
2147
|
+
async function walk(dir) {
|
|
2148
|
+
const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
2149
|
+
for (const entry of entries) {
|
|
2150
|
+
const abs = join12(dir, entry.name);
|
|
2151
|
+
if (entry.isDirectory()) {
|
|
2152
|
+
await walk(abs);
|
|
2153
|
+
} else if (entry.isFile()) {
|
|
2154
|
+
const rel = relative6(outDir, abs);
|
|
2155
|
+
if (rel === MANIFEST_FILE || rel === LOCK_FILE) continue;
|
|
2156
|
+
found.push(rel);
|
|
2157
|
+
}
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
await walk(outDir);
|
|
2161
|
+
return found.sort();
|
|
2162
|
+
}
|
|
2163
|
+
async function allOutputsExist(outDir, files) {
|
|
2164
|
+
const present = new Set(await listOutputFiles(outDir));
|
|
2165
|
+
return files.every((file) => present.has(file));
|
|
2166
|
+
}
|
|
2167
|
+
async function isManifestFresh(outDir, manifest, inputsHash) {
|
|
2168
|
+
if (manifest === null) return false;
|
|
2169
|
+
if (manifest.version !== VERSION) return false;
|
|
2170
|
+
if (manifest.hash !== inputsHash) return false;
|
|
2171
|
+
if (manifest.files.length === 0) return false;
|
|
2172
|
+
return allOutputsExist(outDir, manifest.files);
|
|
2173
|
+
}
|
|
2174
|
+
|
|
2082
2175
|
// src/util/debug-log.ts
|
|
2083
2176
|
var debugEnabled = false;
|
|
2084
2177
|
function setCodegenDebug(enabled) {
|
|
@@ -2091,6 +2184,12 @@ function debugWarn(message) {
|
|
|
2091
2184
|
// src/generate.ts
|
|
2092
2185
|
async function generate(config, inputRoutes = []) {
|
|
2093
2186
|
setCodegenDebug(config.debug);
|
|
2187
|
+
const inputsHash = await computeInputsHash(config);
|
|
2188
|
+
const manifest = await readManifest(config.codegen.outDir);
|
|
2189
|
+
if (await isManifestFresh(config.codegen.outDir, manifest, inputsHash)) {
|
|
2190
|
+
console.log(`[nestjs-codegen] ${config.codegen.outDir} up to date, skipped`);
|
|
2191
|
+
return;
|
|
2192
|
+
}
|
|
2094
2193
|
const extensions = config.extensions ?? [];
|
|
2095
2194
|
let routes = inputRoutes;
|
|
2096
2195
|
const ctx = createExtensionContext(config, () => routes);
|
|
@@ -2147,21 +2246,27 @@ async function generate(config, inputRoutes = []) {
|
|
|
2147
2246
|
if (extensions.length > 0) {
|
|
2148
2247
|
const extraFiles = await collectEmittedFiles(extensions, ctx);
|
|
2149
2248
|
for (const file of extraFiles) {
|
|
2150
|
-
const dest =
|
|
2249
|
+
const dest = join13(config.codegen.outDir, file.path);
|
|
2151
2250
|
await mkdir9(dirname2(dest), { recursive: true });
|
|
2152
|
-
await
|
|
2251
|
+
await writeFile10(dest, file.contents, "utf8");
|
|
2153
2252
|
}
|
|
2154
2253
|
}
|
|
2254
|
+
const outputFiles = await listOutputFiles(config.codegen.outDir);
|
|
2255
|
+
await writeManifest(config.codegen.outDir, {
|
|
2256
|
+
version: VERSION,
|
|
2257
|
+
hash: inputsHash,
|
|
2258
|
+
files: outputFiles
|
|
2259
|
+
});
|
|
2155
2260
|
}
|
|
2156
2261
|
|
|
2157
2262
|
// src/watch/watcher.ts
|
|
2158
|
-
import { readFile as
|
|
2159
|
-
import { join as
|
|
2263
|
+
import { readFile as readFile4 } from "fs/promises";
|
|
2264
|
+
import { join as join16 } from "path";
|
|
2160
2265
|
import chokidar from "chokidar";
|
|
2161
2266
|
|
|
2162
2267
|
// src/discovery/contracts-fast.ts
|
|
2163
|
-
import { join as
|
|
2164
|
-
import
|
|
2268
|
+
import { join as join14, resolve as resolve3 } from "path";
|
|
2269
|
+
import fg3 from "fast-glob";
|
|
2165
2270
|
import {
|
|
2166
2271
|
Node as Node8,
|
|
2167
2272
|
Project as Project3
|
|
@@ -3938,7 +4043,7 @@ async function discoverContractsFast(opts) {
|
|
|
3938
4043
|
const { cwd, glob, tsconfig } = opts;
|
|
3939
4044
|
const tsconfigPath = resolveTsconfigPath(cwd, tsconfig);
|
|
3940
4045
|
const project = createDiscoveryProject(tsconfigPath);
|
|
3941
|
-
const files = await
|
|
4046
|
+
const files = await fg3(glob, { cwd, absolute: true, onlyFiles: true });
|
|
3942
4047
|
for (const f of files) {
|
|
3943
4048
|
project.addSourceFileAtPath(f);
|
|
3944
4049
|
}
|
|
@@ -3946,7 +4051,7 @@ async function discoverContractsFast(opts) {
|
|
|
3946
4051
|
return extractAllRoutes(project);
|
|
3947
4052
|
}
|
|
3948
4053
|
function resolveTsconfigPath(cwd, tsconfig) {
|
|
3949
|
-
return tsconfig ? resolve3(tsconfig) :
|
|
4054
|
+
return tsconfig ? resolve3(tsconfig) : join14(cwd, "tsconfig.json");
|
|
3950
4055
|
}
|
|
3951
4056
|
function createDiscoveryProject(tsconfigPath) {
|
|
3952
4057
|
try {
|
|
@@ -4011,7 +4116,7 @@ var PersistentDiscovery = class _PersistentDiscovery {
|
|
|
4011
4116
|
const project = createDiscoveryProject(tsconfigPath);
|
|
4012
4117
|
bindDiscoveryContext(project, cwd, tsconfigPath);
|
|
4013
4118
|
const instance = new _PersistentDiscovery(project, cwd, glob);
|
|
4014
|
-
const files = await
|
|
4119
|
+
const files = await fg3(glob, { cwd, absolute: true, onlyFiles: true });
|
|
4015
4120
|
for (const f of files) {
|
|
4016
4121
|
project.addSourceFileAtPath(f);
|
|
4017
4122
|
instance.controllerPaths.add(f);
|
|
@@ -4040,7 +4145,7 @@ var PersistentDiscovery = class _PersistentDiscovery {
|
|
|
4040
4145
|
}
|
|
4041
4146
|
}
|
|
4042
4147
|
const globbed = new Set(
|
|
4043
|
-
await
|
|
4148
|
+
await fg3(this.glob, { cwd: this.cwd, absolute: true, onlyFiles: true })
|
|
4044
4149
|
);
|
|
4045
4150
|
for (const f of globbed) {
|
|
4046
4151
|
if (!this.controllerPaths.has(f)) {
|
|
@@ -4321,9 +4426,9 @@ function extractFromSourceFile(sourceFile, project) {
|
|
|
4321
4426
|
|
|
4322
4427
|
// src/watch/lock-file.ts
|
|
4323
4428
|
import { open } from "fs/promises";
|
|
4324
|
-
import { mkdir as mkdir10, readFile as
|
|
4325
|
-
import { join as
|
|
4326
|
-
var
|
|
4429
|
+
import { mkdir as mkdir10, readFile as readFile3, unlink } from "fs/promises";
|
|
4430
|
+
import { join as join15 } from "path";
|
|
4431
|
+
var LOCK_FILE2 = ".watcher.lock";
|
|
4327
4432
|
function isProcessAlive(pid) {
|
|
4328
4433
|
try {
|
|
4329
4434
|
process.kill(pid, 0);
|
|
@@ -4334,7 +4439,7 @@ function isProcessAlive(pid) {
|
|
|
4334
4439
|
}
|
|
4335
4440
|
async function acquireLock(outDir) {
|
|
4336
4441
|
await mkdir10(outDir, { recursive: true });
|
|
4337
|
-
const lockPath =
|
|
4442
|
+
const lockPath = join15(outDir, LOCK_FILE2);
|
|
4338
4443
|
const lockData = { pid: process.pid, startedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
4339
4444
|
try {
|
|
4340
4445
|
const fd = await open(lockPath, "wx");
|
|
@@ -4344,7 +4449,7 @@ async function acquireLock(outDir) {
|
|
|
4344
4449
|
} catch (err) {
|
|
4345
4450
|
if (err.code === "EEXIST") {
|
|
4346
4451
|
try {
|
|
4347
|
-
const raw = await
|
|
4452
|
+
const raw = await readFile3(lockPath, "utf8");
|
|
4348
4453
|
const existing = JSON.parse(raw);
|
|
4349
4454
|
if (isProcessAlive(existing.pid)) return null;
|
|
4350
4455
|
await unlink(lockPath);
|
|
@@ -4369,12 +4474,12 @@ async function acquireLock(outDir) {
|
|
|
4369
4474
|
var PAGES_DEBOUNCE_MS = 150;
|
|
4370
4475
|
var NO_OP_WATCHER = { close: async () => {
|
|
4371
4476
|
} };
|
|
4372
|
-
async function watch(config, onChange) {
|
|
4477
|
+
async function watch(config, onChange, options = {}) {
|
|
4373
4478
|
const lock = await acquireLock(config.codegen.outDir);
|
|
4374
4479
|
if (lock === null) {
|
|
4375
4480
|
let holderPid = "unknown";
|
|
4376
4481
|
try {
|
|
4377
|
-
const raw = await
|
|
4482
|
+
const raw = await readFile4(join16(config.codegen.outDir, ".watcher.lock"), "utf8");
|
|
4378
4483
|
const data = JSON.parse(raw);
|
|
4379
4484
|
if (data.pid !== void 0) holderPid = String(data.pid);
|
|
4380
4485
|
} catch {
|
|
@@ -4397,22 +4502,33 @@ async function watch(config, onChange) {
|
|
|
4397
4502
|
}
|
|
4398
4503
|
return discovery;
|
|
4399
4504
|
}
|
|
4400
|
-
|
|
4401
|
-
const initialRoutes = (await getDiscovery()).discover();
|
|
4402
|
-
lastRoutes = initialRoutes;
|
|
4403
|
-
await generate(config, initialRoutes);
|
|
4404
|
-
} catch (err) {
|
|
4405
|
-
console.warn(
|
|
4406
|
-
`[nestjs-codegen] Initial route discovery failed, falling back to pages-only: ${err instanceof Error ? err.message : String(err)}`
|
|
4407
|
-
);
|
|
4505
|
+
async function runInitialPass() {
|
|
4408
4506
|
try {
|
|
4409
|
-
await
|
|
4410
|
-
|
|
4507
|
+
const initialRoutes = (await getDiscovery()).discover();
|
|
4508
|
+
lastRoutes = initialRoutes;
|
|
4509
|
+
await generate(config, initialRoutes);
|
|
4510
|
+
} catch (err) {
|
|
4511
|
+
console.warn(
|
|
4512
|
+
`[nestjs-codegen] Initial route discovery failed, falling back to pages-only: ${err instanceof Error ? err.message : String(err)}`
|
|
4513
|
+
);
|
|
4514
|
+
try {
|
|
4515
|
+
await generate(config, lastRoutes);
|
|
4516
|
+
} catch {
|
|
4517
|
+
}
|
|
4411
4518
|
}
|
|
4412
4519
|
}
|
|
4520
|
+
if (options.deferInitialGenerate) {
|
|
4521
|
+
void runInitialPass().catch((err) => {
|
|
4522
|
+
console.warn(
|
|
4523
|
+
`[nestjs-codegen] Background initial generate failed: ${err instanceof Error ? err.message : String(err)}`
|
|
4524
|
+
);
|
|
4525
|
+
});
|
|
4526
|
+
} else {
|
|
4527
|
+
await runInitialPass();
|
|
4528
|
+
}
|
|
4413
4529
|
let pagesDebounceTimer;
|
|
4414
4530
|
const pagesGlob = config.pages?.glob ?? ".nestjs-codegen-no-pages";
|
|
4415
|
-
const pagesWatcher = chokidar.watch(
|
|
4531
|
+
const pagesWatcher = chokidar.watch(join16(config.codegen.cwd, pagesGlob), {
|
|
4416
4532
|
ignoreInitial: true,
|
|
4417
4533
|
persistent: true,
|
|
4418
4534
|
awaitWriteFinish: { stabilityThreshold: 80, pollInterval: 20 }
|
|
@@ -4439,7 +4555,7 @@ async function watch(config, onChange) {
|
|
|
4439
4555
|
pagesWatcher.on("unlink", schedulePagesRegenerate);
|
|
4440
4556
|
let contractsDebounceTimer;
|
|
4441
4557
|
const pendingChangedPaths = /* @__PURE__ */ new Set();
|
|
4442
|
-
const contractsWatcher = chokidar.watch(
|
|
4558
|
+
const contractsWatcher = chokidar.watch(join16(config.codegen.cwd, config.contracts.glob), {
|
|
4443
4559
|
ignoreInitial: true,
|
|
4444
4560
|
persistent: true,
|
|
4445
4561
|
awaitWriteFinish: { stabilityThreshold: 80, pollInterval: 20 }
|
|
@@ -4469,7 +4585,7 @@ async function watch(config, onChange) {
|
|
|
4469
4585
|
contractsWatcher.on("add", (p) => scheduleContractsRegenerate(p));
|
|
4470
4586
|
contractsWatcher.on("change", (p) => scheduleContractsRegenerate(p));
|
|
4471
4587
|
contractsWatcher.on("unlink", (p) => scheduleContractsRegenerate(p));
|
|
4472
|
-
const formsWatcher = chokidar.watch(
|
|
4588
|
+
const formsWatcher = chokidar.watch(join16(config.codegen.cwd, config.forms.watch), {
|
|
4473
4589
|
ignoreInitial: true,
|
|
4474
4590
|
persistent: true,
|
|
4475
4591
|
awaitWriteFinish: { stabilityThreshold: 80, pollInterval: 20 }
|
|
@@ -4496,7 +4612,7 @@ async function watch(config, onChange) {
|
|
|
4496
4612
|
}
|
|
4497
4613
|
|
|
4498
4614
|
// src/index.ts
|
|
4499
|
-
var VERSION = "0.
|
|
4615
|
+
var VERSION = "0.12.0";
|
|
4500
4616
|
|
|
4501
4617
|
// src/cli/codegen.ts
|
|
4502
4618
|
async function runCodegen(opts = {}) {
|
|
@@ -4525,13 +4641,13 @@ async function runCodegen(opts = {}) {
|
|
|
4525
4641
|
// src/cli/doctor.ts
|
|
4526
4642
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
4527
4643
|
import { appendFileSync, existsSync, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
|
|
4528
|
-
import { join as
|
|
4644
|
+
import { join as join18 } from "path";
|
|
4529
4645
|
|
|
4530
4646
|
// src/cli/init.ts
|
|
4531
4647
|
import { execFileSync } from "child_process";
|
|
4532
4648
|
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
4533
|
-
import { access as access2, mkdir as mkdir11, readFile as
|
|
4534
|
-
import { join as
|
|
4649
|
+
import { access as access2, mkdir as mkdir11, readFile as readFile5, writeFile as writeFile11 } from "fs/promises";
|
|
4650
|
+
import { join as join17 } from "path";
|
|
4535
4651
|
import { createInterface } from "readline";
|
|
4536
4652
|
|
|
4537
4653
|
// src/cli/patch-utils.ts
|
|
@@ -4593,7 +4709,7 @@ ${bold(title)}`);
|
|
|
4593
4709
|
}
|
|
4594
4710
|
async function readPackageJson(cwd) {
|
|
4595
4711
|
try {
|
|
4596
|
-
const raw = await
|
|
4712
|
+
const raw = await readFile5(join17(cwd, "package.json"), "utf8");
|
|
4597
4713
|
return JSON.parse(raw);
|
|
4598
4714
|
} catch {
|
|
4599
4715
|
return {};
|
|
@@ -4624,7 +4740,7 @@ async function detectTemplateEngine(cwd) {
|
|
|
4624
4740
|
async function detectPackageManager(cwd) {
|
|
4625
4741
|
async function exists(file) {
|
|
4626
4742
|
try {
|
|
4627
|
-
await access2(
|
|
4743
|
+
await access2(join17(cwd, file));
|
|
4628
4744
|
return true;
|
|
4629
4745
|
} catch {
|
|
4630
4746
|
return false;
|
|
@@ -4667,13 +4783,13 @@ async function writeIfNotExists(filePath, content, label) {
|
|
|
4667
4783
|
if (dir) {
|
|
4668
4784
|
await mkdir11(dir, { recursive: true });
|
|
4669
4785
|
}
|
|
4670
|
-
await
|
|
4786
|
+
await writeFile11(filePath, content, "utf8");
|
|
4671
4787
|
logCreated(label);
|
|
4672
4788
|
}
|
|
4673
4789
|
async function handleViteConfig(cwd, framework) {
|
|
4674
|
-
const filePath =
|
|
4790
|
+
const filePath = join17(cwd, "vite.config.ts");
|
|
4675
4791
|
if (await fileExists2(filePath)) {
|
|
4676
|
-
const existing = await
|
|
4792
|
+
const existing = await readFile5(filePath, "utf8");
|
|
4677
4793
|
const hasPlugin = existing.includes("nestInertia") || existing.includes("nestjs-inertia-vite/plugin");
|
|
4678
4794
|
if (!hasPlugin) {
|
|
4679
4795
|
logSkipped("vite.config.ts");
|
|
@@ -4691,13 +4807,13 @@ async function handleViteConfig(cwd, framework) {
|
|
|
4691
4807
|
if (dir) {
|
|
4692
4808
|
await mkdir11(dir, { recursive: true });
|
|
4693
4809
|
}
|
|
4694
|
-
await
|
|
4810
|
+
await writeFile11(filePath, viteConfigTemplate(framework), "utf8");
|
|
4695
4811
|
logCreated("vite.config.ts");
|
|
4696
4812
|
}
|
|
4697
4813
|
async function patchGitignore(gitignorePath) {
|
|
4698
4814
|
let existing = "";
|
|
4699
4815
|
if (await fileExists2(gitignorePath)) {
|
|
4700
|
-
existing = await
|
|
4816
|
+
existing = await readFile5(gitignorePath, "utf8");
|
|
4701
4817
|
}
|
|
4702
4818
|
if (existing.split("\n").some((line) => line.trim() === GITIGNORE_ENTRY)) {
|
|
4703
4819
|
console.log(` ${cyan("\u2192")} .gitignore ${dim("(already contains .nestjs-inertia/, skipped)")}`);
|
|
@@ -4707,7 +4823,7 @@ async function patchGitignore(gitignorePath) {
|
|
|
4707
4823
|
` : `${existing}
|
|
4708
4824
|
${GITIGNORE_ENTRY}
|
|
4709
4825
|
`;
|
|
4710
|
-
await
|
|
4826
|
+
await writeFile11(gitignorePath, newContent, "utf8");
|
|
4711
4827
|
logPatched(".gitignore", "added .nestjs-inertia/");
|
|
4712
4828
|
}
|
|
4713
4829
|
function installDeps(pkgManager, deps, dev) {
|
|
@@ -4729,10 +4845,10 @@ function installDeps(pkgManager, deps, dev) {
|
|
|
4729
4845
|
}
|
|
4730
4846
|
}
|
|
4731
4847
|
async function patchPackageJsonScripts(cwd, scripts) {
|
|
4732
|
-
const pkgPath =
|
|
4848
|
+
const pkgPath = join17(cwd, "package.json");
|
|
4733
4849
|
let pkg = {};
|
|
4734
4850
|
try {
|
|
4735
|
-
pkg = JSON.parse(await
|
|
4851
|
+
pkg = JSON.parse(await readFile5(pkgPath, "utf8"));
|
|
4736
4852
|
} catch {
|
|
4737
4853
|
return;
|
|
4738
4854
|
}
|
|
@@ -4751,7 +4867,7 @@ async function patchPackageJsonScripts(cwd, scripts) {
|
|
|
4751
4867
|
return;
|
|
4752
4868
|
}
|
|
4753
4869
|
pkg.scripts = existing;
|
|
4754
|
-
await
|
|
4870
|
+
await writeFile11(pkgPath, `${JSON.stringify(pkg, null, 2)}
|
|
4755
4871
|
`, "utf8");
|
|
4756
4872
|
}
|
|
4757
4873
|
function patchAppModule(filePath, rootView) {
|
|
@@ -5046,7 +5162,7 @@ export class HomeController {
|
|
|
5046
5162
|
}
|
|
5047
5163
|
`;
|
|
5048
5164
|
function patchTsconfigExclude(cwd, dir, filename = "tsconfig.json") {
|
|
5049
|
-
const filePath =
|
|
5165
|
+
const filePath = join17(cwd, filename);
|
|
5050
5166
|
return patchJsonFile(
|
|
5051
5167
|
filePath,
|
|
5052
5168
|
(json) => {
|
|
@@ -5061,7 +5177,7 @@ function patchTsconfigExclude(cwd, dir, filename = "tsconfig.json") {
|
|
|
5061
5177
|
);
|
|
5062
5178
|
}
|
|
5063
5179
|
function patchNestCliJson(cwd, shellDir) {
|
|
5064
|
-
const filePath =
|
|
5180
|
+
const filePath = join17(cwd, "nest-cli.json");
|
|
5065
5181
|
return patchJsonFile(filePath, (json) => {
|
|
5066
5182
|
const compiler = json.compilerOptions ?? {};
|
|
5067
5183
|
const assets = compiler.assets ?? [];
|
|
@@ -5084,46 +5200,46 @@ async function scaffoldFiles(ctx) {
|
|
|
5084
5200
|
const { cwd, framework, engine, shellFileName, entryExt, pageExt } = ctx;
|
|
5085
5201
|
logSection("Scaffold files");
|
|
5086
5202
|
await writeIfNotExists(
|
|
5087
|
-
|
|
5203
|
+
join17(cwd, "nestjs-inertia.config.ts"),
|
|
5088
5204
|
configTemplate(framework),
|
|
5089
5205
|
"nestjs-inertia.config.ts"
|
|
5090
5206
|
);
|
|
5091
|
-
await writeIfNotExists(
|
|
5207
|
+
await writeIfNotExists(join17(cwd, "nestjs-inertia.d.ts"), DTS_TEMPLATE, "nestjs-inertia.d.ts");
|
|
5092
5208
|
await writeIfNotExists(
|
|
5093
|
-
|
|
5209
|
+
join17(cwd, "tsconfig.inertia.json"),
|
|
5094
5210
|
TSCONFIG_INERTIA_TEMPLATE,
|
|
5095
5211
|
"tsconfig.inertia.json"
|
|
5096
5212
|
);
|
|
5097
5213
|
await writeIfNotExists(
|
|
5098
|
-
|
|
5214
|
+
join17(cwd, "inertia", "tsconfig.json"),
|
|
5099
5215
|
INERTIA_TSCONFIG_TEMPLATE,
|
|
5100
5216
|
"inertia/tsconfig.json"
|
|
5101
5217
|
);
|
|
5102
5218
|
await writeIfNotExists(
|
|
5103
|
-
|
|
5219
|
+
join17(cwd, "inertia", shellFileName),
|
|
5104
5220
|
htmlShellTemplate(framework, engine),
|
|
5105
5221
|
`inertia/${shellFileName}`
|
|
5106
5222
|
);
|
|
5107
5223
|
await handleViteConfig(cwd, framework);
|
|
5108
5224
|
await writeIfNotExists(
|
|
5109
|
-
|
|
5225
|
+
join17(cwd, "inertia", "app", `client.${entryExt}`),
|
|
5110
5226
|
entryPointTemplate(framework),
|
|
5111
5227
|
`inertia/app/client.${entryExt}`
|
|
5112
5228
|
);
|
|
5113
5229
|
await writeIfNotExists(
|
|
5114
|
-
|
|
5230
|
+
join17(cwd, "inertia", "pages", `Home.${pageExt}`),
|
|
5115
5231
|
samplePageTemplate(framework),
|
|
5116
5232
|
`inertia/pages/Home.${pageExt}`
|
|
5117
5233
|
);
|
|
5118
5234
|
await writeIfNotExists(
|
|
5119
|
-
|
|
5235
|
+
join17(cwd, "src", "home.controller.ts"),
|
|
5120
5236
|
SAMPLE_CONTROLLER,
|
|
5121
5237
|
"src/home.controller.ts"
|
|
5122
5238
|
);
|
|
5123
5239
|
}
|
|
5124
5240
|
function patchServerAppModule(ctx) {
|
|
5125
5241
|
const { cwd, rootView } = ctx;
|
|
5126
|
-
const appModulePath =
|
|
5242
|
+
const appModulePath = join17(cwd, "src", "app.module.ts");
|
|
5127
5243
|
const appModuleResult = patchAppModule(appModulePath, rootView);
|
|
5128
5244
|
if (appModuleResult === "patched") {
|
|
5129
5245
|
logPatched("src/app.module.ts", "added InertiaModule.forRoot");
|
|
@@ -5137,7 +5253,7 @@ function patchServerAppModule(ctx) {
|
|
|
5137
5253
|
}
|
|
5138
5254
|
}
|
|
5139
5255
|
function patchServerMainTs(ctx) {
|
|
5140
|
-
const mainTsPath =
|
|
5256
|
+
const mainTsPath = join17(ctx.cwd, "src", "main.ts");
|
|
5141
5257
|
const mainTsResult = patchMainTs(mainTsPath);
|
|
5142
5258
|
if (mainTsResult === "patched") {
|
|
5143
5259
|
logPatched("src/main.ts", "added setupInertiaVite after NestFactory.create");
|
|
@@ -5172,7 +5288,7 @@ function patchBuildConfigs(ctx) {
|
|
|
5172
5288
|
}
|
|
5173
5289
|
async function patchGitignoreAndDist(ctx) {
|
|
5174
5290
|
const { cwd } = ctx;
|
|
5175
|
-
await patchGitignore(
|
|
5291
|
+
await patchGitignore(join17(cwd, ".gitignore"));
|
|
5176
5292
|
const tsconfigDistResult = patchTsconfigExclude(cwd, "dist", "tsconfig.json");
|
|
5177
5293
|
if (tsconfigDistResult === "patched") {
|
|
5178
5294
|
logPatched("tsconfig.json", "excluded dist/ from server compilation");
|
|
@@ -5278,7 +5394,7 @@ ${green("\u2713")} Setup complete! Run: ${bold("nest start --watch")}
|
|
|
5278
5394
|
|
|
5279
5395
|
// src/cli/doctor.ts
|
|
5280
5396
|
function checkFileExists(cwd, file) {
|
|
5281
|
-
return existsSync(
|
|
5397
|
+
return existsSync(join18(cwd, file));
|
|
5282
5398
|
}
|
|
5283
5399
|
function readJson(path) {
|
|
5284
5400
|
try {
|
|
@@ -5314,15 +5430,15 @@ function writeJsonField(filePath, dotPath, value) {
|
|
|
5314
5430
|
}
|
|
5315
5431
|
function getPackageVersion(cwd, pkg) {
|
|
5316
5432
|
try {
|
|
5317
|
-
const pkgJson = readJson(
|
|
5433
|
+
const pkgJson = readJson(join18(cwd, "node_modules", pkg, "package.json"));
|
|
5318
5434
|
return pkgJson?.version ?? null;
|
|
5319
5435
|
} catch {
|
|
5320
5436
|
return null;
|
|
5321
5437
|
}
|
|
5322
5438
|
}
|
|
5323
5439
|
function detectPkgManager(cwd) {
|
|
5324
|
-
if (existsSync(
|
|
5325
|
-
if (existsSync(
|
|
5440
|
+
if (existsSync(join18(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
5441
|
+
if (existsSync(join18(cwd, "yarn.lock"))) return "yarn";
|
|
5326
5442
|
return "npm";
|
|
5327
5443
|
}
|
|
5328
5444
|
async function runDoctor(opts) {
|
|
@@ -5360,7 +5476,7 @@ async function runDoctor(opts) {
|
|
|
5360
5476
|
autoFix: () => runInit({ cwd })
|
|
5361
5477
|
});
|
|
5362
5478
|
if (foundShellDir) {
|
|
5363
|
-
const nestCliPath =
|
|
5479
|
+
const nestCliPath = join18(cwd, "nest-cli.json");
|
|
5364
5480
|
const nestCli = readJson(nestCliPath);
|
|
5365
5481
|
const compiler = nestCli?.compilerOptions ?? {};
|
|
5366
5482
|
const assets = compiler.assets ?? [];
|
|
@@ -5399,7 +5515,7 @@ async function runDoctor(opts) {
|
|
|
5399
5515
|
fix: "Run: nestjs-codegen codegen",
|
|
5400
5516
|
autoFix: () => runCodegen({ cwd })
|
|
5401
5517
|
});
|
|
5402
|
-
const tsconfigPath =
|
|
5518
|
+
const tsconfigPath = join18(cwd, "tsconfig.json");
|
|
5403
5519
|
const tsconfig = readJson(tsconfigPath);
|
|
5404
5520
|
const paths = tsconfig?.compilerOptions?.paths;
|
|
5405
5521
|
checks.push({
|
|
@@ -5410,7 +5526,7 @@ async function runDoctor(opts) {
|
|
|
5410
5526
|
});
|
|
5411
5527
|
const inertiaDir = foundShellDir ?? "inertia";
|
|
5412
5528
|
for (const tsconfigFile of ["tsconfig.json", "tsconfig.build.json"]) {
|
|
5413
|
-
const tsc = readJson(
|
|
5529
|
+
const tsc = readJson(join18(cwd, tsconfigFile));
|
|
5414
5530
|
if (!tsc) continue;
|
|
5415
5531
|
const excl = tsc.exclude ?? [];
|
|
5416
5532
|
const excludesIt = excl.includes(inertiaDir);
|
|
@@ -5436,7 +5552,7 @@ async function runDoctor(opts) {
|
|
|
5436
5552
|
}
|
|
5437
5553
|
});
|
|
5438
5554
|
}
|
|
5439
|
-
const inertiaTsconfigPath =
|
|
5555
|
+
const inertiaTsconfigPath = join18(cwd, "tsconfig.inertia.json");
|
|
5440
5556
|
const inertiaTsconfig = readJson(inertiaTsconfigPath);
|
|
5441
5557
|
checks.push({
|
|
5442
5558
|
name: "tsconfig.inertia.json exists",
|
|
@@ -5488,7 +5604,7 @@ async function runDoctor(opts) {
|
|
|
5488
5604
|
fix: 'Add "nestjs-inertia.d.ts" to include array (resolves InertiaRegistry augmentation)'
|
|
5489
5605
|
});
|
|
5490
5606
|
}
|
|
5491
|
-
const innerTsconfigPath =
|
|
5607
|
+
const innerTsconfigPath = join18(cwd, "inertia", "tsconfig.json");
|
|
5492
5608
|
checks.push({
|
|
5493
5609
|
name: "inertia/tsconfig.json exists (VSCode picks up ~codegen alias)",
|
|
5494
5610
|
pass: existsSync(innerTsconfigPath),
|
|
@@ -5498,7 +5614,7 @@ async function runDoctor(opts) {
|
|
|
5498
5614
|
}
|
|
5499
5615
|
});
|
|
5500
5616
|
if (checkFileExists(cwd, "vite.config.ts")) {
|
|
5501
|
-
const viteContent = readFileSync4(
|
|
5617
|
+
const viteContent = readFileSync4(join18(cwd, "vite.config.ts"), "utf8");
|
|
5502
5618
|
checks.push({
|
|
5503
5619
|
name: "vite.config.ts has resolve.alias",
|
|
5504
5620
|
pass: viteContent.includes("resolve") && viteContent.includes("alias"),
|
|
@@ -5563,7 +5679,7 @@ async function runDoctor(opts) {
|
|
|
5563
5679
|
});
|
|
5564
5680
|
}
|
|
5565
5681
|
if (checkFileExists(cwd, ".gitignore")) {
|
|
5566
|
-
const gitignorePath =
|
|
5682
|
+
const gitignorePath = join18(cwd, ".gitignore");
|
|
5567
5683
|
const gitignore = readFileSync4(gitignorePath, "utf8");
|
|
5568
5684
|
checks.push({
|
|
5569
5685
|
name: ".gitignore includes .nestjs-inertia/",
|
|
@@ -5572,7 +5688,7 @@ async function runDoctor(opts) {
|
|
|
5572
5688
|
autoFix: () => appendFileSync(gitignorePath, "\n.nestjs-inertia/\n")
|
|
5573
5689
|
});
|
|
5574
5690
|
}
|
|
5575
|
-
const pkgJsonPath =
|
|
5691
|
+
const pkgJsonPath = join18(cwd, "package.json");
|
|
5576
5692
|
const pkgJson = readJson(pkgJsonPath);
|
|
5577
5693
|
const scripts = pkgJson?.scripts ?? {};
|
|
5578
5694
|
checks.push({
|