@adbls/api-types
v1.6.1
Published
Generated TypeScript and zod types for the Adibilis CORE API. Version tracks the core release tag 1:1.
Readme
@adbls/api-types
Generated TypeScript + zod types for the Adibilis CORE API. Nothing here is hand-written.
What it is (and what it isn't)
This package is a build output of core: ajtg reads core's compiled backend bytecode during
mvn process-classes and emits the types into src/. That is why it is published from
core/core and not from core/SDK — publishing it elsewhere would mean re-running core's Java
build in that repo, or copying generated output between repos, which is exactly the drift this
package exists to eliminate.
It is not the SDK. @adbls/sdk is hand-written (API client, form layer, checkout, holidays),
depends on this package, and re-exports the symbols satellites actually need. A satellite normally
installs only the SDK.
Version contract
A released version is 1:1 with the core release tag: @adbls/[email protected] is exactly
the API surface of core v1.4.2. CI stamps it from the tag; the 0.0.0 in package.json is a
placeholder and is never hand-bumped.
The package follows the same three channels as the core image, so the two can never drift:
| core ref | image tag | package version | npm dist-tag | published to |
|---|---|---|---|---|
| v1.4.2 | :v1.4.2 | 1.4.2 | latest | npmjs.org (public) and Forgejo |
| main | :latest | 0.0.0-stage.<run> | stage | Forgejo only |
| dev | :dev | 0.0.0-dev.<run> | dev | Forgejo only |
Releases are public so anyone can build a frontend against core: @adbls/sdk depends on this
package and is public itself. Prereleases stay on Forgejo — they describe unreleased API, and
publishing one per push would flood the public registry.
pnpm add @adbls/api-types # newest released version (npmjs, no token)
pnpm add @adbls/api-types@dev # newest dev build (Forgejo, see below)
pnpm add @adbls/api-types@stage # newest stage build (Forgejo, see below)Prereleases are published under their own dist-tag, so a plain pnpm add never resolves to one.
Pin latest in production satellites; use dev while developing against unreleased API changes.
@adbls/sdk carries its own semver and declares a compatible range on this package, so it can
ship a fix without a core release and state which core versions it speaks to.
Consuming it
Released versions need nothing: pnpm add @adbls/api-types zod resolves them from npmjs.org.
For the dev and stage prereleases, map the scope to Forgejo instead: copy .npmrc.example to
.npmrc and export a read token. The mapping is per scope, so while it is in place every
@adbls/* package — releases included — comes from Forgejo, which carries them too.
@adbls:registry=https://forge.cloud.adibilis.ch/api/packages/core/npm/
//forge.cloud.adibilis.ch/api/packages/core/npm/:_authToken=${NPM_TOKEN}export NPM_TOKEN=<read token>
pnpm add @adbls/api-types zodzod is a peer dependency so you resolve exactly one copy of it.
The npm registry token is build-time and has nothing to do with the WEBSITE API key a satellite uses at runtime to call core. Different lifetimes, different blast radii — do not conflate them.
Publishing (maintainers)
CI publishes with the org-level REGISTRY_TOKEN. Forgejo serves the container registry and the npm
registry from one package subsystem, and both need write:package, so the token that already does
docker login for the image build covers npm publish too — no separate npm secret exists.
Release tags then reach npmjs.org by trusted publishing, which npm only offers to GitHub, GitLab and
CircleCI — not Forgejo. So the release job pings publish-api-types in the public
Adibilis/sdk repo (secret SDK_DISPATCH_TOKEN), which copies
the Forgejo tarball to npmjs. Its hourly schedule catches a missed ping. No npm token exists.
Consumers of prereleases still need their own read-scoped Forgejo token; do not hand out the publishing one.
What you get
- Validated DTOs → a zod schema plus its inferred type:
ContactRequestModel(schema) andContactRequest(type). - Enums →
UserRoleModel(schema) andUserRole(type). - Unvalidated DTOs → a plain interface, default-exported and also re-exported by name from the barrel.
import { ContactRequestModel, type ContactRequest } from '@adbls/api-types';
const parsed = ContactRequestModel.safeParse(formValues);Schemas mirror the backend's Bean Validation exactly: a @NotBlank field is required in the
schema, so parse({}) fails rather than silently passing.
Notes and limits
- CommonJS output. The generator emits extensionless relative imports, which Node's ESM loader
rejects; CJS resolves them, and every consuming bundler (Next.js, Vite) handles CJS fine. Types
come from the
.d.tsfiles either way. - No Angular services. The build emits them (ajtg-angular is on the plugin classpath) but routes
them to a throwaway directory via
typesOnlyOutputDirectories— they import@angular/*and would break a satellite's build. - The barrel is generated (
scripts/generate-index.mjs, run asprebuild). ajtg wipessrc/on every build, so it cannot be a committed file. src/anddist/are gitignored. Regenerate withmvn clean package -DskipTestsfrom the repo root, thenpnpm buildhere.
