@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
TypeScript
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 {
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 {};