@sqb/connect
Version:
Multi-dialect database connection framework written with TypeScript
70 lines (69 loc) • 2.56 kB
JavaScript
import { EntityMetadata } from '../model/entity-metadata.js';
import { LinkChain } from '../model/link-chain.js';
export function Link(options) {
let root;
let chain;
const fn = (target, propertyKey) => {
if (typeof propertyKey !== 'string')
throw new TypeError('Symbol properties are not allowed');
const reflectType = Reflect.getMetadata('design:type', target, propertyKey);
if (!root) {
if (reflectType === Array) {
throw new TypeError(`Can't get type information while it is an array. Please define entity type`);
}
if (!EntityMetadata.get(reflectType))
throw new TypeError(`No entity metadata found for type "${reflectType}"`);
fn.toOne(reflectType);
}
if (reflectType !== Array && root.first.returnsMany()) {
throw new TypeError(`Link returns single instance however property type is an array`);
}
if (reflectType === Array && !root.first.returnsMany()) {
throw new TypeError(`Link returns array of instances however property type is not an array`);
}
const entity = EntityMetadata.define(target.constructor);
// @ts-ignore
// noinspection JSConstantReassignment
root.first.source = entity.ctor;
EntityMetadata.defineAssociationField(entity, propertyKey, root.first, options);
};
fn.toOne = (type, args) => {
if (chain) {
chain = chain.linkToOne(type, args?.targetKey, args?.sourceKey);
if (args?.where)
chain.where(args.where);
return fn;
}
root = linkToOne(type, args?.targetKey, args?.sourceKey);
chain = root;
if (args?.where)
chain.where(args.where);
return fn;
};
fn.toMany = (type, args) => {
if (chain) {
chain = chain.linkToMany(type, args?.targetKey, args?.sourceKey);
if (args?.where)
chain.where(args.where);
return fn;
}
root = linkToMany(type, args?.targetKey, args?.sourceKey);
chain = root;
if (args?.where)
chain.where(args.where);
return fn;
};
return fn;
}
/**
* Crates an Link Chain object
*/
function linkToOne(type, targetKey, sourceKey) {
return new LinkChain(type, targetKey, sourceKey);
}
/**
* Crates an Link Chain object
*/
function linkToMany(type, targetKey, sourceKey) {
return new LinkChain(type, targetKey, sourceKey, true);
}