Type Generation
Lucent automatically generates TypeScript types from your collections and custom endpoints into a single lucent-types.ts file. This enables end-to-end type safety for both the REST API client (via Eden Treaty) and the server-side programmatic API.
Running Type Generation
Types are automatically generated each time lucent dev starts. You can also trigger generation manually:
lucent build # generate types + validate config
lucent typegen # generate types only
Configuration
Configure the output path and optional custom type files in lucent.config.ts:
import { defineLucentConfig } from "@codesordinatestudio/lucent";
export default defineLucentConfig({
/* ... */
typegen: {
output: "./lucent-types.ts", // where to write the file
customTypes: ["./utils/my.types.ts"], // optional extra type files to inline
},
sdk: {
enabled: true,
manifest: {
output: "./sdk.json",
route: "/api/sdk.json",
exposeInDev: true,
exposeInProduction: false,
},
},
});
What Gets Generated
Collection interfaces
For every collection Lucent generates:
<Slug>Config— full document shape including timestamps<Slug>CreateInput— fields accepted on create<Slug>UpdateInput—Partial<CreateInput>for PATCH<Slug>ListResponse,<Slug>ItemResponse,<Slug>CreateResponse, etc.<Slug>WhereClause/<Slug>QueryArgsfor typed filtering
For auth-enabled collections it also generates <Slug>RegisterInput, <Slug>LoginInput, and the corresponding response types.
Custom endpoint schemas
Export any TypeBox t.Object(...) schema from an endpoint file and Lucent will automatically generate a matching TypeScript interface for it — using the exact export name, with no renaming:
// src/endpoints/auth.ts
import { t } from "elysia";
import type { LucentEndpoint } from "../lucent-types";
export const AuthBodySchema = t.Object({
name: t.String(),
file: t.File(),
});
export const myAuth: LucentEndpoint = (app) => {
app.post(
"/auth/upload",
({ body }) => {
/* ... */
},
{
body: AuthBodySchema,
},
);
};
After lucent build (or on next lucent dev start), lucent-types.ts will contain:
export interface AuthBodySchema {
name: string;
file: File;
}
No extra config is needed — Lucent discovers the endpoint files automatically from the endpoints array in your config.
Eden Treaty app type
A _buildLucentApp() phantom builder and LucentApp type are generated so you can wire up a Lucent client with full route type safety:
import { lucent } from "@codesordinatestudio/lucent";
import type { LucentApp } from "./lucent-types";
const api = lucent.client<LucentApp>({
url: "http://localhost:3000",
});
// Fully typed — body, response, query params
const { data } = await api.api.posts.get({ query: { page: 1 } });
lucent.client() uses Eden Treaty under the hood, sends cookies by default with credentials: "include", and can attach a bearer token plus an onResponse callback when needed.
Portable SDK manifest
When sdk.enabled is set, Lucent also generates a portable sdk.json manifest from the same metadata pipeline used by lucent-types.ts.
This file is intended to be copied, downloaded, or bundled into a client application that uses the standalone fetch-based lucent-sdk package. The optional manifest route is mainly useful for local development and tooling.
LucentEndpoint type
The generated file also exports a LucentEndpoint type that is pre-wired with your project's collection types:
import type { LucentEndpoint } from "./lucent-types"; // ← use this, not the package
export const myEndpoint: LucentEndpoint = (app) => {
// `lucent` and `user` are fully typed with your collections
app.get("/hello", ({ lucent, user }) => {
/* ... */
});
};