@lenne.tech/nest-server 11.32.0 → 11.32.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.
@@ -0,0 +1,84 @@
1
+ # Migration Guide: 11.32.0 → 11.32.1
2
+
3
+ ## Overview
4
+
5
+ | Category | Change | Effort |
6
+ |----------|--------|--------|
7
+ | **Bugfix** | A missing `migrations/` directory no longer blocks the server boot | None — automatic |
8
+ | **Bugfix** | A spec in `src/core/` no longer breaks vendor-mode projects | None — automatic |
9
+
10
+ **No code changes required.** Both fixes are internal.
11
+
12
+ ## Quick Migration
13
+
14
+ ```bash
15
+ pnpm update @lenne.tech/nest-server
16
+ ```
17
+
18
+ Vendor-mode projects: `/lt-dev:backend:update-nest-server-core`.
19
+
20
+ ---
21
+
22
+ ## What was fixed
23
+
24
+ ### A missing `migrations/` directory no longer blocks the boot
25
+
26
+ `MigrationRunner.loadMigrationFiles()` called `fs.readdirSync()` without checking that the
27
+ directory exists. A missing directory threw `ENOENT` — and because the standard start script is
28
+ `migrate:up && start:local`, the `&&` turned that into a server that never starts, with an error
29
+ that does not point at the cause.
30
+
31
+ This is a state people produce routinely: *"delete all migrations"* reads to most as *"throw the
32
+ folder away"*.
33
+
34
+ A missing directory now means the same thing as an empty one — there are no migrations:
35
+
36
+ ```
37
+ [migrate] migrations directory not found — treating as empty: ./migrations
38
+ ```
39
+
40
+ `up()` and `status()` continue and exit 0. **`down()` is unchanged and still fails hard** —
41
+ rollback is an explicit operator action, never a boot path, and an exit 0 with no rollback
42
+ performed would mislead scripted rollbacks. `NSC__MIGRATE__STRICT=true` still turns a
43
+ recorded-but-missing migration into a hard error, so the integrity guard is intact.
44
+
45
+ If your project kept a `migrations/.gitkeep` purely to work around this, you can drop it — though
46
+ keeping it does no harm.
47
+
48
+ > Tracked as DEV-2634.
49
+
50
+ ### A `src/core/` spec no longer breaks vendor-mode projects
51
+
52
+ `hub-mermaid.helper.spec.ts` mixed a value and a type import in one statement
53
+ (`import { buildErDiagram, type HubModelDescriptor } from …`). The lt CLI's vendor conversion drops
54
+ the inline `type` specifier, so the file arrived in vendored projects as
55
+ `import { buildErDiagram }` and failed to compile with `TS2304: Cannot find name
56
+ 'HubModelDescriptor'` — breaking `pnpm run check` in every freshly generated vendor-mode project.
57
+
58
+ The import is now split into two statements, which survives the conversion. Only vendor-mode
59
+ projects were affected; npm-mode consumers never saw it.
60
+
61
+ > The underlying CLI defect is tracked separately. Splitting the import keeps `src/core/`
62
+ > vendor-safe regardless.
63
+
64
+ ---
65
+
66
+ ## Compatibility Notes
67
+
68
+ | Pattern | Status |
69
+ |---------|:------:|
70
+ | Everything from 11.32.0 | Unchanged |
71
+ | `MigrationRunner` public API | Unchanged |
72
+ | `down()` behaviour on a missing rollback file | Unchanged (still hard error) |
73
+ | `NSC__MIGRATE__STRICT` | Unchanged |
74
+
75
+ Still relevant from the previous release: **[the two security overrides your project needs](11.31.3-to-11.32.0.md#security-add-two-overrides)** — pnpm `overrides:` are not inherited from this package. If you skipped that step, do it now.
76
+
77
+ ---
78
+
79
+ ## Troubleshooting
80
+
81
+ | Symptom | Cause | Fix |
82
+ |---------|-------|-----|
83
+ | `ENOENT: no such file or directory, scandir './migrations'` on start | Pre-11.32.1 | Update; no code change needed |
84
+ | `TS2304: Cannot find name 'HubModelDescriptor'` in a vendored core | Pre-11.32.1 vendored copy | Re-sync the core, or split the import in that one spec by hand |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lenne.tech/nest-server",
3
- "version": "11.32.0",
3
+ "version": "11.32.1",
4
4
  "description": "Modern, fast, powerful Node.js web framework in TypeScript based on Nest with a GraphQL API and a connection to MongoDB (or other databases).",
5
5
  "keywords": [
6
6
  "node",
@@ -1,6 +1,13 @@
1
1
  import { describe, expect, it } from 'vitest';
2
2
 
3
- import { buildErDiagram, type HubModelDescriptor } from './hub-mermaid.helper';
3
+ // Value and type imports are deliberately split into two statements. The lt CLI's vendor
4
+ // conversion drops an INLINE `type` specifier from a mixed import — `{ buildErDiagram, type
5
+ // HubModelDescriptor }` arrives in a vendored project as `{ buildErDiagram }`, and the file then
6
+ // fails to compile with TS2304. Keeping the two forms separate survives the conversion.
7
+ // (The CLI defect is tracked separately; this keeps src/core/ vendor-safe meanwhile.)
8
+ import type { HubModelDescriptor } from './hub-mermaid.helper';
9
+
10
+ import { buildErDiagram } from './hub-mermaid.helper';
4
11
 
5
12
  describe('buildErDiagram', () => {
6
13
  const models: HubModelDescriptor[] = [
@@ -159,6 +159,23 @@ export class MigrationRunner {
159
159
  * compiled-production intent; the duplicate is skipped with a warning.
160
160
  */
161
161
  private async loadMigrationFiles(): Promise<MigrationFile[]> {
162
+ // A MISSING directory means the same thing as an EMPTY one: there are no migrations.
163
+ // Treat it that way instead of throwing ENOENT.
164
+ //
165
+ // This is a boot blocker otherwise: `pnpm start` is `migrate:up && start:local`, so the `&&`
166
+ // turns a readdirSync ENOENT into a server that will not start — with an error that does not
167
+ // point at the cause. And it is a state people produce routinely: "delete all migrations"
168
+ // reads to most as "throw the folder away".
169
+ //
170
+ // The runner already tolerates the RELATED case — a migration recorded in the database whose
171
+ // file is gone is non-fatal unless `NSC__MIGRATE__STRICT` is set. Only the wholly absent
172
+ // directory fell outside that tolerance. `down()` stays hard, consistent with its own
173
+ // reasoning. See DEV-2634.
174
+ if (!fs.existsSync(this.options.migrationsDirectory)) {
175
+ console.warn(`[migrate] migrations directory not found — treating as empty: ${this.options.migrationsDirectory}`);
176
+ return [];
177
+ }
178
+
162
179
  const files = fs
163
180
  .readdirSync(this.options.migrationsDirectory)
164
181
  .filter((file) => this.pattern.test(file))