ActiveRecord API reference
Look up record, query and field methods, options and return types. Start with the guide for the normal workflow.
On this page
Source-backed MarkdownUse the guide first
This reference is generated from the package declarations. Use it to check a method signature or option in the four public entry points below.
Import normal model APIs from @db3.ai/app/db. Source-relative imports in a declaration are internal type dependencies, not new supported import paths. The package is still pre-release; availability is explained in the walkthrough.
Records, validation and persistence
Use create()/new for an unsaved model; save() persists. find()/findByPk() return null when absent; findOrFail() throws. Request filling, validation, errors, dirty state, JSON, soft deletion and form metadata are listed below.
withDb() provides a scoped connection. useDb(), constructor db options, setDb() and explicit query connections are lower-level controls; do not thread an optional database parameter through ordinary feature functions.
import type { Knex } from 'knex';
import { DbRow, DbWriteData, DomFormRenderSpec, FieldError, type FieldClass, type FieldDbValue, type FieldDefinition, type FieldDisplayValue, type FieldMap, type FieldInputMap, type FieldInputValue, FieldType, type FieldValue, FrontendComponentSpec, type DbWriteOptions } from './FieldType.js';
import { ActiveQueryBuilder } from './ActiveQueryBuilder.js';
import { type ActiveRecordSoftDeleteConfig } from './SoftDeletes.js';
import type { FieldBuilder } from './fields/field.js';
import { type ActiveRecordLookup } from './errors.js';
import type { ValidationRules } from '../validation/index.js';
export type { FieldBuilder } from './fields/field.js';
export { RecordNotFoundError } from './errors.js';
export type { ActiveRecordLookup } from './errors.js';
export interface ModelFormOptions {
name?: string;
mode?: 'create' | 'edit' | 'search';
includeGenerated?: boolean;
}
/**
* Options accepted by the ActiveRecord constructor.
*/
export interface ActiveRecordOptions {
/** Optional database connection/session for this record instance. */
db?: Knex;
/** True when the provided input is a raw database row. */
fromDb?: boolean;
/** Whether the record already exists in the database. */
persisted?: boolean;
}
/**
* Options for assigning untrusted request/form values to a record.
*/
export interface ActiveRecordRequestOptions {
/** Whether primary-key fields may be set from request data. Defaults to false. */
includePrimary?: boolean;
/** Whether generated fields may be set from request data. Defaults to false. */
includeGenerated?: boolean;
/** Explicit fillable fields for this request. Defaults to the model config. */
fillable?: readonly string[];
/** Explicit guarded fields for this request. Defaults to the model config. */
guarded?: readonly string[];
}
export interface ActiveRecordValidationRulesOptions extends ActiveRecordRequestOptions {
/** Whether hidden fields should be included. Defaults to false. */
includeHidden?: boolean;
}
export type ActiveRecordRequestMap = Record<string, string>;
export type ActiveRecordConstructor<TRecord extends ActiveRecord = ActiveRecord> = {
new (input?: Record<string, unknown>, options?: ActiveRecordOptions): TRecord;
};
export type ActiveRecordInstance<TModel extends ActiveRecordConstructor> = InstanceType<TModel>;
/**
* Static side of an ActiveRecord model class.
*
* Each subclass acts as its own schema by defining static `table`, `primaryKey`,
* and a `fields(field)` method.
*/
export type ActiveRecordClass<TRecord extends ActiveRecord = ActiveRecord> = ActiveRecordConstructor<TRecord> & {
/** Runtime JavaScript class name. */
readonly name: string;
/** Database table name. */
table: string;
/** Developer-facing model note for generated schemas and tooling. */
comment?: string;
/** Logical primary-key field name. */
primaryKey: string;
/** Fields used to render row labels when this model is linked from another model. */
labelFields?: string[];
/** Logical fields that request filling may assign. Undefined means all non-guarded fields. */
requestFillable?: readonly string[];
/** Logical fields that request filling may not assign. */
requestGuarded?: readonly string[];
/** Static field definitions for the model. */
fields(field: FieldBuilder): FieldInputMap;
/** Resolved static field definitions for the model. */
getFields(): FieldMap;
/** Returns a DomForm render spec composed from the model's FieldTypes. */
getForm(options?: ModelFormOptions): DomFormRenderSpec;
/** Returns search filter render specs composed from the model's FieldTypes. */
getSearchFilters(options?: ModelFormOptions): Record<string, FrontendComponentSpec>;
/** Looks up one resolved static field definition. */
getField(fieldName: string): FieldType<any, any, any, any, any>;
/** Optional default database connection for this model. Falls back to the shared app connection. */
db?: Knex;
/** Whether inserts/updates should call `.returning('*')`. */
returning?: boolean;
/** Soft-delete setting. True uses the conventional `deletedAt` logical field. */
softDeletes: ActiveRecordSoftDeleteConfig;
/** Returns the database connection for this model in the current app/scope. */
getDb(): Knex;
/** Runs work with a temporary database connection for all ActiveRecord statics. */
withDb<TResult>(db: Knex, callback: () => TResult): TResult;
/** Binds a default database connection to the model class. */
useDb<TModel extends ActiveRecordConstructor>(this: TModel, db: Knex): TModel;
/** Creates a new unsaved record bound to the model's current database. */
create<TModel extends ActiveRecordConstructor>(this: TModel, input?: Record<string, unknown>, options?: Omit<ActiveRecordOptions, 'db'>): ActiveRecordInstance<TModel>;
/** Starts a field-aware query for the model. */
query<TModel extends ActiveRecordConstructor>(this: TModel, db?: Knex): ActiveQueryBuilder<ActiveRecordInstance<TModel>>;
/** Starts a query that includes soft-deleted rows. */
withTrashed<TModel extends ActiveRecordConstructor>(this: TModel, db?: Knex): ActiveQueryBuilder<ActiveRecordInstance<TModel>>;
/** Starts a query that only includes soft-deleted rows. */
onlyTrashed<TModel extends ActiveRecordConstructor>(this: TModel, db?: Knex): ActiveQueryBuilder<ActiveRecordInstance<TModel>>;
/** Starts a query that excludes soft-deleted rows. */
withoutTrashed<TModel extends ActiveRecordConstructor>(this: TModel, db?: Knex): ActiveQueryBuilder<ActiveRecordInstance<TModel>>;
/** Convenience helper for `query().where(...)`. */
where<TModel extends ActiveRecordConstructor>(this: TModel, criteria: Record<string, unknown>): ActiveQueryBuilder<ActiveRecordInstance<TModel>>;
where<TModel extends ActiveRecordConstructor>(this: TModel, fieldName: string, value: unknown): ActiveQueryBuilder<ActiveRecordInstance<TModel>>;
where<TModel extends ActiveRecordConstructor>(this: TModel, fieldName: string, operator: string, value: unknown): ActiveQueryBuilder<ActiveRecordInstance<TModel>>;
/** Finds one record by the configured primary key. */
findByPk<TModel extends ActiveRecordConstructor>(this: TModel, id: unknown, db?: Knex): Promise<ActiveRecordInstance<TModel> | null>;
/** Finds one record by the configured primary key. */
find<TModel extends ActiveRecordConstructor>(this: TModel, lookup: ActiveRecordLookup, db?: Knex): Promise<ActiveRecordInstance<TModel> | null>;
/** Finds one record by the configured primary key or throws an error if not found. */
findOrFail<TModel extends ActiveRecordConstructor>(this: TModel, lookup: ActiveRecordLookup, db?: Knex): Promise<ActiveRecordInstance<TModel>>;
/** Hydrates a model instance from a raw database row. */
fromDb<TModel extends ActiveRecordConstructor>(this: TModel, row: DbRow, db?: Knex): ActiveRecordInstance<TModel>;
/** Returns validation rules generated from model fields. */
validationRules(options?: ActiveRecordValidationRulesOptions): ValidationRules;
};
/**
* Minimal ActiveRecord base class.
*
* Subclasses define their table and fields statically. Each instance creates
* private live field objects, and public model properties proxy through to those
* fields.
*
* Example:
*
* ```ts
* class User extends ActiveRecord {
* static table = 'users';
* static fields(field: FieldBuilder) {
* return {
* email: field.email({ required: true }),
* };
* }
* }
*
* const user = new User();
* user.email = '[email protected]';
* console.log(user.email); // '[email protected]'
* ```
*/
export declare abstract class ActiveRecord {
/** Database table name. Override in subclasses. */
static table: string;
/** Developer-facing model note for generated schemas and tooling. */
static comment: string;
/** Logical primary-key field name. Override if not `id`. */
static primaryKey: string;
/** Fields used to render row labels when this model is linked from another model. */
static labelFields: string[];
/** Logical fields that request filling may assign. Undefined means all non-guarded fields. */
static requestFillable?: readonly string[];
/** Logical fields that request filling may not assign. */
static requestGuarded: readonly string[];
/** Static field factory. Override in subclasses. */
static fields(_field: FieldBuilder): FieldInputMap;
/** Optional model-level database connection. Falls back to the shared app connection. */
static db?: Knex;
/**
* Whether to call `.returning('*')` after inserts/updates.
*
* This is usually desirable for PostgreSQL. Set to `false` for dialects where
* returning is unsupported or unwanted.
*/
static returning: boolean;
/** Soft-delete setting. True uses the conventional `deletedAt` logical field. */
static softDeletes: ActiveRecordSoftDeleteConfig;
/** Per-record live fields, keyed by logical field name. */
private readonly $fields;
/** Whether the record currently represents an existing database row. */
protected $persisted: boolean;
/** Optional instance-level database connection/session. */
protected $db?: Knex;
constructor(input?: Record<string, unknown>, options?: ActiveRecordOptions);
/**
* Binds a custom default database connection to the model class.
*
* Most models can use the active app connection automatically. For tests,
* prefer creating an app with the test database. For scoped work such as
* transactions, use `withDb()`.
*/
static useDb<TModel extends ActiveRecordConstructor>(this: TModel, db: Knex): TModel;
/**
* Returns the database connection for the current ActiveRecord operation.
*/
static getDb(): Knex;
/**
* Runs work with a temporary database connection for all ActiveRecord statics.
*/
static withDb<TResult>(db: Knex, callback: () => TResult): TResult;
/**
* Creates a new unsaved record bound to this model's current database.
*/
static create<TModel extends ActiveRecordConstructor>(this: TModel, input?: Record<string, unknown>, options?: Omit<ActiveRecordOptions, 'db'>): ActiveRecordInstance<TModel>;
/**
* Resolves the model's static field factory with the framework field helper.
*/
static getFields<TRecord extends ActiveRecord>(this: ActiveRecordClass<TRecord>): FieldMap;
/**
* Returns a DomForm render spec composed from this model's FieldTypes.
*/
static getForm<TRecord extends ActiveRecord>(this: ActiveRecordClass<TRecord>, options?: ModelFormOptions): DomFormRenderSpec;
/**
* Returns search filter render specs composed from this model's FieldTypes.
*/
static getSearchFilters<TRecord extends ActiveRecord>(this: ActiveRecordClass<TRecord>, options?: ModelFormOptions): Record<string, FrontendComponentSpec>;
/**
* Looks up one resolved field definition by logical field name.
*/
static getField<TRecord extends ActiveRecord>(this: ActiveRecordClass<TRecord>, fieldName: string): FieldType<any, any, any, any, any>;
/**
* Starts a field-aware query for this model.
*/
static query<TModel extends ActiveRecordConstructor>(this: TModel, db?: Knex): ActiveQueryBuilder<ActiveRecordInstance<TModel>>;
/**
* Starts a query that includes soft-deleted rows.
*/
static withTrashed<TModel extends ActiveRecordConstructor>(this: TModel, db?: Knex): ActiveQueryBuilder<ActiveRecordInstance<TModel>>;
/**
* Starts a query that only includes soft-deleted rows.
*/
static onlyTrashed<TModel extends ActiveRecordConstructor>(this: TModel, db?: Knex): ActiveQueryBuilder<ActiveRecordInstance<TModel>>;
/**
* Starts a query that excludes soft-deleted rows.
*/
static withoutTrashed<TModel extends ActiveRecordConstructor>(this: TModel, db?: Knex): ActiveQueryBuilder<ActiveRecordInstance<TModel>>;
/**
* Convenience helper for `Model.query().where(...)`.
*/
static where<TModel extends ActiveRecordConstructor>(this: TModel, criteria: Record<string, unknown>): ActiveQueryBuilder<ActiveRecordInstance<TModel>>;
static where<TModel extends ActiveRecordConstructor>(this: TModel, fieldName: string, value: unknown): ActiveQueryBuilder<ActiveRecordInstance<TModel>>;
static where<TModel extends ActiveRecordConstructor>(this: TModel, fieldName: string, operator: string, value: unknown): ActiveQueryBuilder<ActiveRecordInstance<TModel>>;
/**
* Finds one record by the configured primary key.
*/
static findByPk<TModel extends ActiveRecordConstructor>(this: TModel, id: unknown, db?: Knex): Promise<ActiveRecordInstance<TModel> | null>;
/**
* Finds one record by the configured primary key or field criteria.
*/
static find<TModel extends ActiveRecordConstructor>(this: TModel, lookup: ActiveRecordLookup, db?: Knex): Promise<ActiveRecordInstance<TModel> | null>;
/**
* Finds one record by the configured primary key or field criteria.
*
* Throws a `RecordNotFoundError` if no matching row exists.
*/
static findOrFail<TModel extends ActiveRecordConstructor>(this: TModel, lookup: ActiveRecordLookup, db?: Knex): Promise<ActiveRecordInstance<TModel>>;
private static queryForLookup;
/**
* Hydrates a model instance from a raw database row.
*/
static fromDb<TModel extends ActiveRecordConstructor>(this: TModel, row: DbRow, db?: Knex): ActiveRecordInstance<TModel>;
/**
* Returns Laravel-style validation rules generated from this model's fields.
*/
static validationRules<TRecord extends ActiveRecord>(this: ActiveRecordClass<TRecord>, options?: ActiveRecordValidationRulesOptions): ValidationRules;
/**
* Assigns app/input values by logical field name.
*
* Unknown keys are ignored. Use `set(fieldName, value)` if you want an error
* for unknown fields.
*/
assign(input: Record<string, unknown>): this;
/**
* Assigns request/form values using logical model field names.
*/
assignFromRequest(input: unknown, options?: ActiveRecordRequestOptions): this;
/**
* Fills this record from request/form values using logical model field names.
*
* Unknown keys are ignored. Primary/generated/guarded fields are skipped by
* default, and model/request fillable config controls what may be assigned.
*/
setFromRequest(input: unknown, options?: ActiveRecordRequestOptions): this;
/**
* Fills this record from request/form values using a request-key to model-field map.
*/
setFromRequestWithMap(input: unknown, dataToFieldMap: ActiveRecordRequestMap, options?: ActiveRecordRequestOptions): this;
/**
* Dynamically sets a field by logical name.
*
* Useful for runtime/database-stored schemas where TypeScript cannot know the
* field names at compile time.
*/
set(fieldName: string, value: unknown): this;
/**
* Dynamically gets a field by logical name.
*/
get(fieldName: string): unknown;
/**
* Dynamically binds this record instance to a database connection/session.
*/
setDb(db: Knex): this;
/**
* Returns true if the model has the given logical field.
*/
hasField(fieldName: string): boolean;
/**
* Returns the bound runtime field for framework-level hydration helpers.
*/
getBoundField(fieldName: string): FieldType<any, any, any, any, any>;
/**
* Validates fields and stores field errors on each field state.
*/
validate(options?: {
onlyDirty?: boolean;
}): Promise<boolean>;
/**
* Clears all current validation errors.
*/
clearErrors(): void;
/**
* Returns true if any field currently has validation errors.
*/
hasErrors(): boolean;
/**
* Returns all field errors on this record.
*/
getErrors(): FieldError[];
/**
* Returns current validation errors for one field.
*/
getFieldErrors(fieldName: string): FieldError[];
/**
* Returns database insert/update data for the record.
*
* This calls every field's `getDataForDb()` method. This is where passwords
* are hashed, JSON fields are stringified, link fields produce foreign keys,
* and compound fields can return multiple columns.
*/
getDataForDb(options?: Partial<DbWriteOptions>): Promise<DbWriteData>;
/**
* Inserts or updates this record.
*
* Validation runs before any SQL is executed. On validation failure this throws
* `RecordValidationError` containing all field errors.
*/
save(): Promise<this>;
/**
* Deletes the current database row.
*
* Models with `softDeletes` enabled update their delete timestamp instead of
* physically removing the row.
*/
delete(db?: Knex): Promise<number>;
/**
* Physically deletes the current database row.
*/
forceDelete(db?: Knex): Promise<number>;
/**
* Restores the current soft-deleted database row.
*/
restore(db?: Knex): Promise<number>;
/**
* Returns true when this soft-deletable record has been trashed.
*/
trashed(): boolean;
/**
* Returns hydrated backend values keyed by logical field name.
*/
toAppData(): Record<string, unknown>;
/**
* Serialises this record using each field's display value.
*/
toDisplayData(): Record<string, unknown>;
/**
* JSON transport alias for display data.
*/
toJSON(): Record<string, unknown>;
/**
* Returns true if this record was loaded from or saved to the database.
*/
isPersisted(): boolean;
/**
* Returns whether one field or any field has unsaved in-memory changes.
*
* @param fieldName - Optional logical field name to inspect.
* @returns True when the selected field scope contains unsaved changes.
*/
isDirty(fieldName?: string): boolean;
/**
* Protected field getter used by generated accessors and `get()`.
*/
protected $get(fieldName: string): unknown;
/**
* Protected field setter used by generated accessors and `set()`.
*/
protected $set(fieldName: string, value: unknown): void;
/**
* Hydrates all fields from a raw database row.
*/
protected $hydrateFromDb(row: DbRow): void;
/**
* Marks all fields as clean after a successful save/hydration.
*/
protected $markClean(): void;
/**
* Returns a database where-clause object for the primary key.
*/
protected $primaryKeyWhere(): Record<string, unknown>;
/**
* Returns one of this record's live field objects.
*/
protected $field(fieldName: string): FieldType<any, any, any, any, any>;
/**
* Soft deletes the current database row.
*/
private softDelete;
/**
* Mirrors soft-delete timestamp writes into this record's live field state.
*/
private $setSoftDeleteFieldValues;
/**
* Returns the static model class for this instance.
*/
private $model;
private $canFillFromRequest;
/**
* Defines an instance getter/setter for a configured field.
*/
private $installAccessor;
/**
* Checks whether a model class owns a custom accessor for a field.
*
* Explicit model accessors may wrap the underlying field through `$get`
* and `$set` when a domain value needs a stable model-owned interface.
*
* @param fieldName - Logical field name being installed.
* @returns True when a subclass prototype defines a getter or setter.
*/
private $hasModelAccessor;
}
type ResolvedFieldInput<TInput> = TInput extends FieldType<any, any, any, any, any> ? TInput : TInput extends FieldClass<infer TField> ? TField : TInput extends FieldDefinition<infer TField> ? TField : never;
type ModelFieldInputs<TModel extends {
fields(field: FieldBuilder): FieldInputMap;
}> = ReturnType<TModel['fields']>;
export declare namespace ActiveRecord {
type InferInput<TModel extends {
fields(field: FieldBuilder): FieldInputMap;
}> = {
[fieldName in keyof ModelFieldInputs<TModel>]: FieldInputValue<ResolvedFieldInput<ModelFieldInputs<TModel>[fieldName]>>;
};
type InferValue<TModel extends {
fields(field: FieldBuilder): FieldInputMap;
}> = {
[fieldName in keyof ModelFieldInputs<TModel>]: FieldValue<ResolvedFieldInput<ModelFieldInputs<TModel>[fieldName]>>;
};
type InferDbRow<TModel extends {
fields(field: FieldBuilder): FieldInputMap;
}> = {
[fieldName in keyof ModelFieldInputs<TModel>]: FieldDbValue<ResolvedFieldInput<ModelFieldInputs<TModel>[fieldName]>>;
};
type InferDisplay<TModel extends {
fields(field: FieldBuilder): FieldInputMap;
}> = {
[fieldName in keyof ModelFieldInputs<TModel>]: FieldDisplayValue<ResolvedFieldInput<ModelFieldInputs<TModel>[fieldName]>>;
};
}
Queries, filters and results
The builder accepts logical field names. It covers field selection, filters, vector similarity, ordering, bounded reads, counts and deletion. toKnex() exposes the underlying query for advanced work; the application then owns raw result handling and SQL-level choices.
import type { Knex } from 'knex';
import type { ActiveRecord, ActiveRecordClass } from './ActiveRecord.js';
export interface VectorSimilarityOptions {
/** SQL result alias used for the computed vector distance. Defaults to `distance`. */
as?: string;
/** Optional maximum vector distance for filtering candidate rows. */
maxDistance?: number;
/** Whether to order rows by closest distance. Defaults to ascending distance. */
orderBy?: 'asc' | 'desc' | false;
}
/**
* Field-aware query builder that wraps Knex.
*
* Add wrapper methods as you need them. `toKnex()` is the escape hatch for raw
* Knex operations.
*/
export declare class ActiveQueryBuilder<TRecord extends ActiveRecord> {
private readonly Model;
private readonly db;
private readonly qb;
private readonly includedFields;
private readonly includedRelations;
private selectedFields;
private softDeleteScope;
constructor(Model: ActiveRecordClass<TRecord>, db: Knex);
/**
* Includes soft-deleted rows in query results and write operations.
*/
withTrashed(): this;
/**
* Restricts the query to soft-deleted rows only.
*/
onlyTrashed(): this;
/**
* Restricts the query to rows that have not been soft deleted.
*/
withoutTrashed(): this;
/**
* Includes an opt-in field that normal fetches omit by default.
*/
withField(fieldName: string): this;
/**
* Eager-loads a link field and serializes it as nested model JSON.
*
* The relation name may be the logical link field name, the target model table
* name, or the target model class name. Prefer the field name when a model has
* more than one link to the same table.
*/
with(relationName: string): this;
/**
* Restricts hydrated query results to the requested logical model fields.
*
* This is intended for bounded read models and polling endpoints that should
* not load large model columns they do not render.
*
* @param fieldNames - Logical model field names to select.
* @returns This query builder.
*
* @example
* const pages = await WebsitePage
* .where('website', websiteId)
* .select('analyzeStatus', 'analyzeData')
* .all();
*/
select(...fieldNames: string[]): this;
/**
* Adds field-aware equality conditions from an object.
*/
where(criteria: Record<string, unknown>): this;
/**
* Adds a field-aware `where field = value` condition.
*/
where(fieldName: string, value: unknown): this;
/**
* Adds a field-aware `where field operator value` condition.
*/
where(fieldName: string, operator: string, value: unknown): this;
/**
* Adds a primary-key equality condition.
*/
wherePk(id: unknown): this;
/**
* Adds a field-aware `where in (...)` condition.
*/
whereIn(fieldName: string, values: unknown[]): this;
/**
* Adds a field-aware `where column is null` condition.
*/
whereNull(fieldName: string): this;
/**
* Adds a field-aware `where column is not null` condition.
*/
whereNotNull(fieldName: string): this;
/**
* Adds a raw where clause.
*
* Prefer field-aware methods where possible. Use parameter bindings to avoid
* SQL injection when using raw SQL.
*/
whereRaw(sql: string, bindings?: readonly unknown[]): this;
/**
* Adds a dialect-aware vector similarity projection, optional distance filter,
* and closest-first ordering for a vector field.
*
* @param fieldName - Logical vector field name.
* @param vector - Query vector to compare against the stored field.
* @param options - Projection alias, optional distance threshold, and ordering.
* @returns This query builder.
*
* @example
* WebsiteEmbedding
* .query()
* .where('website', websiteId)
* .whereVectorSimilarTo('embedding', queryVector)
* .limit(10)
* .toKnex()
*/
whereVectorSimilarTo(fieldName: string, vector: readonly number[], options?: VectorSimilarityOptions): this;
/**
* Returns whether the active database dialect can run vector similarity search.
*
* @returns True when `whereVectorSimilarTo()` can build SQL for this connection.
*/
supportsVectorSimilaritySearch(): boolean;
/**
* Returns a model-visible message for unsupported vector similarity dialects.
*
* @returns Readable unsupported-dialect message.
*/
vectorSimilarityUnsupportedMessage(): string;
/**
* Adds field-aware ordering.
*/
orderBy(fieldName: string, direction?: 'asc' | 'desc'): this;
/**
* Limits the number of returned records.
*/
limit(count: number): this;
/**
* Offsets returned records.
*/
offset(count: number): this;
/**
* Escape hatch for raw database column names.
*
* This bypasses field conversion and validation. Use it for low-level cases,
* not normal application queries.
*/
whereColumn(column: string, value: unknown): this;
whereColumn(column: string, operator: string, value: unknown): this;
/**
* Executes the query and returns the first hydrated record, or null.
*/
first(): Promise<TRecord | null>;
/**
* Executes the query and returns the first hydrated record.
*
* @returns First matching record.
* @throws {RecordNotFoundError} When the query has no matching rows.
*
* @example
* const user = await User
* .where('email', email)
* .firstOrFail();
*/
firstOrFail(): Promise<TRecord>;
/**
* Executes the query and returns hydrated records.
*/
all(): Promise<TRecord[]>;
/**
* Counts matching records without hydrating or transferring model rows.
*
* @param fieldName - Optional logical field whose non-null values should be counted.
* @returns Number of matching records or non-null field values.
*
* @example
* const keywordCount = await Keywords
* .where('website', websiteId)
* .count();
*/
count(fieldName?: string): Promise<number>;
/**
* Updates matching rows using field-aware assignment/conversion.
*
* This does not load records before updating them.
*/
patch(input: Record<string, unknown>): Promise<number>;
/**
* Deletes matching rows, using soft deletes when the model opts in.
*/
delete(): Promise<number>;
/**
* Physically deletes matching rows, bypassing soft delete behavior.
*/
forceDelete(): Promise<number>;
/**
* Restores matching soft-deleted rows by clearing their delete timestamp.
*/
restore(): Promise<number>;
/**
* Returns a scoped clone of the underlying Knex query builder.
*
* After calling this, you are outside the ActiveRecord hydration layer. Raw
* Knex results will not automatically become model instances.
*/
toKnex(): Knex.QueryBuilder;
/**
* Looks up a field by logical model field name.
*/
private getField;
/**
* Looks up a field and requires it to be a native vector field.
*
* @param fieldName - Logical model field name.
* @returns Native vector field instance.
*/
private getVectorField;
/**
* Builds a dialect-aware vector distance expression for a vector field.
*
* @param field - Vector field being compared.
* @param vector - Query vector to compare against.
* @returns SQL expression and bindings for the active dialect.
*/
private vectorDistanceSql;
/**
* Returns the supported vector-search dialect name for this query connection.
*
* @returns Supported dialect name, or null when not supported.
*/
private vectorDistanceDialect;
/**
* Returns a model-table-qualified database column name for field-aware clauses.
*
* @param field - Model field or metadata whose storage column should be referenced.
* @returns Column qualified with the ActiveRecord model table.
*/
private qualifiedColumn;
/**
* Looks up a requested relation and requires it to resolve to one link field.
*/
private getRelationField;
/**
* Loads included link records in batches and attaches them to each record.
*/
private loadIncludedRelations;
/**
* Loads one included link relation for all hydrated records.
*/
private loadIncludedRelation;
/**
* Attaches loaded relation records to the bound link fields.
*/
private attachLoadedRelation;
/**
* Returns table-qualified columns for fields included in model hydration.
*/
private selectedColumns;
/**
* Returns true when a field should be included in hydrated query results.
*/
private shouldSelectField;
/**
* Applies the current soft-delete scope to a Knex query clone.
*/
private applySoftDeleteScope;
}
Joined and computed read shapes
ActiveProjection converts SQL rows through reusable fields without pretending a joined result is a writable table record. Import it from @db3.ai/app/db. Your query owns aliases and scope; the projection owns conversion and output.
import { DbRow, FieldConfig, type FieldClass, type FieldDbValue, type FieldDefinition, type FieldDisplayValue, type FieldInputMap, type FieldInputValue, type FieldMap, FieldType, type FieldValue } from './FieldType.js';
import type { ActiveRecordClass } from './ActiveRecord.js';
import { type FieldBuilder } from './fields/field.js';
export interface ProjectionSourceFieldOptions {
/** Row key used when a query aliases the source column. */
alias?: string;
/** Explicit row key. Defaults to `alias`, then the source field's DB column. */
column?: string;
/** Projection-only default used when the row omits the projected column. */
default?: FieldConfig['default'];
}
export interface ProjectionFromModelOptions {
/** Optional logical fields to include from the source model. Defaults to all fields. */
fields?: readonly string[];
/** Optional logical fields to omit from the source model. */
except?: readonly string[];
/** Prefix for projected logical field names. */
prefix?: string;
/** Per-field aliases used by the query row. */
aliases?: Record<string, string>;
/** Per-field projection defaults. */
defaults?: Record<string, FieldConfig['default']>;
}
export interface ProjectionFieldBuilder extends FieldBuilder {
from<TModel extends {
fields(field: FieldBuilder): FieldInputMap;
} & ActiveRecordClass, TFieldName extends keyof ModelFieldInputs<TModel> & string>(Model: TModel, fieldName: TFieldName, options?: ProjectionSourceFieldOptions): ResolvedFieldInput<ModelFieldInputs<TModel>[TFieldName]>;
fromModel<TModel extends ActiveRecordClass>(Model: TModel, options?: ProjectionFromModelOptions): FieldInputMap;
}
export type ActiveProjectionConstructor<TProjection extends ActiveProjection = ActiveProjection> = {
new (row?: DbRow): TProjection;
};
export type ActiveProjectionClass<TProjection extends ActiveProjection = ActiveProjection> = ActiveProjectionConstructor<TProjection> & {
readonly name: string;
table: string;
primaryKey: string;
fields(field: ProjectionFieldBuilder): FieldInputMap;
getFields(): FieldMap;
fromDb<TClass extends ActiveProjectionConstructor>(this: TClass, row: DbRow): InstanceType<TClass>;
fromDbRows<TClass extends ActiveProjectionConstructor>(this: TClass, rows: readonly DbRow[]): InstanceType<TClass>[];
};
export declare abstract class ActiveProjection {
static table: string;
static primaryKey: string;
static fields(_field: ProjectionFieldBuilder): FieldInputMap;
private readonly $fields;
constructor(row?: DbRow);
static getFields<TProjection extends ActiveProjection>(this: ActiveProjectionClass<TProjection>): FieldMap;
static fromDb<TClass extends ActiveProjectionConstructor>(this: TClass, row: DbRow): InstanceType<TClass>;
static fromDbRows<TClass extends ActiveProjectionConstructor>(this: TClass, rows: readonly DbRow[]): InstanceType<TClass>[];
setFromDb(row: DbRow): this;
get(fieldName: string): unknown;
toAppData(): Record<string, unknown>;
toDisplayData(): Record<string, unknown>;
toJSON(): Record<string, unknown>;
protected $field(fieldName: string): FieldType<any, any, any, any, any>;
private $projection;
private $installAccessor;
}
export declare const projectionField: ProjectionFieldBuilder;
type ResolvedFieldInput<TInput> = TInput extends FieldType<any, any, any, any, any> ? TInput : TInput extends FieldClass<infer TField> ? TField : TInput extends FieldDefinition<infer TField> ? TField : never;
type ModelFieldInputs<TModel extends {
fields(field: FieldBuilder): FieldInputMap;
}> = ReturnType<TModel['fields']>;
type ProjectionFieldInputs<TProjection extends {
fields(field: ProjectionFieldBuilder): FieldInputMap;
}> = ReturnType<TProjection['fields']>;
export declare namespace ActiveProjection {
type InferInput<TProjection extends {
fields(field: ProjectionFieldBuilder): FieldInputMap;
}> = {
[fieldName in keyof ProjectionFieldInputs<TProjection>]: FieldInputValue<ResolvedFieldInput<ProjectionFieldInputs<TProjection>[fieldName]>>;
};
type InferValue<TProjection extends {
fields(field: ProjectionFieldBuilder): FieldInputMap;
}> = {
[fieldName in keyof ProjectionFieldInputs<TProjection>]: FieldValue<ResolvedFieldInput<ProjectionFieldInputs<TProjection>[fieldName]>>;
};
type InferDbRow<TProjection extends {
fields(field: ProjectionFieldBuilder): FieldInputMap;
}> = {
[fieldName in keyof ProjectionFieldInputs<TProjection>]: FieldDbValue<ResolvedFieldInput<ProjectionFieldInputs<TProjection>[fieldName]>>;
};
type InferDisplay<TProjection extends {
fields(field: ProjectionFieldBuilder): FieldInputMap;
}> = {
[fieldName in keyof ProjectionFieldInputs<TProjection>]: FieldDisplayValue<ResolvedFieldInput<ProjectionFieldInputs<TProjection>[fieldName]>>;
};
}
export {};
Field conversion and extension points
FieldType describes input, backend, database and display values. Use existing fields first. A custom field should override only the parts of that lifecycle which differ, and supply validation and schema metadata for its behaviour.
import type { Knex } from 'knex';
import type { ValidationRule } from '../validation/index.js';
import type { DatabaseDialect, DatabaseValueOptions } from './dialects/index.js';
/**
* Generic database row shape returned by the SQL driver.
*/
export type DbRow = Record<string, unknown>;
/**
* Partial database row used for inserts and updates.
*
* A field returns an object instead of a scalar because some fields may map to
* multiple database columns. For example, a map/location field could return
* `{ location_lat, location_lng }`.
*/
export type DbWriteData = Record<string, unknown>;
/**
* A structured validation error attached to a specific model field.
*/
export interface FieldError {
/** Logical field name on the model, for example `email` or `password`. */
field: string;
/** Human-readable error message. */
message: string;
/** Stable machine-readable error code, for example `required`. */
code?: string;
/** Offending value, where safe to expose. Avoid storing secrets here. */
value?: unknown;
/** Extra structured data for UI/API consumers. */
details?: unknown;
}
/**
* Error thrown by `ActiveRecord.save()` when one or more fields are invalid.
*/
export declare class RecordValidationError extends Error {
readonly errors: FieldError[];
constructor(errors: FieldError[]);
}
export type FieldDefault = null | string | number | boolean | Record<string, unknown> | unknown[];
export type FieldDefaultFactory = () => unknown;
export type GeneratedValue = boolean | 'db' | 'ulid' | 'uuid-v4' | 'now';
export interface FrontendComponentSpec {
component: string;
props: Record<string, unknown>;
}
export interface DomFormRenderSpec {
component: 'DomForm';
props: Record<string, unknown>;
children: FrontendComponentSpec[];
}
export interface FieldFrontendConfig {
component?: string;
props?: Record<string, unknown>;
searchComponent?: string;
searchProps?: Record<string, unknown>;
}
export interface FieldRenderOptions {
mode?: 'create' | 'edit' | 'search';
}
/**
* Core configuration shared by all fields.
*
* Concrete field types should extend this with their own options.
*/
export interface FieldConfig {
/** Database column name. Defaults to the model field name. */
column?: string;
/** Developer-facing note for generated models and schema tooling. */
comment?: string;
/** Whether the field must have a non-empty value. */
required?: boolean;
/** Whether the field is the model primary key. */
primary?: boolean;
/** Whether the value should be omitted from `toJSON()`. */
hidden?: boolean;
/** Whether normal ActiveRecord fetches should include this field's columns. */
selectedByDefault?: boolean;
/** Whether the generated database schema should include a unique constraint. */
unique?: boolean;
/** Whether the generated database schema should include an index on this field's primary column. */
index?: boolean;
/** Optional name for the generated single-column index. */
indexName?: string;
/** Additional generated database schema indexes for this field. */
indexes?: DbIndexSpec[];
/** Optional human-friendly label for UI/admin/form generation. */
label?: string;
/** Static default value or runtime factory. Use static values for serializable config. */
default?: FieldDefault | FieldDefaultFactory;
/** Named generation strategy. This is serializable and lets the field/framework decide how to generate the value. */
generated?: GeneratedValue;
/** Frontend rendering hints composed by FieldType render helpers. */
frontend?: FieldFrontendConfig;
}
export type FieldClass<TField extends FieldType<any, any, any, any, any> = FieldType<any, any, any, any, any>> = new (config?: any) => TField;
export interface FieldDefinition<TField extends FieldType<any, any, any, any, any> = FieldType<any, any, any, any, any>> {
type: FieldClass<TField>;
config: ConstructorParameters<FieldClass<TField>>[0];
}
export type FieldInput<TField extends FieldType<any, any, any, any, any> = FieldType<any, any, any, any, any>> = FieldClass<TField> | FieldDefinition<TField> | TField;
export type FieldInputMap = Record<string, FieldInput<any>>;
export type FieldMap = Record<string, FieldType<any, any, any, any, any>>;
export type FieldMapFactory = (field: any) => FieldInputMap;
/**
* Context passed into low-level field methods.
*
* Record instances normally use the higher-level field instance API. This
* context remains for schema/query work and for concrete field internals.
*/
export interface FieldContext {
/** The model class metadata. */
model: ModelMetadata;
/** Database dialect used for schema/value conversion when available. */
dialect?: DatabaseDialect;
/** Knex table builder when schema is being applied to the database. */
table?: Knex.TableBuilder;
/** Options used when writing columns through `table`. */
columnWriteOptions?: DbColumnWriteOptions;
/** The active record instance when available. Query code may omit this. */
record?: unknown;
/** Logical field name on the model, for example `email`. */
fieldName: string;
}
/**
* Minimal model metadata required by fields.
*
* This avoids importing `ActiveRecord` into the field base class and keeps the
* dependency direction simple.
*/
export interface ModelMetadata {
/** Database table name. */
table: string;
/** Logical primary-key field name. */
primaryKey: string;
/** Static field definitions on the model class. */
fields: FieldMapFactory;
}
/**
* Options passed when collecting database write data from fields.
*/
export interface DbWriteOptions {
/** True for insert, false for update. */
isInsert: boolean;
/** Whether clean fields should be excluded from the generated row. */
onlyDirty: boolean;
/** Database value conversion context for driver-specific field storage. */
valueOptions?: DatabaseValueOptions;
}
/**
* Basic state used by most one-column value fields.
*/
export interface BasicFieldState<TValue = unknown> {
/** Current app-memory value. */
value: TValue;
/** Value originally loaded from the database or initial default. */
originalValue: TValue;
/** Whether the current value differs from the original value. */
dirty: boolean;
/** Validation errors for this field on this record. */
errors: FieldError[];
}
/**
* Database column description produced by a field's `getDbSchema()`.
*
* The `type` string comes from the active dialect and is applied directly by
* `Database` via Knex `specificType`.
*/
export interface DbColumnSpec {
/** Database column name. */
name: string;
/** Database column type, e.g. `varchar(255)`, `char(26)`, `json`, or `longtext`. */
type: string;
/** Whether null is allowed. */
nullable?: boolean;
/** Whether this column is the primary key. */
primary?: boolean;
/** Whether this column has a unique constraint. */
unique?: boolean;
/** Database default value. */
default?: unknown;
/** Database-native column comment where supported, such as MySQL. */
comment?: string;
}
/**
* Options for writing a column onto a Knex table builder.
*/
export interface DbColumnWriteOptions {
alter?: boolean;
alterNullable?: boolean;
alterType?: boolean;
applyDefault?: boolean;
applyComment?: boolean;
}
/**
* Writes a column spec onto a Knex table builder.
*/
export declare function writeDbColumn(table: Knex.TableBuilder, column: DbColumnSpec, options?: DbColumnWriteOptions): void;
/**
* Neutral database index description.
*/
export interface DbIndexSpec {
/** Columns included in the index. */
columns: DbIndexColumnSpec[];
/** Optional index name. */
name?: string;
/** Whether the index is unique. */
unique?: boolean;
/** Database index kind. Defaults to a normal scalar index. */
type?: 'normal' | 'vector';
}
export type DbIndexColumnSpec = string | {
name: string;
order?: 'asc' | 'desc';
};
export declare function fieldSchemaIndexes(column: string, config: FieldConfig): DbIndexSpec[] | undefined;
/**
* Neutral foreign-key description.
*/
export interface DbForeignKeySpec {
/** Local database column. */
column: string;
/** Referenced database table. */
referencesTable: string;
/** Referenced database column. */
referencesColumn: string;
/** Optional ON DELETE action. */
onDelete?: 'CASCADE' | 'RESTRICT' | 'SET NULL' | 'NO ACTION';
/** Optional ON UPDATE action. */
onUpdate?: 'CASCADE' | 'RESTRICT' | 'SET NULL' | 'NO ACTION';
}
/**
* Database schema contribution produced by a single field.
*/
export interface DbSchemaPart {
/** Columns required by this field. */
columns?: DbColumnSpec[];
/** Indexes required by this field. */
indexes?: DbIndexSpec[];
/** Foreign keys required by this field. */
foreignKeys?: DbForeignKeySpec[];
}
/**
* Base class for reusable field behaviour.
*
* Static model fields are schema definitions. Each ActiveRecord instance creates
* private live field objects that own their value, dirty state, errors, field
* name, and parent record reference.
*
* The low-level lifecycle remains:
*
* - `createState()` creates per-record storage.
* - `setValue()` handles input assignment and stores the hydrated backend value.
* - `getValue()` handles normal property reads.
* - `validate()` stores field errors.
* - `getDataForDb()` returns database write data.
* - `setFromDb()` hydrates state from a database row.
* - `getDisplayValue()` serializes for frontend/form/API-safe output.
*/
export declare abstract class FieldType<TValue = unknown, TDbValue = TValue, TDisplayValue = TValue, TInput = TValue, TState extends {
errors: FieldError[];
} = BasicFieldState<TValue>> {
readonly config: FieldConfig;
private $fieldName?;
private $model?;
private $record?;
private $state?;
private $activeContext?;
constructor(config?: FieldConfig);
/**
* Logical field name on the parent record.
*/
get name(): string;
/**
* Logical field name on the parent record/model.
*/
get fieldName(): string;
/**
* Parent model metadata.
*/
get model(): ModelMetadata;
/**
* Parent ActiveRecord instance.
*/
get record(): unknown;
required(value?: boolean): this;
/**
* Primary database column for this bound field.
*/
get column(): string;
/**
* Current app-memory value for this bound field.
*/
get value(): TValue;
set value(input: TInput);
/**
* Whether this bound field has changed since hydration/default creation.
*/
get dirty(): boolean;
/**
* Current validation errors for this bound field.
*/
get errors(): FieldError[];
/**
* Clears validation errors for this bound field.
*/
clearErrors(): void;
/**
* Hydrates this bound field from a database row.
*/
hydrate(row: DbRow): void;
/**
* Validates this bound field.
*/
validateField(): Promise<FieldError[]>;
/**
* Returns database write data for this bound field.
*/
getBoundDataForDb(options: DbWriteOptions): Promise<DbWriteData>;
/**
* Returns a frontend/form/API-safe value for this bound field.
*/
getBoundDisplayValue(): TDisplayValue | undefined;
/**
* Converts a query value for this bound field.
*/
getBoundQueryValue(input: TInput): unknown;
/**
* Marks this bound field as clean.
*/
markBoundClean(): void;
/**
* Returns the column for this field blueprint on a model.
*/
getColumnFor(model: ModelMetadata, fieldName: string): string;
/**
* Converts a query value for this field blueprint on a model.
*/
getQueryValueFor(model: ModelMetadata, fieldName: string, input: TInput): unknown;
/**
* Returns schema metadata for this field blueprint on a model.
*/
getDbSchemaFor(model: ModelMetadata, fieldName: string): DbSchemaPart;
/**
* Returns the DomStudio component spec for rendering this field in a form.
*/
getFormComponent(options?: FieldRenderOptions, ctx?: FieldContext): FrontendComponentSpec;
/**
* Returns the DomStudio component spec for rendering this field as a search filter.
*/
getSearchFilterComponent(options?: FieldRenderOptions, ctx?: FieldContext): FrontendComponentSpec | null;
/**
* Returns a form component spec for an unbound model field.
*/
getFormComponentFor(model: ModelMetadata, fieldName: string, options?: FieldRenderOptions): FrontendComponentSpec;
/**
* Returns a search component spec for an unbound model field.
*/
getSearchFilterComponentFor(model: ModelMetadata, fieldName: string, options?: FieldRenderOptions): FrontendComponentSpec | null;
/**
* Returns the primary database column for this field.
*
* Compound fields may still return additional columns from `getDataForDb()`.
*/
getColumn(ctx?: FieldContext): string;
/**
* Creates per-record runtime state for this field.
*/
createState(ctx?: FieldContext): TState;
/**
* Handles app-level assignment, e.g. `user.email = '[email protected]'`.
*
* Keep this mostly synchronous. Async work such as hashing should usually
* happen in `getDataForDb()` during save.
*/
setValue(state: TState, input: TInput, ctx?: FieldContext): void;
/**
* Handles app-level property reads, e.g. `user.email`.
*/
getValue(state: TState, ctx?: FieldContext): TValue;
/**
* Hydrates field state from a raw database row.
*/
setFromDb(state: TState, row: DbRow, ctx?: FieldContext): void;
/**
* Validates the field and stores the resulting errors on the field state.
*/
validate(state: TState, ctx?: FieldContext): Promise<FieldError[]>;
/**
* Returns current validation errors for this field state.
*/
getErrors(state: TState): FieldError[];
/**
* Returns true if this field state currently has validation errors.
*/
hasErrors(state: TState): boolean;
/**
* Returns true if the field has changed since hydration/default creation.
*/
isDirty(state: TState): boolean;
/**
* Marks the state as clean after a successful save or hydration.
*/
markClean(state: TState): void;
/**
* Returns database write data for this field.
*
* The default implementation maps one field to one column.
*/
getDataForDb(state: TState, options: DbWriteOptions): Promise<DbWriteData>;
getDataForDb(state: TState, ctx: FieldContext, options: DbWriteOptions): Promise<DbWriteData>;
/**
* Returns a frontend/form/API-safe value for this field.
*/
getDisplayValue(state: TState, ctx?: FieldContext): TDisplayValue | undefined;
/**
* Alias used by JSON transport. Framework docs call this display data.
*/
getJsonValue(state: TState, ctx?: FieldContext): TDisplayValue | undefined;
/**
* Converts an input query value into its database representation.
*
* Query builder methods call this so `where('email', '[email protected]')`
* can compare against the normalized database value.
*/
getQueryValue(input: TInput, ctx?: FieldContext): unknown;
/**
* Returns database schema metadata for dev sync and diff tooling.
*
* When `ctx.table` is present the field also writes its column(s) onto that
* Knex builder using the dialect-owned SQL type string.
*/
getDbSchema(ctx?: FieldContext): DbSchemaPart;
/**
* Returns request/input validation rules for this field.
*/
getValidationRules(ctx?: FieldContext): ValidationRule[];
/**
* Parses app/input assignment into the field's app-memory value.
*/
protected parse(input: TInput): TValue;
/**
* Default form component for this field type.
*/
protected defaultFormComponent(): string;
/**
* Default form props derived from FieldType config.
*/
protected defaultFormComponentProps(_options: FieldRenderOptions): Record<string, unknown>;
/**
* Default search component for this field type.
*/
protected defaultSearchFilterComponent(): string | null;
/**
* Default search props derived from FieldType config.
*/
protected defaultSearchFilterComponentProps(_options: FieldRenderOptions): Record<string, unknown>;
protected fieldLabel(): string;
/**
* Converts a raw database value into app memory.
*/
protected fromDbValue(input: TDbValue): TValue;
/**
* Converts an app-memory value into database storage form.
*/
protected toDbValue(input: TValue, _options?: DatabaseValueOptions): TDbValue;
/**
* Converts a hydrated backend value into frontend/form display data.
*/
protected toDisplayValue(input: TValue): TDisplayValue;
/**
* Collects validation errors for this field state.
*
* Concrete fields should call `super.collectErrors()` then append their own
* errors.
*/
protected collectErrors(state: TState): Promise<FieldError[]>;
/**
* Tests whether a value should count as empty for required validation.
*/
protected isEmpty(value: unknown): boolean;
/**
* Returns the database schema default implied by the runtime field default.
*/
protected getDbDefaultValue(): unknown;
/**
* Context for this bound field.
*/
protected get context(): FieldContext;
/**
* Dialect for schema generation, falling back to the configured connection.
*/
protected schemaDialect(): DatabaseDialect;
/**
* Returns schema metadata and optionally writes columns onto `ctx.table`.
*/
protected completeDbSchema(part: DbSchemaPart, ctx?: FieldContext): DbSchemaPart;
/**
* State for this bound field.
*/
protected get state(): TState;
/**
* Attaches this field instance to a model without creating record state.
*/
bindToModel(model: ModelMetadata, fieldName: string): this;
/**
* Returns an unbound copy of this field definition.
*/
clone(): this;
/**
* Returns a cloned field definition with config overrides applied.
*/
withConfig(config: Partial<FieldConfig>): this;
/**
* Attaches this field instance to a concrete ActiveRecord instance.
*/
bindToRecord(record: unknown, fieldName: string): this;
bindToRecord(model: ModelMetadata, record: unknown, fieldName: string): this;
protected resolveDbWriteArgs(ctxOrOptions: FieldContext | DbWriteOptions, options?: DbWriteOptions): {
ctx?: FieldContext;
options: DbWriteOptions;
};
/**
* We are trying to deprecate this function in favour of using object functions like this.get
* @param ctx @deprecated this.schemaDialect()
* @returns
*/
protected withContext<TResult>(ctx: FieldContext | undefined, callback: () => TResult): TResult;
private modelFromRecord;
private requireModel;
private requireFieldName;
/**
* Resolves the configured default value.
*/
private getDefaultValue;
}
export type FieldValue<TField> = TField extends FieldType<infer TValue, any, any, any, any> ? TValue : never;
export type FieldDbValue<TField> = TField extends FieldType<any, infer TDbValue, any, any, any> ? TDbValue : never;
export type FieldDisplayValue<TField> = TField extends FieldType<any, any, infer TDisplayValue, any, any> ? TDisplayValue : never;
export type FieldInputValue<TField> = TField extends FieldType<any, any, any, infer TInput, any> ? TInput : never;