UNPKG

@lordfokas/magic-orm

Version:

A class-based ORM in TypeScript. Unorthodox and extremely opinionated, made to fit my specific use cases.

110 lines (109 loc) 6.8 kB
import { Logger } from '@lordfokas/loggamus'; import { type Connection } from './DB.js'; import { SelectBuilder, type Filter } from './QueryBuilder.js'; import { Class, NS, UUID, SkipUUID, NamespacedUUID, EntityConfig, Primitive, TableFields } from './Structures.js'; import { Serializer } from './Serializer.js'; /** Define a new logger to send output to */ export declare function useLogger(logger: Logger): void; type EClass<T> = typeof Entity & Class<T>; export type FieldSet<T extends typeof Entity> = keyof (T["$config"]["fields"]) & keyof TableFields; export type Inflate<T extends typeof Entity> = keyof (T["$config"]["inflates"]); export declare class Entity { #private; static readonly Serializer: typeof Serializer; static readonly $config: EntityConfig; uuid?: UUID<NS>; /** Create link-expansion relationships between entities. */ static link(child: typeof Entity, parent?: typeof Entity): { to: (...ps: (typeof Entity)[]) => any; }; /** Apply an async function to every link of this Entity */ static forEachLink(entity: Entity, fn: (x: typeof Entity) => Promise<any>): Promise<void>; /** Apply an async function to every expansion of this Entity */ static forEachExpand(entity: Entity, fn: (x: typeof Entity) => Promise<any>): Promise<void>; /** Create an Entity in the database, along with all dependencies and relationships. */ static createComposite(db: Connection, entity: Entity, skip: SkipUUID): Promise<void>; /** Query and inflate Entities. This entails recursion and complexity */ static inflate<C extends EClass<any>>(this: C, db: false, inflate: Inflate<C>, ...params: Primitive[]): Promise<SelectBuilder>; static inflate<C extends EClass<any>>(this: C, db: Connection, inflate: Inflate<C>, ...params: Primitive[]): Promise<InstanceType<C>[]>; /** Recursively build parent entities from joined tables in the query */ private static recursiveLink; /** * Recursively build child entities by querying the database again and awaiting results. * Also applies to children of linked parent entities, including self. */ private recursiveExpand; /** Get one entity from this table, by UUID. */ static uuid<K extends NS, T extends NamespacedUUID<K>, C extends EClass<T>, I extends InstanceType<C>>(this: C, db: Connection, uuid: UUID<K>, select?: FieldSet<C>): Promise<I[]>; /** Get all the entities from this table */ static all<K extends NS, T extends NamespacedUUID<K>, C extends EClass<T>, I extends InstanceType<C>>(this: C, db: Connection, select?: FieldSet<C>): Promise<I[]>; /** Get all entities from this table where {field} is in {list}. */ static in<K extends NS, T extends NamespacedUUID<K>, C extends EClass<T>, I extends InstanceType<C>>(this: C, db: Connection, field: string, list: Primitive[], select?: FieldSet<C>): Promise<I[]>; /** Insert all Entities in the given list as a single query. All Entities must be of this type. */ static bulkInsert<C extends EClass<any>>(this: C, db: Connection, entities: InstanceType<C>[]): Promise<any>; /** Create one or more Entities in the database. If many, a bulk query is written. */ static create<C extends EClass<any>>(this: C, db: Connection, ...entities: InstanceType<C>[]): Promise<any>; /** Update one or more database rows with the data contained in this Entity */ static update<C extends EClass<any>>(this: C, db: Connection, entity: InstanceType<C>, update?: FieldSet<C>, filters?: Filter[]): Promise<any>; /** Read one or more records from the database. If Connection === false returns the query builder instead */ static read<C extends EClass<any>>(this: C, db: false, select?: FieldSet<C>, filters?: Filter[]): Promise<SelectBuilder>; static read<C extends EClass<any>>(this: C, db: Connection, select?: FieldSet<C>, filters?: Filter[]): Promise<InstanceType<C>[]>; /** Get a SelectBuilder for a set of columns and filters */ static select<C extends EClass<any>>(this: C, select?: FieldSet<C>, filters?: Filter[]): SelectBuilder; /** Build an Entity from a given object */ constructor(obj?: object); /** * Build an Entity from a database row. * Scans this row for fields that belong to the same table as this object. * Any matching fields are injected into the object. * This is done by expecting fields to be prefixed with the table's 2-letter code. */ private $ingest; /** Use this entity as a link (instance of parent entity) */ private useLink; /** Use this entity as an expand (instance of child entity) */ private useExpand; /** Generate a UUID for this Entity. Will fail if the field is already filled. */ protected generateUUID(): void; /** Generate a zero UUID for this Entity. Will fail if the field is already filled. */ protected generateZERO(): void; /** Get the list of fields in this Entity, with UUIDs in front and sorted */ private prioritizeUUIDs; /** * Insert this Entity into the database. * If skip isn't present, a UUID will be generated automatically. */ insert(db: Connection, skip?: SkipUUID): Promise<any>; /** * Update this Entity's DB record. Optionally specify a stricter list of fields to update. * Will fail if a UUID isn't present. */ update(db: Connection, fields?: string): Promise<any>; /** Upserts (update or insert) this Entity, depending on wether or not this object has a UUID. */ upsert(db: Connection, fields?: string): Promise<any>; /** * Creates a list of fields for a SELECT query, aliased as XX_col_name * where XX is this table's 2-letter code. */ static ALIAS(...columns: string[]): string; /** Creates a list of fields for a SELECT query */ static COL(...columns: string[]): string; /** Returns this table aliased with its 2-letter code for use in queries. */ static TABLE(): string; /** Generate a zero-filled UUID with an appropriate size for this table's PK. */ protected static ZERO(): UUID<NS>; /** * Generate a UUID with an appropriate size for this table's PK. * A different generator can be provided, default is UUID v4. */ protected static UUID(gen?: () => string): UUID<NS>; /** Transforms a JSON structure into concrete entities */ static fromJSON<T extends Entity>(this: EClass<T>, data: string): T; /** Transforms an object into concrete entities */ static fromObject<T extends Entity>(this: EClass<T>, data: object): T; /** Validate that a type has a correct structure */ protected static $validateOwnType<T extends Entity>(this: EClass<T>, obj: T): void; /** Shortcut to get the class config from an instance */ private get $config(); } export {};