Schema
Define your data model with type-safe schemas.
DatafnSchema
A DataFn schema is the central definition of your data model. It declares the resources (tables), their fields, indices, and the relations between them.
type DatafnSchema = {
resources: DatafnResourceSchema[];
relations?: DatafnRelationSchema[];
multiTenant?: boolean; // defaults to true
};| Property | Type | Description |
|---|---|---|
resources | DatafnResourceSchema[] | Array of resource definitions. Must contain at least one resource. Maximum 100 resources. |
relations | DatafnRelationSchema[] | Optional array of relation definitions. Defaults to []. |
multiTenant | boolean | Enables row-level namespace isolation. Defaults to true. Set to false only for single-tenant deployments. |
defineSchema
Use defineSchema for full TypeScript type safety. It preserves literal types for field names and constrains index entries to only reference declared fields within each resource.
import { defineSchema } from "@datafn/core";
const schema = defineSchema({
resources: [
{
name: "projects",
version: 1,
idPrefix: "prj",
fields: [
{ name: "title", type: "string", required: true, maxLength: 200 },
{ name: "status", type: "string", required: true, enum: ["active", "archived"] },
{ name: "budget", type: "number", required: false, min: 0 },
],
indices: { base: ["title", "status"] },
},
{
name: "tasks",
version: 1,
idPrefix: "tsk",
fields: [
{ name: "title", type: "string", required: true },
{ name: "completed", type: "boolean", required: true, default: false },
{ name: "description", type: "string", required: false },
{ name: "tags", type: "array", required: false },
],
indices: {
base: ["title", "completed"],
search: ["description"],
},
},
],
relations: [
{
from: "projects",
to: "tasks",
type: "one-many",
relation: "projectTasks",
},
],
});The const generic on defineSchema ensures that field names like "title" and "completed" are inferred as string literals, not widened to string. This means the indices property will produce a type error if you reference a field name that does not exist on the resource.
validateSchema
At runtime, validateSchema checks the schema structure and returns a normalized result inside an envelope.
import { validateSchema } from "@datafn/core";
const result = validateSchema(schema);
if (!result.ok) {
console.error(result.error.code, result.error.message);
// e.g. "SCHEMA_INVALID" "Invalid schema: duplicate resource name: tasks"
} else {
const normalizedSchema = result.result;
}Validation checks:
resourcesmust be present and be a non-empty array (max 100 resources).- Each resource must have a unique
name(string) and an integerversion. fieldsmust be an array with unique field names within each resource (max 200 fields per resource).- Index field names must reference declared fields on the resource.
- Relation
fromandtomust reference declared resource names. joinTablemust be a string;joinColumnsmust havefromandtostring properties.
Index Normalization
If indices is provided as a flat string array, it is normalized to { base: [...], search: [], vector: [] }. If omitted entirely, all three arrays default to empty.
// Shorthand:
indices: ["title", "status"]
// Normalized to:
indices: { base: ["title", "status"], search: [], vector: [] }multiTenant Default
The multiTenant flag defaults to true. Only an explicit multiTenant: false disables row-level namespace isolation. This ensures safe defaults for multi-tenant deployments. See Multi-Tenancy for details.