express-zod-api 25.5.2 → 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 +91 -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/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## Version 25
|
|
4
4
|
|
|
5
|
+
### v25.5.3
|
|
6
|
+
|
|
7
|
+
- Updated environment requirements in the Readme:
|
|
8
|
+
- Version 25 should be run in an ESM environment because it installs the Zod plugin using the `import` statement;
|
|
9
|
+
- To ensure this, either set `type: module` in `package.json`, use `.mts` extension, or run using `tsx`/`vite-node`;
|
|
10
|
+
- Although all Node.js versions support `require(ESM)`, `zod` remains a dual package with both CJS and ESM copies;
|
|
11
|
+
- If your code uses `require("zod")` (CJS), it is not the same instance that the framework operates;
|
|
12
|
+
- This can lead to `TypeError: example is not a function` and loss of metadata set by the `.meta()` method;
|
|
13
|
+
- This issue was reported by [@squishykid](https://github.com/squishykid).
|
|
14
|
+
|
|
5
15
|
### v25.5.2
|
|
6
16
|
|
|
7
17
|
- Added `z.function()` to the list of JSON-incompatible schemas:
|
|
@@ -1464,7 +1474,7 @@ const config = createConfig({
|
|
|
1464
1474
|
- The ESLint plugin was introduced in v20.0.0 for automated migration from v19 (except assertions in tests);
|
|
1465
1475
|
- For migrating from v19 use the following minimal config and run `eslint --fix`:
|
|
1466
1476
|
|
|
1467
|
-
```
|
|
1477
|
+
```js
|
|
1468
1478
|
// eslint.config.js (or .mjs if you're developing in a CommonJS environment)
|
|
1469
1479
|
import parser from "@typescript-eslint/parser";
|
|
1470
1480
|
import migration from "express-zod-api/migration";
|
|
@@ -1497,7 +1507,7 @@ export default [
|
|
|
1497
1507
|
- it can also be a function returning one of those values depending on duration in milliseconds;
|
|
1498
1508
|
- thus, you can immediately assess the measured performance.
|
|
1499
1509
|
|
|
1500
|
-
```
|
|
1510
|
+
```ts
|
|
1501
1511
|
const done = logger.profile({
|
|
1502
1512
|
message: "expensive operation",
|
|
1503
1513
|
severity: (ms) => (ms > 500 ? "error" : "info"),
|
|
@@ -1515,14 +1525,14 @@ done(); // error: expensive operation '555.55ms'
|
|
|
1515
1525
|
- The output severity is `debug` (will be customizable later), so logger must have the corresponding `level`;
|
|
1516
1526
|
- It prints the duration in log using adaptive units: from picoseconds to minutes.
|
|
1517
1527
|
|
|
1518
|
-
```
|
|
1528
|
+
```ts
|
|
1519
1529
|
// usage assuming that logger is an instance of BuiltinLogger
|
|
1520
1530
|
const done = logger.profile("expensive operation");
|
|
1521
1531
|
doExpensiveOperation();
|
|
1522
1532
|
done(); // debug: expensive operation '555 milliseconds'
|
|
1523
1533
|
```
|
|
1524
1534
|
|
|
1525
|
-
```
|
|
1535
|
+
```ts
|
|
1526
1536
|
// to set up config using the built-in logger do this:
|
|
1527
1537
|
import { createConfig, BuiltinLogger } from "express-zod-api";
|
|
1528
1538
|
|
|
@@ -1547,7 +1557,7 @@ declare module "express-zod-api" {
|
|
|
1547
1557
|
- The method returns: `Promise<{ output, requestMock, responseMock, loggerMock }>`;
|
|
1548
1558
|
- Export fixed in v20.14.3.
|
|
1549
1559
|
|
|
1550
|
-
```
|
|
1560
|
+
```ts
|
|
1551
1561
|
import { z } from "zod";
|
|
1552
1562
|
import { Middleware, testMiddleware } from "express-zod-api";
|
|
1553
1563
|
|
|
@@ -1951,7 +1961,7 @@ const after = ez.raw({
|
|
|
1951
1961
|
- Consider reusing `const` across your files for persistent connections;
|
|
1952
1962
|
- In case of intentional non-persistent connection, consider resources cleanup if necessary:
|
|
1953
1963
|
|
|
1954
|
-
```
|
|
1964
|
+
```ts
|
|
1955
1965
|
import { createResultHandler } from "express-zod-api";
|
|
1956
1966
|
|
|
1957
1967
|
const resultHandlerWithCleanup = createResultHandler({
|
|
@@ -2176,7 +2186,7 @@ withRest: # z.tuple([z.boolean()]).rest(z.string())
|
|
|
2176
2186
|
- Suggested use case: database clients that do not close their connections when their instances are destroyed.
|
|
2177
2187
|
- The `options` coming to Result Handler can be empty or incomplete in case of errors and failures.
|
|
2178
2188
|
|
|
2179
|
-
```
|
|
2189
|
+
```ts
|
|
2180
2190
|
import {
|
|
2181
2191
|
createResultHandler,
|
|
2182
2192
|
EndpointsFactory,
|
|
@@ -2213,7 +2223,7 @@ const dbEquippedFactory = new EndpointsFactory(
|
|
|
2213
2223
|
- Please note: the `.debug()` method of the configured logger is used for upload related logging, therefore the
|
|
2214
2224
|
severity `level` of that logger must be configured accordingly in order to see those messages.
|
|
2215
2225
|
|
|
2216
|
-
```
|
|
2226
|
+
```ts
|
|
2217
2227
|
import { createConfig } from "express-zod-api";
|
|
2218
2228
|
import { Logger } from "winston";
|
|
2219
2229
|
|
|
@@ -2256,7 +2266,7 @@ info: POST: /v1/avatar/upload
|
|
|
2256
2266
|
- It can be used to connect a middleware that restricts the ability to upload;
|
|
2257
2267
|
- It accepts a function similar to `beforeRouting`, having `app` and `logger` in its argument.
|
|
2258
2268
|
|
|
2259
|
-
```
|
|
2269
|
+
```ts
|
|
2260
2270
|
import createHttpError from "http-errors";
|
|
2261
2271
|
import { createConfig } from "express-zod-api";
|
|
2262
2272
|
|
|
@@ -2380,7 +2390,7 @@ after:
|
|
|
2380
2390
|
- The option controls how deeply the objects should be inspected, serialized and printed.
|
|
2381
2391
|
- It can be set to `null` or `Infinity` for unlimited depth.
|
|
2382
2392
|
|
|
2383
|
-
```
|
|
2393
|
+
```ts
|
|
2384
2394
|
// Reproduction example
|
|
2385
2395
|
import { createConfig, createServer } from "express-zod-api";
|
|
2386
2396
|
|
|
@@ -2395,7 +2405,7 @@ subject.prop = subject;
|
|
|
2395
2405
|
logger.error("Circular reference", subject);
|
|
2396
2406
|
```
|
|
2397
2407
|
|
|
2398
|
-
```
|
|
2408
|
+
```ts
|
|
2399
2409
|
// Feature example
|
|
2400
2410
|
import { createConfig } from "express-zod-api";
|
|
2401
2411
|
|
|
@@ -2408,7 +2418,7 @@ createConfig({ logger: { level: "warn", depth: null } });
|
|
|
2408
2418
|
|
|
2409
2419
|
- Fixed logging arrays by the default `winston` logger.
|
|
2410
2420
|
|
|
2411
|
-
```
|
|
2421
|
+
```ts
|
|
2412
2422
|
// before: Items { '0': 123 }
|
|
2413
2423
|
// after: Items [ 123 ]
|
|
2414
2424
|
logger.debug("Items", [123]);
|
|
@@ -2545,7 +2555,7 @@ after:
|
|
|
2545
2555
|
- The provider function receives the initially configured logger and the request, it can also be asynchronous;
|
|
2546
2556
|
- Consider the following example in case of Winston logger:
|
|
2547
2557
|
|
|
2548
|
-
```
|
|
2558
|
+
```ts
|
|
2549
2559
|
import { createConfig } from "express-zod-api";
|
|
2550
2560
|
import { Logger } from "winston"; // or another compatible logger
|
|
2551
2561
|
import { randomUUID } from "node:crypto";
|
|
@@ -2827,7 +2837,7 @@ operationId:
|
|
|
2827
2837
|
- Consider using `logger` property supplied to `createConfig()` instead;
|
|
2828
2838
|
- Otherwise, supply also the `winston` argument to the helper (`import winston from "winston"`).
|
|
2829
2839
|
|
|
2830
|
-
```
|
|
2840
|
+
```ts
|
|
2831
2841
|
import winston from "winston";
|
|
2832
2842
|
import { createConfig, createLogger, createServer } from "express-zod-api";
|
|
2833
2843
|
|
|
@@ -2850,7 +2860,7 @@ declare module "express-zod-api" {
|
|
|
2850
2860
|
const { app, httpServer } = await createServer(config, routing);
|
|
2851
2861
|
```
|
|
2852
2862
|
|
|
2853
|
-
```
|
|
2863
|
+
```ts
|
|
2854
2864
|
// Adjust your tests: set the MockOverrides type once anywhere
|
|
2855
2865
|
declare module "express-zod-api" {
|
|
2856
2866
|
interface MockOverrides extends jest.Mock {} // or Mock from vitest
|
|
@@ -2880,7 +2890,7 @@ declare module "express-zod-api" {
|
|
|
2880
2890
|
|
|
2881
2891
|
- Hotfix for 14.2.4: handling the case of empty object supplied as a second argument to the logger methods.
|
|
2882
2892
|
|
|
2883
|
-
```
|
|
2893
|
+
```ts
|
|
2884
2894
|
logger.info("Payload", {});
|
|
2885
2895
|
```
|
|
2886
2896
|
|
|
@@ -2888,7 +2898,7 @@ logger.info("Payload", {});
|
|
|
2888
2898
|
|
|
2889
2899
|
- Fixed internal logging format when primitive are supplied as a second argument to the logger methods.
|
|
2890
2900
|
|
|
2891
|
-
```
|
|
2901
|
+
```ts
|
|
2892
2902
|
logger.info("Listening", 8090);
|
|
2893
2903
|
```
|
|
2894
2904
|
|
|
@@ -2924,7 +2934,7 @@ logger.info("Listening", 8090);
|
|
|
2924
2934
|
- `ez.raw()` — which is the same as `z.object({ raw: ez.file().buffer() })`.
|
|
2925
2935
|
- Thus, the raw data becomes available to a handler as `input.raw` property.
|
|
2926
2936
|
|
|
2927
|
-
```
|
|
2937
|
+
```ts
|
|
2928
2938
|
import express from "express";
|
|
2929
2939
|
import { createConfig, defaultEndpointsFactory, ez } from "express-zod-api";
|
|
2930
2940
|
|
|
@@ -2955,7 +2965,7 @@ const rawAcceptingEndpoint = defaultEndpointsFactory.build({
|
|
|
2955
2965
|
[in Node.js documentation](https://nodejs.org/dist/latest-v20.x/docs/api/net.html#serverlistenoptions-callback).
|
|
2956
2966
|
- Thanks to [@huyhoang160593](https://github.com/huyhoang160593) for noticing the lack of configurability.
|
|
2957
2967
|
|
|
2958
|
-
```
|
|
2968
|
+
```ts
|
|
2959
2969
|
import { createConfig } from "express-zod-api";
|
|
2960
2970
|
|
|
2961
2971
|
createConfig({
|
|
@@ -3004,7 +3014,7 @@ createConfig({
|
|
|
3004
3014
|
- or `npm install -D @types/express @types/node @types/http-errors`
|
|
3005
3015
|
- The property `DependsOnMethod::methods` is renamed to `endpoints`.
|
|
3006
3016
|
|
|
3007
|
-
```
|
|
3017
|
+
```ts
|
|
3008
3018
|
// before
|
|
3009
3019
|
import { createHttpError } from "express-zod-api";
|
|
3010
3020
|
// after
|
|
@@ -3024,7 +3034,7 @@ import createHttpError from "http-errors";
|
|
|
3024
3034
|
- Featuring an ability to specify multiple server URLs when generating documentation.
|
|
3025
3035
|
- This feature is a shorthand for `new Documentation().addServer()`
|
|
3026
3036
|
|
|
3027
|
-
```
|
|
3037
|
+
```ts
|
|
3028
3038
|
new Documentation({
|
|
3029
3039
|
serverUrl: ["https://example1.com", "https://example2.com"],
|
|
3030
3040
|
// ...
|
|
@@ -3036,7 +3046,7 @@ new Documentation({
|
|
|
3036
3046
|
- Feature: ability to assign a function to the `operationId` property of the `EndpointsFactory::build()` argument.
|
|
3037
3047
|
- This can help to customize the Operation ID for the endpoints serving multiple methods.
|
|
3038
3048
|
|
|
3039
|
-
```
|
|
3049
|
+
```ts
|
|
3040
3050
|
import { defaultEndpointsFactory } from "express-zod-api";
|
|
3041
3051
|
|
|
3042
3052
|
defaultEndpointsFactory.build({
|
|
@@ -3054,7 +3064,7 @@ defaultEndpointsFactory.build({
|
|
|
3054
3064
|
- When using this feature, you must ensure the uniqueness of the IDs you specified across your API endpoints.
|
|
3055
3065
|
- The feature is implemented by [@john-schmitz](https://github.com/john-schmitz).
|
|
3056
3066
|
|
|
3057
|
-
```
|
|
3067
|
+
```ts
|
|
3058
3068
|
import { defaultEndpointsFactory } from "express-zod-api";
|
|
3059
3069
|
|
|
3060
3070
|
defaultEndpointsFactory.build({
|
|
@@ -3071,7 +3081,7 @@ defaultEndpointsFactory.build({
|
|
|
3071
3081
|
- The headers are lowercase when describing their validation schema.
|
|
3072
3082
|
- Parameters in request headers described the following way are supported by the documentation generator.
|
|
3073
3083
|
|
|
3074
|
-
```
|
|
3084
|
+
```ts
|
|
3075
3085
|
import { createConfig, defaultEndpointsFactory } from "express-zod-api";
|
|
3076
3086
|
import { z } from "zod";
|
|
3077
3087
|
|
|
@@ -3598,7 +3608,7 @@ after:
|
|
|
3598
3608
|
implementation.
|
|
3599
3609
|
- Read the [customization instructions](README.md#customizing-input-sources).
|
|
3600
3610
|
|
|
3601
|
-
```
|
|
3611
|
+
```ts
|
|
3602
3612
|
// Your custom ResultHandler
|
|
3603
3613
|
// Before: if you're having an expression like this:
|
|
3604
3614
|
if (error instanceof z.ZodError) {
|
|
@@ -3632,7 +3642,7 @@ inputSources: { delete: ["body", "query", "params"] }
|
|
|
3632
3642
|
- `mimeType` overrides `mimeTypes` when both are specified.
|
|
3633
3643
|
- The `createApiResponse()` method is deprecated and will be removed in next major release.
|
|
3634
3644
|
|
|
3635
|
-
```
|
|
3645
|
+
```ts
|
|
3636
3646
|
// JSON responding ResultHandler Example
|
|
3637
3647
|
// before
|
|
3638
3648
|
createResultHandler({
|
|
@@ -3647,7 +3657,7 @@ createResultHandler({
|
|
|
3647
3657
|
});
|
|
3648
3658
|
```
|
|
3649
3659
|
|
|
3650
|
-
```
|
|
3660
|
+
```ts
|
|
3651
3661
|
// Example on customizing MIME types and status codes
|
|
3652
3662
|
// before
|
|
3653
3663
|
createResultHandler({
|
|
@@ -3730,7 +3740,7 @@ after:
|
|
|
3730
3740
|
- The list of required object properties was depicted incorrectly by the OpenAPI generator in case of using the new
|
|
3731
3741
|
`coerce` feature in the response schema.
|
|
3732
3742
|
|
|
3733
|
-
```
|
|
3743
|
+
```ts
|
|
3734
3744
|
// reproduction example
|
|
3735
3745
|
const endpoint = defaultEndpointsFactory.build({
|
|
3736
3746
|
// ...
|
|
@@ -3766,7 +3776,7 @@ after:
|
|
|
3766
3776
|
- `ZodNativeEnum` (similar to `ZodEnum`), `ZodCatch`, `ZodBranded`, `ZodPipeline`.
|
|
3767
3777
|
- Additionally, the representation of some schemas have been changed slightly:
|
|
3768
3778
|
|
|
3769
|
-
```
|
|
3779
|
+
```ts
|
|
3770
3780
|
interface Changes<T> {
|
|
3771
3781
|
ZodFile: {
|
|
3772
3782
|
before: any;
|
|
@@ -3829,7 +3839,7 @@ output/anything: Number must be greater than 0
|
|
|
3829
3839
|
- The regular expression used for validating `z.dateIn()` made easier
|
|
3830
3840
|
by [@niklashigi](https://github.com/niklashigi).
|
|
3831
3841
|
|
|
3832
|
-
```
|
|
3842
|
+
```ts
|
|
3833
3843
|
const before = /^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d{3})?)?Z?$/;
|
|
3834
3844
|
const after = /^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d+)?)?Z?$/;
|
|
3835
3845
|
```
|
|
@@ -3852,7 +3862,7 @@ const after = /^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d+)?)?Z?$/;
|
|
|
3852
3862
|
- The list of the allowed methods in the response to `OPTIONS` request did only contain the first method declared
|
|
3853
3863
|
within `DependsOnMethod` instance.
|
|
3854
3864
|
|
|
3855
|
-
```
|
|
3865
|
+
```ts
|
|
3856
3866
|
// reproduction minimal setup
|
|
3857
3867
|
const routing: Routing = {
|
|
3858
3868
|
test: new DependsOnMethod({
|
|
@@ -3938,7 +3948,7 @@ after:
|
|
|
3938
3948
|
- The feature suggested by [@johngeorgewright](https://github.com/johngeorgewright)
|
|
3939
3949
|
and [ssteuteville](https://github.com/ssteuteville).
|
|
3940
3950
|
|
|
3941
|
-
```
|
|
3951
|
+
```ts
|
|
3942
3952
|
// example
|
|
3943
3953
|
import { z } from "express-zod-api";
|
|
3944
3954
|
|
|
@@ -3972,7 +3982,7 @@ const endpoint = endpointsFactory.build({
|
|
|
3972
3982
|
generated from the `description` by trimming.
|
|
3973
3983
|
- You can optionally disable this behavior with the new option `hasSummaryFromDescription` of the `OpenAPI` generator.
|
|
3974
3984
|
|
|
3975
|
-
```
|
|
3985
|
+
```ts
|
|
3976
3986
|
const exampleEndpoint = yourEndpointsFactory.build({
|
|
3977
3987
|
// ...
|
|
3978
3988
|
description: "The detailed explanaition on what this endpoint does.",
|
|
@@ -3994,7 +4004,7 @@ const exampleEndpoint = yourEndpointsFactory.build({
|
|
|
3994
4004
|
- The feature suggested by [@TheWisestOne](https://github.com/TheWisestOne).
|
|
3995
4005
|
- The property `scopes` (introduced in v7.9.0) has got its singular variation `scope`.
|
|
3996
4006
|
|
|
3997
|
-
```
|
|
4007
|
+
```ts
|
|
3998
4008
|
import {
|
|
3999
4009
|
createConfig,
|
|
4000
4010
|
EndpointsFactory,
|
|
@@ -4054,7 +4064,7 @@ const exampleEndpoint = taggedEndpointsFactory.build({
|
|
|
4054
4064
|
- The list of the allowed methods in the response to `OPTIONS` request did only contain the first method declared
|
|
4055
4065
|
within `DependsOnMethod` instance.
|
|
4056
4066
|
|
|
4057
|
-
```
|
|
4067
|
+
```ts
|
|
4058
4068
|
// reproduction minimal setup
|
|
4059
4069
|
const routing: Routing = {
|
|
4060
4070
|
test: new DependsOnMethod({
|
|
@@ -4087,7 +4097,7 @@ const routing: Routing = {
|
|
|
4087
4097
|
- In this case that entity will be stringified into a `.message` of `Error`.
|
|
4088
4098
|
- The issue manifested itself as a positive API response without data.
|
|
4089
4099
|
|
|
4090
|
-
```
|
|
4100
|
+
```ts
|
|
4091
4101
|
// reproduction example
|
|
4092
4102
|
const myEndpoint = defaultEndpointsFactory.build({
|
|
4093
4103
|
method: "get",
|
|
@@ -4117,7 +4127,7 @@ const myEndpoint = defaultEndpointsFactory.build({
|
|
|
4117
4127
|
flows including scopes.
|
|
4118
4128
|
- Endpoints utilizing those middlewares can now specify their `scopes`.
|
|
4119
4129
|
|
|
4120
|
-
```
|
|
4130
|
+
```ts
|
|
4121
4131
|
import { createMiddleware, defaultEndpointsFactory, z } from "express-zod-api";
|
|
4122
4132
|
|
|
4123
4133
|
// example middleware
|
|
@@ -4174,7 +4184,7 @@ const myEndpoint = defaultEndpointsFactory.addMiddleware(myMiddleware).build({
|
|
|
4174
4184
|
- Supported security types: `basic`, `bearer`, `input`, `header`, `cookie`, `openid` and `oauth2`.
|
|
4175
4185
|
- OpenID and OAuth2 security types are currently have the limited support: without scopes.
|
|
4176
4186
|
|
|
4177
|
-
```
|
|
4187
|
+
```ts
|
|
4178
4188
|
// example middleware
|
|
4179
4189
|
import { createMiddleware } from "express-zod-api";
|
|
4180
4190
|
|
|
@@ -4244,7 +4254,7 @@ createMiddleware({
|
|
|
4244
4254
|
- **Please note:** If using both `cors` package (express middleware) and `cors` configuration option, the
|
|
4245
4255
|
configuration option sets CORS headers first, so the middleware can override them if needed.
|
|
4246
4256
|
|
|
4247
|
-
```
|
|
4257
|
+
```ts
|
|
4248
4258
|
import { defaultEndpointsFactory } from "express-zod-api";
|
|
4249
4259
|
import cors from "cors";
|
|
4250
4260
|
|
|
@@ -4266,7 +4276,7 @@ const myFactory = defaultEndpointsFactory.addExpressMiddleware(
|
|
|
4266
4276
|
- Setting `cors: true` implies the default headers;
|
|
4267
4277
|
- The feature suggested by [@HardCoreQual](https://github.com/HardCoreQual).
|
|
4268
4278
|
|
|
4269
|
-
```
|
|
4279
|
+
```ts
|
|
4270
4280
|
import { createConfig } from "express-zod-api";
|
|
4271
4281
|
|
|
4272
4282
|
const config = createConfig({
|
|
@@ -4291,7 +4301,7 @@ Access-Control-Max-Age: 5000
|
|
|
4291
4301
|
The output was empty, considering the first argument to be a message.
|
|
4292
4302
|
It's fixed in this version by adding `[No message]` message before printing the object.
|
|
4293
4303
|
|
|
4294
|
-
```
|
|
4304
|
+
```ts
|
|
4295
4305
|
// reproduction example
|
|
4296
4306
|
logger.debug({ something: "test" });
|
|
4297
4307
|
```
|
|
@@ -4369,7 +4379,7 @@ logger.debug({ something: "test" });
|
|
|
4369
4379
|
- `zod-to-ts` version is 1.0.0.
|
|
4370
4380
|
- The type of optional I/O parameters in the generated Client is aligned with `zod` definition.
|
|
4371
4381
|
|
|
4372
|
-
```
|
|
4382
|
+
```ts
|
|
4373
4383
|
interface Before {
|
|
4374
4384
|
foo: number | undefined;
|
|
4375
4385
|
}
|
|
@@ -4395,7 +4405,7 @@ interface After {
|
|
|
4395
4405
|
- Its parameter `path` now contains substituted path params;
|
|
4396
4406
|
- The feature suggested by [@hellovai](https://github.com/hellovai).
|
|
4397
4407
|
|
|
4398
|
-
```
|
|
4408
|
+
```ts
|
|
4399
4409
|
// example client-generator.ts
|
|
4400
4410
|
import fs from "fs";
|
|
4401
4411
|
import { Client } from "express-zod-api";
|
|
@@ -4403,7 +4413,7 @@ import { Client } from "express-zod-api";
|
|
|
4403
4413
|
fs.writeFileSync("./frontend/client.ts", new Client(routing).print(), "utf-8");
|
|
4404
4414
|
```
|
|
4405
4415
|
|
|
4406
|
-
```
|
|
4416
|
+
```ts
|
|
4407
4417
|
// example frontend using the most simple Implementation based on fetch
|
|
4408
4418
|
import { ExpressZodAPIClient } from "./client.ts";
|
|
4409
4419
|
|
|
@@ -4453,7 +4463,7 @@ client.provide("get", "/v1/user/retrieve", { id: "10" });
|
|
|
4453
4463
|
- Instead, it is now documented using `oneOf` OpenAPI notation.
|
|
4454
4464
|
- In addition, you can now also use the new `z.discriminatedUnion()` as the input schema on the top level.
|
|
4455
4465
|
|
|
4456
|
-
```
|
|
4466
|
+
```ts
|
|
4457
4467
|
// how to migrate
|
|
4458
4468
|
export const myMiddleware = createMiddleware({
|
|
4459
4469
|
input: z
|
|
@@ -4466,7 +4476,7 @@ export const myMiddleware = createMiddleware({
|
|
|
4466
4476
|
});
|
|
4467
4477
|
```
|
|
4468
4478
|
|
|
4469
|
-
```
|
|
4479
|
+
```ts
|
|
4470
4480
|
// example
|
|
4471
4481
|
const endpoint = defaultEndpointsFactory.build({
|
|
4472
4482
|
method: "post",
|
|
@@ -4516,7 +4526,7 @@ const endpoint = defaultEndpointsFactory.build({
|
|
|
4516
4526
|
- You can also specify an error transformer so that the `ResultHandler` would send the status you need.
|
|
4517
4527
|
- In case the error is not a `HttpError`, the `ResultHandler` will send the status `500`.
|
|
4518
4528
|
|
|
4519
|
-
```
|
|
4529
|
+
```ts
|
|
4520
4530
|
import { defaultEndpointsFactory, createHttpError } from "express-zod-api";
|
|
4521
4531
|
import cors from "cors";
|
|
4522
4532
|
import { auth } from "express-oauth2-jwt-bearer";
|
|
@@ -4573,7 +4583,7 @@ const advancedUsage = defaultEndpointsFactory.use(auth(), {
|
|
|
4573
4583
|
- `z.dateOut()`, on the contrary, accepts a `Date` and provides `ResultHanlder` with a `string` representation in ISO
|
|
4574
4584
|
format for the response transmission.
|
|
4575
4585
|
|
|
4576
|
-
```
|
|
4586
|
+
```ts
|
|
4577
4587
|
import { z, defaultEndpointsFactory } from "express-zod-api";
|
|
4578
4588
|
|
|
4579
4589
|
const updateUserEndpoint = defaultEndpointsFactory.build({
|
|
@@ -4619,7 +4629,7 @@ const updateUserEndpoint = defaultEndpointsFactory.build({
|
|
|
4619
4629
|
- Only responses with compressible content types are subject to compression.
|
|
4620
4630
|
- There is also a default threshold of 1KB that can be configured.
|
|
4621
4631
|
|
|
4622
|
-
```
|
|
4632
|
+
```ts
|
|
4623
4633
|
import { createConfig } from "express-zod-api";
|
|
4624
4634
|
|
|
4625
4635
|
const config = createConfig({
|
|
@@ -4665,7 +4675,7 @@ const config = createConfig({
|
|
|
4665
4675
|
- You can find the documentation on these arguments here: http://expressjs.com/en/4x/api.html#express.static
|
|
4666
4676
|
- The feature suggested by [@Isaac-Leonard](https://github.com/Isaac-Leonard).
|
|
4667
4677
|
|
|
4668
|
-
```
|
|
4678
|
+
```ts
|
|
4669
4679
|
import { Routing, ServeStatic } from "express-zod-api";
|
|
4670
4680
|
import path from "path";
|
|
4671
4681
|
|
|
@@ -4687,7 +4697,7 @@ const routing: Routing = {
|
|
|
4687
4697
|
- The method executes the endpoint and returns the created mocks.
|
|
4688
4698
|
- After that you only need to assert your expectations in the test.
|
|
4689
4699
|
|
|
4690
|
-
```
|
|
4700
|
+
```ts
|
|
4691
4701
|
import { testEndpoint } from "express-zod-api";
|
|
4692
4702
|
|
|
4693
4703
|
test("should respond successfully", async () => {
|
|
@@ -4715,7 +4725,7 @@ test("should respond successfully", async () => {
|
|
|
4715
4725
|
- This option is only available when using `createServer()` method.
|
|
4716
4726
|
- New configuration option `https`:
|
|
4717
4727
|
|
|
4718
|
-
```
|
|
4728
|
+
```ts
|
|
4719
4729
|
import { createConfig } from "express-zod-api";
|
|
4720
4730
|
|
|
4721
4731
|
const config = createConfig({
|
|
@@ -4750,7 +4760,7 @@ const config = createConfig({
|
|
|
4750
4760
|
- Under the hood the method creates a middleware with an empty input and attaches it to the factory.
|
|
4751
4761
|
- The argument supplied to the method is available within `options` parameter of the Endpoint's `handler`.
|
|
4752
4762
|
|
|
4753
|
-
```
|
|
4763
|
+
```ts
|
|
4754
4764
|
import { defaultEndpointsFactory } from "express-zod-api";
|
|
4755
4765
|
|
|
4756
4766
|
const newFactory = defaultEndpointsFactory.addOptions({
|
|
@@ -4808,7 +4818,7 @@ after: "/v1/user/{id}"
|
|
|
4808
4818
|
- You no longer need a middleware like `paramsProviderMiddleware` to handle path params.
|
|
4809
4819
|
- The route path params are now reflected in the generated documentation.
|
|
4810
4820
|
|
|
4811
|
-
```
|
|
4821
|
+
```ts
|
|
4812
4822
|
const routingExample: Routing = {
|
|
4813
4823
|
v1: {
|
|
4814
4824
|
user: {
|
|
@@ -4836,7 +4846,7 @@ const getUserEndpoint = endpointsFactory.build({
|
|
|
4836
4846
|
|
|
4837
4847
|
- The default configuration of `inputSources` has been changed.
|
|
4838
4848
|
|
|
4839
|
-
```
|
|
4849
|
+
```ts
|
|
4840
4850
|
const newInputSourcesByDefault: InputSources = {
|
|
4841
4851
|
get: ["query", "params"],
|
|
4842
4852
|
post: ["body", "params", "files"],
|
|
@@ -4880,7 +4890,7 @@ const newInputSourcesByDefault: InputSources = {
|
|
|
4880
4890
|
- Notice: `withMeta()` mutates its argument;
|
|
4881
4891
|
- The feature suggested by [@digimuza](https://github.com/digimuza).
|
|
4882
4892
|
|
|
4883
|
-
```
|
|
4893
|
+
```ts
|
|
4884
4894
|
import { defaultEndpointsFactory } from "express-zod-api";
|
|
4885
4895
|
|
|
4886
4896
|
const exampleEndpoint = defaultEndpointsFactory.build({
|
|
@@ -4947,7 +4957,7 @@ example:
|
|
|
4947
4957
|
- New config option `inputSources` allows you to specify the properties of the request, that are combined into an
|
|
4948
4958
|
input that is being validated and available to your endpoints and middlewares.
|
|
4949
4959
|
|
|
4950
|
-
```
|
|
4960
|
+
```ts
|
|
4951
4961
|
import { createConfig } from "express-zod-api";
|
|
4952
4962
|
|
|
4953
4963
|
createConfig({
|
|
@@ -4965,7 +4975,7 @@ createConfig({
|
|
|
4965
4975
|
|
|
4966
4976
|
- For example, in case you need `query` along with `body` available to your endpoints handling POST requests, consider:
|
|
4967
4977
|
|
|
4968
|
-
```
|
|
4978
|
+
```ts
|
|
4969
4979
|
createConfig({
|
|
4970
4980
|
// ...,
|
|
4971
4981
|
inputSources: {
|
|
@@ -4984,7 +4994,7 @@ createConfig({
|
|
|
4984
4994
|
so I add startup logo in this regard.
|
|
4985
4995
|
- However, you can turn it off with a simple setting:
|
|
4986
4996
|
|
|
4987
|
-
```
|
|
4997
|
+
```ts
|
|
4988
4998
|
import {createConfig} from 'express-zod-api';
|
|
4989
4999
|
|
|
4990
5000
|
const config = createConfig({
|
|
@@ -5000,7 +5010,7 @@ const config = createConfig({
|
|
|
5000
5010
|
- In case of using enums and literals in the key schema they will be described as required ones in the generated
|
|
5001
5011
|
OpenAPI / Swagger documentation.
|
|
5002
5012
|
|
|
5003
|
-
```
|
|
5013
|
+
```ts
|
|
5004
5014
|
// example
|
|
5005
5015
|
z.record(
|
|
5006
5016
|
z.enum(["option1", "option2"]), // keys
|
|
@@ -5011,7 +5021,7 @@ z.record(
|
|
|
5011
5021
|
- Feature #145: `attachRouting()` now returns the `logger` instance and `notFoundHandler`. You can use it with your
|
|
5012
5022
|
custom express app for handling `404` (not found) errors:
|
|
5013
5023
|
|
|
5014
|
-
```
|
|
5024
|
+
```ts
|
|
5015
5025
|
const { notFoundHandler } = attachRouting(config, routing);
|
|
5016
5026
|
app.use(notFoundHandler);
|
|
5017
5027
|
app.listen();
|
|
@@ -5019,7 +5029,7 @@ app.listen();
|
|
|
5019
5029
|
|
|
5020
5030
|
- Or you can use the `logger` instance with any `ResultHandler` for the same purpose:
|
|
5021
5031
|
|
|
5022
|
-
```
|
|
5032
|
+
```ts
|
|
5023
5033
|
const { logger } = attachRouting(config, routing);
|
|
5024
5034
|
app.use((request, response) => {
|
|
5025
5035
|
defaultResultHandler.handler({
|
|
@@ -5054,7 +5064,7 @@ app.listen();
|
|
|
5054
5064
|
- Introducing the new schema: `z.upload()`.
|
|
5055
5065
|
- New configuration option:
|
|
5056
5066
|
|
|
5057
|
-
```
|
|
5067
|
+
```ts
|
|
5058
5068
|
const config = createConfig({
|
|
5059
5069
|
server: {
|
|
5060
5070
|
upload: true,
|
|
@@ -5073,7 +5083,7 @@ const config = createConfig({
|
|
|
5073
5083
|
|
|
5074
5084
|
- Creating the `Endpoint`:
|
|
5075
5085
|
|
|
5076
|
-
```
|
|
5086
|
+
```ts
|
|
5077
5087
|
const fileUploadEndpoint = defaultEndpointsFactory.build({
|
|
5078
5088
|
method: "post",
|
|
5079
5089
|
type: "upload", // <- new option, required
|
|
@@ -5112,7 +5122,7 @@ after:
|
|
|
5112
5122
|
Please avoid using it for Endpoint outputs.
|
|
5113
5123
|
- Supporting default values of optional properties in OpenAPI/Swagger documentation.
|
|
5114
5124
|
|
|
5115
|
-
```
|
|
5125
|
+
```ts
|
|
5116
5126
|
// example
|
|
5117
5127
|
z.object({
|
|
5118
5128
|
name: z.string().optional().default("John Wick"),
|
|
@@ -5136,7 +5146,7 @@ z.object({
|
|
|
5136
5146
|
- Please use helper function `createConfig()`.
|
|
5137
5147
|
- This way it assigns the correct type for using configuration with `createServer()` and `attachRouting()`.
|
|
5138
5148
|
|
|
5139
|
-
```
|
|
5149
|
+
```ts
|
|
5140
5150
|
// before
|
|
5141
5151
|
const configBefore: ConfigType = {
|
|
5142
5152
|
server: {
|
|
@@ -5243,7 +5253,7 @@ ZodString: # z.string()
|
|
|
5243
5253
|
`.base64()` which also reflected in the generated Swagger / OpenAPI documentation.
|
|
5244
5254
|
You can use it instead of `z.string()` with `createApiResponse()`:
|
|
5245
5255
|
|
|
5246
|
-
```
|
|
5256
|
+
```ts
|
|
5247
5257
|
// before
|
|
5248
5258
|
const fileStreamingEndpointsFactoryBefore = new EndpointsFactory(
|
|
5249
5259
|
createResultHandler({
|
|
@@ -5300,7 +5310,7 @@ const fileStreamingEndpointsFactoryAfter = new EndpointsFactory(
|
|
|
5300
5310
|
facilitate type inference with essentially double nesting of generic types. Typescript does not yet support such
|
|
5301
5311
|
features as `MyGenericType<A<B>>`.
|
|
5302
5312
|
|
|
5303
|
-
```
|
|
5313
|
+
```ts
|
|
5304
5314
|
// before
|
|
5305
5315
|
export const endpointsFactoryBefore = new EndpointsFactory();
|
|
5306
5316
|
// after
|
|
@@ -5309,14 +5319,14 @@ export const endpointsFactoryAfter = new EndpointsFactory(defaultResultHandler);
|
|
|
5309
5319
|
import { defaultEndpointsFactory } from "express-zod-api";
|
|
5310
5320
|
```
|
|
5311
5321
|
|
|
5312
|
-
```
|
|
5322
|
+
```ts
|
|
5313
5323
|
// before
|
|
5314
5324
|
resultHandler: ResultHandler; // optional
|
|
5315
5325
|
// after
|
|
5316
5326
|
errorHandler: ResultHandlerDefinition<any, any>; // optional, default: defaultResultHandler
|
|
5317
5327
|
```
|
|
5318
5328
|
|
|
5319
|
-
```
|
|
5329
|
+
```ts
|
|
5320
5330
|
// Example. Before (v1):
|
|
5321
5331
|
import { EndpointOutput } from "express-zod-api";
|
|
5322
5332
|
|
|
@@ -5359,7 +5369,7 @@ type MyEndpointResponse = EndpointResponse<typeof myEndpointV2>; // => the follo
|
|
|
5359
5369
|
// }
|
|
5360
5370
|
```
|
|
5361
5371
|
|
|
5362
|
-
```
|
|
5372
|
+
```ts
|
|
5363
5373
|
// before
|
|
5364
5374
|
new OpenAPI({
|
|
5365
5375
|
/* ... */
|
|
@@ -5370,7 +5380,7 @@ new OpenAPI({
|
|
|
5370
5380
|
}).getSpecAsYaml();
|
|
5371
5381
|
```
|
|
5372
5382
|
|
|
5373
|
-
```
|
|
5383
|
+
```ts
|
|
5374
5384
|
// before
|
|
5375
5385
|
const myResultHandlerV1: ResultHandler = ({
|
|
5376
5386
|
error,
|
|
@@ -5429,7 +5439,7 @@ const myResultHandlerV2 = createResultHandler({
|
|
|
5429
5439
|
- Ability to specify the endpoint description and export it to the Swagger / OpenAPI specification:
|
|
5430
5440
|
- The feature suggested by [@glitch452](https://github.com/glitch452).
|
|
5431
5441
|
|
|
5432
|
-
```
|
|
5442
|
+
```ts
|
|
5433
5443
|
// example
|
|
5434
5444
|
const endpoint = endpointsFactory.build({
|
|
5435
5445
|
description: "Here is an example description of the endpoint",
|
|
@@ -5439,7 +5449,7 @@ const endpoint = endpointsFactory.build({
|
|
|
5439
5449
|
|
|
5440
5450
|
- Ability to specify either `methods` or `method` property to `.build()`. This is just a more convenient way for a single method case.
|
|
5441
5451
|
|
|
5442
|
-
```
|
|
5452
|
+
```ts
|
|
5443
5453
|
// example
|
|
5444
5454
|
const endpoint = endpointsFactory.build({
|
|
5445
5455
|
method: "get", // same as methods:['get'] before
|
|
@@ -5451,7 +5461,7 @@ const endpoint = endpointsFactory.build({
|
|
|
5451
5461
|
It can also be the same Endpoint that handle multiple methods as well.
|
|
5452
5462
|
This is a solution for the question raised in issue [#29](https://github.com/RobinTail/express-zod-api/issues/29).
|
|
5453
5463
|
|
|
5454
|
-
```
|
|
5464
|
+
```ts
|
|
5455
5465
|
// example of different I/O schemas for /v1/user
|
|
5456
5466
|
const routing: Routing = {
|
|
5457
5467
|
v1: {
|
|
@@ -5496,7 +5506,7 @@ const routing: Routing = {
|
|
|
5496
5506
|
- Zod version is v3.0.0-beta.1.
|
|
5497
5507
|
- Ability to use z.ZodIntersection and z.ZodUnion as an I/O schema for handlers and middlewares.
|
|
5498
5508
|
|
|
5499
|
-
```
|
|
5509
|
+
```ts
|
|
5500
5510
|
// example
|
|
5501
5511
|
const middleware = createMiddleware({
|
|
5502
5512
|
input: z
|
|
@@ -5516,7 +5526,7 @@ const middleware = createMiddleware({
|
|
|
5516
5526
|
|
|
5517
5527
|
- Ability to use `z.transform()` in handler's output schema.
|
|
5518
5528
|
|
|
5519
|
-
```
|
|
5529
|
+
```ts
|
|
5520
5530
|
// example
|
|
5521
5531
|
const endpoint = factory.build({
|
|
5522
5532
|
methods: ["post"],
|
|
@@ -5544,7 +5554,7 @@ const endpoint = factory.build({
|
|
|
5544
5554
|
|
|
5545
5555
|
- `ConfigType` changes:
|
|
5546
5556
|
|
|
5547
|
-
```
|
|
5557
|
+
```ts
|
|
5548
5558
|
// before
|
|
5549
5559
|
export interface ConfigType {
|
|
5550
5560
|
server: {
|
|
@@ -5578,7 +5588,7 @@ export type ConfigType = (
|
|
|
5578
5588
|
|
|
5579
5589
|
- More convenient way to attach routing to your custom express app:
|
|
5580
5590
|
|
|
5581
|
-
```
|
|
5591
|
+
```ts
|
|
5582
5592
|
// before
|
|
5583
5593
|
initRouting({ app, logger, config, routing });
|
|
5584
5594
|
// after
|
|
@@ -5596,7 +5606,7 @@ attachRouting(config, routing);
|
|
|
5596
5606
|
- Ability to specify your custom Winston logger in config.
|
|
5597
5607
|
- `createLogger()` now accepts `LoggerConfig` as an argument:
|
|
5598
5608
|
|
|
5599
|
-
```
|
|
5609
|
+
```ts
|
|
5600
5610
|
// before
|
|
5601
5611
|
createLogger(config);
|
|
5602
5612
|
// after
|
|
@@ -5612,7 +5622,7 @@ createLogger(config.logger);
|
|
|
5612
5622
|
- Zod version is v3.0.0-alpha33.
|
|
5613
5623
|
- The syntax for generating the Swagger/OpenAPI specification has changed:
|
|
5614
5624
|
|
|
5615
|
-
```
|
|
5625
|
+
```ts
|
|
5616
5626
|
// before
|
|
5617
5627
|
generateOpenApi().getSpecAsYaml();
|
|
5618
5628
|
// after
|