Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v22 is for Tai #2214

Merged
merged 103 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from 96 commits
Commits
Show all changes
103 commits
Select commit Hold shift + click to select a range
66853e1
Changing trigger branches in workflows.
RobinTail Nov 26, 2024
5b7df35
Drop Node 18 (#2063)
RobinTail Nov 26, 2024
486abcd
Merge branch 'master' into make-v22
RobinTail Nov 26, 2024
9e4535d
rm redundant import
RobinTail Nov 27, 2024
e4d6c14
Merge branch 'master' into make-v22
RobinTail Dec 1, 2024
e32e63a
Merge branch 'master' into make-v22
RobinTail Dec 1, 2024
429e0e3
Cleanup migration for v22.
RobinTail Dec 1, 2024
67b0b74
Merge branch 'master' into make-v22
RobinTail Dec 1, 2024
2ec5a75
Cleanup compat test for migration.
RobinTail Dec 1, 2024
5221f86
Drop `provider()` overload having 3 arguments (#2206)
RobinTail Dec 1, 2024
a7d9ce9
Merge branch 'master' into make-v22
RobinTail Dec 2, 2024
2d6ca34
Merge branch 'master' into make-v22
RobinTail Dec 2, 2024
8d216ae
Drop `splitResponse` (#2228)
RobinTail Dec 2, 2024
0723eaf
Merge branch 'master' into make-v22
RobinTail Dec 2, 2024
6f6f993
Merge branch 'master' into make-v22
RobinTail Dec 2, 2024
f5e5302
Merge branch 'master' into make-v22
RobinTail Dec 3, 2024
3dde002
Merge branch 'master' into make-v22
RobinTail Dec 3, 2024
599db21
Merge branch 'master' into make-v22
RobinTail Dec 3, 2024
294f300
Merge branch 'master' into make-v22
RobinTail Dec 3, 2024
b832b2b
Merge branch 'master' into make-v22
RobinTail Dec 3, 2024
2b730fe
Merge branch 'master' into make-v22
RobinTail Dec 4, 2024
d7ba0aa
Merge branch 'master' into make-v22
RobinTail Dec 8, 2024
a929dea
Merge branch 'master' into make-v22
RobinTail Dec 9, 2024
026318d
Merge branch 'master' into make-v22
RobinTail Dec 9, 2024
5d5eb72
Merge branch 'master' into make-v22
RobinTail Dec 9, 2024
297ebcb
Merge branch 'master' into make-v22
RobinTail Dec 10, 2024
293995e
Merge branch 'master' into make-v22
RobinTail Dec 11, 2024
ab21595
Merge branch 'master' into make-v22
RobinTail Dec 11, 2024
0ee26e7
Merge branch 'master' into make-v22
RobinTail Dec 14, 2024
e2492a1
Merge branch 'master' into make-v22
RobinTail Dec 15, 2024
a8bed37
Merge branch 'master' into make-v22
RobinTail Dec 20, 2024
dc0494d
Drop `jsonEndpoints` (#2259)
RobinTail Dec 20, 2024
9cc7bcf
Merge branch 'master' into make-v22
RobinTail Dec 20, 2024
251cb20
Merge branch 'master' into make-v22
RobinTail Dec 20, 2024
44ad5a8
Update CHANGELOG.md
RobinTail Dec 21, 2024
eee45fe
Update CHANGELOG.md
RobinTail Dec 21, 2024
52b6eb6
SECURITY: planning for feb'25
RobinTail Dec 22, 2024
f14a92e
Merge branch 'master' into make-v22
RobinTail Dec 24, 2024
b035594
Merge branch 'master' into make-v22
RobinTail Dec 26, 2024
0f531ee
Merge branch 'master' into make-v22
RobinTail Dec 26, 2024
b215590
Dedicated to Tai’Vion Lathan.
RobinTail Dec 27, 2024
a26caaa
Merge branch 'master' into make-v22
RobinTail Dec 28, 2024
778a57a
Merge branch 'master' into make-v22
RobinTail Dec 29, 2024
ae76f9f
Merge branch 'master' into make-v22
RobinTail Dec 31, 2024
e106558
Merge branch 'master' into make-v22
RobinTail Dec 31, 2024
3734948
Merge branch 'master' into make-v22
RobinTail Dec 31, 2024
bdf12da
Drop `MethodPath` type (#2276)
RobinTail Dec 31, 2024
2ed233f
Merge branch 'master' into make-v22
RobinTail Jan 1, 2025
4d51d3a
Merge branch 'master' into make-v22
RobinTail Jan 1, 2025
78b3ba0
Merge branch 'master' into make-v22
RobinTail Jan 1, 2025
ec11bd5
Add eslint rule for makePromise().
RobinTail Jan 3, 2025
26e7afe
Minor: using Partial for makeParams() for consistency.
RobinTail Jan 3, 2025
4144294
Allow explicit types for makeTypeParams().
RobinTail Jan 3, 2025
646bac8
Allow type params on `makeArrowFn()` (#2281)
RobinTail Jan 3, 2025
3da9c16
Also allow params as an object on makeArrowFn().
RobinTail Jan 3, 2025
a74832e
Revert "Also allow params as an object on makeArrowFn()."
RobinTail Jan 3, 2025
1b7b1bd
Fix: optional last arg for makeArrowFn()
RobinTail Jan 3, 2025
97cc884
Merge branch 'master' into make-v22
RobinTail Jan 4, 2025
595a833
Changelog: migration guide.
RobinTail Jan 4, 2025
3959e49
22.0.0-beta.1
RobinTail Jan 4, 2025
35851ff
Merge branch 'master' into make-v22
RobinTail Jan 5, 2025
26967cb
Minor: line split in migration.
RobinTail Jan 5, 2025
df2dc1c
Merge branch 'master' into make-v22
RobinTail Jan 5, 2025
4184232
Moving tags to augmentation (#2284)
RobinTail Jan 5, 2025
61531c2
22.0.0-beta.2
RobinTail Jan 5, 2025
76e8d11
Merge branch 'master' into make-v22
RobinTail Jan 6, 2025
2a4d52f
Organizing Typescipt API (#2287)
RobinTail Jan 6, 2025
8535b8b
Merge branch 'master' into make-v22
RobinTail Jan 6, 2025
0d31e1d
Improve consistency of Typescript API (#2288)
RobinTail Jan 7, 2025
1c479cd
Fix: simpler expression for Integration (#2290)
RobinTail Jan 8, 2025
042b15b
Merge branch 'master' into make-v22
RobinTail Jan 9, 2025
faa19fb
Rev: Security: not deprecating v18 - will do it in April.
RobinTail Jan 11, 2025
32cac4d
Merge branch 'master' into make-v22
RobinTail Jan 11, 2025
2fe07af
Merge branch 'master' into make-v22
RobinTail Jan 12, 2025
9bf42f1
ref(v22): Integration base (#2299)
RobinTail Jan 13, 2025
0bd6289
Merge branch 'master' into make-v22
RobinTail Jan 13, 2025
ebf8b47
ref(v22): `parseRequest()` and `substitute()` functions (#2303)
RobinTail Jan 13, 2025
22c36a2
22.0.0-beta.3
RobinTail Jan 13, 2025
ea01e08
ref(v22): makeParam and makeParams API methods adjustment (#2305)
RobinTail Jan 13, 2025
87821ca
fix(v22): Integration cleanup and constraints adjustments (#2306)
RobinTail Jan 13, 2025
d2ea9ae
ref(v22): Minimizing ids (#2307)
RobinTail Jan 14, 2025
adeb8d8
Merge branch 'master' into make-v22
RobinTail Jan 14, 2025
d97a25d
Adjusting client constructor (#2312)
RobinTail Jan 14, 2025
e1b1e71
Minor: imports diff reduction.
RobinTail Jan 14, 2025
88a0a66
Renaming `ExpressZodAPIClient` to just `Client` (#2313)
RobinTail Jan 14, 2025
f3e1450
ref(v22): makePublicClass() arguments (#2314)
RobinTail Jan 15, 2025
d01bd80
Fix: comment.
RobinTail Jan 15, 2025
b1c3d03
Fix: makeUsageStatements() to return just nodes.
RobinTail Jan 15, 2025
c73ba3e
22.0.0-beta.4
RobinTail Jan 15, 2025
e99f451
Merge branch 'master' into make-v22
RobinTail Jan 15, 2025
057945e
Merge branch 'master' into make-v22
RobinTail Jan 17, 2025
e581b67
Merge branch 'master' into make-v22
RobinTail Jan 17, 2025
c351b32
Merge branch 'master' into make-v22
RobinTail Jan 18, 2025
aade841
Merge branch 'master' into make-v22
RobinTail Jan 18, 2025
b543c30
Merge branch 'master' into make-v22
RobinTail Jan 18, 2025
773c417
Changelog: Apply suggestions from code review
RobinTail Jan 18, 2025
e3aaf56
Merge branch 'master' into make-v22
RobinTail Jan 19, 2025
6bfa296
`Endpoint::getSecurity()` to return an array of containers (#2333)
RobinTail Jan 22, 2025
3354109
Merge branch 'master' into make-v22
RobinTail Jan 22, 2025
aa3bf02
Merge branch 'master' into make-v22
RobinTail Jan 23, 2025
d8f8192
feat(v22): Handle all headers (#2337)
RobinTail Jan 24, 2025
3f500e7
rev: trigger branches, no more prs
RobinTail Jan 24, 2025
131e4bb
Merge branch 'master' into make-v22
RobinTail Jan 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ name: "CodeQL"

on:
push:
branches: [ master, v18, v19, v20 ]
branches: [ master, v19, v20, v21, make-v22 ]
RobinTail marked this conversation as resolved.
Show resolved Hide resolved
pull_request:
# The branches below must be a subset of the branches above
branches: [ master, v18, v19, v20 ]
branches: [ master, v19, v20, v21, make-v22 ]
RobinTail marked this conversation as resolved.
Show resolved Hide resolved
schedule:
- cron: '26 8 * * 1'

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/minor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20
- uses: fregante/setup-git-user@v2
- run: |
yarn install
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ name: Node.js CI

on:
push:
branches: [ master, v18, v19, v20 ]
branches: [ master, v19, v20, v21, make-v22 ]
RobinTail marked this conversation as resolved.
Show resolved Hide resolved
pull_request:
branches: [ master, v18, v19, v20 ]
branches: [ master, v19, v20, v21, make-v22 ]
RobinTail marked this conversation as resolved.
Show resolved Hide resolved

jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: [18.18.0, 18.x, 20.9.0, 20.x, 22.0.0, 22.x]
node-version: [20.9.0, 20.x, 22.0.0, 22.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- name: Get yarn cache dir
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/npm-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20
registry-url: https://registry.npmjs.org/
- run: yarn install
- run: npm publish --provenance --tag ${{ inputs.tag }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/patch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20
- uses: fregante/setup-git-user@v2
- run: |
yarn install
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: OpenAPI Validation

on:
push:
branches: [ master, v18, v19, v20 ]
branches: [ master, v19, v20, v21, make-v22 ]
RobinTail marked this conversation as resolved.
Show resolved Hide resolved
pull_request:
branches: [ master, v18, v19, v20 ]
branches: [ master, v19, v20, v21, make-v22 ]
RobinTail marked this conversation as resolved.
Show resolved Hide resolved


jobs:
Expand Down
73 changes: 73 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,78 @@
# Changelog

## Version 22

### v22.0.0

- Minimum supported Node versions: 20.9.0 and 22.0.0:
RobinTail marked this conversation as resolved.
Show resolved Hide resolved
- Node 18 is no longer supported, its end of life is April 30, 2025.
- `BuiltinLogger::profile()` behavior changed for picoseconds: expressing them through nanoseconds;
- The `splitResponse` property on the `Integration::constructor()` argument is removed;
- Changes to the client code generated by `Integration`:
- The class name changed from `ExpressZodAPIClient` to just `Client`;
- The overload of the `Client::provide()` having 3 arguments and the `Provider` type are removed;
- The public `jsonEndpoints` const is removed — use the `content-type` header of an actual response instead;
- The public type `MethodPath` is removed — use the `Request` type instead.
- The approach on tagging endpoints changed:
- The `tags` property moved from the argument of `createConfig()` to `Documentation::constructor()`;
- The overload of `EndpointsFactory::constructor()` accepting `config` property is removed;
- The argument of `EventStreamFactory::constructor()` is now the events map (formerly assigned to `events` property);
- Tags should be declared as the keys of the augmented interface `TagOverrides` instead;
- Consider the automated migration using the built-in ESLint rule.

```js
// eslint.config.mjs — minimal ESLint 9 config to apply migrations automatically using "eslint --fix"
import parser from "@typescript-eslint/parser";
import migration from "express-zod-api/migration";

export default [
{ languageOptions: { parser }, plugins: { migration } },
{ files: ["**/*.ts"], rules: { "migration/v22": "error" } },
];
```

```diff
createConfig({
- tags: {},
});

new Documentation({
+ tags: {},
});

new EndpointsFactory(
- { config, resultHandler: new ResultHandler() }
+ new ResultHandler()
);

new EventStreamFactory(
- { config, events: {} }
+ {} // events map only
);
```

```ts
// new tagging approach
import { defaultEndpointsFactory, Documentation } from "express-zod-api";

// Add similar declaration once, somewhere in your code, preferably near config
declare module "express-zod-api" {
interface TagOverrides {
users: unknown;
files: unknown;
subscriptions: unknown;
}
}

// Add extended description of the tags to Documentation (optional)
new Documentation({
tags: {
users: "All about users",
files: { description: "All about files", url: "https://example.com" },
},
});
```

## Version 21

### v21.11.1
Expand Down
51 changes: 24 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1206,7 +1206,7 @@ import { EventStreamFactory } from "express-zod-api";
import { setTimeout } from "node:timers/promises";

const subscriptionEndpoint = EventStreamFactory({
events: { time: z.number().int().positive() },
time: z.number().int().positive(),
}).buildVoid({
input: z.object({}), // optional input schema
handler: async ({ options: { emit, isClosed } }) => {
Expand Down Expand Up @@ -1264,9 +1264,9 @@ Consuming the generated client requires Typescript version 4.1 or higher.

```typescript
// example frontend, simple implementation based on fetch()
import { ExpressZodAPIClient } from "./client.ts"; // the generated file
import { Client } from "./client.ts"; // the generated file

const client = new ExpressZodAPIClient(async (method, path, params) => {
const client = new Client(async (method, path, params) => {
const hasBody = !["get", "delete"].includes(method);
const searchParams = hasBody ? "" : `?${new URLSearchParams(params)}`;
const response = await fetch(`https://example.com${path}${searchParams}`, {
Expand Down Expand Up @@ -1322,36 +1322,33 @@ _See the example of the generated documentation

## Tagging the endpoints

When generating documentation, you may find it necessary to classify endpoints into groups. For this, the
possibility of tagging endpoints is provided. In order to achieve the consistency of tags across all endpoints, the
possible tags should be declared in the configuration first and another instantiation approach of the
`EndpointsFactory` is required. Consider the following example:
When generating documentation, you may find it necessary to classify endpoints into groups. The possibility of tagging
endpoints is available for that purpose. In order to establish the constraints on tags across all the endpoints, they
should be declared as keys of `TagOverrides` interface. Consider the following example:

```typescript
import {
createConfig,
EndpointsFactory,
defaultResultHandler,
} from "express-zod-api";
import { defaultEndpointsFactory, Documentation } from "express-zod-api";

const config = createConfig({
tags: {
users: "Everything about the users", // or advanced syntax:
files: {
description: "Everything about the files processing",
url: "https://example.com",
},
},
});
// Add similar declaration once, somewhere in your code, preferably near config
declare module "express-zod-api" {
interface TagOverrides {
users: unknown;
files: unknown;
subscriptions: unknown;
}
}

// instead of defaultEndpointsFactory use the following approach:
const taggedEndpointsFactory = new EndpointsFactory({
resultHandler: defaultResultHandler, // or use your custom one
config, // <—— supply your config here
// Use the declared tags for endpoints
const exampleEndpoint = defaultEndpointsFactory.build({
tag: "users", // or array ["users", "files"]
});

const exampleEndpoint = taggedEndpointsFactory.build({
tag: "users", // or array ["users", "files"]
// Add extended description of the tags to Documentation (optional)
new Documentation({
tags: {
users: "All about users",
files: { description: "All about files", url: "https://example.com" },
},
});
```

Expand Down
1 change: 1 addition & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

| Version | Release | Supported |
| ------: | :------ | :----------------: |
| 22.x.x | 02.2025 | :white_check_mark: |
| 21.x.x | 11.2024 | :white_check_mark: |
| 20.x.x | 06.2024 | :white_check_mark: |
| 19.x.x | 05.2024 | :white_check_mark: |
Expand Down
27 changes: 18 additions & 9 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const tsFactoryConcerns = [
message: "use makeType() or makePublicLiteralType() helpers",
},
{
selector: "Identifier[name='createVariableDeclarationList']",
selector: "Identifier[name='createVariableStatement']",
message: "use makeConst() helper",
},
{
Expand All @@ -73,7 +73,7 @@ const tsFactoryConcerns = [
},
{
selector: "Identifier[name='createConstructorDeclaration']",
message: "use makeEmptyInitializingConstructor() helper",
message: "use makePublicConstructor() helper",
},
{
selector: "Identifier[name='createParameterDeclaration']",
Expand All @@ -86,16 +86,25 @@ const tsFactoryConcerns = [
message: "use makePropCall() helper",
},
{
selector: "Identifier[name='AmpersandAmpersandToken']",
message: "use makeAnd() helper",
selector: "Identifier[name='KeyOfKeyword']",
message: "use makeKeyOf() helper",
},
{
selector: "Identifier[name='EqualsEqualsEqualsToken']",
message: "use makeEqual() helper",
selector: "Identifier[name='createTemplateExpression']",
message: "use makeTemplate() helper",
},
{
selector: "Identifier[name='KeyOfKeyword']",
message: "use makeKeyOf() helper",
selector: "Identifier[name='createNewExpression']",
message: "use makeNew() helper",
},
{
selector: "Literal[value='Promise']",
message: "use makePromise() helper",
},
{
selector:
"CallExpression[callee.property.name='createTypeReferenceNode'][arguments.length=1]",
message: "use ensureTypeNode() helper",
},
];

Expand Down Expand Up @@ -143,7 +152,7 @@ export default tsPlugin.config(
},
{
name: "source/integration",
files: ["src/integration.ts"],
files: ["src/integration.ts", "src/integration-base.ts", "src/zts.ts"],
rules: {
"no-restricted-syntax": [
"warn",
Expand Down
16 changes: 11 additions & 5 deletions example/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@ export const config = createConfig({
app.use("/docs", ui.serve, ui.setup(documentation));
},
cors: true,
tags: {
users: "Everything about the users",
files: "Everything about the files processing",
subscriptions: "Everything about the subscriptions",
},
});

// Uncomment these lines when using a custom logger, for example winston:
Expand All @@ -39,3 +34,14 @@ declare module "express-zod-api" {
interface LoggerOverrides extends BuiltinLogger {}
}
*/

// Uncomment these lines for introducing constraints on tags
/*
declare module "express-zod-api" {
interface TagOverrides {
users: unknown;
files: unknown;
subscriptions: unknown;
}
}
*/
5 changes: 2 additions & 3 deletions example/endpoints/accept-raw.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { z } from "zod";
import { ez } from "../../src";
import { taggedEndpointsFactory } from "../factories";
import { defaultEndpointsFactory, ez } from "../../src";

export const rawAcceptingEndpoint = taggedEndpointsFactory.build({
export const rawAcceptingEndpoint = defaultEndpointsFactory.build({
method: "post",
tag: "files",
input: ez.raw({
Expand Down
4 changes: 2 additions & 2 deletions example/endpoints/retrieve-user.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import createHttpError from "http-errors";
import assert from "node:assert/strict";
import { z } from "zod";
import { taggedEndpointsFactory } from "../factories";
import { defaultEndpointsFactory } from "../../src";
import { methodProviderMiddleware } from "../middlewares";

// Demonstrating circular schemas using z.lazy()
Expand All @@ -15,7 +15,7 @@ const feature: z.ZodType<Feature> = baseFeature.extend({
features: z.lazy(() => feature.array()),
});

export const retrieveUserEndpoint = taggedEndpointsFactory
export const retrieveUserEndpoint = defaultEndpointsFactory
.addMiddleware(methodProviderMiddleware)
.build({
tag: "users",
Expand Down
5 changes: 2 additions & 3 deletions example/endpoints/upload-avatar.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { z } from "zod";
import { ez } from "../../src";
import { defaultEndpointsFactory, ez } from "../../src";
import { createHash } from "node:crypto";
import { taggedEndpointsFactory } from "../factories";

export const uploadAvatarEndpoint = taggedEndpointsFactory.build({
export const uploadAvatarEndpoint = defaultEndpointsFactory.build({
method: "post",
tag: "files",
description: "Handles a file upload.",
Expand Down
Loading
Loading