Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@athenna/database

Package Overview
Dependencies
Maintainers
1
Versions
205
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@athenna/database - npm Package Compare versions

Comparing version
5.54.0
to
5.55.0
+15
src/models/annotations/HasManyThrough.d.ts
/**
* @athenna/database
*
* (c) João Lenon <lenon@athenna.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import 'reflect-metadata';
import type { BaseModel } from '#src/models/BaseModel';
import type { HasManyThroughOptions } from '#src/types/relations/HasManyThroughOptions';
/**
* Create has many through relation for model class.
*/
export declare function HasManyThrough<T extends BaseModel = any, R extends BaseModel = any, H extends BaseModel = any>(model: (() => new () => R) | string, through: (() => new () => H) | string, options?: Omit<HasManyThroughOptions<T, R, H>, 'type' | 'model' | 'through' | 'property'>): (target: T, key: any) => void;
/**
* @athenna/database
*
* (c) João Lenon <lenon@athenna.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import 'reflect-metadata';
import { debug } from '#src/debug';
import { Annotation } from '#src/helpers/Annotation';
import { Is, Options } from '@athenna/common';
/**
* Create has many through relation for model class.
*/
export function HasManyThrough(model, through, options = {}) {
return (target, key) => {
const Target = target.constructor;
options = Options.create(options, {
isIncluded: false,
inverse: false
});
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
options.type = 'hasManyThrough';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
options.model = Is.String(model)
? () => ioc.safeUse(`App/Models/${model}`).constructor
: model;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
options.through = Is.String(through)
? () => ioc.safeUse(`App/Models/${through}`).constructor
: through;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
options.property = key;
debug('registering hasManyThrough metadata for model %s: %o', Target.name, options);
Annotation.defineHasManyThroughMeta(Target, options);
};
}
/**
* @athenna/database
*
* (c) João Lenon <lenon@athenna.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import 'reflect-metadata';
import type { BaseModel } from '#src/models/BaseModel';
import type { HasOneThroughOptions } from '#src/types/relations/HasOneThroughOptions';
/**
* Create has one through relation for model class.
*/
export declare function HasOneThrough<T extends BaseModel = any, R extends BaseModel = any, H extends BaseModel = any>(model: (() => new () => R) | string, through: (() => new () => H) | string, options?: Omit<HasOneThroughOptions<T, R, H>, 'type' | 'model' | 'through' | 'property'>): (target: T, key: any) => void;
/**
* @athenna/database
*
* (c) João Lenon <lenon@athenna.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import 'reflect-metadata';
import { debug } from '#src/debug';
import { Annotation } from '#src/helpers/Annotation';
import { Is, Options } from '@athenna/common';
/**
* Create has one through relation for model class.
*/
export function HasOneThrough(model, through, options = {}) {
return (target, key) => {
const Target = target.constructor;
options = Options.create(options, {
isIncluded: false,
inverse: false
});
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
options.type = 'hasOneThrough';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
options.model = Is.String(model)
? () => ioc.safeUse(`App/Models/${model}`).constructor
: model;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
options.through = Is.String(through)
? () => ioc.safeUse(`App/Models/${through}`).constructor
: through;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
options.property = key;
debug('registering hasOneThrough metadata for model %s: %o', Target.name, options);
Annotation.defineHasOneThroughMeta(Target, options);
};
}
/**
* @athenna/database
*
* (c) João Lenon <lenon@athenna.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import type { BaseModel } from '#src/models/BaseModel';
import type { HasManyThroughOptions } from '#src/types';
import type { Driver } from '#src/database/drivers/Driver';
export declare class HasManyThroughRelation {
/**
* Get the options with defined default values.
*/
static options(Parent: typeof BaseModel, relation: HasManyThroughOptions): HasManyThroughOptions;
/**
* Load a has many through relation.
*/
static load(model: BaseModel, relation: HasManyThroughOptions): Promise<any>;
/**
* Load all models that has many through relation.
*/
static loadAll(models: BaseModel[], relation: HasManyThroughOptions): Promise<any[]>;
/**
* Apply a where has relation to the query when the given model
* has many through relations.
*/
static whereHas(Model: typeof BaseModel, query: Driver, relation: HasManyThroughOptions): void;
}
/**
* @athenna/database
*
* (c) João Lenon <lenon@athenna.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { String } from '@athenna/common';
export class HasManyThroughRelation {
/**
* Get the options with defined default values.
*/
static options(Parent, relation) {
const Through = relation.through();
const Final = relation.model();
relation.localKey =
relation.localKey || Parent.schema().getMainPrimaryKeyProperty();
relation.firstKey =
relation.firstKey || `${String.toCamelCase(Parent.name)}Id`;
if (relation.inverse) {
relation.secondLocalKey =
relation.secondLocalKey || `${String.toCamelCase(Final.name)}Id`;
relation.secondKey =
relation.secondKey || Final.schema().getMainPrimaryKeyProperty();
}
else {
relation.secondLocalKey =
relation.secondLocalKey || Through.schema().getMainPrimaryKeyProperty();
relation.secondKey =
relation.secondKey || `${String.toCamelCase(Through.name)}Id`;
}
return relation;
}
/**
* Load a has many through relation.
*/
static async load(model, relation) {
this.options(model.constructor, relation);
const throughRows = await relation
.through()
.query()
.where(relation.firstKey, model[relation.localKey])
.findMany();
const linkValues = throughRows
.map(r => r[relation.secondLocalKey])
.filter(v => v !== undefined && v !== null);
if (!linkValues.length) {
model[relation.property] = [];
return model;
}
model[relation.property] = await relation
.model()
.query()
.whereIn(relation.secondKey, linkValues)
.when(relation.withClosure, relation.withClosure)
.findMany();
return model;
}
/**
* Load all models that has many through relation.
*/
static async loadAll(models, relation) {
if (!models.length) {
return models;
}
this.options(models[0].constructor, relation);
const Final = relation.model();
const finalPK = Final.schema().getMainPrimaryKeyProperty();
const parentValues = models.map(m => m[relation.localKey]);
const throughRows = await relation
.through()
.query()
.whereIn(relation.firstKey, parentValues)
.findMany();
const parentToLinks = new Map();
const allLinks = [];
for (const t of throughRows) {
const link = t[relation.secondLocalKey];
if (link === undefined || link === null) {
continue;
}
allLinks.push(link);
const arr = parentToLinks.get(t[relation.firstKey]) || [];
arr.push(link);
parentToLinks.set(t[relation.firstKey], arr);
}
const finals = allLinks.length
? await relation
.model()
.query()
.whereIn(relation.secondKey, allLinks)
.when(relation.withClosure, relation.withClosure)
.findMany()
: [];
const linkToFinals = new Map();
for (const f of finals) {
const arr = linkToFinals.get(f[relation.secondKey]) || [];
arr.push(f);
linkToFinals.set(f[relation.secondKey], arr);
}
return models.map(m => {
const links = parentToLinks.get(m[relation.localKey]) || [];
const collected = [];
const seen = new Set();
for (const link of links) {
const matches = linkToFinals.get(link) || [];
for (const f of matches) {
const pk = f[finalPK];
if (seen.has(pk)) {
continue;
}
seen.add(pk);
collected.push(f);
}
}
m[relation.property] = collected;
return m;
});
}
/**
* Apply a where has relation to the query when the given model
* has many through relations.
*/
static whereHas(Model, query, relation) {
this.options(Model, relation);
const Through = relation.through();
const Final = relation.model();
const modelTable = Model.table();
const throughTable = Through.table();
const finalTable = Final.table();
const modelLocal = Model.schema().getColumnNameByProperty(relation.localKey) ||
Model.schema().getMainPrimaryKeyName();
const throughFK = Through.schema().getColumnNameByProperty(relation.firstKey) ||
Through.schema().getColumnNameByProperty(`${String.toCamelCase(Model.name)}Id`);
const throughLink = Through.schema().getColumnNameByProperty(relation.secondLocalKey);
const finalLink = Final.schema().getColumnNameByProperty(relation.secondKey);
let outerWhereRaw = `${throughTable}.${throughFK} = ${modelTable}.${modelLocal}`;
switch (Through.schema().getModelDriverName()) {
case 'sqlite':
case 'postgres':
outerWhereRaw = `"${throughTable}"."${throughFK}" = "${modelTable}"."${modelLocal}"`;
}
Through.query()
.setDriver(query, throughTable)
.whereRaw(outerWhereRaw)
.whereExists(innerQuery => {
let innerWhereRaw = `${finalTable}.${finalLink} = ${throughTable}.${throughLink}`;
switch (Final.schema().getModelDriverName()) {
case 'sqlite':
case 'postgres':
innerWhereRaw = `"${finalTable}"."${finalLink}" = "${throughTable}"."${throughLink}"`;
}
Final.query()
.setDriver(innerQuery, finalTable)
.whereRaw(innerWhereRaw)
.when(relation.closure, relation.closure);
});
}
}
/**
* @athenna/database
*
* (c) João Lenon <lenon@athenna.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import type { BaseModel } from '#src/models/BaseModel';
import type { HasOneThroughOptions } from '#src/types';
import type { Driver } from '#src/database/drivers/Driver';
export declare class HasOneThroughRelation {
/**
* Load a has one through relation.
*/
static load(model: BaseModel, relation: HasOneThroughOptions): Promise<any>;
/**
* Load all models that has one through relation.
*/
static loadAll(models: BaseModel[], relation: HasOneThroughOptions): Promise<any[]>;
/**
* Apply a where has relation to the query when the given model
* has one through relation.
*/
static whereHas(Model: typeof BaseModel, query: Driver, relation: HasOneThroughOptions): void;
}
/**
* @athenna/database
*
* (c) João Lenon <lenon@athenna.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { HasManyThroughRelation } from '#src/models/relations/HasManyThrough/HasManyThroughRelation';
export class HasOneThroughRelation {
/**
* Load a has one through relation.
*/
static async load(model, relation) {
await HasManyThroughRelation.load(model, relation);
const arr = model[relation.property] || [];
model[relation.property] = arr[0] ?? null;
return model;
}
/**
* Load all models that has one through relation.
*/
static async loadAll(models, relation) {
const result = await HasManyThroughRelation.loadAll(models, relation);
return result.map(m => {
const arr = m[relation.property] || [];
m[relation.property] = arr[0] ?? null;
return m;
});
}
/**
* Apply a where has relation to the query when the given model
* has one through relation.
*/
static whereHas(Model, query, relation) {
return HasManyThroughRelation.whereHas(Model, query, relation);
}
}
/**
* @athenna/database
*
* (c) João Lenon <lenon@athenna.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import type { ModelColumns } from '#src/types';
import type { BaseModel } from '#src/models/BaseModel';
import type { ModelQueryBuilder } from '#src/models/builders/ModelQueryBuilder';
export type HasManyThroughOptions<T extends BaseModel = any, R extends BaseModel = any, H extends BaseModel = any> = {
/**
* The relation option type.
*
* @readonly
* @default 'hasManyThrough'
*/
type?: 'hasManyThrough';
/**
* The closure that should be executed while
* querying the relation data from database.
*
* Used by `whereHas()` for the WHERE EXISTS subquery.
*
* @default undefined
*/
closure?: (query: ModelQueryBuilder<R>) => any;
/**
* The closure provided to `with()` for eager loading.
* Kept separate from {@link closure} so that a `whereHas()` call
* on the same relation never overwrites the eager-load filter.
*
* @default undefined
*/
withClosure?: (query: ModelQueryBuilder<R>) => any;
/**
* The property name in class of the relation.
*
* @readonly
* @default key
*/
property?: string;
/**
* The final relation model that is being referenced
* through the intermediate model.
*
* @readonly
*/
model?: () => typeof BaseModel;
/**
* The intermediate model used to traverse from the
* parent model to the final relation model.
*
* @readonly
*/
through?: () => typeof BaseModel;
/**
* Set if the model will be included when fetching
* data.
* If this option is true, you don't need to call
* methods like `with()` to eager load your relation.
*
* @default false
*/
isIncluded?: boolean;
/**
* Internal flag when `whereHas()` applies a constraint on this relation.
* Does not eager-load; use {@link isIncluded} / `with()` to load related rows.
*
* @default false
*/
isWhereHasIncluded?: boolean;
/**
* The column on the parent model that links to the
* intermediate model via {@link firstKey}.
*
* @default Model.schema().getMainPrimaryKeyProperty()
*/
localKey?: ModelColumns<T>;
/**
* The column on the intermediate model that points
* back at the parent model.
*
* @default `${String.toCamelCase(Model.name)}Id`
*/
firstKey?: ModelColumns<H>;
/**
* The column on the intermediate model that participates
* in the link to the final model.
*
* - Shape A (default): `Through.schema().getMainPrimaryKeyProperty()`
* - Shape B (`inverse: true`): `${String.toCamelCase(Final.name)}Id`
*/
secondLocalKey?: ModelColumns<H>;
/**
* The column on the final model that participates
* in the link to the intermediate model.
*
* - Shape A (default): `${String.toCamelCase(Through.name)}Id`
* - Shape B (`inverse: true`): `Final.schema().getMainPrimaryKeyProperty()`
*/
secondKey?: ModelColumns<R>;
/**
* Flip the defaults so the foreign key linking the
* intermediate model to the final model lives on the
* intermediate model (shape B).
*
* @default false
*/
inverse?: boolean;
};
/**
* @athenna/database
*
* (c) João Lenon <lenon@athenna.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
export {};
/**
* @athenna/database
*
* (c) João Lenon <lenon@athenna.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import type { ModelColumns } from '#src/types';
import type { BaseModel } from '#src/models/BaseModel';
import type { ModelQueryBuilder } from '#src/models/builders/ModelQueryBuilder';
export type HasOneThroughOptions<T extends BaseModel = any, R extends BaseModel = any, H extends BaseModel = any> = {
/**
* The relation option type.
*
* @readonly
* @default 'hasOneThrough'
*/
type?: 'hasOneThrough';
/**
* The closure that should be executed while
* querying the relation data from database.
*
* Used by `whereHas()` for the WHERE EXISTS subquery.
*
* @default undefined
*/
closure?: (query: ModelQueryBuilder<R>) => any;
/**
* The closure provided to `with()` for eager loading.
* Kept separate from {@link closure} so that a `whereHas()` call
* on the same relation never overwrites the eager-load filter.
*
* @default undefined
*/
withClosure?: (query: ModelQueryBuilder<R>) => any;
/**
* The property name in class of the relation.
*
* @readonly
* @default key
*/
property?: string;
/**
* The final relation model that is being referenced
* through the intermediate model.
*
* @readonly
*/
model?: () => typeof BaseModel;
/**
* The intermediate model used to traverse from the
* parent model to the final relation model.
*
* @readonly
*/
through?: () => typeof BaseModel;
/**
* Set if the model will be included when fetching
* data.
* If this option is true, you don't need to call
* methods like `with()` to eager load your relation.
*
* @default false
*/
isIncluded?: boolean;
/**
* Internal flag when `whereHas()` applies a constraint on this relation.
* Does not eager-load; use {@link isIncluded} / `with()` to load related rows.
*
* @default false
*/
isWhereHasIncluded?: boolean;
/**
* The column on the parent model that links to the
* intermediate model via {@link firstKey}.
*
* @default Model.schema().getMainPrimaryKeyProperty()
*/
localKey?: ModelColumns<T>;
/**
* The column on the intermediate model that points
* back at the parent model.
*
* @default `${String.toCamelCase(Model.name)}Id`
*/
firstKey?: ModelColumns<H>;
/**
* The column on the intermediate model that participates
* in the link to the final model.
*
* - Shape A (default): `Through.schema().getMainPrimaryKeyProperty()`
* - Shape B (`inverse: true`): `${String.toCamelCase(Final.name)}Id`
*/
secondLocalKey?: ModelColumns<H>;
/**
* The column on the final model that participates
* in the link to the intermediate model.
*
* - Shape A (default): `${String.toCamelCase(Through.name)}Id`
* - Shape B (`inverse: true`): `Final.schema().getMainPrimaryKeyProperty()`
*/
secondKey?: ModelColumns<R>;
/**
* Flip the defaults so the foreign key linking the
* intermediate model to the final model lives on the
* intermediate model (shape B).
*
* @default false
*/
inverse?: boolean;
};
/**
* @athenna/database
*
* (c) João Lenon <lenon@athenna.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
export {};
+1
-1
{
"name": "@athenna/database",
"version": "5.54.0",
"version": "5.55.0",
"description": "The Athenna database handler for SQL/NoSQL.",

@@ -5,0 +5,0 @@ "license": "MIT",

@@ -12,3 +12,5 @@ /**

export declare const HAS_MANY_KEY = "database:hasMany:options";
export declare const HAS_ONE_THROUGH_KEY = "database:hasOneThrough:options";
export declare const HAS_MANY_THROUGH_KEY = "database:hasManyThrough:options";
export declare const BELONGS_TO_KEY = "database:belongsTo:options";
export declare const BELONGS_TO_MANY_KEY = "database:belongsToMany:options";

@@ -12,3 +12,5 @@ /**

export const HAS_MANY_KEY = 'database:hasMany:options';
export const HAS_ONE_THROUGH_KEY = 'database:hasOneThrough:options';
export const HAS_MANY_THROUGH_KEY = 'database:hasManyThrough:options';
export const BELONGS_TO_KEY = 'database:belongsTo:options';
export const BELONGS_TO_MANY_KEY = 'database:belongsToMany:options';

@@ -9,3 +9,3 @@ /**

*/
import type { RelationOptions, ColumnOptions, HasOneOptions, HasManyOptions, BelongsToOptions, BelongsToManyOptions } from '#src/types';
import type { RelationOptions, ColumnOptions, HasOneOptions, HasManyOptions, HasOneThroughOptions, HasManyThroughOptions, BelongsToOptions, BelongsToManyOptions } from '#src/types';
export declare class Annotation {

@@ -19,2 +19,6 @@ static getColumnsMeta(target: any): ColumnOptions[];

static defineHasManyMeta(target: any, options: HasManyOptions): void;
static getHasOneThroughMeta(target: any): HasOneThroughOptions[];
static defineHasOneThroughMeta(target: any, options: HasOneThroughOptions): void;
static getHasManyThroughMeta(target: any): HasManyThroughOptions[];
static defineHasManyThroughMeta(target: any, options: HasManyThroughOptions): void;
static getBelongsToMeta(target: any): BelongsToOptions[];

@@ -21,0 +25,0 @@ static defineBelongsToMeta(target: any, options: BelongsToOptions): void;

@@ -9,3 +9,3 @@ /**

*/
import { COLUMNS_KEY, HAS_ONE_KEY, HAS_MANY_KEY, BELONGS_TO_KEY, BELONGS_TO_MANY_KEY } from '#src/constants/MetadataKeys';
import { COLUMNS_KEY, HAS_ONE_KEY, HAS_MANY_KEY, HAS_ONE_THROUGH_KEY, HAS_MANY_THROUGH_KEY, BELONGS_TO_KEY, BELONGS_TO_MANY_KEY } from '#src/constants/MetadataKeys';
export class Annotation {

@@ -24,2 +24,4 @@ static getColumnsMeta(target) {

...this.getHasManyMeta(target),
...this.getHasOneThroughMeta(target),
...this.getHasManyThroughMeta(target),
...this.getBelongsToMeta(target),

@@ -45,2 +47,18 @@ ...this.getBelongsToManyMeta(target)

}
static getHasOneThroughMeta(target) {
return Reflect.getMetadata(HAS_ONE_THROUGH_KEY, target) || [];
}
static defineHasOneThroughMeta(target, options) {
const hasOneThrough = Reflect.getMetadata(HAS_ONE_THROUGH_KEY, target) || [];
hasOneThrough.push(options);
Reflect.defineMetadata(HAS_ONE_THROUGH_KEY, hasOneThrough, target);
}
static getHasManyThroughMeta(target) {
return Reflect.getMetadata(HAS_MANY_THROUGH_KEY, target) || [];
}
static defineHasManyThroughMeta(target, options) {
const hasManyThrough = Reflect.getMetadata(HAS_MANY_THROUGH_KEY, target) || [];
hasManyThrough.push(options);
Reflect.defineMetadata(HAS_MANY_THROUGH_KEY, hasManyThrough, target);
}
static getBelongsToMeta(target) {

@@ -47,0 +65,0 @@ return Reflect.getMetadata(BELONGS_TO_KEY, target) || [];

@@ -16,2 +16,4 @@ /**

export * from '#src/models/annotations/HasMany';
export * from '#src/models/annotations/HasOneThrough';
export * from '#src/models/annotations/HasManyThrough';
export * from '#src/models/annotations/BelongsTo';

@@ -18,0 +20,0 @@ export * from '#src/models/annotations/BelongsToMany';

@@ -16,2 +16,4 @@ /**

export * from '#src/models/annotations/HasMany';
export * from '#src/models/annotations/HasOneThrough';
export * from '#src/models/annotations/HasManyThrough';
export * from '#src/models/annotations/BelongsTo';

@@ -18,0 +20,0 @@ export * from '#src/models/annotations/BelongsToMany';

@@ -19,2 +19,4 @@ /**

import { BelongsToManyRelation } from '#src/models/relations/BelongsToMany/BelongsToManyRelation';
import { HasOneThroughRelation } from '#src/models/relations/HasOneThrough/HasOneThroughRelation';
import { HasManyThroughRelation } from '#src/models/relations/HasManyThrough/HasManyThroughRelation';
export class ModelQueryBuilder extends QueryBuilder {

@@ -408,2 +410,6 @@ constructor(model, driver) {

return HasManyRelation.whereHas(this.Model, query, snapshot);
case 'hasOneThrough':
return HasOneThroughRelation.whereHas(this.Model, query, snapshot);
case 'hasManyThrough':
return HasManyThroughRelation.whereHas(this.Model, query, snapshot);
case 'belongsTo':

@@ -441,2 +447,6 @@ return BelongsToRelation.whereHas(this.Model, query, snapshot);

return HasManyRelation.whereHas(this.Model, query, snapshot);
case 'hasOneThrough':
return HasOneThroughRelation.whereHas(this.Model, query, snapshot);
case 'hasManyThrough':
return HasManyThroughRelation.whereHas(this.Model, query, snapshot);
case 'belongsTo':

@@ -443,0 +453,0 @@ return BelongsToRelation.whereHas(this.Model, query, snapshot);

@@ -14,2 +14,4 @@ /**

import { HasManyRelation } from '#src/models/relations/HasMany/HasManyRelation';
import { HasOneThroughRelation } from '#src/models/relations/HasOneThrough/HasOneThroughRelation';
import { HasManyThroughRelation } from '#src/models/relations/HasManyThrough/HasManyThroughRelation';
import { BelongsToRelation } from '#src/models/relations/BelongsTo/BelongsToRelation';

@@ -77,2 +79,6 @@ import { BelongsToManyRelation } from '#src/models/relations/BelongsToMany/BelongsToManyRelation';

return HasManyRelation.load(model, relation);
case 'hasOneThrough':
return HasOneThroughRelation.load(model, relation);
case 'hasManyThrough':
return HasManyThroughRelation.load(model, relation);
case 'belongsTo':

@@ -111,2 +117,6 @@ return BelongsToRelation.load(model, relation);

return HasManyRelation.loadAll(models, relation);
case 'hasOneThrough':
return HasOneThroughRelation.loadAll(models, relation);
case 'hasManyThrough':
return HasManyThroughRelation.loadAll(models, relation);
case 'belongsTo':

@@ -113,0 +123,0 @@ return BelongsToRelation.loadAll(models, relation);

@@ -19,2 +19,4 @@ /**

export * from '#src/types/relations/HasManyOptions';
export * from '#src/types/relations/HasOneThroughOptions';
export * from '#src/types/relations/HasManyThroughOptions';
export * from '#src/types/relations/BelongsToOptions';

@@ -21,0 +23,0 @@ export * from '#src/types/relations/BelongsToManyOptions';

@@ -19,2 +19,4 @@ /**

export * from '#src/types/relations/HasManyOptions';
export * from '#src/types/relations/HasOneThroughOptions';
export * from '#src/types/relations/HasManyThroughOptions';
export * from '#src/types/relations/BelongsToOptions';

@@ -21,0 +23,0 @@ export * from '#src/types/relations/BelongsToManyOptions';

@@ -11,4 +11,6 @@ /**

import type { HasManyOptions } from '#src/types/relations/HasManyOptions';
import type { HasOneThroughOptions } from '#src/types/relations/HasOneThroughOptions';
import type { HasManyThroughOptions } from '#src/types/relations/HasManyThroughOptions';
import type { BelongsToOptions } from '#src/types/relations/BelongsToOptions';
import type { BelongsToManyOptions } from '#src/types/relations/BelongsToManyOptions';
export type RelationOptions = HasOneOptions | HasManyOptions | BelongsToOptions | BelongsToManyOptions;
export type RelationOptions = HasOneOptions | HasManyOptions | HasOneThroughOptions | HasManyThroughOptions | BelongsToOptions | BelongsToManyOptions;