Functions

@system-inc/base-foundation · 515c140 · 78 symbols

and

function
and(...conditions: (OrmFilter<T>)[]): OrmAndFilter<T>

View source ↗

between

function
between(min: T, max: T): OrmBetweenFilter<T>

View source ↗

checkSchemaSet(tables: OrmTableMetadata[], dialect: "sqlite" | "mysql"): void

View source ↗

checkTableSchema(tableMeta: OrmTableMetadata, _dialect: "sqlite" | "mysql"): void

View source ↗

columnFiltersToFindOperators(filters: ColumnFilterInput[]): object

View source ↗

entityAfterDelete(entities: readonly OrmTrackingEntity[], metadata: OrmTableMetadata): void

View source ↗

entityAfterInsert(entities: readonly OrmTrackingEntity[], metadata: OrmTableMetadata): void

View source ↗

entityAfterUpdate(entities: readonly OrmTrackingEntity[], metadata: OrmTableMetadata): void

View source ↗

entityBeforeDelete(entities: readonly OrmTrackingEntity[], metadata: OrmTableMetadata): void

View source ↗

entityBeforeInsert(entities: readonly OrmTrackingEntity[], metadata: OrmTableMetadata): void

View source ↗

entityBeforeUpdate(entities: readonly OrmTrackingEntity[], metadata: OrmTableMetadata): void

View source ↗

equals

function
equals(value: T): OrmEqualsFilter<T>

View source ↗

exists

function
exists(value: any): OrmExistsFilter

View source ↗

Renders findings as an error a human can act on without opening MySQL docs: which index, how far over, which column is carrying the weight, and the character count that would fit.

formatIndexKeyLengthFindings(findings: OrmIndexKeyLengthFinding[]): string

View source ↗

Every SET column value on the entity — the field set insert/upsert persist. Dirty tracking (getChangedFields) is an UPDATE optimization: driving insert with it silently dropped the values of clean entities (a clone()d or hydrated entity carries its data in the value slots with an empty dirty set), storing NULL rows.

getInsertValues(entity: EntityType, metadata: OrmTableMetadata): OrmPartialEntity<EntityType>

View source ↗

Get all primary key columns from the primary key info

getPrimaryKeyColumns(primaryKey?: OrmPrimaryKeyInfo): string[]

View source ↗

getPrimaryKeyConditions(entity: EntityType, metadata: OrmTableMetadata): OrmPartialEntity<EntityType>

View source ↗

Get the property keys of all primary key columns

getPrimaryKeyPropertyKeys(metadata: OrmTableMetadata): string[]

View source ↗

Calculates the timezone offset in minutes for a given IANA timezone at a specific point in time. Uses Intl.DateTimeFormat so DST transitions are handled correctly. Shared by the dialect adapters' time-series bucketing.

getTimezoneOffsetMinutes(timeZone: string, epochSec: number): number
  • timeZone

    IANA timezone string (e.g., 'America/New_York')

  • epochSec

    Unix timestamp in seconds

ReturnsOffset in minutes, matching `Date.getTimezoneOffset()` convention (positive = behind UTC, negative = ahead of UTC)

View source ↗

Splits [startEpochSec, endEpochSec) into segments of constant UTC offset for the zone — one segment per side of each DST transition. Bucketing with a single offset frozen at range start put every post-transition row in the wrong local bucket for part of the day; the adapters compile these segments into a per-row CASE instead. Transition instants are located by bisection (to the minute), so a multi-year range costs a handful of offset lookups per transition.

getTimezoneOffsetSegments(timeZone: string, startEpochSec: number, endEpochSec: number): TimezoneOffsetSegment[]

View source ↗

gt

function
gt(value: T): OrmGtFilter<T>

View source ↗

gte

function
gte(value: T): OrmGteFilter<T>

View source ↗

Check if the table has any primary key columns

hasPrimaryKey(metadata: OrmTableMetadata): boolean

View source ↗

inArray

function
inArray(value: T[]): OrmInArrayFilter<T>

View source ↗

isColumnKind

function
isColumnKind(meta: OrmColumnMetadata, kind: K): meta is OrmColumnMetadataOf<K>

View source ↗

Check if a column is part of the primary key

isColumnPrimaryKey(primaryKey: OrmPrimaryKeyInfo | undefined, column: string): boolean

View source ↗

isDurableAdapter(adapter: OrmAdapter): adapter is OrmDurableAdapter

View source ↗

isDurableObjectStorage(storage: any): storage is DurableObjectStorage

View source ↗

isNotNull

function
isNotNull(): OrmIsNotNullFilter

View source ↗

isNull

function
isNull(): OrmIsNullFilter

View source ↗

isOrmAdapterProvider(provider: unknown): provider is OrmAdapterProvider<OrmSettings<"drizzle">, "drizzle", OrmAdapter>

View source ↗

isOrmFilter

function

Type guard to check if a value is an ORM filter

isOrmFilter(value: any): value is OrmFilter<any>

View source ↗

isOrmSettingsBetterSQLite(settings: OrmSettings<A>): settings is OrmSettingsBetterSQLite<A>

View source ↗

