exisjs 0.8.1 → 0.9.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/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/build.js +20 -1
- package/dist/cli/commands/build.js.map +1 -1
- package/dist/cli/commands/dev.d.ts +8 -0
- package/dist/cli/commands/dev.d.ts.map +1 -1
- package/dist/cli/commands/dev.js +96 -36
- package/dist/cli/commands/dev.js.map +1 -1
- package/dist/cli/index.js +1 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/manifest.d.ts.map +1 -1
- package/dist/cli/manifest.js +2 -1
- package/dist/cli/manifest.js.map +1 -1
- package/dist/cli/routes.d.ts +2 -0
- package/dist/cli/routes.d.ts.map +1 -1
- package/dist/cli/routes.js +14 -5
- package/dist/cli/routes.js.map +1 -1
- package/dist/config/config.d.ts +3 -1
- package/dist/config/config.d.ts.map +1 -1
- package/dist/config/config.js.map +1 -1
- package/dist/config/types.d.ts +11 -1
- package/dist/config/types.d.ts.map +1 -1
- package/dist/cron/job.d.ts +2 -0
- package/dist/cron/job.d.ts.map +1 -1
- package/dist/cron/job.js +33 -1
- package/dist/cron/job.js.map +1 -1
- package/dist/cron/manager.d.ts +12 -1
- package/dist/cron/manager.d.ts.map +1 -1
- package/dist/cron/manager.js +7 -1
- package/dist/cron/manager.js.map +1 -1
- package/dist/cron/types.d.ts +24 -0
- package/dist/cron/types.d.ts.map +1 -1
- package/dist/database/lifecycle.d.ts +19 -2
- package/dist/database/lifecycle.d.ts.map +1 -1
- package/dist/database/lifecycle.js +92 -53
- package/dist/database/lifecycle.js.map +1 -1
- package/dist/decorators/index.d.ts +1 -0
- package/dist/decorators/index.d.ts.map +1 -1
- package/dist/decorators/index.js +5 -0
- package/dist/decorators/index.js.map +1 -1
- package/dist/decorators/pipes.d.ts +2 -0
- package/dist/decorators/pipes.d.ts.map +1 -1
- package/dist/decorators/pipes.js +39 -18
- package/dist/decorators/pipes.js.map +1 -1
- package/dist/decorators/transaction.d.ts +0 -21
- package/dist/decorators/transaction.d.ts.map +1 -1
- package/dist/decorators/transaction.js +52 -32
- package/dist/decorators/transaction.js.map +1 -1
- package/dist/di/container.d.ts +6 -0
- package/dist/di/container.d.ts.map +1 -1
- package/dist/di/container.js +73 -57
- package/dist/di/container.js.map +1 -1
- package/dist/docs/content/boundaries.mdx +2 -0
- package/dist/docs/content/cli/commands.mdx +2 -1
- package/dist/docs/content/config.mdx +6 -4
- package/dist/docs/content/cron.mdx +25 -1
- package/dist/docs/content/decorators.mdx +5 -5
- package/dist/docs/content/errors.mdx +37 -36
- package/dist/docs/content/installation.mdx +3 -4
- package/dist/docs/content/introduction.mdx +1 -1
- package/dist/docs/content/middleware.mdx +4 -2
- package/dist/docs/content/providers.mdx +2 -0
- package/dist/docs/content/requests.mdx +4 -2
- package/dist/docs/content/responses.mdx +72 -0
- package/dist/docs/content/security.mdx +93 -4
- package/dist/docs/content/testing.mdx +38 -0
- package/dist/docs/content/validation.mdx +34 -1
- package/dist/docs/reference/README.md +16 -16
- package/dist/docs/reference/config.mdx +1 -1
- package/dist/docs/reference/database.mdx +3 -2
- package/dist/docs/reference/decorators.mdx +2 -4
- package/dist/docs/reference/middleware.mdx +1 -1
- package/dist/docs/reference/router.mdx +5 -7
- package/dist/docs/reference/validator.mdx +3 -0
- package/dist/error/errors.d.ts +9 -1
- package/dist/error/errors.d.ts.map +1 -1
- package/dist/error/errors.js +24 -15
- package/dist/error/errors.js.map +1 -1
- package/dist/index.d.ts +11 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/inspect-routes.js +2 -0
- package/dist/lib/inspect-routes.js.map +1 -1
- package/dist/middleware/compression.d.ts.map +1 -1
- package/dist/middleware/compression.js +6 -5
- package/dist/middleware/compression.js.map +1 -1
- package/dist/middleware/idempotency.d.ts +25 -23
- package/dist/middleware/idempotency.d.ts.map +1 -1
- package/dist/middleware/idempotency.js +70 -35
- package/dist/middleware/idempotency.js.map +1 -1
- package/dist/middleware/middleware.d.ts.map +1 -1
- package/dist/middleware/middleware.js +48 -34
- package/dist/middleware/middleware.js.map +1 -1
- package/dist/middleware/rate-limit.d.ts +36 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -1
- package/dist/middleware/rate-limit.js +33 -19
- package/dist/middleware/rate-limit.js.map +1 -1
- package/dist/middleware/security.d.ts.map +1 -1
- package/dist/middleware/security.js +12 -5
- package/dist/middleware/security.js.map +1 -1
- package/dist/router/authorize.d.ts +43 -0
- package/dist/router/authorize.d.ts.map +1 -0
- package/dist/router/authorize.js +66 -0
- package/dist/router/authorize.js.map +1 -0
- package/dist/router/controller-registrar.d.ts.map +1 -1
- package/dist/router/controller-registrar.js +121 -156
- package/dist/router/controller-registrar.js.map +1 -1
- package/dist/router/route-scanner.d.ts +3 -0
- package/dist/router/route-scanner.d.ts.map +1 -1
- package/dist/router/route-scanner.js +32 -21
- package/dist/router/route-scanner.js.map +1 -1
- package/dist/router/router.d.ts +5 -0
- package/dist/router/router.d.ts.map +1 -1
- package/dist/router/router.js +83 -75
- package/dist/router/router.js.map +1 -1
- package/dist/router/scanner/boundary-loader.d.ts.map +1 -1
- package/dist/router/scanner/boundary-loader.js +37 -38
- package/dist/router/scanner/boundary-loader.js.map +1 -1
- package/dist/router/scanner/cron-mounter.d.ts.map +1 -1
- package/dist/router/scanner/cron-mounter.js +32 -18
- package/dist/router/scanner/cron-mounter.js.map +1 -1
- package/dist/router/scanner/functional-compiler.d.ts.map +1 -1
- package/dist/router/scanner/functional-compiler.js +55 -156
- package/dist/router/scanner/functional-compiler.js.map +1 -1
- package/dist/router/send-result.d.ts +24 -0
- package/dist/router/send-result.d.ts.map +1 -0
- package/dist/router/send-result.js +81 -0
- package/dist/router/send-result.js.map +1 -0
- package/dist/server/app.d.ts +5 -0
- package/dist/server/app.d.ts.map +1 -1
- package/dist/server/app.js +48 -6
- package/dist/server/app.js.map +1 -1
- package/dist/server/engines/node-engine.d.ts.map +1 -1
- package/dist/server/engines/node-engine.js +6 -1
- package/dist/server/engines/node-engine.js.map +1 -1
- package/dist/server/helpers/body-parser.d.ts +1 -1
- package/dist/server/helpers/body-parser.d.ts.map +1 -1
- package/dist/server/helpers/body-parser.js +9 -7
- package/dist/server/helpers/body-parser.js.map +1 -1
- package/dist/server/helpers/conditional.d.ts +60 -0
- package/dist/server/helpers/conditional.d.ts.map +1 -0
- package/dist/server/helpers/conditional.js +189 -0
- package/dist/server/helpers/conditional.js.map +1 -0
- package/dist/server/helpers/etag.d.ts +0 -1
- package/dist/server/helpers/etag.d.ts.map +1 -1
- package/dist/server/helpers/etag.js +0 -10
- package/dist/server/helpers/etag.js.map +1 -1
- package/dist/server/helpers/index.d.ts +2 -1
- package/dist/server/helpers/index.d.ts.map +1 -1
- package/dist/server/helpers/index.js +16 -2
- package/dist/server/helpers/index.js.map +1 -1
- package/dist/server/request-handler.d.ts +2 -0
- package/dist/server/request-handler.d.ts.map +1 -1
- package/dist/server/request-handler.js +23 -4
- package/dist/server/request-handler.js.map +1 -1
- package/dist/server/request.d.ts +19 -4
- package/dist/server/request.d.ts.map +1 -1
- package/dist/server/request.js +60 -84
- package/dist/server/request.js.map +1 -1
- package/dist/server/response.d.ts +45 -2
- package/dist/server/response.d.ts.map +1 -1
- package/dist/server/response.js +157 -70
- package/dist/server/response.js.map +1 -1
- package/dist/swagger/mounter.d.ts.map +1 -1
- package/dist/swagger/mounter.js +2 -0
- package/dist/swagger/mounter.js.map +1 -1
- package/dist/testing/client.d.ts +32 -0
- package/dist/testing/client.d.ts.map +1 -1
- package/dist/testing/client.js +69 -0
- package/dist/testing/client.js.map +1 -1
- package/dist/testing/index.d.ts +10 -2
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +7 -2
- package/dist/testing/index.js.map +1 -1
- package/dist/validator/builder.d.ts +33 -16
- package/dist/validator/builder.d.ts.map +1 -1
- package/dist/validator/builder.js +11 -17
- package/dist/validator/builder.js.map +1 -1
- package/dist/validator/engine.d.ts +28 -1
- package/dist/validator/engine.d.ts.map +1 -1
- package/dist/validator/engine.js +212 -124
- package/dist/validator/engine.js.map +1 -1
- package/dist/validator/error.d.ts +4 -0
- package/dist/validator/error.d.ts.map +1 -1
- package/dist/validator/error.js +20 -4
- package/dist/validator/error.js.map +1 -1
- package/dist/validator/index.d.ts +12 -1
- package/dist/validator/index.d.ts.map +1 -1
- package/dist/validator/index.js.map +1 -1
- package/dist/validator/tex-types.d.ts +29 -2
- package/dist/validator/tex-types.d.ts.map +1 -1
- package/package.json +3 -5
package/dist/di/container.js
CHANGED
|
@@ -21,6 +21,39 @@ class Container {
|
|
|
21
21
|
this.providers = new Map();
|
|
22
22
|
this.singletonCache = new Map();
|
|
23
23
|
this.inFlight = new Set();
|
|
24
|
+
// One frame per class being built. A frame is marked when anything built
|
|
25
|
+
// inside it is request-scoped, so the class holding it is request-scoped
|
|
26
|
+
// too instead of a singleton that keeps the first request's instance.
|
|
27
|
+
this.scopeFrames = [];
|
|
28
|
+
}
|
|
29
|
+
markRequestScoped() {
|
|
30
|
+
const frame = this.scopeFrames[this.scopeFrames.length - 1];
|
|
31
|
+
if (frame)
|
|
32
|
+
frame.request = true;
|
|
33
|
+
}
|
|
34
|
+
build(create) {
|
|
35
|
+
const frame = { request: false };
|
|
36
|
+
this.scopeFrames.push(frame);
|
|
37
|
+
try {
|
|
38
|
+
return { value: create(), dependsOnRequest: frame.request };
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
this.scopeFrames.pop();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
store(token, value, scope, dependsOnRequest, requestCache) {
|
|
45
|
+
if (scope === 'request' || dependsOnRequest)
|
|
46
|
+
this.markRequestScoped();
|
|
47
|
+
if (scope === 'transient')
|
|
48
|
+
return;
|
|
49
|
+
if (scope === 'request' || dependsOnRequest) {
|
|
50
|
+
if (!requestCache) {
|
|
51
|
+
throw new Error(`Cannot resolve request-scoped provider '${String(token)}' outside of a request context. This usually happens if you try to resolve a request-scoped dependency during app startup, inside a background job, or without passing the request context cache.`);
|
|
52
|
+
}
|
|
53
|
+
requestCache.set(token, value);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
this.singletonCache.set(token, value);
|
|
24
57
|
}
|
|
25
58
|
provide(tokenOrProvider, provider) {
|
|
26
59
|
if (provider === undefined &&
|
|
@@ -42,6 +75,10 @@ class Container {
|
|
|
42
75
|
this.providers.set(unwrappedToken, provider);
|
|
43
76
|
this.singletonCache.delete(unwrappedToken);
|
|
44
77
|
}
|
|
78
|
+
/** The cached singleton for a token, without building anything. */
|
|
79
|
+
peekSingleton(token) {
|
|
80
|
+
return this.singletonCache.get(token);
|
|
81
|
+
}
|
|
45
82
|
clearCache() {
|
|
46
83
|
this.singletonCache.clear();
|
|
47
84
|
this.inFlight.clear();
|
|
@@ -179,6 +216,7 @@ class Container {
|
|
|
179
216
|
}
|
|
180
217
|
// 2. Check request cache
|
|
181
218
|
if (requestCache && requestCache.has(unwrappedToken)) {
|
|
219
|
+
this.markRequestScoped();
|
|
182
220
|
return requestCache.get(unwrappedToken);
|
|
183
221
|
}
|
|
184
222
|
// 3. Circular Dependency Resolution: Return Lazy Proxy
|
|
@@ -210,19 +248,8 @@ class Container {
|
|
|
210
248
|
this.inFlight.add(unwrappedToken);
|
|
211
249
|
try {
|
|
212
250
|
const scope = unwrappedToken.prototype?.[exports.SCOPE_METADATA] || 'singleton';
|
|
213
|
-
const instance = this.instantiateClass(unwrappedToken, requestCache);
|
|
214
|
-
|
|
215
|
-
return instance;
|
|
216
|
-
}
|
|
217
|
-
if (scope === 'request') {
|
|
218
|
-
if (!requestCache) {
|
|
219
|
-
throw new Error(`Cannot resolve request-scoped provider '${String(unwrappedToken)}' outside of a request context. This usually happens if you try to resolve a request-scoped dependency during app startup, inside a background job, or without passing the request context cache.`);
|
|
220
|
-
}
|
|
221
|
-
requestCache.set(unwrappedToken, instance);
|
|
222
|
-
}
|
|
223
|
-
else {
|
|
224
|
-
this.singletonCache.set(unwrappedToken, instance);
|
|
225
|
-
}
|
|
251
|
+
const { value: instance, dependsOnRequest } = this.build(() => this.instantiateClass(unwrappedToken, requestCache));
|
|
252
|
+
this.store(unwrappedToken, instance, scope, dependsOnRequest, requestCache);
|
|
226
253
|
return instance;
|
|
227
254
|
}
|
|
228
255
|
catch (err) {
|
|
@@ -237,55 +264,44 @@ class Container {
|
|
|
237
264
|
}
|
|
238
265
|
throw new Error('Provider not found for token: ' + String(unwrappedToken));
|
|
239
266
|
}
|
|
240
|
-
let resolvedValue;
|
|
241
267
|
let scope = 'singleton';
|
|
242
268
|
this.inFlight.add(unwrappedToken);
|
|
243
269
|
try {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}
|
|
249
|
-
else if (provider && typeof provider === 'object') {
|
|
250
|
-
if ('scope' in provider && provider.scope) {
|
|
251
|
-
scope = provider.scope;
|
|
252
|
-
}
|
|
253
|
-
if ('useValue' in provider) {
|
|
254
|
-
resolvedValue = provider.useValue;
|
|
270
|
+
const { value: resolvedValue, dependsOnRequest } = this.build(() => {
|
|
271
|
+
if (typeof provider === 'function') {
|
|
272
|
+
scope = provider.prototype?.[exports.SCOPE_METADATA] || 'singleton';
|
|
273
|
+
return this.instantiateClass(provider, requestCache);
|
|
255
274
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
throw new Error(`Cannot resolve request-scoped provider '${String(unwrappedToken)}' outside of a request context. This usually happens if you try to resolve a request-scoped dependency during app startup, inside a background job, or without passing the request context cache.`);
|
|
275
|
+
if (provider && typeof provider === 'object') {
|
|
276
|
+
if ('scope' in provider && provider.scope) {
|
|
277
|
+
scope = provider.scope;
|
|
278
|
+
}
|
|
279
|
+
if ('useValue' in provider) {
|
|
280
|
+
return provider.useValue;
|
|
281
|
+
}
|
|
282
|
+
if ('useExisting' in provider) {
|
|
283
|
+
return this.resolve(provider.useExisting, requestCache);
|
|
284
|
+
}
|
|
285
|
+
if ('useFactory' in provider) {
|
|
286
|
+
const factoryProv = provider;
|
|
287
|
+
const injectTokens = Array.isArray(factoryProv.inject)
|
|
288
|
+
? factoryProv.inject
|
|
289
|
+
: [];
|
|
290
|
+
const injectedDeps = injectTokens.map((depToken) => this.resolve(depToken, requestCache));
|
|
291
|
+
return factoryProv.useFactory(...injectedDeps);
|
|
292
|
+
}
|
|
293
|
+
if ('useClass' in provider) {
|
|
294
|
+
// Without an explicit scope, the class's @Injectable({ scope }) applies
|
|
295
|
+
if (!('scope' in provider && provider.scope)) {
|
|
296
|
+
scope =
|
|
297
|
+
provider.useClass.prototype?.[exports.SCOPE_METADATA] || 'singleton';
|
|
298
|
+
}
|
|
299
|
+
return this.instantiateClass(provider.useClass, requestCache);
|
|
300
|
+
}
|
|
283
301
|
}
|
|
284
|
-
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
this.singletonCache.set(unwrappedToken, resolvedValue);
|
|
288
|
-
}
|
|
302
|
+
return provider;
|
|
303
|
+
});
|
|
304
|
+
this.store(unwrappedToken, resolvedValue, scope, dependsOnRequest, requestCache);
|
|
289
305
|
return resolvedValue;
|
|
290
306
|
}
|
|
291
307
|
finally {
|
package/dist/di/container.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/di/container.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/di/container.ts"],"names":[],"mappings":"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"}
|
|
@@ -148,6 +148,8 @@ export default class AdminBoundary {
|
|
|
148
148
|
}
|
|
149
149
|
```
|
|
150
150
|
|
|
151
|
+
`next()` resolves with what the route sent. Returning that value (or returning nothing) sends the route's response exactly as the route sent it, with the same type and `Content-Type`; a `Buffer` stays binary. Returning a different value replaces the response, and that value is sent like a handler's return value.
|
|
152
|
+
|
|
151
153
|
---
|
|
152
154
|
|
|
153
155
|
## Boundary Cascading & Execution Order
|
|
@@ -26,10 +26,11 @@ npx exisjs dev [options]
|
|
|
26
26
|
| `-p, --port <port>` | `number` | `3000` | Port to listen on (overrides `.env` and `exis.config.ts`). |
|
|
27
27
|
| `-H, --host <host>` | `string` | `localhost` | Host address to bind to. |
|
|
28
28
|
| `-e, --entry <file>` | `string` | `src/http/server.ts` | Custom entry file path to bootstrap the application. |
|
|
29
|
+
| `--force` | `boolean` | `false` | Start even if a dev server for the same port appears to be running. |
|
|
29
30
|
|
|
30
31
|
### Behavior
|
|
31
32
|
- **Port Collision Detection**: If the specified port is in use, the CLI automatically increments to the next open port.
|
|
32
|
-
- **
|
|
33
|
+
- **One server per port**: `.exis/dev-<port>.pid` stops a second `exisjs dev` on the same port. A second instance on another port (`--port 4010`, for example against a test database) is allowed. A lock left by a crashed process is ignored once its port is free; `--force` skips the check.
|
|
33
34
|
|
|
34
35
|
---
|
|
35
36
|
|
|
@@ -147,11 +147,13 @@ export default defineConfig({
|
|
|
147
147
|
| Option | Type | Default | Description |
|
|
148
148
|
| :--- | :--- | :--- | :--- |
|
|
149
149
|
| `cors` | `boolean \| CorsConfig` | `{ origin: '*' }` | Global CORS policy. Can be overridden in boundaries or routes. `credentials: true` requires explicit origins: with `origin: '*'` it is ignored and a warning is logged, because browsers reject that combination. |
|
|
150
|
-
| `helmet` | `boolean \| HelmetConfig` | `{ enabled: true }` | Security headers
|
|
150
|
+
| `helmet` | `boolean \| HelmetConfig` | `{ enabled: true }` | Security headers, including a same-origin `Content-Security-Policy`. `contentSecurityPolicy: false` sends no CSP; a string replaces the default. |
|
|
151
|
+
| `authorization` | `AuthorizationConfig` | `{}` | `defaultPolicy: 'authenticated'` closes controller routes that declare no rule unless they are `@Public()`. `superUser: (user) => boolean` lets matching users pass every `@Roles` / `@Permissions` rule. |
|
|
152
|
+
| `errors` | `{ legacyFields?: boolean }` | `{}` | `legacyFields: true` adds the pre-0.9 duplicate fields to error bodies. Deprecated. |
|
|
151
153
|
| `compression` | `boolean` | `false` | Gzip/Brotli HTTP response compression. |
|
|
152
154
|
| `bodyLimit` | `number` | `10485760` (10MB) | Maximum request payload body size in bytes. |
|
|
153
155
|
| `blockSuspiciousProbes` | `boolean \| BlockProbesOptions` | `false` | Blocks known vulnerability scanners and malicious probes (`.php`, `wp-admin`). |
|
|
154
|
-
| `etag` | `boolean` | `false` |
|
|
156
|
+
| `etag` | `boolean` | `false` | Weak ETags on successful GET/HEAD responses, with `304 Not Modified` for a matching `If-None-Match`. See [Caching & Conditional Requests](/docs/responses#caching--conditional-requests-etag-304-412). |
|
|
155
157
|
| `transformResponse` | `boolean \| Function` | `false` | Standardizes handler response payload envelopes. |
|
|
156
158
|
|
|
157
159
|
### Logging & Diagnostics
|
|
@@ -161,8 +163,8 @@ export default defineConfig({
|
|
|
161
163
|
| `logger` | `boolean \| LoggerConfig` | `false` | Pino logger settings (`level`, `pretty`, `redact`). |
|
|
162
164
|
| `debugRouting` | `boolean` | `false` | Outputs detailed route resolution logs per request in development. |
|
|
163
165
|
| `asyncContext` | `boolean` | `false` | Enables `AsyncLocalStorage` context tracking (`getContext()`). |
|
|
164
|
-
| `docs` / `swagger` | `boolean \| SwaggerConfig` | `{ enabled: false }` | OpenAPI 3.1 specification and Swagger UI endpoint generation. Served in every environment when enabled;
|
|
165
|
-
| `healthcheck` | `boolean \| HealthCheckConfig` | `{ enabled: false }` |
|
|
166
|
+
| `docs` / `swagger` | `boolean \| SwaggerConfig` | `{ enabled: false }` | OpenAPI 3.1 specification and Swagger UI endpoint generation. Served in every environment when enabled; the project template uses `enabled: process.env.NODE_ENV !== 'production'` so published API docs do not help attackers. |
|
|
167
|
+
| `healthcheck` | `boolean \| HealthCheckConfig` | `{ enabled: false }` | `path` (`/_health`): liveness, runs `checks`. `readyPath` (`/_ready`, `false` to disable): readiness, `503` unless `checks` pass, registered databases are healthy and the app is not shutting down. |
|
|
166
168
|
| `metrics` | `boolean \| MetricsConfig` | `{ enabled: false }` | Prometheus metrics endpoint (`path: '/metrics'`). |
|
|
167
169
|
| `telemetry` | `boolean \| TelemetryConfig` | `{ enabled: false }` | OpenTelemetry tracing and metrics export. |
|
|
168
170
|
|
|
@@ -239,13 +239,37 @@ CronExpression.EVERY_YEAR // '0 0 1 1 *'
|
|
|
239
239
|
### 1. Overlap Prevention (`preventOverlap: true`)
|
|
240
240
|
If a job takes longer than its scheduling frequency (for example, a database migration running for 90 seconds on a 60-second interval), standard Node.js timers cause overlapping concurrent runs. ExisJS locks execution during active runs and skips overlapping ticks until the current run completes.
|
|
241
241
|
|
|
242
|
+
`preventOverlap` works inside one process. When the app runs on several instances, every instance runs every job; set `app.cron.lock` so only the instance holding the lock runs each tick:
|
|
243
|
+
|
|
244
|
+
```typescript filename="src/http/server.ts"
|
|
245
|
+
import { randomUUID } from 'node:crypto'
|
|
246
|
+
const instanceId = randomUUID()
|
|
247
|
+
|
|
248
|
+
export default exis({
|
|
249
|
+
async onStart(app) {
|
|
250
|
+
app.cron.lock = {
|
|
251
|
+
acquire: async (job, ttlMs) =>
|
|
252
|
+
(await redis.set(`cron:${job}`, instanceId, 'PX', ttlMs, 'NX')) === 'OK',
|
|
253
|
+
release: async (job) => {
|
|
254
|
+
if ((await redis.get(`cron:${job}`)) === instanceId) await redis.del(`cron:${job}`)
|
|
255
|
+
},
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
})
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
The lock is held for at most `lockTtlMs` (default: the interval, or 5 minutes for cron patterns). A Postgres advisory lock (`pg_try_advisory_lock`) works the same way. `app.cron.trigger(name)` runs a job without the lock.
|
|
262
|
+
|
|
242
263
|
### 2. Isolated Error Sandbox
|
|
243
264
|
Exceptions thrown inside cron handlers are caught within an isolated execution boundary. An uncaught error in a background task will never crash the HTTP server or prevent subsequent scheduled runs. Errors are logged with execution duration and forwarded to your `onError` handler.
|
|
244
265
|
|
|
245
266
|
### 3. Accurate Timezone & DST Calculation
|
|
246
267
|
Cron schedules evaluate IANA timezones (e.g. `'America/Chicago'`, `'Europe/Berlin'`, `'UTC'`) using native `Intl.DateTimeFormat` evaluations, adjusting accurately for Daylight Saving Time (DST) transitions.
|
|
247
268
|
|
|
248
|
-
### 4.
|
|
269
|
+
### 4. Quiet Under Tests
|
|
270
|
+
Under `NODE_ENV=test` jobs are registered but not started; see [Testing](/docs/testing). Each job file is loaded once: from `src/` during development and tests, and from the compiled `.exis/server/src/` in production.
|
|
271
|
+
|
|
272
|
+
### 5. Graceful Shutdown & Drain Window
|
|
249
273
|
When the server receives `SIGTERM` or `SIGINT`:
|
|
250
274
|
1. The scheduler halts all future timer registrations.
|
|
251
275
|
2. Active timers are unreferenced (`timer.unref()`).
|
|
@@ -312,7 +312,7 @@ export default class CheckoutController {
|
|
|
312
312
|
@Post('/')
|
|
313
313
|
@Timeout(15000)
|
|
314
314
|
@Idempotent({ ttlMs: 86400000 })
|
|
315
|
-
@Dedupe({
|
|
315
|
+
@Dedupe({ keyGenerator: (req) => req.user?.id ?? req.ip })
|
|
316
316
|
@Compress()
|
|
317
317
|
async processPayment() {
|
|
318
318
|
return { status: 'processed' }
|
|
@@ -385,9 +385,9 @@ export default class RolesController {
|
|
|
385
385
|
|
|
386
386
|
| Decorator | Target | Description |
|
|
387
387
|
| :--- | :--- | :--- |
|
|
388
|
-
| `@Roles(...roles: string[])` | Class / Method |
|
|
389
|
-
| `@Permissions(...perms: string[])` | Class / Method |
|
|
390
|
-
| `@Public()` / `@IsPublic()` / `@AllowAnonymous()` | Class / Method | Marks route as unauthenticated. |
|
|
388
|
+
| `@Roles(...roles: string[])` | Class / Method | Requires `req.user` to have **one** of the roles (`user.roles` or `user.role`). No user: `401`; wrong role: `403`. |
|
|
389
|
+
| `@Permissions(...perms: string[])` | Class / Method | Requires **all** listed permissions in `req.user.permissions`. A role is never counted as a permission. No user: `401`; missing permission: `403`. |
|
|
390
|
+
| `@Public()` / `@IsPublic()` / `@AllowAnonymous()` | Class / Method | Marks route as unauthenticated. Wins over `@Roles` / `@Permissions` on the same route (a warning is logged at startup). |
|
|
391
391
|
|
|
392
392
|
---
|
|
393
393
|
|
|
@@ -475,7 +475,7 @@ export class OrderService implements OnInit, OnDestroy {
|
|
|
475
475
|
| :--- | :--- | :--- |
|
|
476
476
|
| `@Cacheable(options?)` | Method | Caches return value. Options: `{ ttl?: number, key?: string \| ((...args) => string) }`. |
|
|
477
477
|
| `@CacheEvict(options)` | Method | Evicts cache keys on method completion. Options: `{ key: string \| ((...args) => string) }`. |
|
|
478
|
-
| `@Transactional(options?)` | Method | Wraps execution in a database transaction (Prisma,
|
|
478
|
+
| `@Transactional(options?)` | Method | Wraps execution in a database transaction (Prisma, Drizzle, Knex, SQL). Inside the call, the service's client property (`db`, `database`, `prisma`, `dataSource` or `connection`) is the transaction, including in methods it calls; concurrent requests using the same service keep the normal client. |
|
|
479
479
|
| `@Profile(options?)` | Method | Measures execution time using `performance.now()`. |
|
|
480
480
|
| `OnInit` (`onInit()`) | Class Interface | Invoked once after service instantiation. |
|
|
481
481
|
| `OnDestroy` (`onDestroy()`) | Class Interface | Invoked once during graceful shutdown. |
|
|
@@ -139,15 +139,13 @@ Every error response has the same core shape, whatever caused it:
|
|
|
139
139
|
| `statusCode` | Same as the HTTP status |
|
|
140
140
|
| `error.code` | Stable machine-readable code: `NOT_FOUND`, `UNAUTHORIZED`, `VALIDATION_ERROR`, `INTERNAL_ERROR`... |
|
|
141
141
|
| `error.message` | Human-readable message. For unexpected errors in production it is a generic message; internals are never exposed |
|
|
142
|
-
| `error.details` | Optional extra data (validation issues, or the `details` passed to an `HttpError`) |
|
|
142
|
+
| `error.details` | Optional extra data (validation issues, or the `details` passed to an `HttpError`). Never copied to the top level |
|
|
143
143
|
|
|
144
|
-
Clients can rely on `error.code` and `error.message` for every failed request.
|
|
144
|
+
Clients can rely on `error.code` and `error.message` for every failed request: thrown errors, validation, `@Roles` / `@Permissions` / guard rejections, `404` and `405` all use this shape. Codes the framework itself sends include `VALIDATION_ERROR`, `INVALID_JSON`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `METHOD_NOT_ALLOWED` (with an `Allow` header), `RATE_LIMIT_EXCEEDED`, `IDEMPOTENCY_KEY_REUSED`, `IDEMPOTENCY_IN_PROGRESS` and `INTERNAL_ERROR`. A handler that rejects with `null` or `undefined` is a `500`, never a `404`.
|
|
145
145
|
|
|
146
146
|
### Validation Error Responses
|
|
147
147
|
|
|
148
|
-
When schema validation fails (via `tex`, Zod, or
|
|
149
|
-
|
|
150
|
-
The top-level `message`, `validationErrors`, `errors` and `details` fields are kept for existing clients; new code should read `error.details`. Values of credential fields (`password`, `token`, `secret`...) are replaced with `[Redacted]` in responses and logs.
|
|
148
|
+
When schema validation fails (via `tex`, Zod, Yup or a DTO's `validate()`), the response is a `400` with **one entry per failing field** in `error.details` (up to 100):
|
|
151
149
|
|
|
152
150
|
```json filename="HTTP 400 Validation Error Response"
|
|
153
151
|
{
|
|
@@ -155,37 +153,40 @@ The top-level `message`, `validationErrors`, `errors` and `details` fields are k
|
|
|
155
153
|
"statusCode": 400,
|
|
156
154
|
"error": {
|
|
157
155
|
"code": "VALIDATION_ERROR",
|
|
158
|
-
"message": "Validation Error
|
|
159
|
-
"details": [
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
156
|
+
"message": "Validation Error",
|
|
157
|
+
"details": [
|
|
158
|
+
{
|
|
159
|
+
"field": "email",
|
|
160
|
+
"message": "Must be a valid email address",
|
|
161
|
+
"expected": "valid email address",
|
|
162
|
+
"received": "\"invalid-email\"",
|
|
163
|
+
"code": "INVALID_EMAIL",
|
|
164
|
+
"httpPart": "body"
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"field": "age",
|
|
168
|
+
"message": "Must be at least 18",
|
|
169
|
+
"expected": "must be at least 18",
|
|
170
|
+
"received": "16",
|
|
171
|
+
"code": "VALUE_TOO_SMALL",
|
|
172
|
+
"httpPart": "body"
|
|
173
|
+
}
|
|
174
|
+
]
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
`received` never shows secrets: credential fields (`password`, `token`, `secret`, `apiKey`...) and connection settings (`DATABASE_URL`, `REDIS_URI`, `SENTRY_DSN`, `*_CONNECTION`...) are `[Redacted]`, and the password of any `scheme://user:password@host` value is masked as `***`, in responses, logs and `tex.env` startup errors.
|
|
180
|
+
|
|
181
|
+
**Status codes.** Malformed input that cannot be parsed at all is `400` (`INVALID_JSON` for a broken JSON body); input that parses but breaks the schema is `400` `VALIDATION_ERROR`. Use `HttpError.unprocessable()` (`422`) for business rules that the schema cannot express, such as "this email is already registered".
|
|
182
|
+
|
|
183
|
+
#### Pre-0.9 duplicate fields
|
|
184
|
+
|
|
185
|
+
Before 0.9, error bodies also carried `message`, `validationErrors`, `errors`, `details` and `timestamp` at the top level. They are gone by default. Clients that still read them can get them back while they migrate:
|
|
186
|
+
|
|
187
|
+
```typescript filename="exis.config.ts"
|
|
188
|
+
export default {
|
|
189
|
+
errors: { legacyFields: true }, // deprecated, removed in 1.0
|
|
189
190
|
}
|
|
190
191
|
```
|
|
191
192
|
|
|
@@ -205,9 +205,8 @@ const config: ExisConfig = {
|
|
|
205
205
|
helmet: { enabled: true },
|
|
206
206
|
compression: true,
|
|
207
207
|
|
|
208
|
-
// Swagger UI at /docs
|
|
209
|
-
|
|
210
|
-
docs: { enabled: true },
|
|
208
|
+
// Swagger UI at /docs, development only
|
|
209
|
+
docs: { enabled: process.env.NODE_ENV !== 'production' },
|
|
211
210
|
}
|
|
212
211
|
|
|
213
212
|
export default config
|
|
@@ -283,7 +282,7 @@ npm run dev
|
|
|
283
282
|
Output:
|
|
284
283
|
|
|
285
284
|
```text filename="Terminal"
|
|
286
|
-
[exis] starting development server (v0.
|
|
285
|
+
[exis] starting development server (v0.9.0)...
|
|
287
286
|
EXIS ready in 125 ms
|
|
288
287
|
|
|
289
288
|
→ Local: http://localhost:4000/
|
|
@@ -50,7 +50,7 @@ ExisJS combines convention-based file routing, built-in standard modules, and a
|
|
|
50
50
|
The file-system routing engine scans the `src/http` directory and compiles route paths into a radix tree at startup. Purely static paths resolve through an exact-match table; parameterized paths walk the tree with no per-request parsing of the route definitions.
|
|
51
51
|
|
|
52
52
|
### 2. Dual-Paradigm Parity
|
|
53
|
-
ExisJS
|
|
53
|
+
ExisJS supports a functional and a class-based (OOP) paradigm. Both share the router, validation, boundaries, error handling, response handling and route authorization; a project uses **one** of them throughout (`exisjs dev` and `exisjs build` stop with the file names if they are mixed). Class-based controllers add decorator and dependency-injection work per request, so functional routes are somewhat faster.
|
|
54
54
|
- **Functional**: `controller()`, `route.get()`, `route.post()`, `defineBoundary()`, `inject()`.
|
|
55
55
|
- **Class-Based (OOP)**: `@Controller()`, `@Get()`, `@Post()`, `@Boundary()`, `@Injectable()`.
|
|
56
56
|
|
|
@@ -28,7 +28,7 @@ All standard middlewares can be imported directly from `exisjs/middleware`. Cust
|
|
|
28
28
|
| `idempotent` | `idempotent(options?)` | Duplicate mutation caching keyed by `Idempotency-Key` headers. |
|
|
29
29
|
| `dedupe` | `dedupe(options)` | Merges simultaneous identical in-flight `GET` requests into a single operation. |
|
|
30
30
|
| `backpressure` | `backpressure(options?)` | Queues requests during high load and sheds excess traffic with `503 Service Unavailable`. |
|
|
31
|
-
| `serveStatic` | `serveStatic(root, options?)` | Serves static assets from disk with
|
|
31
|
+
| `serveStatic` | `serveStatic(root, options?)` | Serves static assets from disk with ETag / Last-Modified revalidation and Brotli/Gzip pre-compression. |
|
|
32
32
|
| `timeout` | `timeout(ms \| options)` | Terminates requests exceeding the duration limit with `503 Service Unavailable`. |
|
|
33
33
|
| `fileUpload` | `fileUpload(options?)` | Streaming multipart/form-data parser supporting disk/memory storage and MIME checks. |
|
|
34
34
|
| `fromExpress` | `fromExpress(middleware)` | Connect/Express bridge adapter running third-party middleware (e.g. Multer) directly. |
|
|
@@ -151,6 +151,8 @@ export const requireAuth = defineMiddleware<AuthContext>(async (req, res, next)
|
|
|
151
151
|
})
|
|
152
152
|
```
|
|
153
153
|
|
|
154
|
+
Middleware may be `async`. ExisJS awaits the returned promise. If it throws, or rejects with an `HttpError` (such as `UnauthorizedException` above), that error becomes the response through the error handler, with the standard error envelope. You don't need to catch it and call `next(err)` yourself.
|
|
155
|
+
|
|
154
156
|
### 2. Using Typed Middleware in Functional Routes
|
|
155
157
|
|
|
156
158
|
```typescript filename="src/http/profile/route.ts"
|
|
@@ -287,4 +289,4 @@ export default exis({
|
|
|
287
289
|
})
|
|
288
290
|
```
|
|
289
291
|
|
|
290
|
-
`serveStatic`
|
|
292
|
+
`serveStatic` handles MIME detection and serves a pre-compressed `.br` or `.gz` file when one exists and the client accepts that encoding (`br;q=0` counts as a refusal). Every file gets an `ETag` (from its size and modification time; each encoded file has its own) and `Last-Modified`, and conditional requests are answered with `304` or `412` as described in [Caching & Conditional Requests](/docs/responses#caching--conditional-requests-etag-304-412). `Vary: Accept-Encoding` is always sent so shared caches keep the variants apart.
|
|
@@ -199,6 +199,8 @@ export class RequestContextService {
|
|
|
199
199
|
```
|
|
200
200
|
|
|
201
201
|
> [!WARNING]
|
|
202
|
+
> **Scopes propagate**: a controller or service that depends on a request-scoped provider is itself created per request, so it can never keep one request's instance for the next. `transient` providers get a new instance for every injection.
|
|
203
|
+
|
|
202
204
|
> **Request Scope Lifecycle**: Request-scoped providers can only be resolved within an active HTTP request context. Attempting to resolve a request-scoped provider during boot scripts, background cron tasks, or standalone worker processes will throw a container error.
|
|
203
205
|
|
|
204
206
|
---
|
|
@@ -33,9 +33,9 @@ ExisJS wraps the standard Node.js `IncomingMessage` in an `ExisRequest` instance
|
|
|
33
33
|
| `req.signal` | `AbortSignal` | Standard `AbortSignal` triggered when client cancels connection |
|
|
34
34
|
| `req.fresh` | `boolean` | `true` if client cache matches current `ETag` or `Last-Modified` |
|
|
35
35
|
| `req.stale` | `boolean` | Inverse of `req.fresh` |
|
|
36
|
-
| `req.user` | `ExisUser` | Authenticated user
|
|
36
|
+
| `req.user` | `ExisUser` | Authenticated user set by your auth middleware or guard. Type it once with `declare module 'exisjs' { interface ExisUser { id: string; roles: string[]; permissions: string[] } }` |
|
|
37
37
|
| `req.session` | `Record<string, any>` | Session data store when session middleware is enabled |
|
|
38
|
-
| `req.log` | `Logger` | Request-scoped Pino logger
|
|
38
|
+
| `req.log` | `Logger` | Request-scoped Pino logger; every line carries `requestId` |
|
|
39
39
|
| `req.requestId` | `string` | Unique request identifier header |
|
|
40
40
|
| `req.raw` | `IncomingMessage` | Underlying Node.js `IncomingMessage` stream |
|
|
41
41
|
|
|
@@ -106,6 +106,8 @@ const data = await req.json<{ username: string }>()
|
|
|
106
106
|
const { fields, files } = await req.formData()
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
+
The body is read from the network once; these methods share the result. `req.buffer()` returns the bytes exactly as the client sent them, so binary payloads (images, protobuf, compressed or signed data) are safe. A body over `bodyLimit` makes these calls fail with `413 Payload Too Large`.
|
|
110
|
+
|
|
109
111
|
### Webhooks with `@RawBody()` (Class Controllers)
|
|
110
112
|
|
|
111
113
|
In class-based controllers, use the `@RawBody()` parameter decorator to inject the raw `Buffer` or decoded string directly:
|
|
@@ -51,6 +51,24 @@ export default class UsersController {
|
|
|
51
51
|
}
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
+
### What a Return Value Becomes
|
|
55
|
+
|
|
56
|
+
Both paradigms answer the same way:
|
|
57
|
+
|
|
58
|
+
| Handler returns | Response |
|
|
59
|
+
| :--- | :--- |
|
|
60
|
+
| Object, array, number, boolean, `null` | JSON (`null` is the JSON value `null`) |
|
|
61
|
+
| String | `text/plain` |
|
|
62
|
+
| `Buffer` / `Uint8Array` | `application/octet-stream` (set `Content-Type` first to change it) |
|
|
63
|
+
| Stream or async iterable | Streamed |
|
|
64
|
+
| `download(data, name)` | Attachment |
|
|
65
|
+
| `res`, or the result of `res.json()` / `res.send()` | Nothing more: the response was already sent |
|
|
66
|
+
| `undefined`, nothing sent | `204 No Content` (or the status set with `@HttpCode` / `res.status()`, with an empty body) |
|
|
67
|
+
|
|
68
|
+
Prefer returning a value. Call `res.json()` / `res.send()` yourself only when you need to, and do not do both. A handler that receives the response object (`@Res()`, or `(req, res)` with no decorators) may also answer later, for example from a callback; it is then responsible for sending exactly one response.
|
|
69
|
+
|
|
70
|
+
`HEAD` is answered by the matching `GET` route without a body. A path that exists under other methods answers `405 METHOD_NOT_ALLOWED` with an `Allow` header instead of `404`.
|
|
71
|
+
|
|
54
72
|
---
|
|
55
73
|
|
|
56
74
|
## Response Envelope Builders (`exisjs/response`)
|
|
@@ -433,6 +451,60 @@ export default controller({
|
|
|
433
451
|
})
|
|
434
452
|
```
|
|
435
453
|
|
|
454
|
+
## Caching & Conditional Requests (ETag, 304, 412)
|
|
455
|
+
|
|
456
|
+
ExisJS follows the conditional request rules of RFC 9110 §13 everywhere: for automatic ETags, in `res.checkPreconditions()`, for `serveStatic` and for `res.download(path)`.
|
|
457
|
+
|
|
458
|
+
| Request header | Checked against | Result when it does not hold |
|
|
459
|
+
| :--- | :--- | :--- |
|
|
460
|
+
| `If-Match` | `ETag`, strong comparison | `412 Precondition Failed` |
|
|
461
|
+
| `If-Unmodified-Since` (only without `If-Match`) | `Last-Modified` | `412 Precondition Failed` |
|
|
462
|
+
| `If-None-Match` | `ETag`, weak comparison; lists and `*` supported | Matches: `304` for GET/HEAD, `412` for writes |
|
|
463
|
+
| `If-Modified-Since` (only without `If-None-Match`, GET/HEAD) | `Last-Modified` | Unchanged: `304 Not Modified` |
|
|
464
|
+
|
|
465
|
+
A `304` carries the `ETag`, `Last-Modified`, `Cache-Control` and `Vary` of the `200` it replaces, and no body or `Content-Type`. Errors use the standard envelope (`PRECONDITION_FAILED`, `PRECONDITION_REQUIRED`).
|
|
466
|
+
|
|
467
|
+
### Automatic ETags
|
|
468
|
+
|
|
469
|
+
With `etag: true` in `exis.config.ts` (or `conditionalGet()` on some routes), every successful `GET`/`HEAD` response sent with `res.json()`, `res.send()` or a returned value gets a weak ETag hashed from its body, and a matching `If-None-Match` is answered with `304`. The handler still runs, so this saves bandwidth, not work. Writes and error responses get no ETag.
|
|
470
|
+
|
|
471
|
+
### Validators from your data: `res.checkPreconditions()`
|
|
472
|
+
|
|
473
|
+
When the resource has a version or update time, check it **before** doing the work. On reads this skips the query for the body and serialization; on writes it prevents lost updates: a client that edited an old copy gets `412` instead of overwriting someone else's change.
|
|
474
|
+
|
|
475
|
+
```typescript filename="src/http/documents/[id]/route.ts"
|
|
476
|
+
import { controller, route } from 'exisjs/router'
|
|
477
|
+
|
|
478
|
+
export default controller({
|
|
479
|
+
read: route.get('/', {
|
|
480
|
+
async handle({ params, res }) {
|
|
481
|
+
const meta = await documents.meta(params.id) // cheap: version + updatedAt
|
|
482
|
+
// Sets ETag / Last-Modified; answers 304 and returns true when current
|
|
483
|
+
if (res.checkPreconditions({ etag: `v${meta.version}`, lastModified: meta.updatedAt })) return
|
|
484
|
+
return documents.find(params.id)
|
|
485
|
+
},
|
|
486
|
+
}),
|
|
487
|
+
|
|
488
|
+
update: route.put('/', {
|
|
489
|
+
async handle({ params, body, res }) {
|
|
490
|
+
const current = await documents.meta(params.id)
|
|
491
|
+
// 412 if the client's If-Match is stale; 428 if it sent no precondition
|
|
492
|
+
res.checkPreconditions({ etag: `v${current.version}` }, { required: true })
|
|
493
|
+
const updated = await documents.update(params.id, body)
|
|
494
|
+
res.setHeader('ETag', `"v${updated.version}"`) // the new state
|
|
495
|
+
return updated
|
|
496
|
+
},
|
|
497
|
+
}),
|
|
498
|
+
})
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
- `etag` may be bare (`v3` is sent as `"v3"`) or a full tag (`W/"v3"`). Use a value that changes whenever the representation changes: a version column, a hash, `updatedAt`.
|
|
502
|
+
- `lastModified` takes a `Date`, a timestamp or an HTTP date. It is rounded to whole seconds, and a time in the future is capped at the current time.
|
|
503
|
+
- For "create only if absent" (`PUT` with `If-None-Match: *`), pass `exists: false` when the resource does not exist yet; an existing one answers `412`.
|
|
504
|
+
- On writes, the old validators are not sent back. Set the new `ETag` after the change, as above.
|
|
505
|
+
|
|
506
|
+
`req.fresh` (and `req.stale`) apply the same rules to the response headers set so far.
|
|
507
|
+
|
|
436
508
|
---
|
|
437
509
|
|
|
438
510
|
## Next Steps
|