@decaf-ts/db-decorators
Version:
Agnostic database decorators and repository
152 lines (151 loc) • 7.63 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseRepository = void 0;
const decorator_validation_1 = require("@decaf-ts/decorator-validation");
const utils_1 = require("./utils.cjs");
const constants_1 = require("../operations/constants.cjs");
const errors_1 = require("./errors.cjs");
const wrappers_1 = require("./wrappers.cjs");
const utils_2 = require("../identity/utils.cjs");
const Context_1 = require("./Context.cjs");
class BaseRepository {
get class() {
if (!this._class)
throw new errors_1.InternalError(`No class definition found for this repository`);
return this._class;
}
get pk() {
if (!this._pk)
this._pk = (0, utils_2.findPrimaryKey)(new this.class()).id;
return this._pk;
}
constructor(clazz) {
if (clazz)
this._class = clazz;
// eslint-disable-next-line @typescript-eslint/no-this-alias
const self = this;
[this.create, this.read, this.update, this.delete].forEach((m) => {
const name = m.name;
(0, wrappers_1.wrapMethodWithContext)(self, self[name + "Prefix"], m, self[name + "Suffix"]);
});
}
async createAll(models, ...args) {
return Promise.all(models.map((m) => this.create(m, ...args)));
}
async createPrefix(model, ...args) {
const contextArgs = await Context_1.Context.args(constants_1.OperationKeys.CREATE, this.class, args);
model = new this.class(model);
await (0, utils_1.enforceDBDecorators)(this, contextArgs.context, model, constants_1.OperationKeys.CREATE, constants_1.OperationKeys.ON);
return [model, ...contextArgs.args];
}
async createSuffix(model, context) {
await (0, utils_1.enforceDBDecorators)(this, context, model, constants_1.OperationKeys.CREATE, constants_1.OperationKeys.AFTER);
return model;
}
async createAllPrefix(models, ...args) {
const contextArgs = await Context_1.Context.args(constants_1.OperationKeys.CREATE, this.class, args);
await Promise.all(models.map(async (m) => {
m = new this.class(m);
await (0, utils_1.enforceDBDecorators)(this, contextArgs.context, m, constants_1.OperationKeys.CREATE, constants_1.OperationKeys.ON);
return m;
}));
return [models, ...contextArgs.args];
}
async createAllSuffix(models, context) {
await Promise.all(models.map((m) => (0, utils_1.enforceDBDecorators)(this, context, m, constants_1.OperationKeys.CREATE, constants_1.OperationKeys.AFTER)));
return models;
}
async readAll(keys, ...args) {
return await Promise.all(keys.map((id) => this.read(id, ...args)));
}
async readSuffix(model, context) {
await (0, utils_1.enforceDBDecorators)(this, context, model, constants_1.OperationKeys.READ, constants_1.OperationKeys.AFTER);
return model;
}
async readPrefix(key, ...args) {
const contextArgs = await Context_1.Context.args(constants_1.OperationKeys.READ, this.class, args);
const model = new this.class();
model[this.pk] = key;
await (0, utils_1.enforceDBDecorators)(this, contextArgs.context, model, constants_1.OperationKeys.READ, constants_1.OperationKeys.ON);
return [key, ...contextArgs.args];
}
async readAllPrefix(keys, ...args) {
const contextArgs = await Context_1.Context.args(constants_1.OperationKeys.READ, this.class, args);
await Promise.all(keys.map(async (k) => {
const m = new this.class();
m[this.pk] = k;
return (0, utils_1.enforceDBDecorators)(this, contextArgs.context, m, constants_1.OperationKeys.READ, constants_1.OperationKeys.ON);
}));
return [keys, ...contextArgs.args];
}
async readAllSuffix(models, context) {
await Promise.all(models.map((m) => (0, utils_1.enforceDBDecorators)(this, context, m, constants_1.OperationKeys.READ, constants_1.OperationKeys.AFTER)));
return models;
}
async updateAll(models, ...args) {
return Promise.all(models.map((m) => this.update(m, ...args)));
}
async updateSuffix(model, context) {
await (0, utils_1.enforceDBDecorators)(this, context, model, constants_1.OperationKeys.UPDATE, constants_1.OperationKeys.AFTER);
return model;
}
async updatePrefix(model, ...args) {
const contextArgs = await Context_1.Context.args(constants_1.OperationKeys.UPDATE, this.class, args);
const id = model[this.pk];
if (!id)
throw new errors_1.InternalError(`No value for the Id is defined under the property ${this.pk}`);
const oldModel = await this.read(id);
await (0, utils_1.enforceDBDecorators)(this, contextArgs.context, model, constants_1.OperationKeys.UPDATE, constants_1.OperationKeys.ON, oldModel);
return [model, ...contextArgs.args];
}
async updateAllPrefix(models, ...args) {
const contextArgs = await Context_1.Context.args(constants_1.OperationKeys.UPDATE, this.class, args);
await Promise.all(models.map((m) => {
m = new this.class(m);
(0, utils_1.enforceDBDecorators)(this, contextArgs.context, m, constants_1.OperationKeys.UPDATE, constants_1.OperationKeys.ON);
return m;
}));
return [models, ...contextArgs.args];
}
async updateAllSuffix(models, context) {
await Promise.all(models.map((m) => (0, utils_1.enforceDBDecorators)(this, context, m, constants_1.OperationKeys.UPDATE, constants_1.OperationKeys.AFTER)));
return models;
}
async deleteAll(keys, ...args) {
return Promise.all(keys.map((k) => this.delete(k, ...args)));
}
async deleteSuffix(model, context) {
await (0, utils_1.enforceDBDecorators)(this, context, model, constants_1.OperationKeys.DELETE, constants_1.OperationKeys.AFTER);
return model;
}
async deletePrefix(key, ...args) {
const contextArgs = await Context_1.Context.args(constants_1.OperationKeys.DELETE, this.class, args);
const model = await this.read(key, ...contextArgs.args);
await (0, utils_1.enforceDBDecorators)(this, contextArgs.context, model, constants_1.OperationKeys.DELETE, constants_1.OperationKeys.ON);
return [key, ...contextArgs.args];
}
async deleteAllPrefix(keys, ...args) {
const contextArgs = await Context_1.Context.args(constants_1.OperationKeys.DELETE, this.class, args);
const models = await this.readAll(keys, ...contextArgs.args);
await Promise.all(models.map(async (m) => {
return (0, utils_1.enforceDBDecorators)(this, contextArgs.context, m, constants_1.OperationKeys.DELETE, constants_1.OperationKeys.ON);
}));
return [keys, ...contextArgs.args];
}
async deleteAllSuffix(models, context) {
await Promise.all(models.map((m) => (0, utils_1.enforceDBDecorators)(this, context, m, constants_1.OperationKeys.DELETE, constants_1.OperationKeys.AFTER)));
return models;
}
merge(oldModel, model) {
const extract = (model) => Object.entries(model).reduce((accum, [key, val]) => {
if (typeof val !== "undefined")
accum[key] = val;
return accum;
}, {});
return new this.class(Object.assign({}, extract(oldModel), extract(model)));
}
toString() {
return (0, decorator_validation_1.sf)("[{0}] - Repository for {1}", this.constructor.name, this.class.name);
}
}
exports.BaseRepository = BaseRepository;