Skip to content

Commit 2b04ea4

Browse files
v27 is for Nikki Kuhnhausen (#3148)
<img width="1200" height="630" alt="image" src="https://github.com/user-attachments/assets/5af2b247-bd39-4481-98a4-0ab6586afe49" /> Nikki Kuhnhausen was 17 years young transgender woman. She was murdered by David Bogdanov in 2019. Her body was identified from decayed remains on December 7th, in the Larch Mountain area near Vancouver, Washington. Authorities were able to identify the body from personal effects; subsequent examination showed she died from strangulation. Nikki had previously been missing since June 5th when she left with David Bogdanov, a 25-year-old male she met in Snapchat, who has since been charged with second degree murder. Authorities believe that Bogdanov, looking for a sexual encounter, became enraged upon learning of Nikki's transgender origins. https://katu.com/news/local/missing-vancouver-teen-nikki-kuhnhausen-found-dead-in-remote-clark-county-location-suspect-arrested Transgender women suffer too frequently from transphobic violence and cruelty, being the less protected social group. I'd like to raise an awareness of this problem. Humans should be creators — not killers. But most importantly, I want every transgender girl to have an opportunity to create applications quickly and, in general, learn to write code easily in order to receive job offers and leave dangerously transphobic territories for more favorable and civilized ones, and live happily there. Protect transgender women. ------------------ Version 27 makes `typescript` an optional peer dependency with explicit injection of the manually imported module into the `Integration` class constructor (`new Integration({ typescript, ... })`), or by calling the new async `Integration.create()` factory method for automatic loading. The Zod Plugin now leverages Zod 4.3's inheritable metadata feature, removing the need for `pack()` and `unpack()` helpers while simplifying brand handling by storing brands in standard metadata under `x-brand` property. - #3149 - #3162 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Async Integration.create() factory and optional TypeScript injection for client generation * Zod metadata is inheritable (requires Zod ^4.3.4) * **Breaking Changes** * pack/unpack/setBrand removed; branding exposed as "x-brand" via schema.meta() * Integration constructor now accepts a typescript option and usage may require async create() * **Documentation** * Examples updated for TypeScript injection and async create() usage * **Chores** * Version bumps to v27 beta and updated CI branch targets <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent f10a7a0 commit 2b04ea4

38 files changed

Lines changed: 359 additions & 496 deletions

.github/workflows/codeql-analysis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ name: "CodeQL"
1313

1414
on:
1515
push:
16-
branches: [ master, v22, v23, v24, v25 ]
16+
branches: [ master, v23, v24, v25, v26 ]
1717
pull_request:
1818
# The branches below must be a subset of the branches above
19-
branches: [ master, v22, v23, v24, v25 ]
19+
branches: [ master, v23, v24, v25, v26 ]
2020
schedule:
2121
- cron: '26 8 * * 1'
2222

.github/workflows/node.js.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ name: Node.js CI
55

66
on:
77
push:
8-
branches: [ master, v22, v23, v24, v25 ]
8+
branches: [ master, v23, v24, v25, v26 ]
99
pull_request:
10-
branches: [ master, v22, v23, v24, v25 ]
10+
branches: [ master, v23, v24, v25, v26 ]
1111

1212
jobs:
1313
build:

CHANGELOG.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,39 @@
11
# Changelog
22

3+
## Version 27
4+
5+
### v27.0.0
6+
7+
- Supported `zod` versions: `^4.3.4`;
8+
- The new version of Zod Plugin utilizes the inheritable metadata feature of Zod 4.3;
9+
- The `typescript` dependency is now optional and only required for making `Integration`:
10+
- Either import and assign the `typescript` property to its constructor argument;
11+
- Or use the new static async method `create()` to delegate the import;
12+
- This change addresses the memory consumption issue fixed previously in v26.1.0, but with proper ESM handling.
13+
14+
```diff
15+
/** Option 1: import and assign */
16+
import { Integration } from "express-zod-api";
17+
+ import typescript from "typescript";
18+
19+
const client = new Integration({
20+
routing,
21+
config,
22+
+ typescript,
23+
});
24+
```
25+
26+
```diff
27+
/** Option 2: delegate asynchronously */
28+
import { Integration } from "express-zod-api";
29+
30+
- const client = new Integration({
31+
+ const client = await Integration.create({
32+
routing,
33+
config,
34+
});
35+
```
36+
337
## Version 26
438

539
### v26.3.2

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ Install the framework, its peer dependencies and type assistance packages using
182182

183183
```shell
184184
# example for pnpm:
185-
pnpm add express-zod-api express zod typescript http-errors
185+
pnpm add express-zod-api express zod http-errors
186186
pnpm add -D @types/express @types/node @types/http-errors
187187
```
188188

@@ -1076,13 +1076,15 @@ adding the runtime helpers the framework relies on.
10761076

10771077
## Generating a Frontend Client
10781078

1079-
You can generate a TypeScript file containing the IO types of your API and a client for it.
1080-
Consider installing `prettier` and using the async `printFormatted()` method.
1079+
You can generate a TypeScript file containing the IO types of your API and a client for it. Make sure you have
1080+
`typescript` installed. Consider also installing `prettier` and using the async `printFormatted()` method.
10811081

10821082
```ts
1083+
import typescript from "typescript";
10831084
import { Integration } from "express-zod-api";
10841085

10851086
const client = new Integration({
1087+
typescript, // or await Integration.create() to delegate importing
10861088
routing,
10871089
config,
10881090
variant: "client", // <— optional, see also "types" for a DIY solution

SECURITY.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44

55
| Version | Code name | Release | Supported |
66
| ------: | :------------ | :------ | :----------------: |
7+
| 27.x.x | Nikki | 02.2026 | :white_check_mark: |
78
| 26.x.x | Lia | 12.2025 | :white_check_mark: |
89
| 25.x.x | Sara | 08.2025 | :white_check_mark: |
910
| 24.x.x | Ashley | 06.2025 | :white_check_mark: |
1011
| 23.x.x | Sonia | 04.2025 | :white_check_mark: |
11-
| 22.x.x | Tai | 01.2025 | :white_check_mark: |
12+
| 22.x.x | Tai | 01.2025 | :x: |
1213
| 21.x.x | Kesaria | 11.2024 | :x: |
1314
| 20.x.x | Zoey | 06.2024 | :x: |
1415
| 19.x.x | Dime | 05.2024 | :x: |

compat-test/eslint.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ import migration from "@express-zod-api/migration";
33

44
export default [
55
{ languageOptions: { parser }, plugins: { migration } },
6-
{ files: ["**/*.ts"], rules: { "migration/v26": "error" } },
6+
{ files: ["**/*.ts"], rules: { "migration/v27": "error" } },
77
];

compat-test/migration.spec.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { describe, test, expect } from "vitest";
44
describe("Migration", () => {
55
test("should fix the import", async () => {
66
const fixed = await readFile("./sample.ts", "utf-8");
7-
expect(fixed).toBe(`const route = {\nget: someEndpoint,\n}\n`);
7+
expect(fixed).toBe(
8+
`import typescript from "typescript";\n\nnew Integration({ typescript, routing });\n`,
9+
);
810
});
911
});

compat-test/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"type": "module",
44
"private": true,
55
"scripts": {
6-
"pretest": "echo 'const route = new DependsOnMethod({ get: someEndpoint })' > sample.ts",
6+
"pretest": "echo 'new Integration({ routing });' > sample.ts",
77
"test": "eslint --fix && vitest --run",
88
"posttest": "rm sample.ts"
99
},

eslint.config.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ const tsFactoryConcerns = [
176176
selector: "Identifier[name='createUnionTypeNode']",
177177
message: "use makeUnion() helper",
178178
},
179+
{
180+
selector: "Identifier[name='createIdentifier']",
181+
message: "use makeId() helper",
182+
},
179183
];
180184

181185
export default tsPlugin.config(
@@ -238,11 +242,7 @@ export default tsPlugin.config(
238242
files: ["migration/index.ts"],
239243
rules: {
240244
"allowed/dependencies": ["error", { packageDir: migrationDir }],
241-
"no-restricted-syntax": [
242-
"warn",
243-
...importConcerns,
244-
...performanceConcerns,
245-
],
245+
"no-restricted-syntax": ["warn", ...importConcerns],
246246
},
247247
},
248248
{

example/generate-client.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ import { writeFile } from "node:fs/promises";
22
import { Integration } from "express-zod-api";
33
import { routing } from "./routing";
44
import { config } from "./config";
5+
import typescript from "typescript";
56

67
await writeFile(
78
"example.client.ts",
89
await new Integration({
10+
typescript,
911
routing,
1012
config,
1113
serverUrl: `http://localhost:${config.http!.listen}`,

0 commit comments

Comments
 (0)