@themost/jspa
Version:
MOST Web Framework Persistence API
554 lines (543 loc) • 22.4 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var common = require('@themost/common');
var jspa = require('@themost/jspa');
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
function setAttributeDefault(event) {
return __awaiter(this, void 0, void 0, function* () {
const superClass = event.entityClass.__proto__;
if (superClass != null) {
const hasEntityType = Object.prototype.hasOwnProperty.call(superClass, 'Entity');
if (hasEntityType === true) {
const entityType = superClass;
const superModel = event.context.model(entityType.Entity.name);
if (superModel == null) {
throw new TypeError('Super model cannot be found or is inaccessible');
}
yield setAttributeDefault({
context: event.context,
target: event.target,
model: superModel,
entityClass: superClass
});
}
}
// get column defs
const columns = event.entityClass;
for (const column of columns.Column.values()) {
const columnDefault = column;
// if column default value is defined
if (columnDefault.columnDefault != null) {
// get value
const descriptor = Object.getOwnPropertyDescriptor(event.target, columnDefault.name);
if (descriptor && descriptor.value) {
continue;
}
// execute closure
const value = yield columnDefault.columnDefault.closure(event);
// and set value
Object.defineProperty(event.target, columnDefault.name, {
configurable: true,
enumerable: true,
value
});
}
}
});
}
function calculateAttributeValue(event) {
return __awaiter(this, void 0, void 0, function* () {
const superClass = event.entityClass.__proto__;
if (superClass != null) {
const hasEntityType = Object.prototype.hasOwnProperty.call(superClass, 'Entity');
if (hasEntityType === true) {
const entityType = superClass;
const superModel = event.context.model(entityType.Entity.name);
if (superModel == null) {
throw new TypeError('Super model cannot be found or is inaccessible');
}
yield calculateAttributeValue({
context: event.context,
target: event.target,
model: superModel,
entityClass: superClass
});
}
}
// get column defs
const columns = event.entityClass;
for (const column of columns.Column.values()) {
const columnFormula = column;
// if column formula is defined
if (columnFormula.formula != null) {
// execute closure
const value = yield columnFormula.formula.closure(event);
// and set value
Object.defineProperty(event.target, columnFormula.name, {
configurable: true,
enumerable: true,
value
});
}
}
});
}
function inspectStaticCallbackOfType(CallbackType, entityClass) {
const results = [];
const entityListenerCollection = entityClass;
if (Array.isArray(entityListenerCollection.EntityListeners)) {
entityListenerCollection.EntityListeners.forEach((entityListener) => {
const entityCallbackCollection1 = entityListener;
if (Array.isArray(entityCallbackCollection1.CallbackMethods)) {
const addResults = entityCallbackCollection1.CallbackMethods.filter((item) => {
return item.type === CallbackType;
});
// eslint-disable-next-line prefer-spread
results.push.apply(results, addResults);
}
});
}
return results;
}
function inspectCallbackOfType(CallbackType, entityClass) {
const results = [];
const entityCallbackCollection1 = entityClass;
if (Array.isArray(entityCallbackCollection1.CallbackMethods)) {
const addResults = entityCallbackCollection1.CallbackMethods.filter((item) => {
return item.type === CallbackType;
});
// eslint-disable-next-line prefer-spread
results.push.apply(results, addResults);
}
return results;
}
function beforeUpgrade(event, callback) {
const EntityClass = event.model.getDataObjectType();
const listenerCallbacks = inspectStaticCallbackOfType(jspa.PreInit, EntityClass);
const eventEmitter = new common.SequentialEventEmitter();
listenerCallbacks.forEach((listenerCallback) => {
eventEmitter.on('before.upgrade', (innerEvent, innerCallback) => {
listenerCallback.callback({
context: innerEvent.model.context,
model: innerEvent.model,
entityClass: EntityClass
}).then(() => {
return innerCallback();
}).catch((error) => {
return innerCallback(error);
});
});
});
const ownCallbacks = inspectCallbackOfType(jspa.PreInit, EntityClass);
ownCallbacks.forEach((listenerCallback) => {
eventEmitter.on('before.upgrade', (innerEvent, innerCallback) => {
listenerCallback.callback({
context: innerEvent.model.context,
model: innerEvent.model,
entityClass: EntityClass
}).then(() => {
return innerCallback();
}).catch((error) => {
return innerCallback(error);
});
});
});
eventEmitter.emit('before.upgrade', event, (err) => {
return callback(err);
});
}
function afterUpgrade(event, callback) {
const EntityClass = event.model.getDataObjectType();
const listenerCallbacks = inspectStaticCallbackOfType(jspa.PostInit, EntityClass);
const eventEmitter = new common.SequentialEventEmitter();
listenerCallbacks.forEach((listenerCallback) => {
eventEmitter.on('after.upgrade', (innerEvent, innerCallback) => {
listenerCallback.callback({
context: innerEvent.model.context,
model: innerEvent.model,
entityClass: EntityClass
}).then(() => {
return innerCallback();
}).catch((error) => {
return innerCallback(error);
});
});
});
const ownCallbacks = inspectCallbackOfType(jspa.PostInit, EntityClass);
ownCallbacks.forEach((listenerCallback) => {
eventEmitter.on('after.upgrade', (innerEvent, innerCallback) => {
listenerCallback.callback({
context: innerEvent.model.context,
model: innerEvent.model,
entityClass: EntityClass
}).then(() => {
return innerCallback();
}).catch((error) => {
return innerCallback(error);
});
});
});
eventEmitter.emit('after.upgrade', event, (err) => {
return callback(err);
});
}
function beforeExecute(event, callback) {
const EntityClass = event.model.getDataObjectType();
const listenerCallbacks = inspectStaticCallbackOfType(jspa.PreLoad, EntityClass);
const eventEmitter = new common.SequentialEventEmitter();
listenerCallbacks.forEach((listenerCallback) => {
eventEmitter.on('before.execute', (innerEvent, innerCallback) => {
listenerCallback.callback({
context: innerEvent.model.context,
emitter: innerEvent.emitter,
query: innerEvent.query,
entityClass: EntityClass
}).then(() => {
return innerCallback();
}).catch((error) => {
return innerCallback(error);
});
});
});
const ownCallbacks = inspectCallbackOfType(jspa.PreLoad, EntityClass);
ownCallbacks.forEach((listenerCallback) => {
eventEmitter.on('before.execute', (innerEvent, innerCallback) => {
listenerCallback.callback({
context: event.model.context,
emitter: event.emitter,
query: event.query,
entityClass: EntityClass
}).then(() => {
return innerCallback();
}).catch((error) => {
return innerCallback(error);
});
});
});
eventEmitter.emit('before.execute', event, (err) => {
return callback(err);
});
}
function afterExecute(event, callback) {
const EntityClass = event.model.getDataObjectType();
const listenerCallbacks = inspectStaticCallbackOfType(jspa.PostLoad, EntityClass);
const eventEmitter = new common.SequentialEventEmitter();
listenerCallbacks.forEach((listenerCallback) => {
eventEmitter.on('after.execute', (innerEvent, innerCallback) => {
listenerCallback.callback({
context: innerEvent.model.context,
emitter: innerEvent.emitter,
query: innerEvent.query,
entityClass: EntityClass
}).then(() => {
return innerCallback();
}).catch((error) => {
return innerCallback(error);
});
});
});
const ownCallbacks = inspectCallbackOfType(jspa.PostLoad, EntityClass);
ownCallbacks.forEach((listenerCallback) => {
eventEmitter.on('after.execute', (innerEvent, innerCallback) => {
listenerCallback.callback({
context: innerEvent.model.context,
emitter: innerEvent.emitter,
query: innerEvent.query,
entityClass: EntityClass
}).then(() => {
return innerCallback();
}).catch((error) => {
return innerCallback(error);
});
});
});
eventEmitter.emit('after.execute', event, (err) => {
return callback(err);
});
}
// noinspection JSUnusedLocalSymbols
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function beforeUpdate(event, callback) {
const EntityClass = event.model.getDataObjectType();
const listenerCallbacks = inspectStaticCallbackOfType(jspa.PreUpdate, EntityClass);
const eventEmitter = new common.SequentialEventEmitter();
listenerCallbacks.forEach((listenerCallback) => {
eventEmitter.on('before.save', (innerEvent, innerCallback) => {
listenerCallback.callback({
context: innerEvent.model.context,
target: innerEvent.target,
previous: innerEvent.previous,
entityClass: EntityClass
}).then(() => {
return innerCallback();
}).catch((error) => {
return innerCallback(error);
});
});
});
const ownCallbacks = inspectCallbackOfType(jspa.PreUpdate, EntityClass);
ownCallbacks.unshift({
callback: calculateAttributeValue
});
ownCallbacks.forEach((listenerCallback) => {
eventEmitter.on('before.save', (innerEvent, innerCallback) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
listenerCallback.callback.bind(innerEvent.target)({
context: innerEvent.model.context,
target: innerEvent.target,
previous: innerEvent.previous,
entityClass: EntityClass
}).then(() => {
return innerCallback();
}).catch((error) => {
return innerCallback(error);
});
});
});
eventEmitter.emit('before.save', event, (err) => {
return callback(err);
});
}
// noinspection JSUnusedLocalSymbols
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function afterUpdate(event, callback) {
const EntityClass = event.model.getDataObjectType();
const listenerCallbacks = inspectStaticCallbackOfType(jspa.PostUpdate, EntityClass);
const eventEmitter = new common.SequentialEventEmitter();
listenerCallbacks.forEach((listenerCallback) => {
eventEmitter.on('after.save', (innerEvent, innerCallback) => {
listenerCallback.callback({
context: innerEvent.model.context,
target: innerEvent.target,
previous: innerEvent.previous,
entityClass: EntityClass
}).then(() => {
return innerCallback();
}).catch((error) => {
return innerCallback(error);
});
});
});
const ownCallbacks = inspectCallbackOfType(jspa.PostUpdate, EntityClass);
ownCallbacks.forEach((listenerCallback) => {
eventEmitter.on('after.save', (innerEvent, innerCallback) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
listenerCallback.callback.bind(innerEvent.target)({
context: innerEvent.model.context,
target: innerEvent.target,
previous: innerEvent.previous,
entityClass: EntityClass
}).then(() => {
return innerCallback();
}).catch((error) => {
return innerCallback(error);
});
});
});
eventEmitter.emit('after.save', event, (err) => {
return callback(err);
});
}
function beforeInsert(event, callback) {
const EntityClass = event.model.getDataObjectType();
const listenerCallbacks = inspectStaticCallbackOfType(jspa.PrePersist, EntityClass);
const eventEmitter = new common.SequentialEventEmitter();
listenerCallbacks.forEach((listenerCallback) => {
eventEmitter.on('before.save', (innerEvent, innerCallback) => {
try {
listenerCallback.callback({
context: innerEvent.model.context,
target: innerEvent.target,
model: innerEvent.model,
entityClass: EntityClass
}).then(() => {
return innerCallback();
}).catch((error) => {
return innerCallback(error);
});
}
catch (err) {
return innerCallback(err);
}
});
});
const ownCallbacks = inspectCallbackOfType(jspa.PrePersist, EntityClass);
ownCallbacks.unshift({
callback: setAttributeDefault
}, {
callback: calculateAttributeValue
});
ownCallbacks.forEach((listenerCallback) => {
eventEmitter.on('before.save', (innerEvent, innerCallback) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
listenerCallback.callback.bind(innerEvent.target)({
context: innerEvent.model.context,
target: innerEvent.target,
model: innerEvent.model,
entityClass: EntityClass
}).then(() => {
return innerCallback();
}).catch((error) => {
return innerCallback(error);
});
});
});
eventEmitter.emit('before.save', event, (err) => {
return callback(err);
});
}
function afterInsert(event, callback) {
const EntityClass = event.model.getDataObjectType();
const listenerCallbacks = inspectStaticCallbackOfType(jspa.PostPersist, EntityClass);
const eventEmitter = new common.SequentialEventEmitter();
listenerCallbacks.forEach((listenerCallback) => {
eventEmitter.on('after.save', (innerEvent, innerCallback) => {
listenerCallback.callback({
context: innerEvent.model.context,
target: innerEvent.target,
model: innerEvent.model,
entityClass: EntityClass
}).then(() => {
return innerCallback();
}).catch((error) => {
return innerCallback(error);
});
});
});
const ownCallbacks = inspectCallbackOfType(jspa.PostPersist, EntityClass);
ownCallbacks.forEach((listenerCallback) => {
eventEmitter.on('after.save', (innerEvent, innerCallback) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
listenerCallback.callback.bind(innerEvent.target)({
context: innerEvent.model.context,
target: innerEvent.target,
model: innerEvent.model,
entityClass: EntityClass
}).then(() => {
return innerCallback();
}).catch((error) => {
return innerCallback(error);
});
});
});
eventEmitter.emit('after.save', event, (err) => {
return callback(err);
});
}
function beforeSave(event, callback) {
if (event.state === 1) {
return beforeInsert(event, callback);
}
return beforeUpdate(event, callback);
}
function afterSave(event, callback) {
if (event.state === 1) {
return afterInsert(event, callback);
}
return afterUpdate(event, callback);
}
function beforeRemove(event, callback) {
const EntityClass = event.model.getDataObjectType();
const listenerCallbacks = inspectStaticCallbackOfType(jspa.PreRemove, EntityClass);
const eventEmitter = new common.SequentialEventEmitter();
listenerCallbacks.forEach((listenerCallback) => {
eventEmitter.on('before.remove', (innerEvent, innerCallback) => {
listenerCallback.callback({
context: innerEvent.model.context,
target: innerEvent.target,
model: event.model,
entityClass: EntityClass
}).then(() => {
return innerCallback();
}).catch((error) => {
return innerCallback(error);
});
});
});
const ownCallbacks = inspectCallbackOfType(jspa.PreRemove, EntityClass);
ownCallbacks.forEach((listenerCallback) => {
eventEmitter.on('before.remove', (innerEvent, innerCallback) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
listenerCallback.callback.bind(innerEvent.target)({
context: innerEvent.model.context,
target: innerEvent.target,
model: event.model,
entityClass: EntityClass
}).then(() => {
return innerCallback();
}).catch((error) => {
return innerCallback(error);
});
});
});
eventEmitter.emit('before.remove', event, (err) => {
return callback(err);
});
}
function afterRemove(event, callback) {
const EntityClass = event.model.getDataObjectType();
const listenerCallbacks = inspectStaticCallbackOfType(jspa.PostRemove, EntityClass);
const eventEmitter = new common.SequentialEventEmitter();
listenerCallbacks.forEach((listenerCallback) => {
eventEmitter.on('after.remove', (innerEvent, innerCallback) => {
listenerCallback.callback({
context: innerEvent.model.context,
target: innerEvent.target,
model: innerEvent.model,
entityClass: EntityClass
}).then(() => {
return innerCallback();
}).catch((error) => {
return innerCallback(error);
});
});
});
const ownCallbacks = inspectCallbackOfType(jspa.PostRemove, EntityClass);
ownCallbacks.forEach((listenerCallback) => {
eventEmitter.on('after.remove', (innerEvent, innerCallback) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
listenerCallback.callback.bind(innerEvent.target)({
context: innerEvent.model.context,
target: innerEvent.target,
model: innerEvent.model,
entityClass: EntityClass
}).then(() => {
return innerCallback();
}).catch((error) => {
return innerCallback(error);
});
});
});
eventEmitter.emit('after.remove', event, (err) => {
return callback(err);
});
}
exports.afterExecute = afterExecute;
exports.afterRemove = afterRemove;
exports.afterSave = afterSave;
exports.afterUpgrade = afterUpgrade;
exports.beforeExecute = beforeExecute;
exports.beforeRemove = beforeRemove;
exports.beforeSave = beforeSave;
exports.beforeUpgrade = beforeUpgrade;
//# sourceMappingURL=index.js.map