@lenne.tech/nest-server 11.42.6 → 11.42.8
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/rules/configurable-features.md +1 -0
- package/FRAMEWORK-API.md +1 -1
- package/dist/core/common/helpers/swagger.helper.d.ts +11 -0
- package/dist/core/common/helpers/swagger.helper.js +360 -0
- package/dist/core/common/helpers/swagger.helper.js.map +1 -0
- package/dist/core/common/interfaces/swagger-setup-options.interface.d.ts +33 -0
- package/dist/core/common/interfaces/swagger-setup-options.interface.js +3 -0
- package/dist/core/common/interfaces/swagger-setup-options.interface.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth.controller.js +1 -0
- package/dist/core/modules/better-auth/core-better-auth.controller.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/main.js +8 -14
- package/dist/main.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/migration-guides/11.42.5-to-11.42.6.md +16 -0
- package/migration-guides/11.42.6-to-11.42.7.md +115 -0
- package/migration-guides/11.42.7-to-11.42.8.md +74 -0
- package/package.json +5 -5
- package/src/core/common/helpers/swagger.helper.ts +536 -0
- package/src/core/common/interfaces/swagger-setup-options.interface.ts +131 -0
- package/src/core/modules/better-auth/core-better-auth.controller.ts +1 -0
- package/src/index.ts +2 -0
- package/src/main.ts +9 -15
|
@@ -14,11 +14,26 @@
|
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
16
|
pnpm update @lenne.tech/nest-server
|
|
17
|
+
pnpm run update # starter-based projects: raises every exact pin you share with the framework
|
|
17
18
|
```
|
|
18
19
|
|
|
19
20
|
Then check `main.ts` as described in §1. Vendor-mode projects pick up the core update and need the
|
|
20
21
|
same check.
|
|
21
22
|
|
|
23
|
+
**Exact pins below the framework's own split packages in two.** A project that pins `@nestjs/core`,
|
|
24
|
+
`@nestjs/common`, `mongoose` or another package the framework also declares, at a LOWER exact version,
|
|
25
|
+
gets two copies of it. The install only prints a peer warning. The failure appears in the tests, as a
|
|
26
|
+
dependency-injection error that does not look like a version problem (see Troubleshooting).
|
|
27
|
+
`pnpm run update` (`extras/sync-packages.mjs` in starter-based projects) raises those pins. Without
|
|
28
|
+
that script, list the deviations and raise each one:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
node -e "const f=require('@lenne.tech/nest-server/package.json'),p=require('./package.json');const want={...f.dependencies,...f.peerDependencies};for(const s of ['dependencies','devDependencies'])for(const[k,v]of Object.entries(p[s]||{}))if(want[k]&&/^\d/.test(want[k])&&want[k]!==v)console.log(s,k,v,'->',want[k])"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
An `overrides:` entry in `pnpm-workspace.yaml` must not pin such a package below the framework's
|
|
35
|
+
version either: it forces the framework onto the older version without anybody having tested it.
|
|
36
|
+
|
|
22
37
|
## 1. Keep `useBodyParser()` next to a path-scoped parser
|
|
23
38
|
|
|
24
39
|
§1 of the [11.42.3 → 11.42.4 guide](./11.42.3-to-11.42.4.md) recommended moving the body limit from
|
|
@@ -86,6 +101,7 @@ receive these fixes with their template update.
|
|
|
86
101
|
| ------- | ----- | --- |
|
|
87
102
|
| Boot warning "No global json body parser is registered" | `main.ts` registers a path-scoped `json()` and no global parser | Add `server.useBodyParser('json')` to `main.ts` (§1) |
|
|
88
103
|
| Requests arrive with an empty body outside one path; sign-in reports "Missing input" | Same cause, on a version before 11.42.6 | Same fix (§1) |
|
|
104
|
+
| Tests fail with `Nest can't resolve dependencies of the MongooseCoreModule (MongooseConnectionName, ?)` (often hidden behind `Cannot read properties of undefined` from a `beforeAll` that swallows it) | Two copies of `@nestjs/core`: the project pins it below the framework's version | Raise the exact pins (Quick Migration), then check that `pnpm-lock.yaml` holds one copy of each |
|
|
89
105
|
| `check:overrides` prints `could not obtain an audit report (fetch failed)` | The npm registry was not reachable during the audit | Re-run with network access, or pass a captured report with `--audit-file` |
|
|
90
106
|
| `check:overrides` fails with `records a failed audit, not a result` | The report passed with `--audit-file` is a pnpm error, not an audit | Capture the report again once the registry answers |
|
|
91
107
|
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Migration Guide: 11.42.6 → 11.42.7
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
| Category | Details |
|
|
6
|
+
| -------------------- | --------------------------------------------------------------------------------------------------------------- |
|
|
7
|
+
| **New Feature** | `setupSwagger()` — a Swagger document that says how each route is reached: security, API-token scopes, tenant header (§1) |
|
|
8
|
+
| **New Feature** | Optional second document with only the routes an API token may call (§2) |
|
|
9
|
+
| **Dependencies** | `nodemailer` 10.0.15, `@modelcontextprotocol/sdk` 1.32.1, dev: `oxlint` 1.87.0 (§3) |
|
|
10
|
+
| **Breaking Changes** | None |
|
|
11
|
+
| **Migration Effort** | Optional. Switching `main.ts` to the helper replaces the hand-built `DocumentBuilder` block with one call |
|
|
12
|
+
|
|
13
|
+
## Quick Migration
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pnpm update @lenne.tech/nest-server
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Nothing changes until `main.ts` calls the new helper. Vendor-mode projects pick it up with the core
|
|
20
|
+
update.
|
|
21
|
+
|
|
22
|
+
## 1. `setupSwagger()` instead of a hand-built `DocumentBuilder`
|
|
23
|
+
|
|
24
|
+
The starters built the document like this:
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
const config = new DocumentBuilder().setTitle('…').addBearerAuth().build();
|
|
28
|
+
SwaggerModule.setup('swagger', server, () => SwaggerModule.createDocument(server, config, { … }), {
|
|
29
|
+
jsonDocumentUrl: '/api-docs-json',
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`addBearerAuth()` registers a scheme but attaches it to no route. A token entered under "Authorize" is
|
|
34
|
+
therefore sent with almost no request: in one project 10 of 158 operations carried a security entry.
|
|
35
|
+
And what a caller needs to know — is the route public, which API-token scope does it release, does it
|
|
36
|
+
read the tenant header — lived only in decorators.
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import { setupSwagger } from '@lenne.tech/nest-server';
|
|
40
|
+
|
|
41
|
+
setupSwagger(server, {
|
|
42
|
+
description: 'API of my project',
|
|
43
|
+
documentOptions: {
|
|
44
|
+
extraModels: [CoreUserModel, CoreAuthModel, User, PersistenceModel, CorePersistenceModel, FilterArgs],
|
|
45
|
+
},
|
|
46
|
+
title: 'My Project API',
|
|
47
|
+
version: packageJson.version,
|
|
48
|
+
});
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Paths stay as before (`/swagger`, `/api-docs-json`) unless `path` / `jsonDocumentUrl` say otherwise.
|
|
52
|
+
What the document now contains, read from the same metadata the guards read:
|
|
53
|
+
|
|
54
|
+
| Feature in the config | In the document |
|
|
55
|
+
| --- | --- |
|
|
56
|
+
| always | `bearer` as a global security requirement — "Authorize" applies to every route. Public routes (no `@Roles`, or `S_EVERYONE`) carry `security: []` |
|
|
57
|
+
| `betterAuth` + `cookies` on | the session cookie (`iam.session_token`, or the name `COOKIE_PREFIX` / `basePath` produce) as a second, alternative requirement |
|
|
58
|
+
| `apiTokens` on | per operation `x-api-token-scopes` and a description line: "allowed with scope `read`" or "not allowed on this route". `@ApiTokenScopes()` on the method replaces the class declaration, exactly as in `assertApiTokenScopes()` |
|
|
59
|
+
| `multiTenancy` on | a reusable `TenantHeader` parameter (`X-Tenant-Id`, or `multiTenancy.headerName`) on every operation except public ones and `@SkipTenantCheck()`; its description says which callers need it (sessions and personal tokens) and which may omit it (company tokens) |
|
|
60
|
+
|
|
61
|
+
Optional:
|
|
62
|
+
|
|
63
|
+
- `operationTags: (operation) => string[] | undefined` regroups operations by use case instead of by
|
|
64
|
+
controller; `tags: [{ name, description }]` orders and describes them.
|
|
65
|
+
- `configureBuilder: (builder) => builder` adds servers, contact or further schemes.
|
|
66
|
+
- `customOptions` is passed to `SwaggerModule.setup()` for both documents.
|
|
67
|
+
|
|
68
|
+
Each operation is mapped to its handler through the default operation id (`<Controller>_<method>`, with
|
|
69
|
+
`[<n>]` for a handler serving several paths). An own `operationIdFactory` is therefore refused. Two different controller classes with the same name
|
|
70
|
+
cannot be told apart; their operations are left as Swagger built them, with a warning.
|
|
71
|
+
|
|
72
|
+
## 2. A document for API-token callers
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
setupSwagger(server, { …, apiTokenView: true });
|
|
76
|
+
// or: apiTokenView: { path: 'swagger-partner', title: 'Partner API' }
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Serves a second document (default: UI `swagger-api-tokens`, JSON `/api-docs-api-tokens-json`) with only
|
|
80
|
+
the operations that release a scope, the bearer scheme as the only requirement and without the schemas
|
|
81
|
+
nothing refers to any more. Keep its path outside the path of the full UI, which serves its assets below
|
|
82
|
+
its own path.
|
|
83
|
+
|
|
84
|
+
The tenant header stays in this view while personal (user) tokens are enabled (`apiTokens.userTokens`,
|
|
85
|
+
the default): such a token without a company restriction chooses the company like a session does, and
|
|
86
|
+
without the header it is checked against its global roles and refused on company routes. With company
|
|
87
|
+
tokens only (`userTokens: false`) the header is dropped — a company token carries its company.
|
|
88
|
+
|
|
89
|
+
## 3. Dependency updates
|
|
90
|
+
|
|
91
|
+
Patch-level maintenance, no code changes required:
|
|
92
|
+
|
|
93
|
+
| Package | Old | New | Section |
|
|
94
|
+
| --- | --- | --- | --- |
|
|
95
|
+
| `nodemailer` | 10.0.14 | 10.0.15 | dependencies |
|
|
96
|
+
| `@modelcontextprotocol/sdk` | 1.32.0 | 1.32.1 | dependencies |
|
|
97
|
+
| `oxlint` | 1.86.0 | 1.87.0 | devDependencies |
|
|
98
|
+
|
|
99
|
+
A project that pins `oxlint` itself should raise it to 1.87.0 alongside the framework —
|
|
100
|
+
`pnpm run update` in starter-based projects does this. A project that carries a `nodemailer`
|
|
101
|
+
override matching the framework's version (the starter does) should raise it to `10.0.15`.
|
|
102
|
+
|
|
103
|
+
## Compatibility Notes
|
|
104
|
+
|
|
105
|
+
- The helper is additive. `DocumentBuilder` + `SwaggerModule.setup()` keep working unchanged.
|
|
106
|
+
- The document is built on the first request, as before.
|
|
107
|
+
- `buildSwaggerDocument()` and `buildApiTokenSwaggerDocument()` are exported for tests: a project can
|
|
108
|
+
assert in its e2e suite that a route documents the scope it enforces.
|
|
109
|
+
|
|
110
|
+
## References
|
|
111
|
+
|
|
112
|
+
- Helper: `src/core/common/helpers/swagger.helper.ts`
|
|
113
|
+
- Options: `src/core/common/interfaces/swagger-setup-options.interface.ts`
|
|
114
|
+
- Tests: `tests/unit/swagger-helper.spec.ts`
|
|
115
|
+
- [nest-server-starter](https://github.com/lenneTech/nest-server-starter) `src/main.ts`
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Migration Guide: 11.42.7 → 11.42.8
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
| Category | Details |
|
|
6
|
+
| -------------------- | ---------------------------------------------------------------------------------------------------- |
|
|
7
|
+
| **Bugfix** | `setupSwagger()` enriches every operation an `@All()` route produces, including `SEARCH` (§1) |
|
|
8
|
+
| **Bugfix** | The Better-Auth pass-through route no longer appears as `/iam/{path}` in the Swagger document (§2) |
|
|
9
|
+
| **Dependencies** | dev: `vite` 8.3.3; override `js-yaml` 5.4.3 (§3) |
|
|
10
|
+
| **Breaking Changes** | None |
|
|
11
|
+
| **Migration Effort** | None for most projects. Regenerate a client built from `/api-docs-json` if you keep one (§2) |
|
|
12
|
+
|
|
13
|
+
## Quick Migration
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pnpm update @lenne.tech/nest-server
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Vendor-mode projects pick it up with the core update.
|
|
20
|
+
|
|
21
|
+
## 1. `SEARCH` operations of `@All()` routes are enriched
|
|
22
|
+
|
|
23
|
+
For an `@All()` route, `@nestjs/swagger` documents one operation per HTTP method — including
|
|
24
|
+
`SEARCH`, which no OpenAPI version lists as a path-item method. 11.42.7 walked a fixed list of
|
|
25
|
+
methods and skipped it, so that one operation stayed as Swagger built it: no API-token scope line,
|
|
26
|
+
no `security: []` on a public route, no tenant header, and `operationTags` did not reach it — it
|
|
27
|
+
landed in its own tag group next to the regrouped siblings.
|
|
28
|
+
|
|
29
|
+
The helper now reads the operations from the path item itself, so `SEARCH` (and any other method
|
|
30
|
+
`@nestjs/swagger` emits) is treated like every other operation — in the full document and in the
|
|
31
|
+
API-token view.
|
|
32
|
+
|
|
33
|
+
Nothing to change in your code. If you assert on the document in tests, a `search` operation of an
|
|
34
|
+
`@All()` route now carries the same `x-api-token-scopes`, description line and tags as its siblings.
|
|
35
|
+
|
|
36
|
+
## 2. `/iam/{path}` is gone from the document
|
|
37
|
+
|
|
38
|
+
`CoreBetterAuthController.handlePluginRoutes` (`@All('*path')`) forwards every other `/iam/*` request
|
|
39
|
+
to Better-Auth's own handler. It appeared in Swagger as eight `/iam/{path}` operations without
|
|
40
|
+
parameters or description. It is now `@ApiExcludeEndpoint()`; the route itself is unchanged.
|
|
41
|
+
|
|
42
|
+
- **Generated clients:** a client generated from `/api-docs-json` (hey-api, openapi-generator, …)
|
|
43
|
+
loses its `coreBetterAuthControllerHandlePluginRoutes*` functions on the next generation. They
|
|
44
|
+
could not express any real Better-Auth call, so nothing should depend on them — but regenerate and
|
|
45
|
+
let the compiler confirm it.
|
|
46
|
+
- **Own controller:** a project controller that **overrides** `handlePluginRoutes` (re-declaring
|
|
47
|
+
`@All('*path')`) must also re-declare `@ApiExcludeEndpoint()` to keep it out of the document.
|
|
48
|
+
Decorator metadata belongs to the method, so an override starts without it. A controller that
|
|
49
|
+
only inherits the method is covered automatically.
|
|
50
|
+
|
|
51
|
+
## 3. Dependency updates
|
|
52
|
+
|
|
53
|
+
Maintenance only, nothing to change in your project:
|
|
54
|
+
|
|
55
|
+
| Package | Old | New | Where |
|
|
56
|
+
| --- | --- | --- | --- |
|
|
57
|
+
| `vite` | 8.3.2 | 8.3.3 | devDependencies (test tooling) |
|
|
58
|
+
| `js-yaml` 5.x | 5.4.2 | 5.4.3 | override target in `pnpm-workspace.yaml` (parser bug fix) |
|
|
59
|
+
|
|
60
|
+
`mongoose` 9.11.0 / `mongodb` 7.7.0 are deliberately not part of this release: the framework and the
|
|
61
|
+
starter have to raise `mongodb` together, because two driver copies make Better-Auth's Mongo adapter
|
|
62
|
+
reject each other's ids.
|
|
63
|
+
|
|
64
|
+
## Compatibility Notes
|
|
65
|
+
|
|
66
|
+
- Both changes only affect the generated Swagger/OpenAPI document. Routing, guards and API-token
|
|
67
|
+
enforcement are unchanged.
|
|
68
|
+
- The document gets smaller: the framework's own test server goes from 142 to 134 operations.
|
|
69
|
+
|
|
70
|
+
## References
|
|
71
|
+
|
|
72
|
+
- Helper: `src/core/common/helpers/swagger.helper.ts` (`operationsOf()`)
|
|
73
|
+
- Controller: `src/core/modules/better-auth/core-better-auth.controller.ts` (`handlePluginRoutes`)
|
|
74
|
+
- Tests: `tests/unit/swagger-helper.spec.ts`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lenne.tech/nest-server",
|
|
3
|
-
"version": "11.42.
|
|
3
|
+
"version": "11.42.8",
|
|
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",
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"@apollo/server": "5.5.1",
|
|
93
93
|
"@as-integrations/express5": "1.1.2",
|
|
94
94
|
"@getbrevo/brevo": "6.0.3",
|
|
95
|
-
"@modelcontextprotocol/sdk": "1.32.
|
|
95
|
+
"@modelcontextprotocol/sdk": "1.32.1",
|
|
96
96
|
"@nestjs/apollo": "13.4.5",
|
|
97
97
|
"@nestjs/common": "11.2.7",
|
|
98
98
|
"@nestjs/core": "11.2.7",
|
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
"mongoose": "9.10.4",
|
|
130
130
|
"multer": "2.4.0",
|
|
131
131
|
"node-mailjet": "6.0.11",
|
|
132
|
-
"nodemailer": "10.0.
|
|
132
|
+
"nodemailer": "10.0.15",
|
|
133
133
|
"passport": "0.7.0",
|
|
134
134
|
"passport-jwt": "4.0.1",
|
|
135
135
|
"reflect-metadata": "0.2.2",
|
|
@@ -212,7 +212,7 @@
|
|
|
212
212
|
"npm-watch": "0.13.0",
|
|
213
213
|
"otpauth": "9.5.2",
|
|
214
214
|
"oxfmt": "0.71.0",
|
|
215
|
-
"oxlint": "1.
|
|
215
|
+
"oxlint": "1.87.0",
|
|
216
216
|
"rimraf": "6.1.3",
|
|
217
217
|
"smtp-server": "3.19.17",
|
|
218
218
|
"ts-node": "10.9.2",
|
|
@@ -221,7 +221,7 @@
|
|
|
221
221
|
"tus-js-client": "4.3.1",
|
|
222
222
|
"typescript": "5.9.3",
|
|
223
223
|
"unplugin-swc": "2.0.0",
|
|
224
|
-
"vite": "8.3.
|
|
224
|
+
"vite": "8.3.3",
|
|
225
225
|
"vite-plugin-node": "8.0.0",
|
|
226
226
|
"vitest": "4.1.11"
|
|
227
227
|
},
|