isOrmSettingsD1(settings: OrmSettings<A>): settings is OrmSettingsD1<A>

View source ↗

isOrmSettingsDurableSQLite(settings: OrmSettings<A>): settings is OrmSettingsDurableSQLite<A>

View source ↗

isOrmSettingsPlanetScale(settings: OrmSettings<A>): settings is OrmSettingsPlanetScale<A>

View source ↗

isParentColumnReference(value: unknown): value is OrmParentColumnReference

View source ↗

like

function
like(pattern: string): OrmLikeFilter

View source ↗

lt

function
lt(value: T): OrmLtFilter<T>

View source ↗

lte

function
lte(value: T): OrmLteFilter<T>

View source ↗

not

function
not(value: OrmFilter<T>): OrmNotFilter<T>

View source ↗

notBetween

function
notBetween(min: T, max: T): OrmNotBetweenFilter<T>

View source ↗

notEquals

function
notEquals(value: T): OrmNotEqualsFilter<T>

View source ↗

notExists

function
notExists(value: any): OrmNotExistsFilter

View source ↗

notInArray

function
notInArray(value: T[]): OrmNotInArrayFilter<T>

View source ↗

notLike

function
notLike(pattern: string): OrmNotLikeFilter

View source ↗

or

function
or(...conditions: (OrmFilter<T>)[]): OrmOrFilter<T>

View source ↗

ormAddColumn

function
ormAddColumn(ctor: Constructor, propertyKey: string, type: OrmColumnType, options?: OrmColumnOptions): void

View source ↗

Adds a single column index with auto-generated name if not provided

ormAddColumnIndex(ctor: AnyClass, propertyKey: string, customName?: string): void

View source ↗

Adds a single column unique constraint with auto-generated name if not provided

ormAddColumnUnique(ctor: AnyClass, propertyKey: string, customName?: string): void

View source ↗

Adds a single column unique index with auto-generated name if not provided This creates a unique index (different from unique constraint)

ormAddColumnUniqueIndex(ctor: AnyClass, propertyKey: string, customName?: string): void

View source ↗

ormAddDateColumn(ctor: Constructor, event: OrmDateEventType, propertyKey: string, options?: OrmColumnOptions): void

View source ↗

ormAddIndex

function

Adds an index to a table with optional auto-generated name

ormAddIndex(ctor: AnyClass, name: string | undefined, columns: OrmIndexColumn[], options?: OrmTableIndexOptions): void
  • ctor

    The entity class constructor

  • name

    Optional custom name. If not provided, will be auto-generated as ix_<table>_<cols> or ux_<table>_<cols>

  • columns

    The columns to include in the index

  • options

    Additional index options (e.g., unique)

View source ↗

ormAddJoinColumn(ctor: Constructor, propertyKey: string, options?: OrmJoinColumnOptions): void

View source ↗

ormAddListener(ctor: Constructor, event: OrmListenerEventType, methodName: string): void

View source ↗

ormAddPrimaryAutoColumn(ctor: Constructor, propertyKey: string, strategy: "uuid" | "serial", size?: OrmIntegerSizeType): void

View source ↗

ormAddPrimaryKey(ctor: AnyClass, columns: string[], options?: OrmPrimaryKeyOptions): void

View source ↗

ormAddRelation(ctor: Constructor, relation: OrmRelationMetadata): void

View source ↗

ormAddTable

function
ormAddTable(ctor: Constructor, name?: string, options?: OrmTableOptions): void

View source ↗

ormAddUniqueConstraint(ctor: AnyClass, columns: string[], name?: string): void

View source ↗

Checks every index a table declares against InnoDB's key-length ceiling, BEFORE any SQL is generated.

This exists because the failure it catches is invisible everywhere else in the pipeline. The entity decorators accept @OrmTableIndex(['title']) without consulting @OrmColumn's length, the schema builder emits a valid index('...').on(...), drizzle-kit writes a syntactically perfect CREATE INDEX, and the whole thing looks correct on disk. The error surfaces only when MySQL refuses the statement — and drizzle-kit migrate reports that refusal by exiting 1 with nothing but a spinner on stdout, against whichever database was unlucky enough to run it first.

Worse, the DDL that already succeeded stays applied: MySQL auto-commits each statement, so a migration that dies halfway leaves the database in a state no migration ledger records. We shipped exactly that and it cost a day of archaeology across three databases to reconstruct.

Pure arithmetic over metadata, so it runs offline at generate time with no database connection.

ormCheckIndexKeyLength(tableMetadata: OrmTableMetadata): OrmIndexKeyLengthFinding[]

View source ↗

Creates an OrmDatabase for a PlanetScale database outside of a worker's dependency-injection container. Intended for tooling that talks to the database directly with an explicit entity list — most notably integration-test helpers (see test/IntegrationTestClient.getOrmDatabase). Workers should always resolve their databases through DI (@InjectDatabase) instead.

ormCreatePlanetScaleDatabase(options: { databaseName?: string; entities: OrmEntityClass[]; logging?: boolean; url: string }): OrmDatabase

View source ↗

Extracts the string values from an enum column's values option. Accepts an explicit value list or an enum object; for the object form only string values are kept, so enums merged with a namespace of helper functions contribute just their actual values.

