express-zod-api 25.5.1 → 25.5.3
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 +97 -81
- package/README.md +61 -54
- package/dist/index.d.ts +8 -8
- package/dist/index.js +2 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -59,7 +59,8 @@ Start your API server with I/O schema validation and custom middlewares in minut
|
|
|
59
59
|
5. [Graceful shutdown](#graceful-shutdown)
|
|
60
60
|
6. [Subscriptions](#subscriptions)
|
|
61
61
|
8. [Caveats](#caveats)
|
|
62
|
-
1. [
|
|
62
|
+
1. [TypeError: example is not a function](#typeerror-example-is-not-a-function)
|
|
63
|
+
2. [Excessive properties in endpoint output](#excessive-properties-in-endpoint-output)
|
|
63
64
|
9. [Your input to my output](#your-input-to-my-output)
|
|
64
65
|
|
|
65
66
|
See also [Changelog](CHANGELOG.md) and [automated migration](https://www.npmjs.com/package/@express-zod-api/migration).
|
|
@@ -85,6 +86,7 @@ Therefore, many basic tasks can be accomplished faster and easier, in particular
|
|
|
85
86
|
|
|
86
87
|
These people contributed to the improvement of the framework by reporting bugs, making changes and suggesting ideas:
|
|
87
88
|
|
|
89
|
+
[<img src="https://github.com/squishykid.png" alt="@squishykid" width="50px" />](https://github.com/squishykid)
|
|
88
90
|
[<img src="https://github.com/jakub-msqt.png" alt="@jakub-msqt" width="50px" />](https://github.com/jakub-msqt)
|
|
89
91
|
[<img src="https://github.com/misha-z1nchuk.png" alt="@misha-z1nchuk" width="50px" />](https://github.com/misha-z1nchuk)
|
|
90
92
|
[<img src="https://github.com/GreaterTamarack.png" alt="@GreaterTamarack" width="50px" />](https://github.com/GreaterTamarack)
|
|
@@ -183,9 +185,13 @@ pnpm add -D @types/express @types/node @types/http-errors
|
|
|
183
185
|
|
|
184
186
|
## Environment preparation
|
|
185
187
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
188
|
+
Ensure running your code as [ESM](https://nodejs.org/api/esm.html#enabling) by either:
|
|
189
|
+
|
|
190
|
+
- setting `"type": "module"` in your `package.json`;
|
|
191
|
+
- or using `.mts` file extension;
|
|
192
|
+
- or using `tsx` or `vite-node` or similar tools.
|
|
193
|
+
|
|
194
|
+
Enable the following `compilerOptions` in your `tsconfig.json` to make it work as expected:
|
|
189
195
|
|
|
190
196
|
```json
|
|
191
197
|
{
|
|
@@ -201,7 +207,7 @@ Ensure having the following options in order to make it work as expected:
|
|
|
201
207
|
Create a minimal configuration. Find out all configurable options
|
|
202
208
|
[in sources](https://github.com/RobinTail/express-zod-api/blob/master/express-zod-api/src/config-type.ts).
|
|
203
209
|
|
|
204
|
-
```
|
|
210
|
+
```ts
|
|
205
211
|
import { createConfig } from "express-zod-api";
|
|
206
212
|
|
|
207
213
|
const config = createConfig({
|
|
@@ -215,7 +221,7 @@ const config = createConfig({
|
|
|
215
221
|
Use the default factory to make an endpoint that responds with "Hello, World" or "Hello, {name}" depending on inputs.
|
|
216
222
|
Learn how to make factories for [custom response](#response-customization) and by [adding middlewares](#middlewares).
|
|
217
223
|
|
|
218
|
-
```
|
|
224
|
+
```ts
|
|
219
225
|
import { defaultEndpointsFactory } from "express-zod-api";
|
|
220
226
|
import { z } from "zod";
|
|
221
227
|
|
|
@@ -238,7 +244,7 @@ const helloWorldEndpoint = defaultEndpointsFactory.build({
|
|
|
238
244
|
|
|
239
245
|
Connect your endpoint to the `/v1/hello` route:
|
|
240
246
|
|
|
241
|
-
```
|
|
247
|
+
```ts
|
|
242
248
|
import { Routing } from "express-zod-api";
|
|
243
249
|
|
|
244
250
|
const routing: Routing = {
|
|
@@ -252,7 +258,7 @@ const routing: Routing = {
|
|
|
252
258
|
|
|
253
259
|
See the [complete implementation example](https://github.com/RobinTail/express-zod-api/tree/master/example).
|
|
254
260
|
|
|
255
|
-
```
|
|
261
|
+
```ts
|
|
256
262
|
import { createServer } from "express-zod-api";
|
|
257
263
|
|
|
258
264
|
createServer(config, routing);
|
|
@@ -328,7 +334,7 @@ Inputs of middlewares are also available to endpoint handlers within `input`.
|
|
|
328
334
|
|
|
329
335
|
Here is an example of the authentication middleware, that checks a `key` from input and `token` from headers:
|
|
330
336
|
|
|
331
|
-
```
|
|
337
|
+
```ts
|
|
332
338
|
import { z } from "zod";
|
|
333
339
|
import createHttpError from "http-errors";
|
|
334
340
|
import { Middleware } from "express-zod-api";
|
|
@@ -357,7 +363,7 @@ const authMiddleware = new Middleware({
|
|
|
357
363
|
|
|
358
364
|
By using `.addMiddleware()` method before `.build()` you can connect it to the endpoint:
|
|
359
365
|
|
|
360
|
-
```
|
|
366
|
+
```ts
|
|
361
367
|
const yourEndpoint = defaultEndpointsFactory
|
|
362
368
|
.addMiddleware(authMiddleware)
|
|
363
369
|
.build({
|
|
@@ -371,7 +377,7 @@ You can create a new factory by connecting as many middlewares as you want — t
|
|
|
371
377
|
order for all the endpoints produced on that factory. You may also use a shorter inline syntax within the
|
|
372
378
|
`.addMiddleware()` method, and have access to the output of the previously executed middlewares in chain as `options`:
|
|
373
379
|
|
|
374
|
-
```
|
|
380
|
+
```ts
|
|
375
381
|
import { defaultEndpointsFactory } from "express-zod-api";
|
|
376
382
|
|
|
377
383
|
const factory = defaultEndpointsFactory
|
|
@@ -386,7 +392,7 @@ const factory = defaultEndpointsFactory
|
|
|
386
392
|
In case you'd like to provide your endpoints with options that do not depend on Request, like non-persistent connection
|
|
387
393
|
to a database, consider shorthand method `addOptions`. For static options consider reusing `const` across your files.
|
|
388
394
|
|
|
389
|
-
```
|
|
395
|
+
```ts
|
|
390
396
|
import { readFile } from "node:fs/promises";
|
|
391
397
|
import { defaultEndpointsFactory } from "express-zod-api";
|
|
392
398
|
|
|
@@ -401,7 +407,7 @@ const endpointsFactory = defaultEndpointsFactory.addOptions(async () => {
|
|
|
401
407
|
**Notice on resources cleanup**: If necessary, you can release resources at the end of the request processing in a
|
|
402
408
|
custom [Result Handler](#response-customization):
|
|
403
409
|
|
|
404
|
-
```
|
|
410
|
+
```ts
|
|
405
411
|
import { ResultHandler } from "express-zod-api";
|
|
406
412
|
|
|
407
413
|
const resultHandlerWithCleanup = new ResultHandler({
|
|
@@ -422,7 +428,7 @@ In case it's a middleware establishing and serving its own routes, or somehow gl
|
|
|
422
428
|
being an additional request parser (like `cookie-parser`), use the `beforeRouting` option. However, it might be better
|
|
423
429
|
to avoid `cors` here — [the framework handles it on its own](#cross-origin-resource-sharing).
|
|
424
430
|
|
|
425
|
-
```
|
|
431
|
+
```ts
|
|
426
432
|
import { createConfig } from "express-zod-api";
|
|
427
433
|
import ui from "swagger-ui-express";
|
|
428
434
|
|
|
@@ -442,7 +448,7 @@ In case you need a special processing of `request`, or to modify the `response`
|
|
|
442
448
|
`addExpressMiddleware()` of `EndpointsFactory` (or its alias `use()`). The method has two optional features: a provider
|
|
443
449
|
of [options](#options) and an error transformer for adjusting the response status code.
|
|
444
450
|
|
|
445
|
-
```
|
|
451
|
+
```ts
|
|
446
452
|
import { defaultEndpointsFactory } from "express-zod-api";
|
|
447
453
|
import createHttpError from "http-errors";
|
|
448
454
|
import { auth } from "express-oauth2-jwt-bearer";
|
|
@@ -458,7 +464,7 @@ const factory = defaultEndpointsFactory.use(auth(), {
|
|
|
458
464
|
You can implement additional validations within schemas using refinements.
|
|
459
465
|
Validation errors are reported in a response with a status code `400`.
|
|
460
466
|
|
|
461
|
-
```
|
|
467
|
+
```ts
|
|
462
468
|
import { z } from "zod";
|
|
463
469
|
import { Middleware } from "express-zod-api";
|
|
464
470
|
|
|
@@ -478,7 +484,7 @@ const nicknameConstraintMiddleware = new Middleware({
|
|
|
478
484
|
|
|
479
485
|
By the way, you can also refine the whole I/O object, for example in case you need a complex validation of its props.
|
|
480
486
|
|
|
481
|
-
```
|
|
487
|
+
```ts
|
|
482
488
|
const endpoint = endpointsFactory.build({
|
|
483
489
|
input: z
|
|
484
490
|
.object({
|
|
@@ -510,7 +516,7 @@ square brackets. You can choose between those parsers as well as configure a cus
|
|
|
510
516
|
|
|
511
517
|
Since parameters of GET requests come in the form of strings, there is often a need to transform them into numbers.
|
|
512
518
|
|
|
513
|
-
```
|
|
519
|
+
```ts
|
|
514
520
|
import { z } from "zod";
|
|
515
521
|
|
|
516
522
|
const getUserEndpoint = endpointsFactory.buildVoid({
|
|
@@ -590,7 +596,7 @@ provides your endpoint handler or middleware with a `Date`. It supports the foll
|
|
|
590
596
|
`ez.dateOut()`, on the contrary, accepts a `Date` and provides `ResultHandler` with a `string` representation in ISO
|
|
591
597
|
format for the response transmission. Both schemas accept metadata as an argument. Consider the following example:
|
|
592
598
|
|
|
593
|
-
```
|
|
599
|
+
```ts
|
|
594
600
|
import { z } from "zod";
|
|
595
601
|
import { ez, defaultEndpointsFactory } from "express-zod-api";
|
|
596
602
|
|
|
@@ -615,7 +621,7 @@ You can enable your API for other domains using the corresponding configuration
|
|
|
615
621
|
ensure you explicitly choose the correct setting. In addition to being a boolean, `cors` can also be assigned a
|
|
616
622
|
function that overrides default CORS headers. That function has several parameters and can be asynchronous.
|
|
617
623
|
|
|
618
|
-
```
|
|
624
|
+
```ts
|
|
619
625
|
import { createConfig } from "express-zod-api";
|
|
620
626
|
|
|
621
627
|
const config = createConfig({
|
|
@@ -635,7 +641,7 @@ Please note: If you only want to send specific headers on requests to a specific
|
|
|
635
641
|
The modern API standard often assumes the use of a secure data transfer protocol, confirmed by a TLS certificate, also
|
|
636
642
|
often called an SSL certificate in habit. This way you can additionally (or solely) configure and run the HTTPS server:
|
|
637
643
|
|
|
638
|
-
```
|
|
644
|
+
```ts
|
|
639
645
|
import { createConfig, createServer } from "express-zod-api";
|
|
640
646
|
|
|
641
647
|
const config = createConfig({
|
|
@@ -664,7 +670,7 @@ it might be a good idea to enable GZIP and Brotli compression for your API respo
|
|
|
664
670
|
|
|
665
671
|
Install `compression` and `@types/compression`, and enable or configure compression:
|
|
666
672
|
|
|
667
|
-
```
|
|
673
|
+
```ts
|
|
668
674
|
import { createConfig } from "express-zod-api";
|
|
669
675
|
|
|
670
676
|
const config = createConfig({
|
|
@@ -680,7 +686,7 @@ In order to receive a compressed response the client should include the followin
|
|
|
680
686
|
|
|
681
687
|
A simple built-in console logger is used by default with the following options that you can configure:
|
|
682
688
|
|
|
683
|
-
```
|
|
689
|
+
```ts
|
|
684
690
|
import { createConfig } from "express-zod-api";
|
|
685
691
|
const config = createConfig({
|
|
686
692
|
logger: {
|
|
@@ -694,7 +700,7 @@ const config = createConfig({
|
|
|
694
700
|
You can also replace it with a one having at least the following methods: `info()`, `debug()`, `error()` and `warn()`.
|
|
695
701
|
Winston and Pino support is well known. Here is an example configuring `pino` logger with `pino-pretty` extension:
|
|
696
702
|
|
|
697
|
-
```
|
|
703
|
+
```ts
|
|
698
704
|
import pino, { Logger } from "pino";
|
|
699
705
|
import { createConfig } from "express-zod-api";
|
|
700
706
|
|
|
@@ -719,7 +725,7 @@ In case you need a dedicated logger for each request (for example, equipped with
|
|
|
719
725
|
it can also be asynchronous. The child logger returned by that function will replace the `logger` in all handlers.
|
|
720
726
|
You can use the `.child()` method of the built-in logger or [install a custom logger](#customizing-logger) instead.
|
|
721
727
|
|
|
722
|
-
```
|
|
728
|
+
```ts
|
|
723
729
|
import { createConfig, BuiltinLogger } from "express-zod-api";
|
|
724
730
|
import { randomUUID } from "node:crypto";
|
|
725
731
|
|
|
@@ -742,7 +748,7 @@ You can customize the list of `request` properties that are combined into `input
|
|
|
742
748
|
to your endpoints and middlewares. The order here matters: each next item in the array has a higher priority than its
|
|
743
749
|
previous sibling. The following arrangement is default:
|
|
744
750
|
|
|
745
|
-
```
|
|
751
|
+
```ts
|
|
746
752
|
import { createConfig } from "express-zod-api";
|
|
747
753
|
|
|
748
754
|
createConfig({
|
|
@@ -764,7 +770,7 @@ In a similar way you can enable request headers as the input source. This is an
|
|
|
764
770
|
- consider handling headers in `Middleware` and declaring them within `security` property to improve `Documentation`;
|
|
765
771
|
- the request headers acquired that way are always lowercase when describing their validation schemas.
|
|
766
772
|
|
|
767
|
-
```
|
|
773
|
+
```ts
|
|
768
774
|
import { createConfig, Middleware } from "express-zod-api";
|
|
769
775
|
import { z } from "zod";
|
|
770
776
|
|
|
@@ -792,7 +798,7 @@ factory.build({
|
|
|
792
798
|
`ResultHandler` is responsible for transmitting consistent responses containing the endpoint output or an error.
|
|
793
799
|
The `defaultResultHandler` sets the HTTP status code and ensures the following type of the response:
|
|
794
800
|
|
|
795
|
-
```
|
|
801
|
+
```ts
|
|
796
802
|
type DefaultResponse<OUT> =
|
|
797
803
|
| { status: "success"; data: OUT } // Positive response
|
|
798
804
|
| { status: "error"; error: { message: string } }; // or Negative response
|
|
@@ -800,7 +806,7 @@ type DefaultResponse<OUT> =
|
|
|
800
806
|
|
|
801
807
|
You can create your own result handler by using this example as a template:
|
|
802
808
|
|
|
803
|
-
```
|
|
809
|
+
```ts
|
|
804
810
|
import { z } from "zod";
|
|
805
811
|
import {
|
|
806
812
|
ResultHandler,
|
|
@@ -829,7 +835,7 @@ _See also [Different responses for different status codes](#different-responses-
|
|
|
829
835
|
|
|
830
836
|
After creating your custom `ResultHandler` you can use it as an argument for `EndpointsFactory` instance creation:
|
|
831
837
|
|
|
832
|
-
```
|
|
838
|
+
```ts
|
|
833
839
|
import { EndpointsFactory } from "express-zod-api";
|
|
834
840
|
|
|
835
841
|
const endpointsFactory = new EndpointsFactory(yourResultHandler);
|
|
@@ -840,7 +846,7 @@ const endpointsFactory = new EndpointsFactory(yourResultHandler);
|
|
|
840
846
|
For some REST APIs, empty responses are typical: with status code `204` (No Content) and redirects (302). In order to
|
|
841
847
|
describe it set the `mimeType` to `null` and `schema` to `z.never()`:
|
|
842
848
|
|
|
843
|
-
```
|
|
849
|
+
```ts
|
|
844
850
|
const resultHandler = new ResultHandler({
|
|
845
851
|
positive: { statusCode: 204, mimeType: null, schema: z.never() },
|
|
846
852
|
negative: { statusCode: 404, mimeType: null, schema: z.never() },
|
|
@@ -857,7 +863,7 @@ One of them implements file streaming, in this case the endpoint just has to pro
|
|
|
857
863
|
The response schema can be `z.string()`, `z.base64()` or `ez.buffer()` to reflect the data accordingly in the
|
|
858
864
|
[generated documentation](#creating-a-documentation).
|
|
859
865
|
|
|
860
|
-
```
|
|
866
|
+
```ts
|
|
861
867
|
const fileStreamingEndpointsFactory = new EndpointsFactory(
|
|
862
868
|
new ResultHandler({
|
|
863
869
|
positive: { schema: ez.buffer(), mimeType: "image/*" },
|
|
@@ -948,7 +954,7 @@ available options. The `limitHandler` option is replaced by the `limitError` one
|
|
|
948
954
|
middleware for restricting the ability to upload using the `beforeUpload` option. So the configuration for the limited
|
|
949
955
|
and restricted upload might look this way:
|
|
950
956
|
|
|
951
|
-
```
|
|
957
|
+
```ts
|
|
952
958
|
import createHttpError from "http-errors";
|
|
953
959
|
|
|
954
960
|
const config = createConfig({
|
|
@@ -965,7 +971,7 @@ const config = createConfig({
|
|
|
965
971
|
|
|
966
972
|
Then use `ez.upload()` schema for a corresponding property. The request content type must be `multipart/form-data`:
|
|
967
973
|
|
|
968
|
-
```
|
|
974
|
+
```ts
|
|
969
975
|
import { z } from "zod";
|
|
970
976
|
import { ez, defaultEndpointsFactory } from "express-zod-api";
|
|
971
977
|
|
|
@@ -989,7 +995,7 @@ _You can still send other data and specify additional `input` parameters, includ
|
|
|
989
995
|
If you already have your own configured express application, or you find the framework settings not enough, you can
|
|
990
996
|
connect the endpoints to your app or any express router using the `attachRouting()` method:
|
|
991
997
|
|
|
992
|
-
```
|
|
998
|
+
```ts
|
|
993
999
|
import express from "express";
|
|
994
1000
|
import { createConfig, attachRouting, Routing } from "express-zod-api";
|
|
995
1001
|
|
|
@@ -1019,7 +1025,7 @@ makes mocking easier. Under the hood, request and response object are mocked usi
|
|
|
1019
1025
|
[node-mocks-http](https://www.npmjs.com/package/node-mocks-http) library, therefore you can utilize its API for
|
|
1020
1026
|
settings additional properties and asserting expectation using the provided getters, such as `._getStatusCode()`.
|
|
1021
1027
|
|
|
1022
|
-
```
|
|
1028
|
+
```ts
|
|
1023
1029
|
import { testEndpoint } from "express-zod-api";
|
|
1024
1030
|
|
|
1025
1031
|
test("should respond successfully", async () => {
|
|
@@ -1043,7 +1049,7 @@ Middlewares can also be tested individually using the `testMiddleware()` method.
|
|
|
1043
1049
|
from outputs of previous middlewares, if the one being tested somehow depends on them. Possible errors would be handled
|
|
1044
1050
|
either by `errorHandler` configured within given `configProps` or `defaultResultHandler`.
|
|
1045
1051
|
|
|
1046
|
-
```
|
|
1052
|
+
```ts
|
|
1047
1053
|
import { z } from "zod";
|
|
1048
1054
|
import { Middleware, testMiddleware } from "express-zod-api";
|
|
1049
1055
|
|
|
@@ -1076,7 +1082,7 @@ adding the runtime helpers the framework relies on.
|
|
|
1076
1082
|
You can generate a Typescript file containing the IO types of your API and a client for it.
|
|
1077
1083
|
Consider installing `prettier` and using the async `printFormatted()` method.
|
|
1078
1084
|
|
|
1079
|
-
```
|
|
1085
|
+
```ts
|
|
1080
1086
|
import { Integration } from "express-zod-api";
|
|
1081
1087
|
|
|
1082
1088
|
const client = new Integration({
|
|
@@ -1092,7 +1098,7 @@ The generated client is flexibly configurable on the frontend side for using a c
|
|
|
1092
1098
|
makes requests using the libraries and methods of your choice. The default implementation uses `fetch`. The client
|
|
1093
1099
|
asserts the type of request parameters and response. Consuming the generated client requires Typescript version 4.1+.
|
|
1094
1100
|
|
|
1095
|
-
```
|
|
1101
|
+
```ts
|
|
1096
1102
|
import { Client, Implementation, Subscription } from "./client.ts"; // the generated file
|
|
1097
1103
|
|
|
1098
1104
|
const client = new Client(/* optional custom Implementation */);
|
|
@@ -1105,7 +1111,7 @@ new Subscription("get /v1/events/stream", {}).on("time", (time) => {}); // Serve
|
|
|
1105
1111
|
|
|
1106
1112
|
You can generate the specification of your API and write it to a `.yaml` file, that can be used as the documentation:
|
|
1107
1113
|
|
|
1108
|
-
```
|
|
1114
|
+
```ts
|
|
1109
1115
|
import { Documentation } from "express-zod-api";
|
|
1110
1116
|
|
|
1111
1117
|
const yamlString = new Documentation({
|
|
@@ -1122,7 +1128,7 @@ const yamlString = new Documentation({
|
|
|
1122
1128
|
You can add descriptions and examples to your endpoints, their I/O schemas and their properties. It will be included
|
|
1123
1129
|
into the generated documentation of your API. Consider the following example:
|
|
1124
1130
|
|
|
1125
|
-
```
|
|
1131
|
+
```ts
|
|
1126
1132
|
import { defaultEndpointsFactory } from "express-zod-api";
|
|
1127
1133
|
|
|
1128
1134
|
const exampleEndpoint = defaultEndpointsFactory.build({
|
|
@@ -1148,7 +1154,7 @@ When generating documentation, you may find it necessary to classify endpoints i
|
|
|
1148
1154
|
endpoints is available for that purpose. In order to establish the constraints on tags across all the endpoints, they
|
|
1149
1155
|
should be declared as keys of `TagOverrides` interface. Consider the following example:
|
|
1150
1156
|
|
|
1151
|
-
```
|
|
1157
|
+
```ts
|
|
1152
1158
|
import { defaultEndpointsFactory, Documentation } from "express-zod-api";
|
|
1153
1159
|
|
|
1154
1160
|
// Add similar declaration once, somewhere in your code, preferably near config
|
|
@@ -1249,7 +1255,7 @@ for example if your API strictly follows REST standards. It may also be necessar
|
|
|
1249
1255
|
generated Documentation. For that purpose, the constructor of `ResultHandler` accepts flexible declaration of possible
|
|
1250
1256
|
response schemas and their corresponding status codes.
|
|
1251
1257
|
|
|
1252
|
-
```
|
|
1258
|
+
```ts
|
|
1253
1259
|
import { ResultHandler } from "express-zod-api";
|
|
1254
1260
|
|
|
1255
1261
|
new ResultHandler({
|
|
@@ -1290,7 +1296,7 @@ file as an entire body of request. Use the proprietary `ez.raw()` schema as the
|
|
|
1290
1296
|
The default parser in this case is `express.raw()`. You can customize it by assigning the `rawParser` option in config.
|
|
1291
1297
|
The raw data is placed into `request.body.raw` property, having type `Buffer`.
|
|
1292
1298
|
|
|
1293
|
-
```
|
|
1299
|
+
```ts
|
|
1294
1300
|
import { defaultEndpointsFactory, ez } from "express-zod-api";
|
|
1295
1301
|
|
|
1296
1302
|
const rawAcceptingEndpoint = defaultEndpointsFactory.build({
|
|
@@ -1311,7 +1317,7 @@ For debugging and performance testing purposes the framework offers a simple `.p
|
|
|
1311
1317
|
It starts a timer when you call it and measures the duration in adaptive units (from picoseconds to minutes) until you
|
|
1312
1318
|
invoke the returned callback. The default severity of those measurements is `debug`.
|
|
1313
1319
|
|
|
1314
|
-
```
|
|
1320
|
+
```ts
|
|
1315
1321
|
import { createConfig, BuiltinLogger } from "express-zod-api";
|
|
1316
1322
|
|
|
1317
1323
|
// This enables the .profile() method on built-in logger:
|
|
@@ -1327,7 +1333,7 @@ done(); // debug: expensive operation '555 milliseconds'
|
|
|
1327
1333
|
|
|
1328
1334
|
You can also customize the profiler with your own formatter, chosen severity or even performance assessment function:
|
|
1329
1335
|
|
|
1330
|
-
```
|
|
1336
|
+
```ts
|
|
1331
1337
|
logger.profile({
|
|
1332
1338
|
message: "expensive operation",
|
|
1333
1339
|
severity: (ms) => (ms > 500 ? "error" : "info"), // assess immediately
|
|
@@ -1363,7 +1369,7 @@ Client application can subscribe to the event stream using `EventSource` class i
|
|
|
1363
1369
|
[instance of the generated](#generating-a-frontend-client) `Subscription` class. The following example demonstrates
|
|
1364
1370
|
the implementation emitting the `time` event each second.
|
|
1365
1371
|
|
|
1366
|
-
```
|
|
1372
|
+
```ts
|
|
1367
1373
|
import { z } from "zod";
|
|
1368
1374
|
import { EventStreamFactory } from "express-zod-api";
|
|
1369
1375
|
import { setTimeout } from "node:timers/promises";
|
|
@@ -1389,6 +1395,11 @@ framework, [Zod Sockets](https://github.com/RobinTail/zod-sockets), which has si
|
|
|
1389
1395
|
There are some well-known issues and limitations, or third party bugs that cannot be fixed in the usual way, but you
|
|
1390
1396
|
should be aware of them.
|
|
1391
1397
|
|
|
1398
|
+
## TypeError: example is not a function
|
|
1399
|
+
|
|
1400
|
+
If you face this error then [switch your environment to ESM](#environment-preparation).
|
|
1401
|
+
See [issue 2981](https://github.com/RobinTail/express-zod-api/issues/2981) for details.
|
|
1402
|
+
|
|
1392
1403
|
## Excessive properties in endpoint output
|
|
1393
1404
|
|
|
1394
1405
|
The schema validator removes excessive properties by default. However, Typescript
|
|
@@ -1396,14 +1407,10 @@ The schema validator removes excessive properties by default. However, Typescrip
|
|
|
1396
1407
|
in this case during development. You can achieve this verification by assigning the output schema to a constant and
|
|
1397
1408
|
reusing it in forced type of the output:
|
|
1398
1409
|
|
|
1399
|
-
```
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
const output = z.object({
|
|
1403
|
-
anything: z.number(),
|
|
1404
|
-
});
|
|
1410
|
+
```ts
|
|
1411
|
+
const output = z.object({ anything: z.number() });
|
|
1405
1412
|
|
|
1406
|
-
|
|
1413
|
+
factory.build({
|
|
1407
1414
|
output,
|
|
1408
1415
|
handler: async (): Promise<z.input<typeof output>> => ({
|
|
1409
1416
|
anything: 123,
|
package/dist/index.d.ts
CHANGED
|
@@ -15,8 +15,8 @@ import compression from "compression";
|
|
|
15
15
|
import * as express_fileupload0 from "express-fileupload";
|
|
16
16
|
import fileUpload from "express-fileupload";
|
|
17
17
|
import { ListenOptions } from "node:net";
|
|
18
|
-
import * as
|
|
19
|
-
import * as
|
|
18
|
+
import * as express_serve_static_core2 from "express-serve-static-core";
|
|
19
|
+
import * as qs2 from "qs";
|
|
20
20
|
import * as zod_v4_core0 from "zod/v4/core";
|
|
21
21
|
|
|
22
22
|
//#region src/method.d.ts
|
|
@@ -696,11 +696,11 @@ declare const arrayEndpointsFactory: EndpointsFactory<undefined, Record<string,
|
|
|
696
696
|
//#endregion
|
|
697
697
|
//#region src/server.d.ts
|
|
698
698
|
declare const attachRouting: (config: AppConfig, routing: Routing) => {
|
|
699
|
-
notFoundHandler: express.RequestHandler<
|
|
699
|
+
notFoundHandler: express.RequestHandler<express_serve_static_core2.ParamsDictionary, any, any, qs2.ParsedQs, Record<string, any>>;
|
|
700
700
|
logger: AbstractLogger | BuiltinLogger;
|
|
701
701
|
};
|
|
702
702
|
declare const createServer: (config: ServerConfig, routing: Routing) => Promise<{
|
|
703
|
-
app:
|
|
703
|
+
app: express_serve_static_core2.Express;
|
|
704
704
|
logger: AbstractLogger | BuiltinLogger;
|
|
705
705
|
servers: (http.Server<typeof http.IncomingMessage, typeof http.ServerResponse> | https.Server<typeof http.IncomingMessage, typeof http.ServerResponse>)[];
|
|
706
706
|
}>;
|
|
@@ -865,10 +865,10 @@ declare const testEndpoint: <LOG extends FlatObject, REQ extends RequestOptions>
|
|
|
865
865
|
/** @desc The endpoint to test */
|
|
866
866
|
endpoint: AbstractEndpoint;
|
|
867
867
|
}) => Promise<{
|
|
868
|
-
requestMock: node_mocks_http0.MockRequest<Request<
|
|
868
|
+
requestMock: node_mocks_http0.MockRequest<Request<express_serve_static_core2.ParamsDictionary, any, any, qs2.ParsedQs, Record<string, any>> & REQ>;
|
|
869
869
|
responseMock: node_mocks_http0.MockResponse<Response<any, Record<string, any>>>;
|
|
870
870
|
loggerMock: AbstractLogger & LOG & {
|
|
871
|
-
_getLogs: () => Record<"
|
|
871
|
+
_getLogs: () => Record<"error" | "debug" | "info" | "warn", unknown[]>;
|
|
872
872
|
};
|
|
873
873
|
}>;
|
|
874
874
|
declare const testMiddleware: <LOG extends FlatObject, REQ extends RequestOptions>({
|
|
@@ -881,10 +881,10 @@ declare const testMiddleware: <LOG extends FlatObject, REQ extends RequestOption
|
|
|
881
881
|
/** @desc The aggregated output from previously executed middlewares */
|
|
882
882
|
options?: FlatObject;
|
|
883
883
|
}) => Promise<{
|
|
884
|
-
requestMock: node_mocks_http0.MockRequest<Request<
|
|
884
|
+
requestMock: node_mocks_http0.MockRequest<Request<express_serve_static_core2.ParamsDictionary, any, any, qs2.ParsedQs, Record<string, any>> & REQ>;
|
|
885
885
|
responseMock: node_mocks_http0.MockResponse<Response<any, Record<string, any>>>;
|
|
886
886
|
loggerMock: AbstractLogger & LOG & {
|
|
887
|
-
_getLogs: () => Record<"
|
|
887
|
+
_getLogs: () => Record<"error" | "debug" | "info" | "warn", unknown[]>;
|
|
888
888
|
};
|
|
889
889
|
output: FlatObject;
|
|
890
890
|
}>;
|