@lenne.tech/nest-server 11.30.0 → 11.31.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/CLAUDE.md +2 -0
- package/FRAMEWORK-API.md +1 -1
- package/dist/core/modules/migrate/cli/migrate-cli.d.ts +13 -1
- package/dist/core/modules/migrate/cli/migrate-cli.js +16 -1
- package/dist/core/modules/migrate/cli/migrate-cli.js.map +1 -1
- package/dist/core/modules/migrate/migration-runner.d.ts +4 -0
- package/dist/core/modules/migrate/migration-runner.js +46 -6
- package/dist/core/modules/migrate/migration-runner.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/migration-guides/11.29.x-to-11.30.x.md +1 -1
- package/migration-guides/11.30.x-to-11.31.x.md +38 -0
- package/migration-guides/11.31.0-to-11.31.1.md +89 -0
- package/package.json +1 -1
- package/src/core/modules/migrate/README.md +56 -0
- package/src/core/modules/migrate/cli/migrate-cli.ts +27 -3
- package/src/core/modules/migrate/migration-runner.ts +123 -6
package/CLAUDE.md
CHANGED
|
@@ -207,6 +207,8 @@ docker build --build-arg API_DIR=projects/api -t api . # Monorepo
|
|
|
207
207
|
Key files: `Dockerfile`, `docker-entrypoint.sh` (migrations + server start), `.dockerignore`
|
|
208
208
|
|
|
209
209
|
The migration store uses `NSC__MONGOOSE__URI` env var (not `config.env.ts`) for Docker compatibility.
|
|
210
|
+
Set `NSC__MIGRATE__STRICT=true` in production images to fail the boot when a recorded migration
|
|
211
|
+
file is missing (default: tolerate with a warning) — see `src/core/modules/migrate/README.md`.
|
|
210
212
|
|
|
211
213
|
## Environment Configuration
|
|
212
214
|
|
package/FRAMEWORK-API.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @lenne.tech/nest-server — Framework API Reference
|
|
2
2
|
|
|
3
|
-
> Auto-generated from source code on 2026-07-
|
|
3
|
+
> Auto-generated from source code on 2026-07-19 (v11.31.1)
|
|
4
4
|
> File: `FRAMEWORK-API.md` — compact, machine-readable API surface for Claude Code
|
|
5
5
|
|
|
6
6
|
## CoreModule.forRoot()
|
|
@@ -1,3 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
interface CliOptions {
|
|
3
|
+
compiler?: string;
|
|
4
|
+
migrationsDir: string;
|
|
5
|
+
store?: string;
|
|
6
|
+
strict?: boolean;
|
|
7
|
+
templateFile?: string;
|
|
8
|
+
}
|
|
2
9
|
declare function main(): Promise<void>;
|
|
3
|
-
|
|
10
|
+
declare function parseArgs(): {
|
|
11
|
+
command: string;
|
|
12
|
+
name?: string;
|
|
13
|
+
options: CliOptions;
|
|
14
|
+
};
|
|
15
|
+
export { main, parseArgs };
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.main = main;
|
|
5
|
+
exports.parseArgs = parseArgs;
|
|
5
6
|
const fs = require("fs");
|
|
6
7
|
const path = require("path");
|
|
7
8
|
const migration_runner_1 = require("../migration-runner");
|
|
@@ -48,14 +49,16 @@ async function listMigrations(options) {
|
|
|
48
49
|
const runner = new migration_runner_1.MigrationRunner({
|
|
49
50
|
migrationsDirectory: path.resolve(process.cwd(), options.migrationsDir),
|
|
50
51
|
stateStore,
|
|
52
|
+
strict: options.strict,
|
|
51
53
|
});
|
|
52
54
|
const status = await runner.status();
|
|
55
|
+
const missing = new Set(status.missing);
|
|
53
56
|
console.log('\nMigration Status:');
|
|
54
57
|
console.log('=================\n');
|
|
55
58
|
if (status.completed.length > 0) {
|
|
56
59
|
console.log('Completed:');
|
|
57
60
|
status.completed.forEach((name) => {
|
|
58
|
-
console.log(` ✓ ${name}`);
|
|
61
|
+
console.log(` ✓ ${name}${missing.has(name) ? ' (file missing)' : ''}`);
|
|
59
62
|
});
|
|
60
63
|
console.log('');
|
|
61
64
|
}
|
|
@@ -69,6 +72,9 @@ async function listMigrations(options) {
|
|
|
69
72
|
if (status.completed.length === 0 && status.pending.length === 0) {
|
|
70
73
|
console.log('No migrations found\n');
|
|
71
74
|
}
|
|
75
|
+
if (options.strict && status.missing.length > 0) {
|
|
76
|
+
throw new Error(`Strict mode: ${status.missing.length} recorded migration file(s) missing: ${status.missing.join(', ')}`);
|
|
77
|
+
}
|
|
72
78
|
}
|
|
73
79
|
function loadStateStore(storePath) {
|
|
74
80
|
if (!storePath) {
|
|
@@ -133,6 +139,7 @@ function parseArgs() {
|
|
|
133
139
|
let name;
|
|
134
140
|
const options = {
|
|
135
141
|
migrationsDir: './migrations',
|
|
142
|
+
strict: (0, migration_runner_1.parseStrictEnv)(),
|
|
136
143
|
};
|
|
137
144
|
if (args[1] && !args[1].startsWith('-')) {
|
|
138
145
|
name = args[1];
|
|
@@ -151,6 +158,9 @@ function parseArgs() {
|
|
|
151
158
|
else if (arg === '--template-file' || arg === '-t') {
|
|
152
159
|
options.templateFile = args[++i];
|
|
153
160
|
}
|
|
161
|
+
else if (arg === '--strict') {
|
|
162
|
+
options.strict = true;
|
|
163
|
+
}
|
|
154
164
|
}
|
|
155
165
|
return { command, name, options };
|
|
156
166
|
}
|
|
@@ -173,6 +183,7 @@ async function runDown(options) {
|
|
|
173
183
|
const runner = new migration_runner_1.MigrationRunner({
|
|
174
184
|
migrationsDirectory: path.resolve(process.cwd(), options.migrationsDir),
|
|
175
185
|
stateStore,
|
|
186
|
+
strict: options.strict,
|
|
176
187
|
});
|
|
177
188
|
await runner.down();
|
|
178
189
|
}
|
|
@@ -182,6 +193,7 @@ async function runUp(options) {
|
|
|
182
193
|
const runner = new migration_runner_1.MigrationRunner({
|
|
183
194
|
migrationsDirectory: path.resolve(process.cwd(), options.migrationsDir),
|
|
184
195
|
stateStore,
|
|
196
|
+
strict: options.strict,
|
|
185
197
|
});
|
|
186
198
|
await runner.up();
|
|
187
199
|
}
|
|
@@ -200,6 +212,8 @@ Options:
|
|
|
200
212
|
--store, -s <path> Path to state store module
|
|
201
213
|
--compiler, -c <compiler> Compiler to use (e.g., ts:./path/to/ts-compiler.js)
|
|
202
214
|
--template-file, -t <path> Template file for creating migrations
|
|
215
|
+
--strict Fail if a recorded migration's file is missing (default: off / tolerate).
|
|
216
|
+
Applies to up/list; down always fails hard on a missing rollback file.
|
|
203
217
|
|
|
204
218
|
Examples:
|
|
205
219
|
migrate create add-user-email
|
|
@@ -210,6 +224,7 @@ Examples:
|
|
|
210
224
|
|
|
211
225
|
Environment Variables:
|
|
212
226
|
NODE_ENV Set environment (e.g., development, production)
|
|
227
|
+
NSC__MIGRATE__STRICT 1|true|yes → fail on a missing recorded migration file (default: tolerate)
|
|
213
228
|
`);
|
|
214
229
|
}
|
|
215
230
|
if (require.main === module) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrate-cli.js","sourceRoot":"","sources":["../../../../../src/core/modules/migrate/cli/migrate-cli.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"migrate-cli.js","sourceRoot":"","sources":["../../../../../src/core/modules/migrate/cli/migrate-cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,10 +7,13 @@ export interface MigrationFile {
|
|
|
7
7
|
up: () => Promise<void>;
|
|
8
8
|
}
|
|
9
9
|
export declare const DEFAULT_MIGRATION_FILE_PATTERN: RegExp;
|
|
10
|
+
export declare function migrationId(title: string): string;
|
|
11
|
+
export declare function parseStrictEnv(value?: string | undefined): boolean;
|
|
10
12
|
export interface MigrationRunnerOptions {
|
|
11
13
|
migrationsDirectory: string;
|
|
12
14
|
pattern?: RegExp;
|
|
13
15
|
stateStore: MongoStateStore;
|
|
16
|
+
strict?: boolean;
|
|
14
17
|
}
|
|
15
18
|
export declare class MigrationRunner {
|
|
16
19
|
private options;
|
|
@@ -21,6 +24,7 @@ export declare class MigrationRunner {
|
|
|
21
24
|
down(): Promise<void>;
|
|
22
25
|
status(): Promise<{
|
|
23
26
|
completed: string[];
|
|
27
|
+
missing: string[];
|
|
24
28
|
pending: string[];
|
|
25
29
|
}>;
|
|
26
30
|
static create(migrationsDirectory: string, name: string): Promise<string>;
|
|
@@ -1,14 +1,33 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MigrationRunner = exports.DEFAULT_MIGRATION_FILE_PATTERN = void 0;
|
|
4
|
+
exports.migrationId = migrationId;
|
|
5
|
+
exports.parseStrictEnv = parseStrictEnv;
|
|
4
6
|
const fs = require("fs");
|
|
5
7
|
const path = require("path");
|
|
6
8
|
exports.DEFAULT_MIGRATION_FILE_PATTERN = /(?:(?<!\.d)\.ts|\.js)$/;
|
|
9
|
+
const MIGRATION_EXTENSION_PATTERN = /\.(ts|js)$/;
|
|
10
|
+
function migrationId(title) {
|
|
11
|
+
return title.replace(MIGRATION_EXTENSION_PATTERN, '');
|
|
12
|
+
}
|
|
13
|
+
function parseStrictEnv(value = process.env.NSC__MIGRATE__STRICT) {
|
|
14
|
+
if (value === undefined) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
const normalized = value.trim().toLowerCase();
|
|
18
|
+
if (['1', 'true', 'yes'].includes(normalized)) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
if (normalized !== '' && !['0', 'false', 'no'].includes(normalized)) {
|
|
22
|
+
console.warn(`[migrate] Unrecognized NSC__MIGRATE__STRICT value "${value}" — treating as false (tolerate).`);
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
7
26
|
class MigrationRunner {
|
|
8
27
|
options;
|
|
9
28
|
pattern;
|
|
10
29
|
constructor(options) {
|
|
11
|
-
this.options = options;
|
|
30
|
+
this.options = { ...options, strict: options.strict ?? parseStrictEnv() };
|
|
12
31
|
this.pattern = options.pattern || exports.DEFAULT_MIGRATION_FILE_PATTERN;
|
|
13
32
|
}
|
|
14
33
|
async loadMigrationFiles() {
|
|
@@ -17,7 +36,13 @@ class MigrationRunner {
|
|
|
17
36
|
.filter((file) => this.pattern.test(file))
|
|
18
37
|
.sort();
|
|
19
38
|
const migrations = [];
|
|
39
|
+
const seenIds = new Set();
|
|
20
40
|
for (const file of files) {
|
|
41
|
+
const id = migrationId(file);
|
|
42
|
+
if (seenIds.has(id)) {
|
|
43
|
+
console.warn(`[migrate] duplicate files for migration "${id}" — skipping ${file} (a same-named file was already loaded)`);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
21
46
|
const filePath = path.join(this.options.migrationsDirectory, file);
|
|
22
47
|
const module = require(filePath);
|
|
23
48
|
if (!module.up) {
|
|
@@ -26,6 +51,7 @@ class MigrationRunner {
|
|
|
26
51
|
}
|
|
27
52
|
const timestampMatch = file.match(/^(\d+)-/);
|
|
28
53
|
const timestamp = timestampMatch ? parseInt(timestampMatch[1], 10) : Date.now();
|
|
54
|
+
seenIds.add(id);
|
|
29
55
|
migrations.push({
|
|
30
56
|
down: module.down,
|
|
31
57
|
filePath,
|
|
@@ -40,8 +66,18 @@ class MigrationRunner {
|
|
|
40
66
|
const { _endMigration, _startMigration } = await Promise.resolve().then(() => require('./helpers/migration.helper'));
|
|
41
67
|
const allMigrations = await this.loadMigrationFiles();
|
|
42
68
|
const state = await this.options.stateStore.loadAsync();
|
|
43
|
-
const
|
|
44
|
-
const
|
|
69
|
+
const recorded = state.migrations || [];
|
|
70
|
+
const presentIds = new Set(allMigrations.map((m) => migrationId(m.title)));
|
|
71
|
+
const missing = recorded.filter((m) => !presentIds.has(migrationId(m.title)));
|
|
72
|
+
if (missing.length > 0) {
|
|
73
|
+
const list = missing.map((m) => m.title).join(', ');
|
|
74
|
+
if (this.options.strict) {
|
|
75
|
+
throw new Error(`Strict mode: ${missing.length} recorded migration file(s) missing: ${list}`);
|
|
76
|
+
}
|
|
77
|
+
console.warn(`[migrate] ${missing.length} recorded migration file(s) missing — tolerated (strict=false): ${list}`);
|
|
78
|
+
}
|
|
79
|
+
const completedIds = new Set(recorded.map((m) => migrationId(m.title)));
|
|
80
|
+
const pendingMigrations = allMigrations.filter((m) => !completedIds.has(migrationId(m.title)));
|
|
45
81
|
if (pendingMigrations.length === 0) {
|
|
46
82
|
console.log('No pending migrations');
|
|
47
83
|
return;
|
|
@@ -81,9 +117,10 @@ class MigrationRunner {
|
|
|
81
117
|
}
|
|
82
118
|
const lastMigration = completedMigrations[completedMigrations.length - 1];
|
|
83
119
|
const allMigrations = await this.loadMigrationFiles();
|
|
84
|
-
const
|
|
120
|
+
const rollbackId = migrationId(lastMigration.title);
|
|
121
|
+
const migrationToRollback = allMigrations.find((m) => migrationId(m.title) === rollbackId);
|
|
85
122
|
if (!migrationToRollback) {
|
|
86
|
-
throw new Error(`Migration file not found: ${lastMigration.title}
|
|
123
|
+
throw new Error(`Migration file not found: ${lastMigration.title} — restore the file from git to roll back.`);
|
|
87
124
|
}
|
|
88
125
|
if (!migrationToRollback.down) {
|
|
89
126
|
throw new Error(`Migration ${lastMigration.title} has no 'down' function`);
|
|
@@ -108,9 +145,12 @@ class MigrationRunner {
|
|
|
108
145
|
const allMigrations = await this.loadMigrationFiles();
|
|
109
146
|
const state = await this.options.stateStore.loadAsync();
|
|
110
147
|
const completedMigrations = (state.migrations || []).map((m) => m.title);
|
|
148
|
+
const completedIds = new Set(completedMigrations.map(migrationId));
|
|
149
|
+
const presentIds = new Set(allMigrations.map((m) => migrationId(m.title)));
|
|
111
150
|
return {
|
|
112
151
|
completed: completedMigrations,
|
|
113
|
-
|
|
152
|
+
missing: completedMigrations.filter((title) => !presentIds.has(migrationId(title))),
|
|
153
|
+
pending: allMigrations.filter((m) => !completedIds.has(migrationId(m.title))).map((m) => m.title),
|
|
114
154
|
};
|
|
115
155
|
}
|
|
116
156
|
static async create(migrationsDirectory, name) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-runner.js","sourceRoot":"","sources":["../../../../src/core/modules/migrate/migration-runner.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"migration-runner.js","sourceRoot":"","sources":["../../../../src/core/modules/migrate/migration-runner.ts"],"names":[],"mappings":"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"}
|