ormEnumStringValues(values: string[] | Record<string, unknown>): string[]

View source ↗

ormGetEnvironmentCredentials(database: string, configuration: BaseConfiguration, settings: OrmSettingsType): OrmCredentials

View source ↗

ormGetTable

function
ormGetTable(ctor: Constructor): OrmTableMetadata | undefined

View source ↗

Whether ctor (or a base class — reflect-metadata inherits constructor injection metadata through the prototype chain, so the subclass injects too) has a token-less ORM injection.

ormHasTokenlessInjection(ctor: AnyClass): boolean

View source ↗

The byte width MySQL reserves for one column inside an index key.

Returns undefined for a TEXT column, which cannot be indexed at all without an explicit prefix length — a different failure from "too wide", reported separately so the message can say the useful thing.

ormIndexColumnKeyBytes(columnType: OrmColumnType): number | undefined

View source ↗

The property name an index column refers to, whichever form it takes.

ormIndexColumnName(indexColumn: OrmIndexColumn): string

View source ↗

The prefix length, or undefined when the whole column is indexed.

ormIndexColumnPrefixLength(indexColumn: OrmIndexColumn): number | undefined

View source ↗

ormIsAdapterOptions(obj: unknown): obj is OrmAdapterOptions

View source ↗

Whether a failed write was rejected by a unique index, as opposed to failing for any of the reasons a write fails when the database is unwell.

The distinction is what makes a unique index usable as a race arbiter. A caller that inserts and catches everything as "someone else won" carries on as though another writer succeeded - but in a connection reset, a timeout, or a throttle nobody did, the row is still unclaimed, and the next attempt takes the same branch and fails the same way. One transient fault becomes a fault per attempt for as long as the condition lasts, which is precisely when the database is least able to absorb it.

Matched on the driver's own vocabulary rather than a wrapped error type, because nothing between a caller and the driver classifies it: the repository and the adapters pass the raw failure straight through.

The text match is the load-bearing branch, not the fallback. PlanetScale answers over HTTP through Vitess, and what arrives is one string with the code inside it rather than a structured field:

DatabaseError: target: db.-.primary: vttablet: rpc error:
code = AlreadyExists desc = Duplicate entry 'x' for key 'y' (errno 1062)

so errno is prose here and a property check alone would never fire. The property checks cover the drivers that do populate them - mysql2 sets ER_DUP_ENTRY, SQLite sets SQLITE_CONSTRAINT_UNIQUE - and the cause chain is walked because drivers wrap.

ormIsUniqueConstraintViolation(error: unknown): boolean

View source ↗

called by the token-less ORM inject decorators

ormMarkTokenlessInjection(ctor: AnyClass): void

View source ↗

Creates a paginated find query for the given entity.

Where conditions AND-merge across all sources, with server conditions winning over client filters on key collision: client pagination.filters < pagination.scopeWhere(...) < input.where.

Ordering uses the pagination orderBy when present, otherwise input.order.

ormPaginatedFind(input: OrmPaginatedFindOptions<EntityType>): Promise<PaginationResult<EntityType>>

View source ↗

ormRequireTable(entity: Constructor): OrmTableMetadata

View source ↗

Migration runner for Durable SQLite databases.

Runs all pending migrations sequentially, with each migration getting its own blockConcurrencyWhile call for race condition protection and independent 30-second timeout budgets. Errors are fail-fast with automatic retry on next access.

Before judging drift, applied rows carrying an obsolete label — the placeholder tags the tracking-table schema upgrade synthesizes, or a content hash an older runner recorded — are reconciled back to their journal tag by exact createdAt match and rewritten in place, so a DO that lived through the legacy schema keeps booting in every environment.

In Development, detects "journal drift" — applied migration tags that no longer exist in source (which happens after schema:diff auto-folds an unreleased migration). When drift is detected, wipes the DO's user tables and the migrations tracking table, then reapplies from scratch. This makes iteration on a single growing unreleased migration seamless — local DOs don't accumulate stale schema.

In non-Development, the same drift situation is a hard error (this function only sees the situation after the caller's released-list check passes, so drift in prod is an integrity bug).

ormRunPendingMigrations(durableState: DurableObjectState, db: DrizzleSqliteDODatabase<TSchema>, config: DrizzleMigrationConfig, migrationsTable: string, options: { isDevelopment?: boolean }): Promise<void>

View source ↗

parentColumn

function

Creates a OrmParentColumnReference for use in a mapped join's where.

parentColumn(column: string): OrmParentColumnReference

View source ↗

mode is required on bigint, decimal, and datetime columns — the type system enforces it for TypeScript consumers; this guards JavaScript callers and stale metadata with the same loud failure at schema-build time instead of silently picking a representation.

requireColumnMode(meta: OrmColumnMetadata, allowedModes: readonly ModeType[]): ModeType

View source ↗

Throws if the table is not marked truncatable: true in its @OrmTable() options. Called before any truncate() operation to prevent accidental full-table wipes on tables that weren't designed to be wiped.

requireTruncatable(metadata: OrmTableMetadata): void

View source ↗