DataFn
Concepts

Fields

Configure field types, validation constraints, and behavior.

DatafnFieldSchema

Each field in a resource defines its name, type, and validation constraints. Fields are validated on both the client and server.

type DatafnFieldSchema = {
  name: string;
  type: "string" | "number" | "boolean" | "date" | "object" | "array" | "file" | "json";
  required: boolean;
  nullable?: boolean;
  readonly?: boolean;
  default?: unknown;
  enum?: unknown[];
  min?: number;
  max?: number;
  minLength?: number;
  maxLength?: number;
  pattern?: string;
  unique?: boolean | string;
  encrypt?: boolean;
  volatile?: boolean;
};

Field Types

TypeTypeScriptStorageNotes
stringstringTextGeneral-purpose text values.
numbernumberNumericNaN is rejected during validation.
booleanbooleanBooleanStrict true/false only.
datestring | numberEpoch msAccepts ISO 8601 strings or epoch milliseconds. Stored as epoch ms internally.
objectRecord<string, unknown>JSONPlain objects only. Arrays and null are rejected.
arrayunknown[]JSONArray values only.
filestringTextFile reference (URL or path). Validated as a string.
jsonunknownJSONAny valid JSON value: string, number, boolean, object, or array.

Constraints

required

When true, the field must be present and non-undefined in insert mutations. Fields with a default value satisfy the required check automatically.

{ name: "title", type: "string", required: true }

nullable

When true, the field accepts null as a valid value. By default, null is rejected for all types.

{ name: "deletedAt", type: "date", required: false, nullable: true }

readonly

When true, the field can be set on insert but cannot be modified by subsequent update or merge mutations.

{ name: "createdBy", type: "string", required: true, readonly: true }

default

A default value applied when the field is omitted from an insert mutation.

{ name: "status", type: "string", required: true, default: "draft" }
{ name: "viewCount", type: "number", required: true, default: 0 }

enum

Restricts the field to a fixed set of allowed values.

{ name: "priority", type: "string", required: true, enum: ["low", "medium", "high", "critical"] }

min / max

Numeric range constraints. Apply to number and date fields.

{ name: "score", type: "number", required: true, min: 0, max: 100 }

minLength / maxLength

String length constraints. Apply to string fields.

{ name: "username", type: "string", required: true, minLength: 3, maxLength: 64 }

pattern

A regular expression pattern the string value must match.

{ name: "slug", type: "string", required: true, pattern: "^[a-z0-9-]+$" }

unique

When true, enforces a unique constraint on the field across all records in the resource. When set to a string, it defines a named uniqueness group -- fields sharing the same group name form a composite unique constraint.

// Simple unique constraint
{ name: "email", type: "string", required: true, unique: true }

// Composite unique constraint -- (orgId, slug) must be unique together
{ name: "orgId", type: "string", required: true, unique: "org_slug" }
{ name: "slug", type: "string", required: true, unique: "org_slug" }

encrypt

When true, the field value is encrypted at rest. Useful for sensitive data like tokens or personal information.

{ name: "apiKey", type: "string", required: true, encrypt: true }

volatile

When true, the field is excluded from sync operations. Volatile fields exist only in the local client store and are not pushed to the server.

{ name: "localDraft", type: "string", required: false, volatile: true }

Complete Example

import { defineSchema } from "@datafn/core";

const schema = defineSchema({
  resources: [
    {
      name: "users",
      version: 1,
      idPrefix: "usr",
      fields: [
        { name: "email", type: "string", required: true, unique: true, maxLength: 255 },
        { name: "displayName", type: "string", required: true, minLength: 1, maxLength: 100 },
        { name: "role", type: "string", required: true, enum: ["admin", "editor", "viewer"], default: "viewer" },
        { name: "bio", type: "string", required: false, maxLength: 2000, nullable: true },
        { name: "loginCount", type: "number", required: true, default: 0, min: 0 },
        { name: "emailVerified", type: "boolean", required: true, default: false },
        { name: "lastLoginAt", type: "date", required: false, nullable: true },
        { name: "avatar", type: "file", required: false },
        { name: "preferences", type: "json", required: false },
        { name: "settings", type: "object", required: false },
        { name: "favoriteTopics", type: "array", required: false },
        { name: "encryptedToken", type: "string", required: false, encrypt: true },
        { name: "localNotes", type: "string", required: false, volatile: true },
      ],
      indices: {
        base: ["email", "role"],
        search: ["displayName", "bio"],
      },
    },
  ],
});