Skip to content

chore: migrate build from tsup to tsdown and enable publint - #236

Merged
mvantellingen merged 5 commits into
mainfrom
chore/tsdown-publint
Aug 25, 2026
Merged

chore: migrate build from tsup to tsdown and enable publint#236
mvantellingen merged 5 commits into
mainfrom
chore/tsdown-publint

Conversation

@mvantellingen

Copy link
Copy Markdown
Member

Finishes the in-progress tsup → tsdown migration so pnpm build passes again, and wires up publint to validate the published output on every build.

Note: this branch is based on local main, which was ahead of origin/main, so it also carries ci: merge workflow files and chore: mark graphql-yoga as peer dependency.

Fixing the build

tsdown bundles type declarations through rolldown, which cannot inline CommonJS .d.ts files. It externalizes dependencies and peerDependencies, but express and fastify were only devDependencies, so their types got pulled into the bundle and the build failed:

  • express-adapter — declares express as a peer dependency.
  • fastify-adapter — declares fastify and @fastify/cookie as peer dependencies.
  • core — leaked express types through the default type parameters of CompositeTokenSource. Core is framework agnostic (that is what the adapters are for), so the defaults are gone along with the now-unused @types/express dev dependency.

Enabling publint

Enabled through tsdown's built-in integration (publint: true), so it runs as part of pnpm build and CI already covers it.

It immediately caught a regression from the migration: tsdown defaults fixedExtension to true when the platform is node, so it was emitting dist/index.mjs and dist/index.d.mts while every main/module/types/exports field still pointed at dist/index.js. Every package would have published broken. Setting fixedExtension: false keeps the existing paths.

Two smaller things it flagged are fixed too: "sideEffects": false is now declared, and repository.url uses the full git+https://….git form.

Also

  • Config files renamed to tsdown.config.ts.
  • Five changesets added. All six packages resolve to a minor bump, since they are linked in the changesets config.

Reviewer note

Removing the generic defaults on CompositeTokenSource is a breaking type change for anyone referencing the bare type in a type position (let s: CompositeTokenSource). Constructor calls like new CompositeTokenSource([cookieSource]) still infer both parameters and are unaffected. If that is too sharp an edge, the alternative is keeping defaults backed by a minimal locally-defined request/response shape.

Verification

pnpm build (6/6, publint clean), pnpm test (80 tests), pnpm tsc (6/6) and pnpm lint all pass. The 12 lint warnings are pre-existing.

Replace tsup with tsdown in all packages and validate the published
output with publint on every build.

Fixing the build surfaced a few packaging issues:

- tsdown defaults `fixedExtension` to true when the platform is node,
  emitting `dist/index.mjs` and `dist/index.d.mts` while every
  main/module/types/exports field still pointed at `dist/index.js`.
  Set `fixedExtension: false` to keep the existing paths.
- tsdown bundles type declarations through rolldown, which cannot
  inline CommonJS `.d.ts` files. Packages whose public API exposes
  framework types now declare those frameworks as peer dependencies so
  they stay external: express for the express adapter, fastify and
  @fastify/cookie for the fastify adapter.
- The core package leaked express types through the default type
  parameters of `CompositeTokenSource`. Core is framework agnostic, so
  drop the defaults along with the `@types/express` dev dependency.

Also declare `"sideEffects": false` and use the full git URL form for
`repository.url`, both flagged by publint.
@changeset-bot

changeset-bot Bot commented Aug 25, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 150672d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@labdigital/federated-token Major
@labdigital/federated-token-apollo Major
@labdigital/federated-token-express-adapter Major
@labdigital/federated-token-fastify-adapter Major
@labdigital/federated-token-react Major
@labdigital/federated-token-yoga Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

The Node 20 build failed because tsdown loads a TypeScript config through
`unrun`, which is not installed; Node 22+ strips the types natively. Raise
`engines.node` to >=22.0.0 across the workspace and replace Node 20 with
Node 26 in the test matrix. tsdown picks the build target up from engines.

Separately, the test runs failed on every Node version because the bump to
cookie v2 renamed its exports: `parse` and `serialize` are now `parseCookie`
and `stringifySetCookie`, with the latter taking a single object. This did
not reproduce locally because the workspace still had cookie 1.0.2 linked.
Only tests use those functions, so no published code is affected.

Also move `cookie` in the express adapter to a dev dependency, as it is only
used for a type in the tests.
Replace the `any` types flagged by `noExplicitAny` with concrete ones:

- `JWTPayload` now declares the `tokens` and `isAuthenticated` fields the
  code actually reads, so the index signature can be `unknown`.
- `TokenSigner.encryptObject` takes `Record<string, unknown>`, matching how
  the value is used. Callers passing an object are unaffected.
- The fastify reply mock is typed instead of cast through `any`.

Also drop the unused constructor argument from the cookie test adapter,
flagged by `noUnusedPrivateClassMembers`.
@mvantellingen
mvantellingen merged commit 43419ba into main Aug 25, 2026
9 checks passed
@mvantellingen
mvantellingen deleted the chore/tsdown-publint branch August 25, 2026 05:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant