express-fast-json-stringify 1.3.0 → 2.0.0
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/CHANGELOG.md +26 -17
- package/README.md +64 -31
- package/build/main/index.d.ts +1 -1
- package/build/main/index.js +4 -1
- package/build/main/lib/install.d.ts +77 -0
- package/build/main/lib/install.js +98 -0
- package/build/main/lib/middleware.d.ts +8 -38
- package/build/main/lib/middleware.js +13 -36
- package/build/main/lib/openapi.d.ts +30 -36
- package/build/main/lib/openapi.js +82 -53
- package/build/main/lib/send.d.ts +7 -8
- package/build/main/lib/send.js +12 -40
- package/build/module/index.d.ts +1 -1
- package/build/module/index.js +2 -1
- package/build/module/lib/install.d.ts +77 -0
- package/build/module/lib/install.js +92 -0
- package/build/module/lib/middleware.d.ts +8 -38
- package/build/module/lib/middleware.js +14 -26
- package/build/module/lib/openapi.d.ts +30 -36
- package/build/module/lib/openapi.js +81 -53
- package/build/module/lib/send.d.ts +7 -8
- package/build/module/lib/send.js +10 -37
- package/package.json +9 -2
- package/build/main/lib/override.d.ts +0 -17
- package/build/main/lib/override.js +0 -49
- package/build/module/lib/override.d.ts +0 -17
- package/build/module/lib/override.js +0 -44
package/CHANGELOG.md
CHANGED
|
@@ -1,15 +1,30 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.0.0](https://github.com/nigrosimone/express-fast-json-stringify/compare/v1.3.0...v2.0.0) (2026-09-20)
|
|
4
|
+
|
|
5
|
+
### ⚠ BREAKING CHANGES
|
|
6
|
+
|
|
7
|
+
- install once on app.response, the middlewares only choose the schema and the string goes through res.send
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
- add a landing page with links to fast-json and native-json endpoints ([882c2ed](https://github.com/nigrosimone/express-fast-json-stringify/commit/882c2ed6b191e059f49381be2abf0ca017474140))
|
|
12
|
+
- install once on app.response, the middlewares only choose the schema and the string goes through res.send ([83ab193](https://github.com/nigrosimone/express-fast-json-stringify/commit/83ab19300aad0d19c9e77288832f35c378a517bd))
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
- correct json settings check to avoid false negatives with falsy values ([bc13964](https://github.com/nigrosimone/express-fast-json-stringify/commit/bc139640fc7732dfb4081a8395d1260df83e6d51))
|
|
17
|
+
|
|
3
18
|
## [1.3.0](https://github.com/nigrosimone/express-fast-json-stringify/compare/v1.2.9...v1.3.0) (2026-07-26)
|
|
4
19
|
|
|
5
20
|
### Features
|
|
6
21
|
|
|
7
|
-
|
|
8
|
-
|
|
22
|
+
- derive the schema from an OpenAPI or Swagger document ([5ce6622](https://github.com/nigrosimone/express-fast-json-stringify/commit/5ce6622fd216df1074e844c254bef0c7731205cd))
|
|
23
|
+
- opt in override of res.json, so adoption needs no call site changes ([bcfda45](https://github.com/nigrosimone/express-fast-json-stringify/commit/bcfda4579ac8380f53c525b5cadcbc177e835b9c))
|
|
9
24
|
|
|
10
25
|
### Bug Fixes
|
|
11
26
|
|
|
12
|
-
|
|
27
|
+
- align res.fastJson with res.json HTTP semantics; add CI and vitest ([f2c8558](https://github.com/nigrosimone/express-fast-json-stringify/commit/f2c85584c105ce24c6c7327382b6b80022aade10))
|
|
13
28
|
|
|
14
29
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
15
30
|
|
|
@@ -17,33 +32,29 @@ All notable changes to this project will be documented in this file. See [standa
|
|
|
17
32
|
|
|
18
33
|
### [1.2.8](https://github.com/nigrosimone/express-fast-json-stringify/compare/v1.2.6...v1.2.8) (2024-09-29)
|
|
19
34
|
|
|
20
|
-
|
|
21
35
|
### Bug Fixes
|
|
22
36
|
|
|
23
|
-
|
|
37
|
+
- global type ([56fa47c](https://github.com/nigrosimone/express-fast-json-stringify/commit/56fa47c6b395a1de89dd85bc67f55c8cd3f5d852))
|
|
24
38
|
|
|
25
39
|
### [1.2.6](https://github.com/nigrosimone/express-fast-json-stringify/compare/v1.2.4...v1.2.6) (2024-09-29)
|
|
26
40
|
|
|
27
|
-
|
|
28
41
|
### Bug Fixes
|
|
29
42
|
|
|
30
|
-
|
|
43
|
+
- export ([b753280](https://github.com/nigrosimone/express-fast-json-stringify/commit/b753280af8af5aea830715405d404f3fad6f43d7))
|
|
31
44
|
|
|
32
45
|
### [1.2.4](https://github.com/nigrosimone/express-fast-json-stringify/compare/v1.2.2...v1.2.4) (2024-09-29)
|
|
33
46
|
|
|
34
|
-
|
|
35
47
|
### Bug Fixes
|
|
36
48
|
|
|
37
|
-
|
|
49
|
+
- del deps ([0e9e63a](https://github.com/nigrosimone/express-fast-json-stringify/commit/0e9e63af86e647815002079b1df5ca19ff6f7632))
|
|
38
50
|
|
|
39
51
|
### [1.2.2](https://github.com/nigrosimone/express-fast-json-stringify/compare/v1.2.0...v1.2.2) (2024-09-29)
|
|
40
52
|
|
|
41
53
|
## [1.2.0](https://github.com/nigrosimone/express-fast-json-stringify/compare/v1.1.4...v1.2.0) (2024-09-29)
|
|
42
54
|
|
|
43
|
-
|
|
44
55
|
### Features
|
|
45
56
|
|
|
46
|
-
|
|
57
|
+
- add options ([9466dc3](https://github.com/nigrosimone/express-fast-json-stringify/commit/9466dc30c20693a7ceabf2240d5d9701c76280c0))
|
|
47
58
|
|
|
48
59
|
### [1.1.4](https://github.com/nigrosimone/express-fast-json-stringify/compare/v1.1.2...v1.1.4) (2024-09-29)
|
|
49
60
|
|
|
@@ -51,14 +62,12 @@ All notable changes to this project will be documented in this file. See [standa
|
|
|
51
62
|
|
|
52
63
|
## 1.1.0 (2024-09-29)
|
|
53
64
|
|
|
54
|
-
|
|
55
65
|
### Features
|
|
56
66
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
67
|
+
- first commit ([5e3cc3e](https://github.com/nigrosimone/express-fast-json-stringify/commit/5e3cc3e46fc0d35c07299697d1133636d21bee9b))
|
|
68
|
+
- npmignore ([364b397](https://github.com/nigrosimone/express-fast-json-stringify/commit/364b397ec15c14846c427c8c395b756aec839174))
|
|
69
|
+
- vscode ([f962e81](https://github.com/nigrosimone/express-fast-json-stringify/commit/f962e8145aeaa517c8b80dc642f5bca6139dff4d))
|
|
61
70
|
|
|
62
71
|
### Bug Fixes
|
|
63
72
|
|
|
64
|
-
|
|
73
|
+
- ignore publish ([ca95f45](https://github.com/nigrosimone/express-fast-json-stringify/commit/ca95f450e1ce22f957fff4cd9f7520386ee70962))
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
JSON serialization is a critical task in web development, particularly for applications built with Node.js and Express.js. While the native JSON serialization in Node.js (`JSON.stringify()`) is straightforward and convenient, it can become a performance bottleneck, especially under heavy load. This documentation introduces [express-fast-json-stringify](https://www.npmjs.com/package/express-fast-json-stringify), a custom middleware package that leverages [fast-json-stringify](https://www.npmjs.com/package/fast-json-stringify) to significantly boost JSON serialization performance in Express applications.
|
|
2
2
|
|
|
3
|
+
Run it now on [StackBlitz](https://stackblitz.com/github/nigrosimone/express-fast-json-stringify) — it boots the Express server, serves the same payload through `res.json()` and `res.fastJson()`, and prints both responses side by side. The [sources](./example) are in this repository.
|
|
4
|
+
|
|
3
5
|
## What is fast-json-stringify?
|
|
4
6
|
|
|
5
7
|
`fast-json-stringify` is a JSON serialization library developed by the Fastify team. It analyzes JSON schema definitions and compiles them into serialization functions specialized for the exact shape of your payload, so it can skip everything the schema does not describe instead of walking the object generically like `JSON.stringify()` has to.
|
|
@@ -39,15 +41,29 @@ const schema: Schema = {
|
|
|
39
41
|
};
|
|
40
42
|
```
|
|
41
43
|
|
|
44
|
+
## Installing it on the app
|
|
45
|
+
|
|
46
|
+
Call `installFastJson(app)` once, when the app is built. It adds `res.fastJson()` to the
|
|
47
|
+
responses of that app, on `app.response`, so no request pays for it.
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import express from 'express';
|
|
51
|
+
import { installFastJson } from 'express-fast-json-stringify';
|
|
52
|
+
|
|
53
|
+
const app = express();
|
|
54
|
+
installFastJson(app);
|
|
55
|
+
```
|
|
56
|
+
|
|
42
57
|
## Applying the Middleware
|
|
43
58
|
|
|
44
|
-
Use the `fastJsonSchema` middleware in your Express routes, passing the schema object as an argument.
|
|
59
|
+
Use the `fastJsonSchema` middleware in your Express routes, passing the schema object as an argument. It picks the serializer for that route.
|
|
45
60
|
|
|
46
61
|
```ts
|
|
47
62
|
import express from 'express';
|
|
48
|
-
import { fastJsonSchema, Schema } from 'express-fast-json-stringify';
|
|
63
|
+
import { fastJsonSchema, installFastJson, Schema } from 'express-fast-json-stringify';
|
|
49
64
|
|
|
50
65
|
const app = express();
|
|
66
|
+
installFastJson(app);
|
|
51
67
|
|
|
52
68
|
const exampleSchema: Schema = {
|
|
53
69
|
title: 'Example Schema',
|
|
@@ -68,9 +84,10 @@ Instead of using the default `res.json()` method, use the `res.fastJson()` metho
|
|
|
68
84
|
|
|
69
85
|
```ts
|
|
70
86
|
import express from 'express';
|
|
71
|
-
import { fastJsonSchema, Schema } from 'express-fast-json-stringify';
|
|
87
|
+
import { fastJsonSchema, installFastJson, Schema } from 'express-fast-json-stringify';
|
|
72
88
|
|
|
73
89
|
const app = express();
|
|
90
|
+
installFastJson(app);
|
|
74
91
|
|
|
75
92
|
const schema: Schema = {
|
|
76
93
|
title: 'Example Schema',
|
|
@@ -102,12 +119,13 @@ app.get('/', fastJsonSchema(schema), (req, res, next) => {
|
|
|
102
119
|
## Response semantics
|
|
103
120
|
|
|
104
121
|
`res.fastJson()` is a drop-in replacement for `res.json()`: only the
|
|
105
|
-
serialization changes
|
|
122
|
+
serialization changes. The string then goes through `res.send()`, the same
|
|
123
|
+
call `res.json()` makes, so every HTTP detail is the one the framework gives.
|
|
106
124
|
|
|
107
125
|
| Behavior | What `res.fastJson()` does |
|
|
108
126
|
| -------------------- | --------------------------------------------------------------------------------------------------- |
|
|
109
|
-
| `Content-Type` | `application/json; charset=utf-8
|
|
110
|
-
| `Content-Length` |
|
|
127
|
+
| `Content-Type` | `application/json; charset=utf-8`; a type the route set with `res.type()` is kept, charset added. |
|
|
128
|
+
| `Content-Length` | Set by `res.send()`, so the response is never chunked. |
|
|
111
129
|
| `ETag` | Follows the app `etag` setting, exactly like `res.send()`. Set `app.set('etag', false)` to skip it. |
|
|
112
130
|
| Conditional requests | A matching `If-None-Match` answers `304` with no body. |
|
|
113
131
|
| `204` and `304` | No body and no `Content-Type`/`Content-Length`/`Transfer-Encoding`. |
|
|
@@ -116,11 +134,16 @@ serialization changes, every HTTP detail stays the same.
|
|
|
116
134
|
The payload is serialized before the status code is inspected, so a body that
|
|
117
135
|
does not match the schema still throws on a `204` — just like `res.json()`.
|
|
118
136
|
|
|
137
|
+
A route without a schema falls back to `res.json()`. Pass
|
|
138
|
+
`installFastJson(app, { strict: true })` to get an error instead.
|
|
139
|
+
|
|
119
140
|
## Taking the schema from your OpenAPI document
|
|
120
141
|
|
|
121
142
|
If you already publish an OpenAPI (or Swagger) document, the response schemas
|
|
122
143
|
are written there — no need to repeat them in the routes. `fastJsonOpenApi`
|
|
123
|
-
takes that document and resolves the schema per route and per status code
|
|
144
|
+
takes that document and resolves the schema per route and per status code.
|
|
145
|
+
It installs itself, so there is no `installFastJson(app)` to call and no
|
|
146
|
+
middleware runs per request:
|
|
124
147
|
|
|
125
148
|
```ts
|
|
126
149
|
import express from 'express';
|
|
@@ -130,8 +153,8 @@ import document from './openapi.json' with { type: 'json' };
|
|
|
130
153
|
|
|
131
154
|
const app = express();
|
|
132
155
|
|
|
133
|
-
//
|
|
134
|
-
|
|
156
|
+
// Once for the whole app.
|
|
157
|
+
fastJsonOpenApi(app, document);
|
|
135
158
|
|
|
136
159
|
app.get('/users/:id', (req, res, next) => {
|
|
137
160
|
try {
|
|
@@ -179,14 +202,20 @@ There is no dependency on any of them: the middleware only reads `paths`,
|
|
|
179
202
|
- **OpenAPI 3.0 and 3.1** are both supported; `nullable: true` is honoured and
|
|
180
203
|
annotation keywords (`example`, `discriminator`, `xml`, ...) are ignored.
|
|
181
204
|
|
|
182
|
-
Routes the document does not describe fall back to `res.json()`, so
|
|
183
|
-
|
|
184
|
-
|
|
205
|
+
Routes the document does not describe fall back to `res.json()`, so installing
|
|
206
|
+
it app-wide cannot break an undocumented endpoint. Pass `{ strict: true }` to
|
|
207
|
+
get an error instead of a silent fallback.
|
|
208
|
+
|
|
209
|
+
The serializer of a route is found from the route object the framework
|
|
210
|
+
matched and kept beside it, so a request does not rebuild the path or look up
|
|
211
|
+
a string.
|
|
185
212
|
|
|
186
213
|
```ts
|
|
187
|
-
// Read a different media type,
|
|
188
|
-
|
|
189
|
-
|
|
214
|
+
// Read a different media type, forward fast-json-stringify options
|
|
215
|
+
fastJsonOpenApi(app, document, { contentType: 'application/vnd.api+json', rounding: 'ceil' });
|
|
216
|
+
|
|
217
|
+
// A route the document spells differently: take the schema out by hand
|
|
218
|
+
app.get('/v2/people/:id', fastJsonSchema(openApiSchema(document, '/users/{id}', 'get')!), handler);
|
|
190
219
|
```
|
|
191
220
|
|
|
192
221
|
Because the schema decides what gets written, a property that is not in the
|
|
@@ -200,16 +229,16 @@ that means editing every `res.json()` call site, which is a lot of churn for a
|
|
|
200
229
|
serialization change. `overrideJson` removes that step:
|
|
201
230
|
|
|
202
231
|
```ts
|
|
203
|
-
|
|
232
|
+
fastJsonOpenApi(app, document, { overrideJson: true });
|
|
204
233
|
|
|
205
234
|
// Unchanged route. It is now serialized from the `get /users/{id}` -> `200`
|
|
206
235
|
// schema, with no edit at the call site.
|
|
207
236
|
app.get('/users/:id', (req, res) => res.json(user));
|
|
208
237
|
```
|
|
209
238
|
|
|
210
|
-
Only `res.json` is replaced
|
|
211
|
-
`res.json(object)`, so both entry points are
|
|
212
|
-
`res.send` of a string or a Buffer is left alone.
|
|
239
|
+
Only `res.json` is replaced, once, on `app.response`. Express implements
|
|
240
|
+
`res.send(object)` by calling `res.json(object)`, so both entry points are
|
|
241
|
+
covered by the one hook, while `res.send` of a string or a Buffer is left alone.
|
|
213
242
|
|
|
214
243
|
**The override cannot break a route.** It steps aside, and the stock
|
|
215
244
|
`res.json()` runs, whenever:
|
|
@@ -221,24 +250,24 @@ Only `res.json` is replaced. Express implements `res.send(object)` by calling
|
|
|
221
250
|
missing. Pass `onError` to be told when that happens:
|
|
222
251
|
|
|
223
252
|
```ts
|
|
224
|
-
app
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
}),
|
|
229
|
-
);
|
|
253
|
+
fastJsonOpenApi(app, document, {
|
|
254
|
+
overrideJson: true,
|
|
255
|
+
onError: (error, req) => logger.warn({ error, url: req.originalUrl }, 'schema mismatch'),
|
|
256
|
+
});
|
|
230
257
|
```
|
|
231
258
|
|
|
232
259
|
`strict` does not apply here: it governs explicit `res.fastJson()` calls, while
|
|
233
260
|
an overridden `res.json()` always falls back rather than throw.
|
|
234
261
|
|
|
235
|
-
`
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
schema.
|
|
262
|
+
`installFastJson(app, { overrideJson: true })` does the same for the routes
|
|
263
|
+
that carry a `fastJsonSchema`, with one difference: a single schema describes
|
|
264
|
+
the _successful_ payload, so only `2xx` responses take the fast path. An error
|
|
265
|
+
body would otherwise be rewritten into the shape of the success schema.
|
|
239
266
|
|
|
240
267
|
```ts
|
|
241
|
-
app
|
|
268
|
+
installFastJson(app, { overrideJson: true });
|
|
269
|
+
|
|
270
|
+
app.get('/users/:id', fastJsonSchema(userSchema), (req, res) => {
|
|
242
271
|
res.json(user); // serialized through the schema
|
|
243
272
|
res.status(500).json({ error: 'boom' }); // untouched, stock res.json()
|
|
244
273
|
});
|
|
@@ -263,11 +292,15 @@ How much you gain depends on the payload, and on a current V8 it is not a win ac
|
|
|
263
292
|
|
|
264
293
|
Run `npm run example` to get the numbers for your own Node.js version and payload shape before adopting it in a hot path.
|
|
265
294
|
|
|
295
|
+
### On fulmine.js
|
|
296
|
+
|
|
297
|
+
[fulmine.js](https://www.npmjs.com/package/fulmine.js) is Express on uWebSockets.js, and it reads the source of every middleware and handler at startup: when none of them can read a request header, the header copy is skipped for that route. The `fastJsonSchema` middleware only writes `res.locals` and calls `next()`, so it keeps that skip, and so does a handler calling `res.json()`. A handler calling `res.fastJson()` does not, because that is not a method fulmine knows, so on fulmine prefer `overrideJson` and plain `res.json()`. Measured on an API endpoint with eleven request headers, the previous design of this package cost 5 to 9 microseconds of CPU per request there; this one is within half a microsecond of serializing by hand.
|
|
298
|
+
|
|
266
299
|
## Conclusion
|
|
267
300
|
|
|
268
301
|
Integrating `express-fast-json-stringify` into your Express.js application can provide substantial performance improvements when JSON serialization is a bottleneck and your schemas let the serializer skip work. It also guarantees that responses carry exactly the properties the schema describes, which is worth having on its own.
|
|
269
302
|
|
|
270
|
-
To start using `express-fast-json-stringify`, follow the steps outlined in this documentation, and enjoy the benefits of faster JSON serialization in your Express applications. For a runnable demo,
|
|
303
|
+
To start using `express-fast-json-stringify`, follow the steps outlined in this documentation, and enjoy the benefits of faster JSON serialization in your Express applications. For a runnable demo, open it on [StackBlitz](https://stackblitz.com/github/nigrosimone/express-fast-json-stringify) or run it locally from [example/](./example): `npm install && npm run example`.
|
|
271
304
|
|
|
272
305
|
## Support
|
|
273
306
|
|
package/build/main/index.d.ts
CHANGED
package/build/main/index.js
CHANGED
|
@@ -14,6 +14,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.installFastJson = void 0;
|
|
18
|
+
var install_1 = require("./lib/install");
|
|
19
|
+
Object.defineProperty(exports, "installFastJson", { enumerable: true, get: function () { return install_1.installFastJson; } });
|
|
17
20
|
__exportStar(require("./lib/middleware"), exports);
|
|
18
21
|
__exportStar(require("./lib/openapi"), exports);
|
|
19
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
22
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSx5Q0FBbUg7QUFBeEYsMEdBQUEsZUFBZSxPQUFBO0FBQzFDLG1EQUFpQztBQUNqQyxnREFBOEIifQ==
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { Express, Request, Response } from 'express';
|
|
2
|
+
/** What the install needs of an application: the prototype its responses share. Fulmine has one too. */
|
|
3
|
+
export type Application = Pick<Express, 'response'>;
|
|
4
|
+
/** A compiled serializer, as fast-json-stringify builds it. */
|
|
5
|
+
export type Serializer = (body: any) => string;
|
|
6
|
+
/** Finds the serializer for a response from something other than the route, an OpenAPI document. */
|
|
7
|
+
export type SerializerResolver = (res: Response) => Serializer | null;
|
|
8
|
+
/** Notified when an overridden `res.json()` could not use the fast path. */
|
|
9
|
+
export type OverrideErrorHandler = (error: unknown, req: Request) => void;
|
|
10
|
+
export type FastJsonOptions = {
|
|
11
|
+
/**
|
|
12
|
+
* Also route `res.json()`, and `res.send(object)` which Express implements on
|
|
13
|
+
* top of it, through the serializer in force.
|
|
14
|
+
*
|
|
15
|
+
* Off by default. A route's own schema describes the successful payload, so
|
|
16
|
+
* under it only `2xx` responses take the fast path: an error body would
|
|
17
|
+
* otherwise be rewritten into the wrong shape.
|
|
18
|
+
*/
|
|
19
|
+
readonly overrideJson?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Called when an overridden `res.json()` could not use the fast path because
|
|
22
|
+
* the serializer threw. The response falls back to the stock `res.json()`
|
|
23
|
+
* either way; this is only so the mismatch is visible.
|
|
24
|
+
*/
|
|
25
|
+
readonly onError?: OverrideErrorHandler;
|
|
26
|
+
/**
|
|
27
|
+
* Make `res.fastJson()` throw when no schema is known for the response,
|
|
28
|
+
* instead of quietly falling back to `res.json()`. An overridden `res.json()`
|
|
29
|
+
* always falls back.
|
|
30
|
+
*/
|
|
31
|
+
readonly strict?: boolean;
|
|
32
|
+
};
|
|
33
|
+
/** Where `fastJsonSchema` leaves the serializer of the route, on `res.locals`. */
|
|
34
|
+
export declare const kSerializer: unique symbol;
|
|
35
|
+
/**
|
|
36
|
+
* Give an application `res.fastJson()`, and with `overrideJson` a `res.json()`
|
|
37
|
+
* that serializes through the schema in force. Once per app, at setup: the
|
|
38
|
+
* methods go on `app.response`, so a request pays nothing to have them.
|
|
39
|
+
*
|
|
40
|
+
* `fastJsonSchema` chooses the schema per route, `fastJsonOpenApi` per
|
|
41
|
+
* operation from a document and calls this itself.
|
|
42
|
+
*
|
|
43
|
+
* @param {Application} app The application to extend
|
|
44
|
+
* @param {FastJsonOptions} options The options to use (optional)
|
|
45
|
+
*
|
|
46
|
+
* Examples:
|
|
47
|
+
* ```ts
|
|
48
|
+
* import express from 'express';
|
|
49
|
+
* import { installFastJson, fastJsonSchema } from 'express-fast-json-stringify';
|
|
50
|
+
*
|
|
51
|
+
* const app = express();
|
|
52
|
+
* installFastJson(app);
|
|
53
|
+
*
|
|
54
|
+
* app.get('/', fastJsonSchema(schema), (req, res) => {
|
|
55
|
+
* res.fastJson({ firstName: 'Simone', lastName: 'Nigro', age: 40 });
|
|
56
|
+
* });
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export declare const installFastJson: (app: Application, options?: FastJsonOptions) => void;
|
|
60
|
+
/** Registers where the document based serializers come from, see fastJsonOpenApi. */
|
|
61
|
+
export declare const setResolver: (app: Application, resolver: SerializerResolver) => void;
|
|
62
|
+
declare global {
|
|
63
|
+
namespace Express {
|
|
64
|
+
interface Response {
|
|
65
|
+
/**
|
|
66
|
+
* Send JSON response, serialized with the schema in force for the route.
|
|
67
|
+
*
|
|
68
|
+
* Examples:
|
|
69
|
+
* ```ts
|
|
70
|
+
* res.fastJson({ user: 'Simone Nigro' });
|
|
71
|
+
* res.status(200).fastJson({ user: 'Simone Nigro' });
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
fastJson: (body: any) => Response;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setResolver = exports.installFastJson = exports.kSerializer = void 0;
|
|
4
|
+
const send_1 = require("./send");
|
|
5
|
+
/** Where `fastJsonSchema` leaves the serializer of the route, on `res.locals`. */
|
|
6
|
+
exports.kSerializer = Symbol('express-fast-json-stringify');
|
|
7
|
+
// one state per response prototype, which is one per app
|
|
8
|
+
const states = new WeakMap();
|
|
9
|
+
const routeOf = (req) => { var _a, _b; return `${req.baseUrl}${(_b = (_a = req.route) === null || _a === void 0 ? void 0 : _a.path) !== null && _b !== void 0 ? _b : req.path}`; };
|
|
10
|
+
// the route's own serializer first, then what the document says
|
|
11
|
+
const pick = (state, res, successOnly) => {
|
|
12
|
+
const own = res.locals[exports.kSerializer];
|
|
13
|
+
if (own !== undefined && (!successOnly || (res.statusCode >= 200 && res.statusCode < 300))) {
|
|
14
|
+
return own;
|
|
15
|
+
}
|
|
16
|
+
return state.resolver === null ? null : state.resolver(res);
|
|
17
|
+
};
|
|
18
|
+
const fastJsonMethod = (state) => function installFastJson(body) {
|
|
19
|
+
const serialize = pick(state, this, false);
|
|
20
|
+
if (serialize === null) {
|
|
21
|
+
if (state.strict) {
|
|
22
|
+
throw new Error(`express-fast-json-stringify: no schema for ${this.req.method} ${routeOf(this.req)}`);
|
|
23
|
+
}
|
|
24
|
+
return state.stockJson.call(this, body);
|
|
25
|
+
}
|
|
26
|
+
return (0, send_1.sendSerialized)(this, serialize(body));
|
|
27
|
+
};
|
|
28
|
+
// The stock res.json() runs whenever the fast path does not apply: a setting that changes the
|
|
29
|
+
// bytes (json replacer, spaces, escape), no schema for this response, or a body the schema refuses
|
|
30
|
+
const jsonMethod = (state) => function json(body) {
|
|
31
|
+
var _a;
|
|
32
|
+
const app = this.app;
|
|
33
|
+
if (!app.get('json replacer') && !app.get('json spaces') && !app.get('json escape')) {
|
|
34
|
+
const serialize = pick(state, this, true);
|
|
35
|
+
if (serialize !== null) {
|
|
36
|
+
let out;
|
|
37
|
+
try {
|
|
38
|
+
out = serialize(body);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
(_a = state.onError) === null || _a === void 0 ? void 0 : _a.call(state, error, this.req);
|
|
42
|
+
}
|
|
43
|
+
if (out !== undefined) {
|
|
44
|
+
return (0, send_1.sendSerialized)(this, out);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return state.stockJson.call(this, body);
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Give an application `res.fastJson()`, and with `overrideJson` a `res.json()`
|
|
52
|
+
* that serializes through the schema in force. Once per app, at setup: the
|
|
53
|
+
* methods go on `app.response`, so a request pays nothing to have them.
|
|
54
|
+
*
|
|
55
|
+
* `fastJsonSchema` chooses the schema per route, `fastJsonOpenApi` per
|
|
56
|
+
* operation from a document and calls this itself.
|
|
57
|
+
*
|
|
58
|
+
* @param {Application} app The application to extend
|
|
59
|
+
* @param {FastJsonOptions} options The options to use (optional)
|
|
60
|
+
*
|
|
61
|
+
* Examples:
|
|
62
|
+
* ```ts
|
|
63
|
+
* import express from 'express';
|
|
64
|
+
* import { installFastJson, fastJsonSchema } from 'express-fast-json-stringify';
|
|
65
|
+
*
|
|
66
|
+
* const app = express();
|
|
67
|
+
* installFastJson(app);
|
|
68
|
+
*
|
|
69
|
+
* app.get('/', fastJsonSchema(schema), (req, res) => {
|
|
70
|
+
* res.fastJson({ firstName: 'Simone', lastName: 'Nigro', age: 40 });
|
|
71
|
+
* });
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
const installFastJson = (app, options = {}) => {
|
|
75
|
+
const proto = app === null || app === void 0 ? void 0 : app.response;
|
|
76
|
+
if (!proto || typeof proto.json !== 'function') {
|
|
77
|
+
throw new TypeError('express-fast-json-stringify: an Express application is required');
|
|
78
|
+
}
|
|
79
|
+
let state = states.get(proto);
|
|
80
|
+
if (state === undefined) {
|
|
81
|
+
state = { stockJson: proto.json, resolver: null, overrideJson: false, onError: undefined, strict: false };
|
|
82
|
+
states.set(proto, state);
|
|
83
|
+
proto.fastJson = fastJsonMethod(state);
|
|
84
|
+
}
|
|
85
|
+
state.overrideJson = options.overrideJson === true;
|
|
86
|
+
state.onError = options.onError;
|
|
87
|
+
state.strict = options.strict === true;
|
|
88
|
+
// the stock method is put back when the override is off, so nothing runs on res.json() that
|
|
89
|
+
// was not there before, and a framework reading the prototype sees the method it knows
|
|
90
|
+
proto.json = state.overrideJson ? jsonMethod(state) : state.stockJson;
|
|
91
|
+
};
|
|
92
|
+
exports.installFastJson = installFastJson;
|
|
93
|
+
/** Registers where the document based serializers come from, see fastJsonOpenApi. */
|
|
94
|
+
const setResolver = (app, resolver) => {
|
|
95
|
+
states.get(app.response).resolver = resolver;
|
|
96
|
+
};
|
|
97
|
+
exports.setResolver = setResolver;
|
|
98
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5zdGFsbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvaW5zdGFsbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSxpQ0FBd0M7QUFzQ3hDLGtGQUFrRjtBQUNyRSxRQUFBLFdBQVcsR0FBa0IsTUFBTSxDQUFDLDZCQUE2QixDQUFDLENBQUM7QUFZaEYseURBQXlEO0FBQ3pELE1BQU0sTUFBTSxHQUFHLElBQUksT0FBTyxFQUFpQixDQUFDO0FBRTVDLE1BQU0sT0FBTyxHQUFHLENBQUMsR0FBWSxFQUFVLEVBQUUsZUFBQyxPQUFBLEdBQUcsR0FBRyxDQUFDLE9BQU8sR0FBRyxNQUFBLE1BQUEsR0FBRyxDQUFDLEtBQUssMENBQUUsSUFBSSxtQ0FBSSxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUEsRUFBQSxDQUFDO0FBRXpGLGdFQUFnRTtBQUNoRSxNQUFNLElBQUksR0FBRyxDQUFDLEtBQVksRUFBRSxHQUFhLEVBQUUsV0FBb0IsRUFBcUIsRUFBRTtJQUNwRixNQUFNLEdBQUcsR0FBSSxHQUFHLENBQUMsTUFBaUIsQ0FBQyxtQkFBVyxDQUFDLENBQUM7SUFDaEQsSUFBSSxHQUFHLEtBQUssU0FBUyxJQUFJLENBQUMsQ0FBQyxXQUFXLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxJQUFJLEdBQUcsSUFBSSxHQUFHLENBQUMsVUFBVSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUMzRixPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQyxRQUFRLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDOUQsQ0FBQyxDQUFDO0FBRUYsTUFBTSxjQUFjLEdBQUcsQ0FBQyxLQUFZLEVBQUUsRUFBRSxDQUN0QyxTQUFTLGVBQWUsQ0FBaUIsSUFBUztJQUNoRCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztJQUMzQyxJQUFJLFNBQVMsS0FBSyxJQUFJLEVBQUUsQ0FBQztRQUN2QixJQUFJLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNqQixNQUFNLElBQUksS0FBSyxDQUFDLDhDQUE4QyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN4RyxDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUNELE9BQU8sSUFBQSxxQkFBYyxFQUFDLElBQUksRUFBRSxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztBQUMvQyxDQUFDLENBQUM7QUFFSiw4RkFBOEY7QUFDOUYsbUdBQW1HO0FBQ25HLE1BQU0sVUFBVSxHQUFHLENBQUMsS0FBWSxFQUFFLEVBQUUsQ0FDbEMsU0FBUyxJQUFJLENBQWlCLElBQVM7O0lBQ3JDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUM7SUFDckIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDO1FBQ3BGLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzFDLElBQUksU0FBUyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQ3ZCLElBQUksR0FBdUIsQ0FBQztZQUM1QixJQUFJLENBQUM7Z0JBQ0gsR0FBRyxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN4QixDQUFDO1lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDZixNQUFBLEtBQUssQ0FBQyxPQUFPLHNEQUFHLEtBQUssRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDbkMsQ0FBQztZQUNELElBQUksR0FBRyxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUN0QixPQUFPLElBQUEscUJBQWMsRUFBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDbkMsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxLQUFLLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDMUMsQ0FBQyxDQUFDO0FBRUo7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBdUJHO0FBQ0ksTUFBTSxlQUFlLEdBQUcsQ0FBQyxHQUFnQixFQUFFLFVBQTJCLEVBQUUsRUFBUSxFQUFFO0lBQ3ZGLE1BQU0sS0FBSyxHQUFHLEdBQUcsYUFBSCxHQUFHLHVCQUFILEdBQUcsQ0FBRSxRQUFRLENBQUM7SUFDNUIsSUFBSSxDQUFDLEtBQUssSUFBSSxPQUFPLEtBQUssQ0FBQyxJQUFJLEtBQUssVUFBVSxFQUFFLENBQUM7UUFDL0MsTUFBTSxJQUFJLFNBQVMsQ0FBQyxpRUFBaUUsQ0FBQyxDQUFDO0lBQ3pGLENBQUM7SUFDRCxJQUFJLEtBQUssR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzlCLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQ3hCLEtBQUssR0FBRyxFQUFFLFNBQVMsRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQztRQUMxRyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN6QixLQUFLLENBQUMsUUFBUSxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBQ0QsS0FBSyxDQUFDLFlBQVksR0FBRyxPQUFPLENBQUMsWUFBWSxLQUFLLElBQUksQ0FBQztJQUNuRCxLQUFLLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUM7SUFDaEMsS0FBSyxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQztJQUN2Qyw0RkFBNEY7SUFDNUYsdUZBQXVGO0lBQ3ZGLEtBQUssQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDO0FBQ3hFLENBQUMsQ0FBQztBQWpCVyxRQUFBLGVBQWUsbUJBaUIxQjtBQUVGLHFGQUFxRjtBQUM5RSxNQUFNLFdBQVcsR0FBRyxDQUFDLEdBQWdCLEVBQUUsUUFBNEIsRUFBUSxFQUFFO0lBQ2pGLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBVyxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7QUFDMUQsQ0FBQyxDQUFDO0FBRlcsUUFBQSxXQUFXLGVBRXRCIn0=
|
|
@@ -1,36 +1,22 @@
|
|
|
1
1
|
import type { NextFunction, Request, Response } from 'express';
|
|
2
2
|
import { type Options, type Schema } from 'fast-json-stringify';
|
|
3
|
-
import { type OverrideErrorHandler } from './override';
|
|
4
3
|
export type { Schema, Options } from 'fast-json-stringify';
|
|
5
|
-
export type FastJsonSchemaOptions = Omit<Options, 'mode'
|
|
6
|
-
/**
|
|
7
|
-
* Also route `res.json()` — and therefore `res.send(object)`, which Express
|
|
8
|
-
* implements on top of it — through the compiled serializer.
|
|
9
|
-
*
|
|
10
|
-
* Off by default. Because a single schema describes the successful payload,
|
|
11
|
-
* only `2xx` responses take the fast path: an error body would otherwise be
|
|
12
|
-
* rewritten into the shape of the success schema.
|
|
13
|
-
*/
|
|
14
|
-
readonly overrideJson?: boolean;
|
|
15
|
-
/**
|
|
16
|
-
* Called when an overridden `res.json()` could not use the fast path because
|
|
17
|
-
* the serializer threw. The response falls back to the stock `res.json()`
|
|
18
|
-
* either way; this is only so the mismatch is visible.
|
|
19
|
-
*/
|
|
20
|
-
readonly onError?: OverrideErrorHandler;
|
|
21
|
-
};
|
|
4
|
+
export type FastJsonSchemaOptions = Omit<Options, 'mode'>;
|
|
22
5
|
/**
|
|
23
|
-
* Build a
|
|
6
|
+
* Build a middleware that gives its route a serializer compiled from the schema.
|
|
7
|
+
* The application needs `installFastJson(app)` once for `res.fastJson()` to exist.
|
|
8
|
+
*
|
|
24
9
|
* @param {Schema} schema The schema used to stringify values
|
|
25
|
-
* @param {
|
|
10
|
+
* @param {FastJsonSchemaOptions} options The fast-json-stringify options (optional)
|
|
26
11
|
* @see https://www.npmjs.com/package/fast-json-stringify
|
|
27
12
|
*
|
|
28
13
|
* Examples:
|
|
29
14
|
* ```ts
|
|
30
15
|
* import express from 'express';
|
|
31
|
-
* import { fastJsonSchema, Schema } from 'express-fast-json-stringify';
|
|
16
|
+
* import { installFastJson, fastJsonSchema, Schema } from 'express-fast-json-stringify';
|
|
32
17
|
*
|
|
33
18
|
* const app = express();
|
|
19
|
+
* installFastJson(app);
|
|
34
20
|
*
|
|
35
21
|
* const schema: Schema = {
|
|
36
22
|
* title: 'Example Schema',
|
|
@@ -62,20 +48,4 @@ export type FastJsonSchemaOptions = Omit<Options, 'mode'> & {
|
|
|
62
48
|
* });
|
|
63
49
|
* ```
|
|
64
50
|
*/
|
|
65
|
-
export declare const fastJsonSchema: (schema: Schema, options?: FastJsonSchemaOptions) => (
|
|
66
|
-
declare global {
|
|
67
|
-
namespace Express {
|
|
68
|
-
interface Response {
|
|
69
|
-
/**
|
|
70
|
-
* Send JSON response.
|
|
71
|
-
*
|
|
72
|
-
* Examples:
|
|
73
|
-
* ```ts
|
|
74
|
-
* res.fastJson({ user: 'Simone Nigro' });
|
|
75
|
-
* res.status(200).fastJson({ user: 'Simone Nigro' });
|
|
76
|
-
* ```
|
|
77
|
-
*/
|
|
78
|
-
fastJson: (body: any) => Response;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
51
|
+
export declare const fastJsonSchema: (schema: Schema, options?: FastJsonSchemaOptions) => (_req: Request, res: Response, next: NextFunction) => void;
|
|
@@ -1,35 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
-
var t = {};
|
|
4
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
-
t[p] = s[p];
|
|
6
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
-
t[p[i]] = s[p[i]];
|
|
10
|
-
}
|
|
11
|
-
return t;
|
|
12
|
-
};
|
|
13
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
4
|
};
|
|
16
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
6
|
exports.fastJsonSchema = void 0;
|
|
18
7
|
const fast_json_stringify_1 = __importDefault(require("fast-json-stringify"));
|
|
19
|
-
const
|
|
20
|
-
const send_1 = require("./send");
|
|
8
|
+
const install_1 = require("./install");
|
|
21
9
|
/**
|
|
22
|
-
* Build a
|
|
10
|
+
* Build a middleware that gives its route a serializer compiled from the schema.
|
|
11
|
+
* The application needs `installFastJson(app)` once for `res.fastJson()` to exist.
|
|
12
|
+
*
|
|
23
13
|
* @param {Schema} schema The schema used to stringify values
|
|
24
|
-
* @param {
|
|
14
|
+
* @param {FastJsonSchemaOptions} options The fast-json-stringify options (optional)
|
|
25
15
|
* @see https://www.npmjs.com/package/fast-json-stringify
|
|
26
16
|
*
|
|
27
17
|
* Examples:
|
|
28
18
|
* ```ts
|
|
29
19
|
* import express from 'express';
|
|
30
|
-
* import { fastJsonSchema, Schema } from 'express-fast-json-stringify';
|
|
20
|
+
* import { installFastJson, fastJsonSchema, Schema } from 'express-fast-json-stringify';
|
|
31
21
|
*
|
|
32
22
|
* const app = express();
|
|
23
|
+
* installFastJson(app);
|
|
33
24
|
*
|
|
34
25
|
* const schema: Schema = {
|
|
35
26
|
* title: 'Example Schema',
|
|
@@ -65,27 +56,13 @@ const fastJsonSchema = (schema, options) => {
|
|
|
65
56
|
if (!schema || (typeof schema !== 'object' && typeof schema !== 'boolean')) {
|
|
66
57
|
throw new TypeError(`express-fast-json-stringify: invalid schema`);
|
|
67
58
|
}
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
*
|
|
74
|
-
* Examples:
|
|
75
|
-
* ```ts
|
|
76
|
-
* res.fastJson({ user: 'Simone Nigro' });
|
|
77
|
-
* res.status(200).fastJson({ user: 'Simone Nigro' });
|
|
78
|
-
* ```
|
|
79
|
-
*/
|
|
80
|
-
res.fastJson = (body) => (0, send_1.sendJson)(req, res, fjs(body));
|
|
81
|
-
if (overrideJson) {
|
|
82
|
-
// A single schema describes the successful payload, so applying it to an
|
|
83
|
-
// error body would rewrite it into the wrong shape. Only 2xx responses
|
|
84
|
-
// take the fast path; everything else keeps the stock res.json().
|
|
85
|
-
(0, override_1.overrideResJson)(req, res, (status) => (status >= 200 && status < 300 ? fjs : null), onError);
|
|
86
|
-
}
|
|
59
|
+
const serialize = (0, fast_json_stringify_1.default)(schema, options);
|
|
60
|
+
// One write on res.locals and a next(), nothing else on req or res: a framework that reads a
|
|
61
|
+
// middleware's source to skip work, fulmine does, must be able to see this touches no header
|
|
62
|
+
return (_req, res, next) => {
|
|
63
|
+
res.locals[install_1.kSerializer] = serialize;
|
|
87
64
|
next();
|
|
88
65
|
};
|
|
89
66
|
};
|
|
90
67
|
exports.fastJsonSchema = fastJsonSchema;
|
|
91
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
68
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlkZGxld2FyZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvbWlkZGxld2FyZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFDQSw4RUFBbUY7QUFFbkYsdUNBQXlEO0FBTXpEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E2Q0c7QUFDSSxNQUFNLGNBQWMsR0FBRyxDQUFDLE1BQWMsRUFBRSxPQUErQixFQUFFLEVBQUU7SUFDaEYsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLE9BQU8sTUFBTSxLQUFLLFFBQVEsSUFBSSxPQUFPLE1BQU0sS0FBSyxTQUFTLENBQUMsRUFBRSxDQUFDO1FBQzNFLE1BQU0sSUFBSSxTQUFTLENBQUMsNkNBQTZDLENBQUMsQ0FBQztJQUNyRSxDQUFDO0lBQ0QsTUFBTSxTQUFTLEdBQWUsSUFBQSw2QkFBaUIsRUFBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDakUsNkZBQTZGO0lBQzdGLDZGQUE2RjtJQUM3RixPQUFPLENBQUMsSUFBYSxFQUFFLEdBQWEsRUFBRSxJQUFrQixFQUFRLEVBQUU7UUFDL0QsR0FBRyxDQUFDLE1BQWlELENBQUMscUJBQVcsQ0FBQyxHQUFHLFNBQVMsQ0FBQztRQUNoRixJQUFJLEVBQUUsQ0FBQztJQUNULENBQUMsQ0FBQztBQUNKLENBQUMsQ0FBQztBQVhXLFFBQUEsY0FBYyxrQkFXekIifQ==
|