@inertia-node/nest 0.1.0 → 0.1.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.
Files changed (2) hide show
  1. package/README.md +255 -0
  2. package/package.json +4 -3
package/README.md ADDED
@@ -0,0 +1,255 @@
1
+ # @inertia-node/nest
2
+
3
+ NestJS adapter for Inertia.js on the Express platform.
4
+
5
+ `@inertia-node/nest` integrates Inertia into Nest controllers through a module, interceptor, decorators, guards, and a session adapter. It keeps the same protocol behavior as the Express package while using Nest conventions for routing and dependency injection.
6
+
7
+ ## Features
8
+
9
+ - Provides `InertiaModule.forRoot(...)` for application-level setup.
10
+ - Provides `InertiaInterceptor` for controller response conversion.
11
+ - Provides `@Inertia(...)` and `@InertiaRenderOptions(...)` decorators.
12
+ - Provides `InertiaAuthGuard` and `InertiaGuestGuard`.
13
+ - Supports Express sessions through `nestExpressSessionAdapter()`.
14
+ - Supports shared props, lazy props, deferred props, validation errors, flash data, redirects, and SSR.
15
+ - Re-exports shared helpers from `@inertia-node/core`.
16
+
17
+ ## Installation
18
+
19
+ ```sh
20
+ pnpm add @inertia-node/nest @nestjs/common @nestjs/core @nestjs/platform-express express express-session
21
+ ```
22
+
23
+ ```sh
24
+ npm install @inertia-node/nest @nestjs/common @nestjs/core @nestjs/platform-express express express-session
25
+ ```
26
+
27
+ Peer dependencies:
28
+
29
+ - `@nestjs/common >=10 <12`
30
+ - `@nestjs/core >=10 <12`
31
+ - `express >=4.18 <6`
32
+ - `reflect-metadata >=0.1 <1`
33
+ - `rxjs >=7 <8`
34
+
35
+ ## Quick Start
36
+
37
+ ```ts
38
+ import {
39
+ Controller,
40
+ Get,
41
+ Module,
42
+ UseGuards,
43
+ UseInterceptors,
44
+ } from "@nestjs/common";
45
+ import { NestFactory } from "@nestjs/core";
46
+ import session from "express-session";
47
+ import {
48
+ Inertia,
49
+ InertiaAuthGuard,
50
+ InertiaGuestGuard,
51
+ InertiaInterceptor,
52
+ InertiaModule,
53
+ inertiaAuth,
54
+ nestExpressSessionAdapter,
55
+ } from "@inertia-node/nest";
56
+
57
+ type User = {
58
+ id: number;
59
+ name: string;
60
+ email: string;
61
+ };
62
+
63
+ async function findUser(id?: number): Promise<User | null> {
64
+ if (!id) return null;
65
+ return { id, name: "Ada Lovelace", email: "ada@example.com" };
66
+ }
67
+
68
+ @Controller()
69
+ @UseInterceptors(InertiaInterceptor)
70
+ class PageController {
71
+ @Get("/dashboard")
72
+ @UseGuards(InertiaAuthGuard)
73
+ @Inertia("Dashboard/Index")
74
+ dashboard() {
75
+ return {
76
+ stats: {
77
+ users: 42,
78
+ orders: 128,
79
+ },
80
+ };
81
+ }
82
+
83
+ @Get("/login")
84
+ @UseGuards(InertiaGuestGuard)
85
+ @Inertia("Auth/Login")
86
+ login() {
87
+ return {
88
+ title: "Sign in",
89
+ };
90
+ }
91
+ }
92
+
93
+ @Module({
94
+ imports: [
95
+ InertiaModule.forRoot({
96
+ version: "1",
97
+ session: nestExpressSessionAdapter(),
98
+ auth: inertiaAuth({
99
+ getUser: (req) => findUser(req.session?.userId),
100
+ login: (req, user: User) => {
101
+ req.session!.userId = user.id;
102
+ },
103
+ logout: (req) => {
104
+ delete req.session!.userId;
105
+ },
106
+ serializeUser: (user) => ({
107
+ id: user.id,
108
+ name: user.name,
109
+ }),
110
+ redirectTo: "/login",
111
+ home: "/dashboard",
112
+ }),
113
+ share: async ({ request }) => ({
114
+ locale: request.headers["accept-language"] ?? "en",
115
+ }),
116
+ rootView: ({ page }) => `
117
+ <!doctype html>
118
+ <html>
119
+ <head>
120
+ <meta charset="utf-8" />
121
+ <script type="module" src="/src/app.tsx"></script>
122
+ </head>
123
+ <body>
124
+ <div id="app" data-page='${page}'></div>
125
+ </body>
126
+ </html>`,
127
+ }),
128
+ ],
129
+ controllers: [PageController],
130
+ })
131
+ class AppModule {}
132
+
133
+ async function bootstrap() {
134
+ const app = await NestFactory.create(AppModule);
135
+
136
+ app.use(
137
+ session({
138
+ secret: process.env.SESSION_SECRET ?? "replace-me",
139
+ resave: false,
140
+ saveUninitialized: false,
141
+ }),
142
+ );
143
+
144
+ await app.listen(3000);
145
+ }
146
+
147
+ void bootstrap();
148
+ ```
149
+
150
+ ## Controller Patterns
151
+
152
+ Use the decorator form when a route always renders one component:
153
+
154
+ ```ts
155
+ @Get("/users")
156
+ @Inertia("Users/Index")
157
+ index() {
158
+ return {
159
+ users: await loadUsers(),
160
+ };
161
+ }
162
+ ```
163
+
164
+ Use explicit helper results when a route decides what to do at runtime:
165
+
166
+ ```ts
167
+ @Post("/users")
168
+ async store() {
169
+ const valid = false;
170
+
171
+ if (!valid) {
172
+ return Inertia.backWithErrors({
173
+ email: ["Email is required."],
174
+ });
175
+ }
176
+
177
+ return Inertia.redirect("/users");
178
+ }
179
+ ```
180
+
181
+ Supported explicit results:
182
+
183
+ - `Inertia.render(component, props?, options?)`
184
+ - `Inertia.redirect(location, status?)`
185
+ - `Inertia.location(location)`
186
+ - `Inertia.backWithErrors(errors, options?)`
187
+
188
+ ## Module API
189
+
190
+ `InertiaModule.forRoot(options)` accepts `NestInertiaOptions`.
191
+
192
+ Common options:
193
+
194
+ - `version`
195
+ - `rootView`
196
+ - `share`
197
+ - `session`
198
+ - `auth`
199
+ - `ssr`
200
+ - `withAllErrors`
201
+
202
+ The module can also receive a prebuilt `@inertia-node/core` instance through `instance`.
203
+
204
+ ## Auth and Session
205
+
206
+ `nestExpressSessionAdapter()` maps an Express session object to the shared session contract. Register `express-session` before serving routes that depend on auth, flash, or validation errors.
207
+
208
+ `InertiaAuthGuard` redirects unauthenticated users to `auth.redirectTo`, defaulting to `"/login"`.
209
+
210
+ `InertiaGuestGuard` redirects authenticated users to `auth.home`, defaulting to `"/dashboard"`.
211
+
212
+ ## SSR
213
+
214
+ ```ts
215
+ InertiaModule.forRoot({
216
+ ssr: {
217
+ enabled: true,
218
+ url: "http://127.0.0.1:13714/render",
219
+ timeoutMs: 1500,
220
+ },
221
+ });
222
+ ```
223
+
224
+ Use `@inertia-node/ssr` to run the renderer process.
225
+
226
+ ## Exports
227
+
228
+ - `InertiaModule`
229
+ - `InertiaInterceptor`
230
+ - `InertiaAuthGuard`
231
+ - `InertiaGuestGuard`
232
+ - `Inertia`
233
+ - `InertiaRenderOptions`
234
+ - `nestExpressSessionAdapter`
235
+ - `InertiaService`
236
+ - `NestInertiaOptions`
237
+ - `NestInertiaAsyncOptions`
238
+ - `NestRenderOptions`
239
+ - `InertiaControllerResult`
240
+ - Re-exported core helpers such as `always`, `defer`, `merge`, `optional`, `validationError`, `inertiaAuth`, and `createInertia`
241
+
242
+ ## Troubleshooting
243
+
244
+ - If the controller response is returned as normal JSON, confirm `@UseInterceptors(InertiaInterceptor)` is applied.
245
+ - If auth always fails, confirm `express-session` is registered and `session: nestExpressSessionAdapter()` is configured.
246
+ - If validation redirects throw, confirm a session adapter is configured.
247
+ - If full-page requests are missing app HTML, confirm `rootView` returns a document with `data-page='${page}'`.
248
+
249
+ ## Documentation
250
+
251
+ - Repository: https://github.com/inertia-node/inertia-node-adapter
252
+ - Quick start: https://github.com/inertia-node/inertia-node-adapter/blob/main/docs/quickstart.md
253
+ - Auth: https://github.com/inertia-node/inertia-node-adapter/blob/main/docs/auth.md
254
+ - Sessions, flash, and validation: https://github.com/inertia-node/inertia-node-adapter/blob/main/docs/session-flash-validation.md
255
+ - SSR: https://github.com/inertia-node/inertia-node-adapter/blob/main/docs/ssr.md
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inertia-node/nest",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "NestJS adapter for Inertia.js on Node.js.",
5
5
  "license": "MIT",
6
6
  "author": "Inertia Node Adapter contributors",
@@ -32,10 +32,11 @@
32
32
  }
33
33
  },
34
34
  "files": [
35
- "dist"
35
+ "dist",
36
+ "README.md"
36
37
  ],
37
38
  "dependencies": {
38
- "@inertia-node/core": "0.1.0"
39
+ "@inertia-node/core": "0.1.1"
39
40
  },
40
41
  "peerDependencies": {
41
42
  "@nestjs/common": ">=10 <12",