UNPKG

@cloud-cli/store

Version:
129 lines (128 loc) 3.35 kB
const meta = Symbol(); const resourceName = Symbol(); function getMetadataOf(target, property) { const ctor = target.constructor && target.constructor !== Function ? target.constructor : target; let map = ctor[meta]; if (!map) { map = ctor[meta] = new Map(); } if (!property) { return map; } if (!map.get(property)) { const q = { type: String, name: property }; map.set(property, q); return q; } return map.get(property); } export function Model(name) { return function (target) { const meta = getMetadataOf(target); meta.set(resourceName, name); }; } export function NotNull() { return function (target, property) { const meta = getMetadataOf(target, property); meta.notNull = true; }; } export function Unique() { return function (target, property) { const meta = getMetadataOf(target, property); meta.unique = true; }; } export function Primary() { return function (target, property) { const meta = getMetadataOf(target, property); meta.primary = true; }; } export function Property(type, defaultValue) { return function (target, name) { Object.assign(getMetadataOf(target, name), { name, type, defaultValue, }); }; } const operators = { is: '=', isNot: '!=', isLike: 'like', gt: '>', lt: '<', gte: '>=', lte: '<=', }; export class Query { constructor() { this.q = []; } push(field, operator, value) { this.q.push([field, operator, value]); return this; } where(field) { const q = this; const p = new Proxy({}, { get(_t, operator) { return (value) => q.push(field, operators[operator], value); }, }); return p; } toJSON() { return this.q; } } export class Resource { static use(driver) { Resource.driver = driver; } static describe(resourceOrModel) { const resource = typeof resourceOrModel !== 'function' ? Object.getPrototypeOf(resourceOrModel).constructor : resourceOrModel; const meta = getMetadataOf(resource); const name = meta.get(resourceName); if (!name) { throw new Error('Name is missing. Did you add @Model() to your class?'); } const fields = Array.from(meta.entries()) .filter((f) => f[0] !== resourceName) .map((f) => f[1]); if (!fields.find((f) => f.primary)) { fields.unshift({ name: 'id', type: Number, primary: true, }); } return { name, fields }; } static async find(resource, query) { return Resource.driver.findAll(resource, query); } static async create(resource) { return Resource.driver.create(resource); } constructor(props) { if (props) { Object.assign(this, props); } } async save() { return Resource.driver.save(this); } async remove() { return Resource.driver.remove(this); } async find() { return Resource.driver.find(this); } } Resource.getMetadataOf = getMetadataOf; export class ResourceDriver { }