express-zod-api 25.5.2 → 25.6.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 +97 -81
- package/README.md +61 -54
- package/dist/index.d.ts +57 -52
- package/dist/index.js +4 -4
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
## Version 25
|
|
4
4
|
|
|
5
|
+
### v25.6.0
|
|
6
|
+
|
|
7
|
+
- Added `afterRouting` hook to server configuration:
|
|
8
|
+
- Similar to `beforeRouting` one;
|
|
9
|
+
- A code to execute after processing the Routing of your API, but before error handling.
|
|
10
|
+
|
|
11
|
+
### v25.5.3
|
|
12
|
+
|
|
13
|
+
- Updated environment requirements in the Readme:
|
|
14
|
+
- Version 25 should be run in an ESM environment because it installs the Zod plugin using the `import` statement;
|
|
15
|
+
- To ensure this, either set `type: module` in `package.json`, use `.mts` extension, or run using `tsx`/`vite-node`;
|
|
16
|
+
- Although all Node.js versions support `require(ESM)`, `zod` remains a dual package with both CJS and ESM copies;
|
|
17
|
+
- If your code uses `require("zod")` (CJS), it is not the same instance that the framework operates;
|
|
18
|
+
- This can lead to `TypeError: example is not a function` and loss of metadata set by the `.meta()` method;
|
|
19
|
+
- This issue was reported by [@squishykid](https://github.com/squishykid).
|
|
20
|
+
|
|
5
21
|
### v25.5.2
|
|
6
22
|
|
|
7
23
|
- Added `z.function()` to the list of JSON-incompatible schemas:
|
|
@@ -1464,7 +1480,7 @@ const config = createConfig({
|
|
|
1464
1480
|
- The ESLint plugin was introduced in v20.0.0 for automated migration from v19 (except assertions in tests);
|
|
1465
1481
|
- For migrating from v19 use the following minimal config and run `eslint --fix`:
|
|
1466
1482
|
|
|
1467
|
-
```
|
|
1483
|
+
```js
|
|
1468
1484
|
// eslint.config.js (or .mjs if you're developing in a CommonJS environment)
|
|
1469
1485
|
import parser from "@typescript-eslint/parser";
|
|
1470
1486
|
import migration from "express-zod-api/migration";
|
|
@@ -1497,7 +1513,7 @@ export default [
|
|
|
1497
1513
|
- it can also be a function returning one of those values depending on duration in milliseconds;
|
|
1498
1514
|
- thus, you can immediately assess the measured performance.
|
|
1499
1515
|
|
|
1500
|
-
```
|
|
1516
|
+
```ts
|
|
1501
1517
|
const done = logger.profile({
|
|
1502
1518
|
message: "expensive operation",
|
|
1503
1519
|
severity: (ms) => (ms > 500 ? "error" : "info"),
|
|
@@ -1515,14 +1531,14 @@ done(); // error: expensive operation '555.55ms'
|
|
|
1515
1531
|
- The output severity is `debug` (will be customizable later), so logger must have the corresponding `level`;
|
|
1516
1532
|
- It prints the duration in log using adaptive units: from picoseconds to minutes.
|
|
1517
1533
|
|
|
1518
|
-
```
|
|
1534
|
+
```ts
|
|
1519
1535
|
// usage assuming that logger is an instance of BuiltinLogger
|
|
1520
1536
|
const done = logger.profile("expensive operation");
|
|
1521
1537
|
doExpensiveOperation();
|
|
1522
1538
|
done(); // debug: expensive operation '555 milliseconds'
|
|
1523
1539
|
```
|
|
1524
1540
|
|
|
1525
|
-
```
|
|
1541
|
+
```ts
|
|
1526
1542
|
// to set up config using the built-in logger do this:
|
|
1527
1543
|
import { createConfig, BuiltinLogger } from "express-zod-api";
|
|
1528
1544
|
|
|
@@ -1547,7 +1563,7 @@ declare module "express-zod-api" {
|
|
|
1547
1563
|
- The method returns: `Promise<{ output, requestMock, responseMock, loggerMock }>`;
|
|
1548
1564
|
- Export fixed in v20.14.3.
|
|
1549
1565
|
|
|
1550
|
-
```
|
|
1566
|
+
```ts
|
|
1551
1567
|
import { z } from "zod";
|
|
1552
1568
|
import { Middleware, testMiddleware } from "express-zod-api";
|
|
1553
1569
|
|
|
@@ -1951,7 +1967,7 @@ const after = ez.raw({
|
|
|
1951
1967
|
- Consider reusing `const` across your files for persistent connections;
|
|
1952
1968
|
- In case of intentional non-persistent connection, consider resources cleanup if necessary:
|
|
1953
1969
|
|
|
1954
|
-
```
|
|
1970
|
+
```ts
|
|
1955
1971
|
import { createResultHandler } from "express-zod-api";
|
|
1956
1972
|
|
|
1957
1973
|
const resultHandlerWithCleanup = createResultHandler({
|
|
@@ -2176,7 +2192,7 @@ withRest: # z.tuple([z.boolean()]).rest(z.string())
|
|
|
2176
2192
|
- Suggested use case: database clients that do not close their connections when their instances are destroyed.
|
|
2177
2193
|
- The `options` coming to Result Handler can be empty or incomplete in case of errors and failures.
|
|
2178
2194
|
|
|
2179
|
-
```
|
|
2195
|
+
```ts
|
|
2180
2196
|
import {
|
|
2181
2197
|
createResultHandler,
|
|
2182
2198
|
EndpointsFactory,
|
|
@@ -2213,7 +2229,7 @@ const dbEquippedFactory = new EndpointsFactory(
|
|
|
2213
2229
|
- Please note: the `.debug()` method of the configured logger is used for upload related logging, therefore the
|
|
2214
2230
|
severity `level` of that logger must be configured accordingly in order to see those messages.
|
|
2215
2231
|
|
|
2216
|
-
```
|
|
2232
|
+
```ts
|
|
2217
2233
|
import { createConfig } from "express-zod-api";
|
|
2218
2234
|
import { Logger } from "winston";
|
|
2219
2235
|
|
|
@@ -2256,7 +2272,7 @@ info: POST: /v1/avatar/upload
|
|
|
2256
2272
|
- It can be used to connect a middleware that restricts the ability to upload;
|
|
2257
2273
|
- It accepts a function similar to `beforeRouting`, having `app` and `logger` in its argument.
|
|
2258
2274
|
|
|
2259
|
-
```
|
|
2275
|
+
```ts
|
|
2260
2276
|
import createHttpError from "http-errors";
|
|
2261
2277
|
import { createConfig } from "express-zod-api";
|
|
2262
2278
|
|
|
@@ -2380,7 +2396,7 @@ after:
|
|
|
2380
2396
|
- The option controls how deeply the objects should be inspected, serialized and printed.
|
|
2381
2397
|
- It can be set to `null` or `Infinity` for unlimited depth.
|
|
2382
2398
|
|
|
2383
|
-
```
|
|
2399
|
+
```ts
|
|
2384
2400
|
// Reproduction example
|
|
2385
2401
|
import { createConfig, createServer } from "express-zod-api";
|
|
2386
2402
|
|
|
@@ -2395,7 +2411,7 @@ subject.prop = subject;
|
|
|
2395
2411
|
logger.error("Circular reference", subject);
|
|
2396
2412
|
```
|
|
2397
2413
|
|
|
2398
|
-
```
|
|
2414
|
+
```ts
|
|
2399
2415
|
// Feature example
|
|
2400
2416
|
import { createConfig } from "express-zod-api";
|
|
2401
2417
|
|
|
@@ -2408,7 +2424,7 @@ createConfig({ logger: { level: "warn", depth: null } });
|
|
|
2408
2424
|
|
|
2409
2425
|
- Fixed logging arrays by the default `winston` logger.
|
|
2410
2426
|
|
|
2411
|
-
```
|
|
2427
|
+
```ts
|
|
2412
2428
|
// before: Items { '0': 123 }
|
|
2413
2429
|
// after: Items [ 123 ]
|
|
2414
2430
|
logger.debug("Items", [123]);
|
|
@@ -2545,7 +2561,7 @@ after:
|
|
|
2545
2561
|
- The provider function receives the initially configured logger and the request, it can also be asynchronous;
|
|
2546
2562
|
- Consider the following example in case of Winston logger:
|
|
2547
2563
|
|
|
2548
|
-
```
|
|
2564
|
+
```ts
|
|
2549
2565
|
import { createConfig } from "express-zod-api";
|
|
2550
2566
|
import { Logger } from "winston"; // or another compatible logger
|
|
2551
2567
|
import { randomUUID } from "node:crypto";
|
|
@@ -2827,7 +2843,7 @@ operationId:
|
|
|
2827
2843
|
- Consider using `logger` property supplied to `createConfig()` instead;
|
|
2828
2844
|
- Otherwise, supply also the `winston` argument to the helper (`import winston from "winston"`).
|
|
2829
2845
|
|
|
2830
|
-
```
|
|
2846
|
+
```ts
|
|
2831
2847
|
import winston from "winston";
|
|
2832
2848
|
import { createConfig, createLogger, createServer } from "express-zod-api";
|
|
2833
2849
|
|
|
@@ -2850,7 +2866,7 @@ declare module "express-zod-api" {
|
|
|
2850
2866
|
const { app, httpServer } = await createServer(config, routing);
|
|
2851
2867
|
```
|
|
2852
2868
|
|
|
2853
|
-
```
|
|
2869
|
+
```ts
|
|
2854
2870
|
// Adjust your tests: set the MockOverrides type once anywhere
|
|
2855
2871
|
declare module "express-zod-api" {
|
|
2856
2872
|
interface MockOverrides extends jest.Mock {} // or Mock from vitest
|
|
@@ -2880,7 +2896,7 @@ declare module "express-zod-api" {
|
|
|
2880
2896
|
|
|
2881
2897
|
- Hotfix for 14.2.4: handling the case of empty object supplied as a second argument to the logger methods.
|
|
2882
2898
|
|
|
2883
|
-
```
|
|
2899
|
+
```ts
|
|
2884
2900
|
logger.info("Payload", {});
|
|
2885
2901
|
```
|
|
2886
2902
|
|
|
@@ -2888,7 +2904,7 @@ logger.info("Payload", {});
|
|
|
2888
2904
|
|
|
2889
2905
|
- Fixed internal logging format when primitive are supplied as a second argument to the logger methods.
|
|
2890
2906
|
|
|
2891
|
-
```
|
|
2907
|
+
```ts
|
|
2892
2908
|
logger.info("Listening", 8090);
|
|
2893
2909
|
```
|
|
2894
2910
|
|
|
@@ -2924,7 +2940,7 @@ logger.info("Listening", 8090);
|
|
|
2924
2940
|
- `ez.raw()` — which is the same as `z.object({ raw: ez.file().buffer() })`.
|
|
2925
2941
|
- Thus, the raw data becomes available to a handler as `input.raw` property.
|
|
2926
2942
|
|
|
2927
|
-
```
|
|
2943
|
+
```ts
|
|
2928
2944
|
import express from "express";
|
|
2929
2945
|
import { createConfig, defaultEndpointsFactory, ez } from "express-zod-api";
|
|
2930
2946
|
|
|
@@ -2955,7 +2971,7 @@ const rawAcceptingEndpoint = defaultEndpointsFactory.build({
|
|
|
2955
2971
|
[in Node.js documentation](https://nodejs.org/dist/latest-v20.x/docs/api/net.html#serverlistenoptions-callback).
|
|
2956
2972
|
- Thanks to [@huyhoang160593](https://github.com/huyhoang160593) for noticing the lack of configurability.
|
|
2957
2973
|
|
|
2958
|
-
```
|
|
2974
|
+
```ts
|
|
2959
2975
|
import { createConfig } from "express-zod-api";
|
|
2960
2976
|
|
|
2961
2977
|
createConfig({
|
|
@@ -3004,7 +3020,7 @@ createConfig({
|
|
|
3004
3020
|
- or `npm install -D @types/express @types/node @types/http-errors`
|
|
3005
3021
|
- The property `DependsOnMethod::methods` is renamed to `endpoints`.
|
|
3006
3022
|
|
|
3007
|
-
```
|
|
3023
|
+
```ts
|
|
3008
3024
|
// before
|
|
3009
3025
|
import { createHttpError } from "express-zod-api";
|
|
3010
3026
|
// after
|
|
@@ -3024,7 +3040,7 @@ import createHttpError from "http-errors";
|
|
|
3024
3040
|
- Featuring an ability to specify multiple server URLs when generating documentation.
|
|
3025
3041
|
- This feature is a shorthand for `new Documentation().addServer()`
|
|
3026
3042
|
|
|
3027
|
-
```
|
|
3043
|
+
```ts
|
|
3028
3044
|
new Documentation({
|
|
3029
3045
|
serverUrl: ["https://example1.com", "https://example2.com"],
|
|
3030
3046
|
// ...
|
|
@@ -3036,7 +3052,7 @@ new Documentation({
|
|
|
3036
3052
|
- Feature: ability to assign a function to the `operationId` property of the `EndpointsFactory::build()` argument.
|
|
3037
3053
|
- This can help to customize the Operation ID for the endpoints serving multiple methods.
|
|
3038
3054
|
|
|
3039
|
-
```
|
|
3055
|
+
```ts
|
|
3040
3056
|
import { defaultEndpointsFactory } from "express-zod-api";
|
|
3041
3057
|
|
|
3042
3058
|
defaultEndpointsFactory.build({
|
|
@@ -3054,7 +3070,7 @@ defaultEndpointsFactory.build({
|
|
|
3054
3070
|
- When using this feature, you must ensure the uniqueness of the IDs you specified across your API endpoints.
|
|
3055
3071
|
- The feature is implemented by [@john-schmitz](https://github.com/john-schmitz).
|
|
3056
3072
|
|
|
3057
|
-
```
|
|
3073
|
+
```ts
|
|
3058
3074
|
import { defaultEndpointsFactory } from "express-zod-api";
|
|
3059
3075
|
|
|
3060
3076
|
defaultEndpointsFactory.build({
|
|
@@ -3071,7 +3087,7 @@ defaultEndpointsFactory.build({
|
|
|
3071
3087
|
- The headers are lowercase when describing their validation schema.
|
|
3072
3088
|
- Parameters in request headers described the following way are supported by the documentation generator.
|
|
3073
3089
|
|
|
3074
|
-
```
|
|
3090
|
+
```ts
|
|
3075
3091
|
import { createConfig, defaultEndpointsFactory } from "express-zod-api";
|
|
3076
3092
|
import { z } from "zod";
|
|
3077
3093
|
|
|
@@ -3598,7 +3614,7 @@ after:
|
|
|
3598
3614
|
implementation.
|
|
3599
3615
|
- Read the [customization instructions](README.md#customizing-input-sources).
|
|
3600
3616
|
|
|
3601
|
-
```
|
|
3617
|
+
```ts
|
|
3602
3618
|
// Your custom ResultHandler
|
|
3603
3619
|
// Before: if you're having an expression like this:
|
|
3604
3620
|
if (error instanceof z.ZodError) {
|
|
@@ -3632,7 +3648,7 @@ inputSources: { delete: ["body", "query", "params"] }
|
|
|
3632
3648
|
- `mimeType` overrides `mimeTypes` when both are specified.
|
|
3633
3649
|
- The `createApiResponse()` method is deprecated and will be removed in next major release.
|
|
3634
3650
|
|
|
3635
|
-
```
|
|
3651
|
+
```ts
|
|
3636
3652
|
// JSON responding ResultHandler Example
|
|
3637
3653
|
// before
|
|
3638
3654
|
createResultHandler({
|
|
@@ -3647,7 +3663,7 @@ createResultHandler({
|
|
|
3647
3663
|
});
|
|
3648
3664
|
```
|
|
3649
3665
|
|
|
3650
|
-
```
|
|
3666
|
+
```ts
|
|
3651
3667
|
// Example on customizing MIME types and status codes
|
|
3652
3668
|
// before
|
|
3653
3669
|
createResultHandler({
|
|
@@ -3730,7 +3746,7 @@ after:
|
|
|
3730
3746
|
- The list of required object properties was depicted incorrectly by the OpenAPI generator in case of using the new
|
|
3731
3747
|
`coerce` feature in the response schema.
|
|
3732
3748
|
|
|
3733
|
-
```
|
|
3749
|
+
```ts
|
|
3734
3750
|
// reproduction example
|
|
3735
3751
|
const endpoint = defaultEndpointsFactory.build({
|
|
3736
3752
|
// ...
|
|
@@ -3766,7 +3782,7 @@ after:
|
|
|
3766
3782
|
- `ZodNativeEnum` (similar to `ZodEnum`), `ZodCatch`, `ZodBranded`, `ZodPipeline`.
|
|
3767
3783
|
- Additionally, the representation of some schemas have been changed slightly:
|
|
3768
3784
|
|
|
3769
|
-
```
|
|
3785
|
+
```ts
|
|
3770
3786
|
interface Changes<T> {
|
|
3771
3787
|
ZodFile: {
|
|
3772
3788
|
before: any;
|
|
@@ -3829,7 +3845,7 @@ output/anything: Number must be greater than 0
|
|
|
3829
3845
|
- The regular expression used for validating `z.dateIn()` made easier
|
|
3830
3846
|
by [@niklashigi](https://github.com/niklashigi).
|
|
3831
3847
|
|
|
3832
|
-
```
|
|
3848
|
+
```ts
|
|
3833
3849
|
const before = /^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d{3})?)?Z?$/;
|
|
3834
3850
|
const after = /^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d+)?)?Z?$/;
|
|
3835
3851
|
```
|
|
@@ -3852,7 +3868,7 @@ const after = /^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d+)?)?Z?$/;
|
|
|
3852
3868
|
- The list of the allowed methods in the response to `OPTIONS` request did only contain the first method declared
|
|
3853
3869
|
within `DependsOnMethod` instance.
|
|
3854
3870
|
|
|
3855
|
-
```
|
|
3871
|
+
```ts
|
|
3856
3872
|
// reproduction minimal setup
|
|
3857
3873
|
const routing: Routing = {
|
|
3858
3874
|
test: new DependsOnMethod({
|
|
@@ -3938,7 +3954,7 @@ after:
|
|
|
3938
3954
|
- The feature suggested by [@johngeorgewright](https://github.com/johngeorgewright)
|
|
3939
3955
|
and [ssteuteville](https://github.com/ssteuteville).
|
|
3940
3956
|
|
|
3941
|
-
```
|
|
3957
|
+
```ts
|
|
3942
3958
|
// example
|
|
3943
3959
|
import { z } from "express-zod-api";
|
|
3944
3960
|
|
|
@@ -3972,7 +3988,7 @@ const endpoint = endpointsFactory.build({
|
|
|
3972
3988
|
generated from the `description` by trimming.
|
|
3973
3989
|
- You can optionally disable this behavior with the new option `hasSummaryFromDescription` of the `OpenAPI` generator.
|
|
3974
3990
|
|
|
3975
|
-
```
|
|
3991
|
+
```ts
|
|
3976
3992
|
const exampleEndpoint = yourEndpointsFactory.build({
|
|
3977
3993
|
// ...
|
|
3978
3994
|
description: "The detailed explanaition on what this endpoint does.",
|
|
@@ -3994,7 +4010,7 @@ const exampleEndpoint = yourEndpointsFactory.build({
|
|
|
3994
4010
|
- The feature suggested by [@TheWisestOne](https://github.com/TheWisestOne).
|
|
3995
4011
|
- The property `scopes` (introduced in v7.9.0) has got its singular variation `scope`.
|
|
3996
4012
|
|
|
3997
|
-
```
|
|
4013
|
+
```ts
|
|
3998
4014
|
import {
|
|
3999
4015
|
createConfig,
|
|
4000
4016
|
EndpointsFactory,
|
|
@@ -4054,7 +4070,7 @@ const exampleEndpoint = taggedEndpointsFactory.build({
|
|
|
4054
4070
|
- The list of the allowed methods in the response to `OPTIONS` request did only contain the first method declared
|
|
4055
4071
|
within `DependsOnMethod` instance.
|
|
4056
4072
|
|
|
4057
|
-
```
|
|
4073
|
+
```ts
|
|
4058
4074
|
// reproduction minimal setup
|
|
4059
4075
|
const routing: Routing = {
|
|
4060
4076
|
test: new DependsOnMethod({
|
|
@@ -4087,7 +4103,7 @@ const routing: Routing = {
|
|
|
4087
4103
|
- In this case that entity will be stringified into a `.message` of `Error`.
|
|
4088
4104
|
- The issue manifested itself as a positive API response without data.
|
|
4089
4105
|
|
|
4090
|
-
```
|
|
4106
|
+
```ts
|
|
4091
4107
|
// reproduction example
|
|
4092
4108
|
const myEndpoint = defaultEndpointsFactory.build({
|
|
4093
4109
|
method: "get",
|
|
@@ -4117,7 +4133,7 @@ const myEndpoint = defaultEndpointsFactory.build({
|
|
|
4117
4133
|
flows including scopes.
|
|
4118
4134
|
- Endpoints utilizing those middlewares can now specify their `scopes`.
|
|
4119
4135
|
|
|
4120
|
-
```
|
|
4136
|
+
```ts
|
|
4121
4137
|
import { createMiddleware, defaultEndpointsFactory, z } from "express-zod-api";
|
|
4122
4138
|
|
|
4123
4139
|
// example middleware
|
|
@@ -4174,7 +4190,7 @@ const myEndpoint = defaultEndpointsFactory.addMiddleware(myMiddleware).build({
|
|
|
4174
4190
|
- Supported security types: `basic`, `bearer`, `input`, `header`, `cookie`, `openid` and `oauth2`.
|
|
4175
4191
|
- OpenID and OAuth2 security types are currently have the limited support: without scopes.
|
|
4176
4192
|
|
|
4177
|
-
```
|
|
4193
|
+
```ts
|
|
4178
4194
|
// example middleware
|
|
4179
4195
|
import { createMiddleware } from "express-zod-api";
|
|
4180
4196
|
|
|
@@ -4244,7 +4260,7 @@ createMiddleware({
|
|
|
4244
4260
|
- **Please note:** If using both `cors` package (express middleware) and `cors` configuration option, the
|
|
4245
4261
|
configuration option sets CORS headers first, so the middleware can override them if needed.
|
|
4246
4262
|
|
|
4247
|
-
```
|
|
4263
|
+
```ts
|
|
4248
4264
|
import { defaultEndpointsFactory } from "express-zod-api";
|
|
4249
4265
|
import cors from "cors";
|
|
4250
4266
|
|
|
@@ -4266,7 +4282,7 @@ const myFactory = defaultEndpointsFactory.addExpressMiddleware(
|
|
|
4266
4282
|
- Setting `cors: true` implies the default headers;
|
|
4267
4283
|
- The feature suggested by [@HardCoreQual](https://github.com/HardCoreQual).
|
|
4268
4284
|
|
|
4269
|
-
```
|
|
4285
|
+
```ts
|
|
4270
4286
|
import { createConfig } from "express-zod-api";
|
|
4271
4287
|
|
|
4272
4288
|
const config = createConfig({
|
|
@@ -4291,7 +4307,7 @@ Access-Control-Max-Age: 5000
|
|
|
4291
4307
|
The output was empty, considering the first argument to be a message.
|
|
4292
4308
|
It's fixed in this version by adding `[No message]` message before printing the object.
|
|
4293
4309
|
|
|
4294
|
-
```
|
|
4310
|
+
```ts
|
|
4295
4311
|
// reproduction example
|
|
4296
4312
|
logger.debug({ something: "test" });
|
|
4297
4313
|
```
|
|
@@ -4369,7 +4385,7 @@ logger.debug({ something: "test" });
|
|
|
4369
4385
|
- `zod-to-ts` version is 1.0.0.
|
|
4370
4386
|
- The type of optional I/O parameters in the generated Client is aligned with `zod` definition.
|
|
4371
4387
|
|
|
4372
|
-
```
|
|
4388
|
+
```ts
|
|
4373
4389
|
interface Before {
|
|
4374
4390
|
foo: number | undefined;
|
|
4375
4391
|
}
|
|
@@ -4395,7 +4411,7 @@ interface After {
|
|
|
4395
4411
|
- Its parameter `path` now contains substituted path params;
|
|
4396
4412
|
- The feature suggested by [@hellovai](https://github.com/hellovai).
|
|
4397
4413
|
|
|
4398
|
-
```
|
|
4414
|
+
```ts
|
|
4399
4415
|
// example client-generator.ts
|
|
4400
4416
|
import fs from "fs";
|
|
4401
4417
|
import { Client } from "express-zod-api";
|
|
@@ -4403,7 +4419,7 @@ import { Client } from "express-zod-api";
|
|
|
4403
4419
|
fs.writeFileSync("./frontend/client.ts", new Client(routing).print(), "utf-8");
|
|
4404
4420
|
```
|
|
4405
4421
|
|
|
4406
|
-
```
|
|
4422
|
+
```ts
|
|
4407
4423
|
// example frontend using the most simple Implementation based on fetch
|
|
4408
4424
|
import { ExpressZodAPIClient } from "./client.ts";
|
|
4409
4425
|
|
|
@@ -4453,7 +4469,7 @@ client.provide("get", "/v1/user/retrieve", { id: "10" });
|
|
|
4453
4469
|
- Instead, it is now documented using `oneOf` OpenAPI notation.
|
|
4454
4470
|
- In addition, you can now also use the new `z.discriminatedUnion()` as the input schema on the top level.
|
|
4455
4471
|
|
|
4456
|
-
```
|
|
4472
|
+
```ts
|
|
4457
4473
|
// how to migrate
|
|
4458
4474
|
export const myMiddleware = createMiddleware({
|
|
4459
4475
|
input: z
|
|
@@ -4466,7 +4482,7 @@ export const myMiddleware = createMiddleware({
|
|
|
4466
4482
|
});
|
|
4467
4483
|
```
|
|
4468
4484
|
|
|
4469
|
-
```
|
|
4485
|
+
```ts
|
|
4470
4486
|
// example
|
|
4471
4487
|
const endpoint = defaultEndpointsFactory.build({
|
|
4472
4488
|
method: "post",
|
|
@@ -4516,7 +4532,7 @@ const endpoint = defaultEndpointsFactory.build({
|
|
|
4516
4532
|
- You can also specify an error transformer so that the `ResultHandler` would send the status you need.
|
|
4517
4533
|
- In case the error is not a `HttpError`, the `ResultHandler` will send the status `500`.
|
|
4518
4534
|
|
|
4519
|
-
```
|
|
4535
|
+
```ts
|
|
4520
4536
|
import { defaultEndpointsFactory, createHttpError } from "express-zod-api";
|
|
4521
4537
|
import cors from "cors";
|
|
4522
4538
|
import { auth } from "express-oauth2-jwt-bearer";
|
|
@@ -4573,7 +4589,7 @@ const advancedUsage = defaultEndpointsFactory.use(auth(), {
|
|
|
4573
4589
|
- `z.dateOut()`, on the contrary, accepts a `Date` and provides `ResultHanlder` with a `string` representation in ISO
|
|
4574
4590
|
format for the response transmission.
|
|
4575
4591
|
|
|
4576
|
-
```
|
|
4592
|
+
```ts
|
|
4577
4593
|
import { z, defaultEndpointsFactory } from "express-zod-api";
|
|
4578
4594
|
|
|
4579
4595
|
const updateUserEndpoint = defaultEndpointsFactory.build({
|
|
@@ -4619,7 +4635,7 @@ const updateUserEndpoint = defaultEndpointsFactory.build({
|
|
|
4619
4635
|
- Only responses with compressible content types are subject to compression.
|
|
4620
4636
|
- There is also a default threshold of 1KB that can be configured.
|
|
4621
4637
|
|
|
4622
|
-
```
|
|
4638
|
+
```ts
|
|
4623
4639
|
import { createConfig } from "express-zod-api";
|
|
4624
4640
|
|
|
4625
4641
|
const config = createConfig({
|
|
@@ -4665,7 +4681,7 @@ const config = createConfig({
|
|
|
4665
4681
|
- You can find the documentation on these arguments here: http://expressjs.com/en/4x/api.html#express.static
|
|
4666
4682
|
- The feature suggested by [@Isaac-Leonard](https://github.com/Isaac-Leonard).
|
|
4667
4683
|
|
|
4668
|
-
```
|
|
4684
|
+
```ts
|
|
4669
4685
|
import { Routing, ServeStatic } from "express-zod-api";
|
|
4670
4686
|
import path from "path";
|
|
4671
4687
|
|
|
@@ -4687,7 +4703,7 @@ const routing: Routing = {
|
|
|
4687
4703
|
- The method executes the endpoint and returns the created mocks.
|
|
4688
4704
|
- After that you only need to assert your expectations in the test.
|
|
4689
4705
|
|
|
4690
|
-
```
|
|
4706
|
+
```ts
|
|
4691
4707
|
import { testEndpoint } from "express-zod-api";
|
|
4692
4708
|
|
|
4693
4709
|
test("should respond successfully", async () => {
|
|
@@ -4715,7 +4731,7 @@ test("should respond successfully", async () => {
|
|
|
4715
4731
|
- This option is only available when using `createServer()` method.
|
|
4716
4732
|
- New configuration option `https`:
|
|
4717
4733
|
|
|
4718
|
-
```
|
|
4734
|
+
```ts
|
|
4719
4735
|
import { createConfig } from "express-zod-api";
|
|
4720
4736
|
|
|
4721
4737
|
const config = createConfig({
|
|
@@ -4750,7 +4766,7 @@ const config = createConfig({
|
|
|
4750
4766
|
- Under the hood the method creates a middleware with an empty input and attaches it to the factory.
|
|
4751
4767
|
- The argument supplied to the method is available within `options` parameter of the Endpoint's `handler`.
|
|
4752
4768
|
|
|
4753
|
-
```
|
|
4769
|
+
```ts
|
|
4754
4770
|
import { defaultEndpointsFactory } from "express-zod-api";
|
|
4755
4771
|
|
|
4756
4772
|
const newFactory = defaultEndpointsFactory.addOptions({
|
|
@@ -4808,7 +4824,7 @@ after: "/v1/user/{id}"
|
|
|
4808
4824
|
- You no longer need a middleware like `paramsProviderMiddleware` to handle path params.
|
|
4809
4825
|
- The route path params are now reflected in the generated documentation.
|
|
4810
4826
|
|
|
4811
|
-
```
|
|
4827
|
+
```ts
|
|
4812
4828
|
const routingExample: Routing = {
|
|
4813
4829
|
v1: {
|
|
4814
4830
|
user: {
|
|
@@ -4836,7 +4852,7 @@ const getUserEndpoint = endpointsFactory.build({
|
|
|
4836
4852
|
|
|
4837
4853
|
- The default configuration of `inputSources` has been changed.
|
|
4838
4854
|
|
|
4839
|
-
```
|
|
4855
|
+
```ts
|
|
4840
4856
|
const newInputSourcesByDefault: InputSources = {
|
|
4841
4857
|
get: ["query", "params"],
|
|
4842
4858
|
post: ["body", "params", "files"],
|
|
@@ -4880,7 +4896,7 @@ const newInputSourcesByDefault: InputSources = {
|
|
|
4880
4896
|
- Notice: `withMeta()` mutates its argument;
|
|
4881
4897
|
- The feature suggested by [@digimuza](https://github.com/digimuza).
|
|
4882
4898
|
|
|
4883
|
-
```
|
|
4899
|
+
```ts
|
|
4884
4900
|
import { defaultEndpointsFactory } from "express-zod-api";
|
|
4885
4901
|
|
|
4886
4902
|
const exampleEndpoint = defaultEndpointsFactory.build({
|
|
@@ -4947,7 +4963,7 @@ example:
|
|
|
4947
4963
|
- New config option `inputSources` allows you to specify the properties of the request, that are combined into an
|
|
4948
4964
|
input that is being validated and available to your endpoints and middlewares.
|
|
4949
4965
|
|
|
4950
|
-
```
|
|
4966
|
+
```ts
|
|
4951
4967
|
import { createConfig } from "express-zod-api";
|
|
4952
4968
|
|
|
4953
4969
|
createConfig({
|
|
@@ -4965,7 +4981,7 @@ createConfig({
|
|
|
4965
4981
|
|
|
4966
4982
|
- For example, in case you need `query` along with `body` available to your endpoints handling POST requests, consider:
|
|
4967
4983
|
|
|
4968
|
-
```
|
|
4984
|
+
```ts
|
|
4969
4985
|
createConfig({
|
|
4970
4986
|
// ...,
|
|
4971
4987
|
inputSources: {
|
|
@@ -4984,7 +5000,7 @@ createConfig({
|
|
|
4984
5000
|
so I add startup logo in this regard.
|
|
4985
5001
|
- However, you can turn it off with a simple setting:
|
|
4986
5002
|
|
|
4987
|
-
```
|
|
5003
|
+
```ts
|
|
4988
5004
|
import {createConfig} from 'express-zod-api';
|
|
4989
5005
|
|
|
4990
5006
|
const config = createConfig({
|
|
@@ -5000,7 +5016,7 @@ const config = createConfig({
|
|
|
5000
5016
|
- In case of using enums and literals in the key schema they will be described as required ones in the generated
|
|
5001
5017
|
OpenAPI / Swagger documentation.
|
|
5002
5018
|
|
|
5003
|
-
```
|
|
5019
|
+
```ts
|
|
5004
5020
|
// example
|
|
5005
5021
|
z.record(
|
|
5006
5022
|
z.enum(["option1", "option2"]), // keys
|
|
@@ -5011,7 +5027,7 @@ z.record(
|
|
|
5011
5027
|
- Feature #145: `attachRouting()` now returns the `logger` instance and `notFoundHandler`. You can use it with your
|
|
5012
5028
|
custom express app for handling `404` (not found) errors:
|
|
5013
5029
|
|
|
5014
|
-
```
|
|
5030
|
+
```ts
|
|
5015
5031
|
const { notFoundHandler } = attachRouting(config, routing);
|
|
5016
5032
|
app.use(notFoundHandler);
|
|
5017
5033
|
app.listen();
|
|
@@ -5019,7 +5035,7 @@ app.listen();
|
|
|
5019
5035
|
|
|
5020
5036
|
- Or you can use the `logger` instance with any `ResultHandler` for the same purpose:
|
|
5021
5037
|
|
|
5022
|
-
```
|
|
5038
|
+
```ts
|
|
5023
5039
|
const { logger } = attachRouting(config, routing);
|
|
5024
5040
|
app.use((request, response) => {
|
|
5025
5041
|
defaultResultHandler.handler({
|
|
@@ -5054,7 +5070,7 @@ app.listen();
|
|
|
5054
5070
|
- Introducing the new schema: `z.upload()`.
|
|
5055
5071
|
- New configuration option:
|
|
5056
5072
|
|
|
5057
|
-
```
|
|
5073
|
+
```ts
|
|
5058
5074
|
const config = createConfig({
|
|
5059
5075
|
server: {
|
|
5060
5076
|
upload: true,
|
|
@@ -5073,7 +5089,7 @@ const config = createConfig({
|
|
|
5073
5089
|
|
|
5074
5090
|
- Creating the `Endpoint`:
|
|
5075
5091
|
|
|
5076
|
-
```
|
|
5092
|
+
```ts
|
|
5077
5093
|
const fileUploadEndpoint = defaultEndpointsFactory.build({
|
|
5078
5094
|
method: "post",
|
|
5079
5095
|
type: "upload", // <- new option, required
|
|
@@ -5112,7 +5128,7 @@ after:
|
|
|
5112
5128
|
Please avoid using it for Endpoint outputs.
|
|
5113
5129
|
- Supporting default values of optional properties in OpenAPI/Swagger documentation.
|
|
5114
5130
|
|
|
5115
|
-
```
|
|
5131
|
+
```ts
|
|
5116
5132
|
// example
|
|
5117
5133
|
z.object({
|
|
5118
5134
|
name: z.string().optional().default("John Wick"),
|
|
@@ -5136,7 +5152,7 @@ z.object({
|
|
|
5136
5152
|
- Please use helper function `createConfig()`.
|
|
5137
5153
|
- This way it assigns the correct type for using configuration with `createServer()` and `attachRouting()`.
|
|
5138
5154
|
|
|
5139
|
-
```
|
|
5155
|
+
```ts
|
|
5140
5156
|
// before
|
|
5141
5157
|
const configBefore: ConfigType = {
|
|
5142
5158
|
server: {
|
|
@@ -5243,7 +5259,7 @@ ZodString: # z.string()
|
|
|
5243
5259
|
`.base64()` which also reflected in the generated Swagger / OpenAPI documentation.
|
|
5244
5260
|
You can use it instead of `z.string()` with `createApiResponse()`:
|
|
5245
5261
|
|
|
5246
|
-
```
|
|
5262
|
+
```ts
|
|
5247
5263
|
// before
|
|
5248
5264
|
const fileStreamingEndpointsFactoryBefore = new EndpointsFactory(
|
|
5249
5265
|
createResultHandler({
|
|
@@ -5300,7 +5316,7 @@ const fileStreamingEndpointsFactoryAfter = new EndpointsFactory(
|
|
|
5300
5316
|
facilitate type inference with essentially double nesting of generic types. Typescript does not yet support such
|
|
5301
5317
|
features as `MyGenericType<A<B>>`.
|
|
5302
5318
|
|
|
5303
|
-
```
|
|
5319
|
+
```ts
|
|
5304
5320
|
// before
|
|
5305
5321
|
export const endpointsFactoryBefore = new EndpointsFactory();
|
|
5306
5322
|
// after
|
|
@@ -5309,14 +5325,14 @@ export const endpointsFactoryAfter = new EndpointsFactory(defaultResultHandler);
|
|
|
5309
5325
|
import { defaultEndpointsFactory } from "express-zod-api";
|
|
5310
5326
|
```
|
|
5311
5327
|
|
|
5312
|
-
```
|
|
5328
|
+
```ts
|
|
5313
5329
|
// before
|
|
5314
5330
|
resultHandler: ResultHandler; // optional
|
|
5315
5331
|
// after
|
|
5316
5332
|
errorHandler: ResultHandlerDefinition<any, any>; // optional, default: defaultResultHandler
|
|
5317
5333
|
```
|
|
5318
5334
|
|
|
5319
|
-
```
|
|
5335
|
+
```ts
|
|
5320
5336
|
// Example. Before (v1):
|
|
5321
5337
|
import { EndpointOutput } from "express-zod-api";
|
|
5322
5338
|
|
|
@@ -5359,7 +5375,7 @@ type MyEndpointResponse = EndpointResponse<typeof myEndpointV2>; // => the follo
|
|
|
5359
5375
|
// }
|
|
5360
5376
|
```
|
|
5361
5377
|
|
|
5362
|
-
```
|
|
5378
|
+
```ts
|
|
5363
5379
|
// before
|
|
5364
5380
|
new OpenAPI({
|
|
5365
5381
|
/* ... */
|
|
@@ -5370,7 +5386,7 @@ new OpenAPI({
|
|
|
5370
5386
|
}).getSpecAsYaml();
|
|
5371
5387
|
```
|
|
5372
5388
|
|
|
5373
|
-
```
|
|
5389
|
+
```ts
|
|
5374
5390
|
// before
|
|
5375
5391
|
const myResultHandlerV1: ResultHandler = ({
|
|
5376
5392
|
error,
|
|
@@ -5429,7 +5445,7 @@ const myResultHandlerV2 = createResultHandler({
|
|
|
5429
5445
|
- Ability to specify the endpoint description and export it to the Swagger / OpenAPI specification:
|
|
5430
5446
|
- The feature suggested by [@glitch452](https://github.com/glitch452).
|
|
5431
5447
|
|
|
5432
|
-
```
|
|
5448
|
+
```ts
|
|
5433
5449
|
// example
|
|
5434
5450
|
const endpoint = endpointsFactory.build({
|
|
5435
5451
|
description: "Here is an example description of the endpoint",
|
|
@@ -5439,7 +5455,7 @@ const endpoint = endpointsFactory.build({
|
|
|
5439
5455
|
|
|
5440
5456
|
- Ability to specify either `methods` or `method` property to `.build()`. This is just a more convenient way for a single method case.
|
|
5441
5457
|
|
|
5442
|
-
```
|
|
5458
|
+
```ts
|
|
5443
5459
|
// example
|
|
5444
5460
|
const endpoint = endpointsFactory.build({
|
|
5445
5461
|
method: "get", // same as methods:['get'] before
|
|
@@ -5451,7 +5467,7 @@ const endpoint = endpointsFactory.build({
|
|
|
5451
5467
|
It can also be the same Endpoint that handle multiple methods as well.
|
|
5452
5468
|
This is a solution for the question raised in issue [#29](https://github.com/RobinTail/express-zod-api/issues/29).
|
|
5453
5469
|
|
|
5454
|
-
```
|
|
5470
|
+
```ts
|
|
5455
5471
|
// example of different I/O schemas for /v1/user
|
|
5456
5472
|
const routing: Routing = {
|
|
5457
5473
|
v1: {
|
|
@@ -5496,7 +5512,7 @@ const routing: Routing = {
|
|
|
5496
5512
|
- Zod version is v3.0.0-beta.1.
|
|
5497
5513
|
- Ability to use z.ZodIntersection and z.ZodUnion as an I/O schema for handlers and middlewares.
|
|
5498
5514
|
|
|
5499
|
-
```
|
|
5515
|
+
```ts
|
|
5500
5516
|
// example
|
|
5501
5517
|
const middleware = createMiddleware({
|
|
5502
5518
|
input: z
|
|
@@ -5516,7 +5532,7 @@ const middleware = createMiddleware({
|
|
|
5516
5532
|
|
|
5517
5533
|
- Ability to use `z.transform()` in handler's output schema.
|
|
5518
5534
|
|
|
5519
|
-
```
|
|
5535
|
+
```ts
|
|
5520
5536
|
// example
|
|
5521
5537
|
const endpoint = factory.build({
|
|
5522
5538
|
methods: ["post"],
|
|
@@ -5544,7 +5560,7 @@ const endpoint = factory.build({
|
|
|
5544
5560
|
|
|
5545
5561
|
- `ConfigType` changes:
|
|
5546
5562
|
|
|
5547
|
-
```
|
|
5563
|
+
```ts
|
|
5548
5564
|
// before
|
|
5549
5565
|
export interface ConfigType {
|
|
5550
5566
|
server: {
|
|
@@ -5578,7 +5594,7 @@ export type ConfigType = (
|
|
|
5578
5594
|
|
|
5579
5595
|
- More convenient way to attach routing to your custom express app:
|
|
5580
5596
|
|
|
5581
|
-
```
|
|
5597
|
+
```ts
|
|
5582
5598
|
// before
|
|
5583
5599
|
initRouting({ app, logger, config, routing });
|
|
5584
5600
|
// after
|
|
@@ -5596,7 +5612,7 @@ attachRouting(config, routing);
|
|
|
5596
5612
|
- Ability to specify your custom Winston logger in config.
|
|
5597
5613
|
- `createLogger()` now accepts `LoggerConfig` as an argument:
|
|
5598
5614
|
|
|
5599
|
-
```
|
|
5615
|
+
```ts
|
|
5600
5616
|
// before
|
|
5601
5617
|
createLogger(config);
|
|
5602
5618
|
// after
|
|
@@ -5612,7 +5628,7 @@ createLogger(config.logger);
|
|
|
5612
5628
|
- Zod version is v3.0.0-alpha33.
|
|
5613
5629
|
- The syntax for generating the Swagger/OpenAPI specification has changed:
|
|
5614
5630
|
|
|
5615
|
-
```
|
|
5631
|
+
```ts
|
|
5616
5632
|
// before
|
|
5617
5633
|
generateOpenApi().getSpecAsYaml();
|
|
5618
5634
|
// after
|