UNPKG

mevn-orm

Version:
99 lines (98 loc) 2.92 kB
/** * Lazy relation query wrapper backed by Knex. * * Relation instances are {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise | Promise-like}: * `await farmer.profile()` auto-executes the query. Chain `where()` before awaiting * to refine the query, or call `first()` / `get()` explicitly. */ class Relation { Related; query; constructor(Related, query) { this.Related = Related; this.query = query; } /** * Appends a `where` constraint to the underlying Knex query. * * @param args - Knex `where` arguments (object or column/value pairs). * @returns This relation instance for chaining. */ where(...args) { this.query?.where(...args); return this; } /** * Executes the relation query and returns the first matching related model. * * @param columns - Columns to select (default `'*'`). * @returns Related model instance, or `null` when no row matches. */ async first(columns = '*') { if (!this.query) { return null; } const row = await this.query.first(columns); if (!row) { return null; } const related = new this.Related(row); return related.stripColumns(related); } /** * Executes the relation query and returns all matching related models. * * @param columns - Columns to select (default `'*'`). * @returns Array of related model instances (empty when no rows match). */ async get(columns = '*') { if (!this.query) { return []; } const rows = await this.query.select(columns); return rows.map((row) => { const related = new this.Related(row); return related.stripColumns(related); }); } /** * Allows `await relation` without calling `first()` or `get()` explicitly. * * @param onFulfilled - Success callback. * @param onRejected - Error callback. */ then(onFulfilled, onRejected) { return this.resolve().then(onFulfilled, onRejected); } } /** * One-to-one relation. Awaiting resolves to a single related model or `null`. * * @typeParam T - Related model instance type. */ class HasOneRelation extends Relation { resolve() { return this.first(); } } /** * One-to-many relation. Awaiting resolves to an array of related models. * * @typeParam T - Related model instance type. */ class HasManyRelation extends Relation { resolve() { return this.get(); } } /** * Inverse belongs-to relation. Awaiting resolves to the parent model or `null`. * * @typeParam T - Related model instance type. */ class BelongsToRelation extends Relation { resolve() { return this.first(); } } export { Relation, HasOneRelation, HasManyRelation, BelongsToRelation, };