Skip to content

Commit 4c88c83

Browse files
JohnMcLearclaude
andcommitted
fix: unblock the admin build on TypeScript 7
develop has been red since #8132 bumped typescript to ^7.0.2: every PR fails at "Build admin ui" with TypeError: Cannot read properties of undefined (reading 'createKeywordTypeNode') openapi-typescript builds its output with the TypeScript *compiler API* (ts.factory, ts.SyntaxKind, the printer). TypeScript 7 is the native port and its main export is only ./lib/version.cjs -- that API is not there at all. Its declared peer range is `typescript: ^5.x` and 7.13.0 is the newest release, so there is nothing to upgrade to yet. Rather than hold the whole workspace back on TypeScript 6, isolate the one tool that can't move. openapi-typescript takes `typescript` as a PEER dependency, so pnpm satisfies it from whichever package depends on it -- while admin both depended on openapi-typescript and declared typescript ^7.0.2, the peer always resolved to 7. Neither `overrides` (openapi-typescript>typescript) nor `packageExtensions` changes that; both were tried and pnpm still linked the _typescript@7.0.2 variant. So move openapi-typescript into a private build-time workspace package, admin/tools/openapi-codegen, whose only TypeScript is 6.x. The peer then resolves to a version with a working compiler API, and admin keeps typescript ^7.0.2 like every other workspace. gen-api.mjs invokes the tool through that package. The codegen only runs at build time to emit admin/src/api/schema.d.ts, and that output is plain text which tsc 7 consumes normally -- the regenerated file is byte-identical to the committed one. Verified: all four workspaces report tsc 7.0.2 and typecheck clean, admin gen:api + full build pass, `pnpm install --frozen-lockfile` is consistent, backend suite 1621 passing / 0 failing. The package README records how to delete it once openapi-typescript supports the native compiler. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 671b15c commit 4c88c83

6 files changed

Lines changed: 68 additions & 7 deletions

File tree

‎admin/package.json‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
"i18next": "^26.3.6",
3838
"i18next-browser-languagedetector": "^8.2.1",
3939
"lucide-react": "^1.31.0",
40-
"openapi-typescript": "^7.13.0",
4140
"react": "^19.2.8",
4241
"react-dom": "^19.2.8",
4342
"react-hook-form": "^7.85.0",

‎admin/scripts/gen-api.mjs‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,14 @@ try {
3737
process.exit(dump.status ?? 1);
3838
}
3939

40+
// Run openapi-typescript out of @etherpad/openapi-codegen rather than from
41+
// admin. It needs the TypeScript compiler API, which TypeScript 7 (the
42+
// native port) does not expose; that package is where its TypeScript is
43+
// pinned to a version that still has one. See its README.
4044
const gen = spawnSync(
4145
'pnpm',
42-
['exec', 'openapi-typescript', specPath, '-o', outFile],
46+
['--filter', '@etherpad/openapi-codegen', 'exec',
47+
'openapi-typescript', specPath, '-o', outFile],
4348
spawnOpts,
4449
);
4550
if (gen.status !== 0) {
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# @etherpad/openapi-codegen
2+
3+
Private, build-time-only package. It exists purely to pin the TypeScript that
4+
`openapi-typescript` runs against.
5+
6+
`openapi-typescript` builds its output using the TypeScript **compiler API**
7+
(`ts.factory`, `ts.SyntaxKind`, the printer). TypeScript 7 is the native port,
8+
and its main export is only `./lib/version.cjs` — the compiler API isn't there
9+
at all, so the codegen dies with:
10+
11+
```
12+
TypeError: Cannot read properties of undefined (reading 'createKeywordTypeNode')
13+
```
14+
15+
Its declared peer range is `typescript: ^5.x`, and 7.13.0 is the newest
16+
release, so there is nothing to upgrade to yet.
17+
18+
Pinning it from the workspace root doesn't work: `openapi-typescript` takes
19+
`typescript` as a *peer* dependency, so pnpm satisfies it from whichever
20+
package depends on it. While `admin` both depended on `openapi-typescript`
21+
and declared `typescript: ^7.0.2`, the peer always resolved to 7 — neither
22+
`overrides` nor `packageExtensions` overrides that. Giving the tool its own
23+
package, whose only TypeScript is 6.x, is what makes the peer resolve to a
24+
version with a working compiler API.
25+
26+
The tool only runs at build time to emit `admin/src/api/schema.d.ts`, and that
27+
output is plain text which `tsc` 7 then consumes normally. Nothing here ships.
28+
29+
**Delete this package** once `openapi-typescript` supports the native compiler:
30+
move `openapi-typescript` back into `admin`'s devDependencies and point
31+
`admin/scripts/gen-api.mjs` at it directly.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"name": "@etherpad/openapi-codegen",
3+
"version": "0.0.0",
4+
"private": true,
5+
"description": "Build-time wrapper that runs openapi-typescript against a TypeScript it can actually use. See README.md.",
6+
"devDependencies": {
7+
"openapi-typescript": "^7.13.0",
8+
"typescript": "^6.0.3"
9+
}
10+
}

‎pnpm-lock.yaml‎

Lines changed: 18 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎pnpm-workspace.yaml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ packages:
44
- bin
55
- doc
66
- ui
7+
# Build-time only: pins the TypeScript that openapi-typescript runs
8+
# against, which cannot be TypeScript 7. See its README.
9+
- admin/tools/openapi-codegen
710
allowBuilds:
811
'@scarf/scarf': set this to true or false
912
esbuild: set this to true or false

0 commit comments

Comments
 (0)