Schema Generation
npx slintorm generate scans your TypeScript source files and producesgenerated.ts — a single file that exports ModelMap, schema, and the interface types. No TypeScript compiler or ts-morph required.
Running the generator
# Scan TypeScript source files and output schema artifacts
npx slintorm generate
# Output:
# src/schema/generated.ts — typed ModelMap for TypeScript
# src/schema/generated.json — JSON schema for edge runtimesgenerated.ts
The primary output. Import ModelMap for typing, schema to skip filesystem scanning — both from the same file.
src/schema/generated.ts
// src/schema/generated.ts (auto-generated — do not edit)
import type { ModelAPI } from 'slintorm';
// Interfaces are inlined automatically from your source files
interface User {
id: number;
email: string;
name: string;
}
interface Post {
id: number;
title: string;
userId: number;
}
export const ModelMap = {
User: {} as ModelAPI<User>,
Post: {} as ModelAPI<Post>,
};
export type ModelMap = typeof ModelMap;generated.json
Also produced by the generator. This is the raw data that generated.ts re-exports as schema. You don't import this file directly — import schemafrom generated.ts instead.
src/schema/generated.json
// src/schema/generated.json (auto-generated)
// Used by edge runtimes — pass as 'schema' option
{
"User": {
"table": "users",
"fields": {
"id": { "auto": true, "primaryKey": true },
"email": { "unique": true },
"name": {}
}
},
"Post": {
"table": "posts",
"fields": {
"id": { "auto": true, "primaryKey": true },
"title": {},
"userId": {
"index": true,
"relation": {
"kind": "manytoone",
"modelName": "User",
"foreignKey": "userId"
}
}
}
}
}How the generator works
// How generator.ts works — no ts-morph, no compiler API
// Tokenizes .ts files with a lightweight regex-based scanner
// 1. Scans every .ts file in the configured 'dir'
// 2. Finds interface declarations and their fields
// 3. Reads // comment annotations above each field
// 4. Produces the FieldMeta map per interface
// 5. Writes generated.ts and generated.json
// This means:
// - No TypeScript compiler dependency at runtime
// - Works in any Node.js environment
// - Fast (no AST build step)
// - Only reads interface declarations (not classes or type aliases)Using ModelMap for a typed db
db.ts
// Use ModelMap for a fully-typed db without individual defineModel exports
import ORMManager from 'slintorm';
import { schema, type ModelMap } from './schema/generated';
const orm = new ORMManager<ModelMap>({
driver: 'sqlite',
databaseUrl: './dev.db',
modelMap: {} as ModelMap,
schema, // skips filesystem scan; required on edge runtimes
});
await orm.migrate();
export const db = orm.db;
// db.User — ModelAPI<User>
// db.Post — ModelAPI<Post>
// TypeScript knows every field on every modelPassing schema to edge runtimes
worker.ts
// Pass schema for edge runtimes (no filesystem reads, no migrate())
// schema is exported directly from generated.ts — no JSON import needed
import ORMManager from 'slintorm/browser';
import { schema } from './schema/generated';
const orm = new ORMManager({
driver: 'postgres',
databaseUrl: process.env.DATABASE_URL!,
schema, // no 'dir', no migrate()
});When to re-run generate
// Re-run 'npx slintorm generate' when:
// - You add a new interface
// - You add, remove, or rename a field
// - You change a relation annotation
// - You add/remove @softDelete, @unique, @index, etc.
// The schema hash in _slint_migrations is SHA-256 of the JSON —
// if the JSON changes, migrate() detects it as a pending migration
// Add to your CI pipeline:
// "prebuild": "npx slintorm generate && npx slintorm migrate"Commit generated files
Commit src/schema/generated.ts to version control. This ensures edge deployments always have the latest schema without needing to run the generator in production. Regenerate locally after any interface changes and commit the result.