@themost/jspa
Version:
MOST Web Framework Persistence API
1,434 lines (1,388 loc) • 51.5 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var data = require('@themost/data');
var common = require('@themost/common');
require('reflect-metadata');
class Duration extends String {
constructor(value) {
super(value);
}
}
class Counter extends Number {
constructor(value) {
super(value);
if (Counter.isCounter(this.valueOf()) === false) {
throw new TypeError('Expected a valid counter.');
}
}
static isCounter(value) {
return value != null && Number.isInteger(value);
}
}
class Language extends String {
constructor(value) {
super(value);
}
}
class Text extends String {
constructor(value) {
super(value);
}
}
function ifNull(value, defaultValue) {
if (value == null) {
return defaultValue;
}
return value;
}
/**
* Integer data type is a 32-bit signed two's complement integer.
*/
class Integer extends Number {
constructor(value) {
super(Integer.isInteger(ifNull(value, 0)) ? ifNull(value, 0) : NaN);
}
static isInteger(value) {
return /^[+-]?\d+$/.test(value);
}
}
/**
* An integer containing only positive values (1,2,..)
*/
class PositiveInteger extends Number {
constructor(value) {
super(PositiveInteger.isPositiveInteger(ifNull(value, 1)) ? ifNull(value, 1) : NaN);
}
static isPositiveInteger(value) {
return /^[+]?[1-9][0-9]*$/.test(value);
}
}
/**
* An integer containing only non-positive values (..,-2,-1,0)
*/
class NonPositiveInteger extends Number {
constructor(value) {
super(NonPositiveInteger.isNonPositiveInteger(ifNull(value, 0)) ? ifNull(value, 0) : NaN);
}
static isNonPositiveInteger(value) {
return /^[-][0-9]*$/.test(value);
}
}
/**
* An integer containing only negative values (..,-2,-1)
*/
class NegativeInteger extends Number {
constructor(value) {
super(NegativeInteger.isNegativeInteger(ifNull(value, -1)) ? ifNull(value, -1) : NaN);
}
static isNegativeInteger(value) {
return /^[-][1-9][0-9]*$/.test(value);
}
}
/**
* An integer containing only non-negative values (0,1,2,..)
*/
class NonNegativeInteger extends Number {
constructor(value) {
super(NonNegativeInteger.isNonNegativeInteger(ifNull(value, 0)) ? ifNull(value, 0) : NaN);
}
static isNonNegativeInteger(value) {
return /^[+]?[0-9]*$/.test(value);
}
}
class DateTime extends Date {
constructor(value) {
super(value);
}
}
class EntityNotFoundException extends Error {
constructor(msg) {
super(msg || 'The specified entity cannot be found or is inaccessible');
}
}
class SymbolTypeNotSupportedException extends Error {
constructor(msg) {
super(msg || 'The current decorator does not support Symbol type property key');
}
}
exports.ColumnType = void 0;
(function (ColumnType) {
ColumnType["Float"] = "Float";
ColumnType["Boolean"] = "Boolean";
ColumnType["Date"] = "Date";
ColumnType["DateTime"] = "DateTime";
ColumnType["Integer"] = "Integer";
ColumnType["Short"] = "Short";
ColumnType["Counter"] = "Counter";
ColumnType["Duration"] = "Duration";
ColumnType["Number"] = "Number";
ColumnType["Text"] = "Text";
ColumnType["Time"] = "Time";
ColumnType["URL"] = "URL";
ColumnType["Language"] = "Language";
ColumnType["Model"] = "Model";
ColumnType["Guid"] = "Guid";
ColumnType["Object"] = "Object";
ColumnType["NegativeInteger"] = "NegativeInteger";
ColumnType["NegativeNumber"] = "NegativeNumber";
ColumnType["NonNegativeInteger"] = "NonNegativeInteger";
ColumnType["NonNegativeNumber"] = "NonNegativeNumber";
ColumnType["NonPositiveInteger"] = "NonPositiveInteger";
ColumnType["NonPositiveNumber"] = "NonPositiveNumber";
ColumnType["PositiveInteger"] = "PositiveInteger";
ColumnType["PositiveNumber"] = "PositiveNumber";
ColumnType["Email"] = "Email";
ColumnType["AbsoluteURI"] = "AbsoluteURI";
ColumnType["RelativeURI"] = "RelativeURI";
})(exports.ColumnType || (exports.ColumnType = {}));
exports.InheritanceType = void 0;
(function (InheritanceType) {
InheritanceType[InheritanceType["Joined"] = 0] = "Joined";
InheritanceType[InheritanceType["SingleTable"] = 1] = "SingleTable";
InheritanceType[InheritanceType["TablePerClass"] = 2] = "TablePerClass";
})(exports.InheritanceType || (exports.InheritanceType = {}));
exports.FetchType = void 0;
(function (FetchType) {
/**
* Defines that data must be eagerly fetched.
*/
FetchType["Eager"] = "EAGER";
/**
* Defines that data can be lazily fetched.
*/
FetchType["Lazy"] = "LAZY";
})(exports.FetchType || (exports.FetchType = {}));
/**
* Defines the set of cascadable operations that are propagated to the associated entity.
*/
exports.CascadeType = void 0;
(function (CascadeType) {
CascadeType[CascadeType["All"] = 31] = "All";
CascadeType[CascadeType["Detach"] = 1] = "Detach";
CascadeType[CascadeType["Merge"] = 2] = "Merge";
CascadeType[CascadeType["Persist"] = 4] = "Persist";
CascadeType[CascadeType["Refresh"] = 8] = "Refresh";
CascadeType[CascadeType["Remove"] = 16] = "Remove";
})(exports.CascadeType || (exports.CascadeType = {}));
class OneToOneAssociationParser {
constructor(model, target) {
this.model = model;
this.target = target;
//
}
parse(column) {
const oneToOneColumn = column;
if (oneToOneColumn.oneToOne) {
this.target.nullable = oneToOneColumn.oneToOne.optional != null ? oneToOneColumn.oneToOne.optional : true;
this.target.many = true;
this.target.multiplicity = 'ZeroOrOne';
if (oneToOneColumn.oneToOne.fetchType === exports.FetchType.Eager) {
this.target.expandable = true;
}
const tableAnnotation = column;
if (tableAnnotation.joinTable) {
// set parentModel (parentField is the primary key)
if (tableAnnotation.joinTable.joinColumns.length != 1) {
throw new common.DataError('E_ANNOTATION', 'One-to-one association joinColumns must be a single-item array.', null, this.model.name, this.target.name);
}
if (tableAnnotation.joinTable.inverseJoinColumns.length != 1) {
throw new common.DataError('E_ANNOTATION', 'One-to-one association inverseJoinColumns must be a single-item array.', null, this.model.name, this.target.name);
}
this.target.mapping = {
associationType: 'junction',
associationAdapter: tableAnnotation.joinTable.name,
parentModel: this.model.name,
parentField: tableAnnotation.joinTable.joinColumns[0].referencedColumnName,
associationObjectField: tableAnnotation.joinTable.joinColumns[0].name,
childModel: typeof column.type === 'string' ? column.type : column.type.name,
childField: tableAnnotation.joinTable.inverseJoinColumns[0].referencedColumnName,
associationValueField: tableAnnotation.joinTable.inverseJoinColumns[0].name
};
}
else {
this.target.mapping = {
associationType: 'association',
parentModel: this.model.name
};
if (oneToOneColumn.oneToOne.mappedBy == null) {
throw new common.DataError('E_ANNOTATION', 'One-to-one association must have a mapped column', null, this.model.name, this.target.name);
}
const targetEntity = oneToOneColumn.oneToOne.targetEntity;
// set childModel, childfield
if (targetEntity) {
if (typeof targetEntity === 'string') {
this.target.mapping.childModel = targetEntity;
this.target.mapping.childField = oneToOneColumn.oneToOne.mappedBy;
}
else if (typeof targetEntity === 'function') {
const targetEntityType = targetEntity;
if (targetEntityType.Entity == null) {
throw new common.DataError('E_ANNOTATION', 'Target entity type cannot be empty', null, this.model.name, this.target.name);
}
this.target.mapping.childModel = targetEntityType.Entity.name;
this.target.mapping.childField = oneToOneColumn.oneToOne.mappedBy;
}
else {
throw new common.DataError('E_ANNOTATION', 'Target entity has an invalid type. Expected string or class', null, this.model.name, this.target.name);
}
}
else if (this.target.type) {
this.target.mapping.childModel = this.target.type;
this.target.mapping.childField = oneToOneColumn.oneToOne.mappedBy;
}
else {
throw new common.DataError('E_ANNOTATION', 'One-to-one association target type cannot be found.', null, this.model.name, this.target.name);
}
}
// set cascade type
if (oneToOneColumn.oneToOne.cascadeType) {
if ((oneToOneColumn.oneToOne.cascadeType & exports.CascadeType.Remove) === exports.CascadeType.Remove) {
this.target.mapping.cascade = 'delete';
}
else if ((oneToOneColumn.oneToOne.cascadeType & exports.CascadeType.Persist) === exports.CascadeType.Persist) {
this.target.nested = true;
}
}
// set privileges
if (Array.isArray(oneToOneColumn.oneToOne.privileges)) {
this.target.mapping.privileges = oneToOneColumn.oneToOne.privileges;
}
}
}
}
class OneToManyAnnotationParser {
constructor(model, target) {
this.model = model;
this.target = target;
//
}
parse(column) {
const oneToManyColumn = column;
if (oneToManyColumn.oneToMany) {
this.target.many = true;
this.target.nullable = true;
if (oneToManyColumn.oneToMany.fetchType === exports.FetchType.Eager) {
this.target.expandable = true;
}
// set association type
this.target.mapping = {
associationType: 'association'
};
// set cascade
if (oneToManyColumn.oneToMany.cascadeType != null) {
if ((oneToManyColumn.oneToMany.cascadeType & exports.CascadeType.Remove) === exports.CascadeType.Remove) {
this.target.mapping.cascade = 'delete';
}
else if ((oneToManyColumn.oneToMany.cascadeType & exports.CascadeType.Persist) === exports.CascadeType.Persist) {
this.target.nested = true;
}
}
if (Array.isArray(oneToManyColumn.oneToMany.privileges)) {
this.target.mapping.privileges = oneToManyColumn.oneToMany.privileges;
}
}
}
}
class ManyToManyAnnotationParser {
constructor(model, target) {
this.model = model;
this.target = target;
//
}
parse(column) {
const manyToManyColumn = column;
if (manyToManyColumn.manyToMany) {
this.target.many = true;
this.target.nullable = true;
this.target.mapping = {
associationType: 'junction'
};
// set exapndable
if (manyToManyColumn.manyToMany.fetchType === exports.FetchType.Eager) {
this.target.expandable = true;
}
if (manyToManyColumn.type) {
new ColumnAnnotationParser(this.model).getTypeString(manyToManyColumn.type);
Object.assign(this.target.mapping, {
parentModel: this.model.name,
});
}
else if (manyToManyColumn.manyToMany.targetEntity) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
new ColumnAnnotationParser(this.model).getTypeString(manyToManyColumn.manyToMany.targetEntity);
Object.assign(this.target.mapping, {
parentModel: manyToManyColumn.manyToMany.targetEntity,
childModel: this.model.name
});
}
if (manyToManyColumn.manyToMany.mappedBy != null) {
// todo: add parentModel, parentField, childModel, childField
Object.assign(this.target.mapping, {
mappedBy: manyToManyColumn.manyToMany.mappedBy
});
}
const joinTableColumn = column;
if (joinTableColumn.joinTable) {
Object.assign(this.target.mapping, {
associationAdapter: joinTableColumn.joinTable.name
});
if (Array.isArray(joinTableColumn.joinTable.joinColumns)) {
const joinColumn = joinTableColumn.joinTable.joinColumns[0];
if (joinColumn) {
this.target.mapping.associationObjectField = joinColumn.name;
}
}
if (Array.isArray(joinTableColumn.joinTable.inverseJoinColumns)) {
const inverseJoinColumn = joinTableColumn.joinTable.inverseJoinColumns[0];
if (inverseJoinColumn) {
this.target.mapping.associationValueField = inverseJoinColumn.name;
}
}
if (Array.isArray(manyToManyColumn.manyToMany.privileges)) {
this.target.mapping.privileges = manyToManyColumn.manyToMany.privileges;
}
}
}
}
}
class ElementCollectionAnnotationParser {
constructor(model, target) {
this.model = model;
this.target = target;
//
}
parse(column) {
const annotation = column;
if (annotation.elementCollection) {
this.target.many = true;
this.target.nullable = annotation.elementCollection.optional === false ? false : true;
this.target.mapping = {
associationType: 'junction',
cascade: 'delete',
associationObjectField: 'object',
associationValueField: 'value'
};
// set exapndable
if (annotation.elementCollection.fetchType === exports.FetchType.Eager) {
this.target.expandable = true;
}
this.target.type = new ColumnAnnotationParser(this.model).getTypeString(annotation.elementCollection.targetClass);
Object.assign(this.target.mapping, {
parentModel: this.model.name
});
const joinTableColumn = column;
if (joinTableColumn.joinTable) {
Object.assign(this.target.mapping, {
associationAdapter: joinTableColumn.joinTable.name
});
if (Array.isArray(joinTableColumn.joinTable.joinColumns)) {
const joinColumn = joinTableColumn.joinTable.joinColumns[0];
if (joinColumn && joinColumn.name) {
this.target.mapping.associationObjectField = joinColumn.name;
}
if (joinColumn && joinColumn.referencedColumnName) {
this.target.mapping.parentField = joinColumn.referencedColumnName;
}
}
if (Array.isArray(joinTableColumn.joinTable.inverseJoinColumns)) {
const inverseJoinColumn = joinTableColumn.joinTable.inverseJoinColumns[0];
if (inverseJoinColumn && inverseJoinColumn.name) {
this.target.mapping.associationValueField = inverseJoinColumn.name;
}
}
if (Array.isArray(annotation.elementCollection.privileges)) {
this.target.mapping.privileges = annotation.elementCollection.privileges;
}
}
}
}
}
class ColumnAnnotationParser {
constructor(model) {
this.model = model;
//
}
getTypeString(type) {
let columnType;
if (typeof type === 'string') {
return type;
}
else {
const targetType = type;
if (targetType.Entity) {
columnType = targetType.Entity.name;
}
else {
columnType = targetType.name;
}
return columnType;
}
}
}
class EntityLoaderStrategy extends data.SchemaLoaderStrategy {
constructor(config) {
super(config);
this.imports = [];
this.models = new Map();
}
getModelDefinition(name) {
const model = this.models.get(name);
if (model == null) {
return null;
}
if (typeof model === 'function') {
const modelDefinition = this.getModelFromEntityClass(model);
this.models.set(name, modelDefinition);
return modelDefinition;
}
return model;
}
setModelDefinition(data) {
this.models = this.models || new Map();
this.models.set(data.name, data);
return this;
}
reload() {
this.readSync();
}
readSync() {
const models = new Map();
for (const module of this.imports) {
Object.keys(module).forEach((member) => {
if (Object.prototype.hasOwnProperty.call(module, member)) {
const exportedMember = module[member];
if (typeof exportedMember === 'function') {
const entityAnnotation = exportedMember;
if (entityAnnotation.Entity && entityAnnotation.Entity.name) {
models.set(entityAnnotation.Entity.name, exportedMember);
}
}
}
});
}
this.models = models;
return Array.from(this.models.keys());
}
getModels() {
if (this.models == null) {
return this.readSync();
}
return Array.from(this.models.keys());
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
getModelFromEntityClass(entityClass) {
if (Object.prototype.hasOwnProperty.call(entityClass, 'Entity') === false) {
return null;
}
// get entity type annotation
const entityType = entityClass;
// prepare schema
const result = {
name: entityType.Entity.name,
version: entityType.Entity.version || '1.0.0',
abstract: false,
hidden: true,
caching: 'none',
inherits: null,
implements: null,
fields: [],
constraints: [],
eventListeners: [],
privileges: [
{
mask: 15,
type: 'global'
},
{
mask: 15,
type: 'global',
account: 'Administrators'
}
]
};
if (entityType.Entity && entityType.Entity.privileges && entityType.Entity.privileges.length > 0) {
result.privileges = entityType.Entity.privileges;
}
// set inherits
if (entityClass.__proto__) {
const inheritedModel = this.getModelFromEntityClass(entityClass.__proto__);
if (inheritedModel != null) {
// validate inherited entity table
const entityInheritance = entityClass.__proto__;
if (entityInheritance.Inheritance && entityInheritance.Inheritance.strategy === exports.InheritanceType.SingleTable) {
throw new common.DataError('E_INHERITANCE', 'Single table inheritance is not supported by @themost/jspa. Please use Joined or TablePerClass strategies', null, result.name);
}
if (entityInheritance.Inheritance && entityInheritance.Inheritance.strategy === exports.InheritanceType.TablePerClass) {
result.implements = inheritedModel.name;
}
else {
result.inherits = inheritedModel.name;
}
}
}
const edmEntityType = entityType;
if (edmEntityType && edmEntityType.entityTypeDecorator) {
result.hidden = false;
}
// get table annotation
if (Object.prototype.hasOwnProperty.call(entityClass, 'Table') === true) {
const entityTable = entityClass;
if (entityTable.Table != null) {
// set source
result.source = entityTable.Table.name;
// todo: set view
if (Array.isArray(entityTable.Table.uniqueConstraints)) {
// set constraints
result.constraints = entityTable.Table.uniqueConstraints.map((item) => {
return {
type: 'unique',
fields: item.columnNames
};
});
}
}
}
if (Object.prototype.hasOwnProperty.call(entityClass, 'Column') === true) {
const entityColumns = entityClass;
if (entityColumns.Column) {
for (const column of entityColumns.Column.values()) {
// set column type
let columnType;
if (typeof column.type === 'string') {
columnType = column.type;
}
else if (typeof column.type === 'function') {
const targetType = column.type;
if (targetType.Entity) {
columnType = targetType.Entity.name;
}
else {
columnType = targetType.name;
}
}
const field = {
name: column.name,
type: columnType,
nullable: column.nullable,
readonly: Object.prototype.hasOwnProperty.call(column, 'insertable') ? !column.insertable : false,
editable: Object.prototype.hasOwnProperty.call(column, 'updatable') ? column.updatable : true
};
// set additional type
if (column.additionalType) {
let columnAdditionalType;
if (typeof column.additionalType === 'string') {
columnAdditionalType = column.additionalType;
}
else if (typeof column.additionalType === 'function') {
const targetType = column.additionalType;
if (targetType.Entity) {
columnAdditionalType = targetType.Entity.name;
}
else {
columnAdditionalType = targetType.name;
}
}
field.additionalType = columnAdditionalType;
}
// set description
if (column.length) {
field.description = column.description;
}
// set size
if (column.length) {
field.size = column.length;
}
// set scale
if (Object.prototype.hasOwnProperty.call(column, 'scale')) {
field.scale = column.scale;
}
// set validation
const columnValidation = column;
if (columnValidation.validation) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
field.validation = columnValidation.validation;
}
// set primary
const idColumn = column;
if (idColumn.id) {
field.primary = true;
if (field.type == null) {
// field type has not been set
// set default type to Counter (auto increment identity)
field.type = 'Counter';
}
}
// set nested
const embeddedColumn = column;
if (embeddedColumn.embedded) {
field.nested = true;
}
// set expandable
const manyToOneColumn = column;
if (manyToOneColumn.manyToOne && manyToOneColumn.manyToOne.fetchType === exports.FetchType.Eager) {
field.expandable = true;
}
const manyToManyColumn = column;
if (manyToManyColumn.manyToMany) {
new ManyToManyAnnotationParser(result, field).parse(column);
}
const elementCollectionColumn = column;
if (elementCollectionColumn.elementCollection) {
new ElementCollectionAnnotationParser(result, field).parse(column);
}
// one-to-many
const oneToManyColumn = column;
if (oneToManyColumn.oneToMany) {
new OneToManyAnnotationParser(result, field).parse(column);
}
// one-to-one
const oneToOneColumn = column;
if (oneToOneColumn.oneToOne) {
new OneToOneAssociationParser(result, field).parse(column);
}
result.fields.push(field);
}
}
}
result.eventListeners = [
{
type: '@themost/data/previous-state-listener'
},
{
type: '@themost/jspa/listener'
}
];
// set class
Object.assign(result, {
DataObjectClass: entityClass
});
return result;
}
}
exports.PrivilegeMask = void 0;
(function (PrivilegeMask) {
PrivilegeMask[PrivilegeMask["Read"] = 1] = "Read";
PrivilegeMask[PrivilegeMask["Create"] = 2] = "Create";
PrivilegeMask[PrivilegeMask["Update"] = 4] = "Update";
PrivilegeMask[PrivilegeMask["Delete"] = 8] = "Delete";
PrivilegeMask[PrivilegeMask["Execute"] = 16] = "Execute";
PrivilegeMask[PrivilegeMask["Full"] = 31] = "Full";
})(exports.PrivilegeMask || (exports.PrivilegeMask = {}));
function Permission(items) {
return (target) => {
const targetItem = target;
if (Array.isArray(items) && items.length === 0) {
targetItem.privileges = items;
}
else {
targetItem.privileges = [
{
mask: exports.PrivilegeMask.Full,
type: 'global'
}
];
}
};
}
function Entity(annotation) {
return (target) => {
const entityType = target;
let embeddable = false;
if (entityType.Entity && entityType.Entity.name === target.name) {
embeddable = entityType.Entity.embeddable;
}
entityType.Entity = Object.assign({
name: target.name,
version: '1.0.0'
}, annotation);
if (embeddable) {
Object.assign(entityType.Entity, {
embeddable
});
}
// set privileges
Permission(annotation && annotation.privileges);
};
}
function Table(annotation) {
return (target) => {
const table = target;
table.Table = Object.assign({
name: `${target.name}Base`
}, annotation);
};
}
function Column(annotation) {
return (target, propertyKey) => {
if (Object.prototype.hasOwnProperty.call(target.constructor, 'Column') === false) {
Object.assign(target.constructor, {
Column: new Map()
});
}
const columns = target.constructor;
const column = columns.Column.get(propertyKey);
const value = Object.assign({
name: propertyKey,
nullable: true,
insertable: true,
updatable: true
}, column, annotation);
if (value.type == null) {
// get metadata
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const r = Reflect.getMetadata('design:type', target, propertyKey);
if (r && r.name) {
value.type = r.name;
}
}
if (value.entity == null) {
const targetEntity = target.constructor;
if (targetEntity.Entity) {
value.entity = targetEntity.Entity.name;
}
}
columns.Column.set(propertyKey, value);
};
}
function Basic() {
return Column();
}
function JoinTable(annotation) {
return (target, propertyKey) => {
if (typeof propertyKey === 'symbol') {
throw new SymbolTypeNotSupportedException();
}
if (Object.prototype.hasOwnProperty.call(target.constructor, 'Column') === false) {
Object.assign(target.constructor, {
Column: new Map()
});
}
const columns = target.constructor;
// get column
let column = columns.Column.get(propertyKey);
if (column == null) {
column = {
name: propertyKey
};
}
// set value property
Object.assign(column, {
joinTable: annotation
});
// finally, set column annotation
columns.Column.set(propertyKey, column);
};
}
function Id() {
return (target, propertyKey) => {
if (typeof propertyKey === 'symbol') {
throw new SymbolTypeNotSupportedException();
}
if (Object.prototype.hasOwnProperty.call(target.constructor, 'Column') === false) {
Object.assign(target.constructor, {
Column: new Map()
});
}
const columns = target.constructor;
let column = columns.Column.get(propertyKey);
if (column == null) {
column = {
name: propertyKey
};
}
// set generated value property
Object.assign(column, {
id: true
});
// finally, reset column annotation
columns.Column.set(propertyKey, column);
};
}
exports.GenerationType = void 0;
(function (GenerationType) {
GenerationType["Auto"] = "AUTO";
GenerationType["Identity"] = "IDENTITY";
GenerationType["Sequence"] = "SEQUENCE";
GenerationType["Table"] = "TABLE";
})(exports.GenerationType || (exports.GenerationType = {}));
function GeneratedValue(annotation) {
return (target, propertyKey) => {
if (typeof propertyKey === 'symbol') {
throw new SymbolTypeNotSupportedException();
}
if (Object.prototype.hasOwnProperty.call(target.constructor, 'Column') === false) {
Object.assign(target.constructor, {
Column: new Map()
});
}
const columns = target.constructor;
const value = Object.assign({
strategy: exports.GenerationType.Identity
}, annotation);
let column = columns.Column.get(propertyKey);
if (column == null) {
column = {
name: propertyKey
};
}
// set generated value property
Object.assign(column, {
generatedValue: value,
nullable: false,
updatable: false
});
// finally, reset column annotation
columns.Column.set(propertyKey, column);
};
}
function ManyToOne(annotation) {
return (target, propertyKey) => {
if (typeof propertyKey === 'symbol') {
throw new SymbolTypeNotSupportedException();
}
if (Object.prototype.hasOwnProperty.call(target.constructor, 'Column') === false) {
Object.assign(target.constructor, {
Column: new Map()
});
}
const columns = target.constructor;
// get value
const value = Object.assign({
fetchType: exports.FetchType.Eager,
optional: true
}, annotation);
Permission(annotation.privileges);
// get column
let column = columns.Column.get(propertyKey);
if (column == null) {
column = {
name: propertyKey
};
}
// set value property
Object.assign(column, {
manyToOne: value
});
// finally, set column annotation
columns.Column.set(propertyKey, column);
};
}
function ManyToMany(annotation) {
return (target, propertyKey) => {
if (typeof propertyKey === 'symbol') {
throw new SymbolTypeNotSupportedException();
}
if (Object.prototype.hasOwnProperty.call(target.constructor, 'Column') === false) {
Object.assign(target.constructor, {
Column: new Map()
});
}
const columns = target.constructor;
// get value
const value = Object.assign({
fetchType: exports.FetchType.Lazy,
optional: true
}, annotation);
// get column
let column = columns.Column.get(propertyKey);
if (column == null) {
column = {
name: propertyKey
};
}
// try to find target entity
let targetEntity;
if (typeof annotation.targetEntity === 'function') {
targetEntity = annotation.targetEntity.name;
}
else if (typeof annotation.targetEntity === 'string') {
targetEntity = annotation.targetEntity;
}
else {
// get type from reflect metadata
const r = Reflect.getMetadata('design:type', target, propertyKey);
if (r && r.name) {
targetEntity = r.name;
}
}
Permission(annotation.privileges);
// set value property
Object.assign(column, {
manyToMany: value
});
if (targetEntity) {
Object.assign(column, {
type: targetEntity
});
}
// finally, set column annotation
columns.Column.set(propertyKey, column);
};
}
function OneToMany(annotation) {
return (target, propertyKey) => {
if (typeof propertyKey === 'symbol') {
throw new SymbolTypeNotSupportedException();
}
if (Object.prototype.hasOwnProperty.call(target.constructor, 'Column') === false) {
Object.assign(target.constructor, {
Column: new Map()
});
}
// get columns
const columns = target.constructor;
// prepare annotation
const oneToMany = Object.assign({
fetchType: exports.FetchType.Lazy,
optional: true
}, annotation);
// get column
let column = columns.Column.get(propertyKey);
if (column == null) {
Column()(target, propertyKey);
column = columns.Column.get(propertyKey);
}
Permission(annotation.privileges);
// set value property
Object.assign(column, {
oneToMany
});
// finally, set column annotation
columns.Column.set(propertyKey, column);
};
}
function OneToOne(annotation) {
return (target, propertyKey) => {
if (typeof propertyKey === 'symbol') {
throw new SymbolTypeNotSupportedException();
}
if (Object.prototype.hasOwnProperty.call(target.constructor, 'Column') === false) {
Object.assign(target.constructor, {
Column: new Map()
});
}
const columns = target.constructor;
// get value
const value = Object.assign({
fetchType: exports.FetchType.Lazy,
optional: true
}, annotation);
// get column
let column = columns.Column.get(propertyKey);
if (column == null) {
column = {
name: propertyKey
};
}
// try to find target entity
let targetEntity;
if (typeof annotation.targetEntity === 'function') {
targetEntity = annotation.targetEntity.name;
}
else if (typeof annotation.targetEntity === 'string') {
targetEntity = annotation.targetEntity;
}
else {
// get type from reflect metadata
const r = Reflect.getMetadata('design:type', target, propertyKey);
if (r && r.name) {
targetEntity = r.name;
}
}
if (targetEntity == null) {
throw new EntityNotFoundException();
}
Permission(annotation.privileges);
// set value property
Object.assign(column, {
oneToOne: value,
type: targetEntity
});
// finally, set column annotation
columns.Column.set(propertyKey, column);
};
}
function Formula(closure) {
return (target, propertyKey) => {
if (typeof propertyKey === 'symbol') {
throw new SymbolTypeNotSupportedException();
}
if (Object.prototype.hasOwnProperty.call(target.constructor, 'Column') === false) {
Object.assign(target.constructor, {
Column: new Map()
});
}
const columns = target.constructor;
// get column
let column = columns.Column.get(propertyKey);
if (column == null) {
column = {
name: propertyKey
};
}
// set value property
Object.assign(column, {
formula: {
closure
}
});
// finally, set column annotation
columns.Column.set(propertyKey, column);
};
}
function ColumnDefault(closure) {
return (target, propertyKey) => {
if (typeof propertyKey === 'symbol') {
throw new SymbolTypeNotSupportedException();
}
if (Object.prototype.hasOwnProperty.call(target.constructor, 'Column') === false) {
Object.assign(target.constructor, {
Column: new Map()
});
}
const columns = target.constructor;
// get column
let column = columns.Column.get(propertyKey);
if (column == null) {
column = {
name: propertyKey
};
}
// set value property
Object.assign(column, {
columnDefault: {
closure
}
});
// finally, set column annotation
columns.Column.set(propertyKey, column);
};
}
function Inheritance(annotation) {
return (target) => {
const entityInheritance = target;
entityInheritance.Inheritance = Object.assign({
strategy: exports.InheritanceType.Joined
}, annotation);
};
}
function AttributeOverride(annotation) {
return (target) => {
if (Object.prototype.hasOwnProperty.call(target, 'AttributeOverrides') === false) {
Object.assign(target, {
AttributeOverrides: []
});
}
const entity = target;
entity.AttributeOverrides.push(annotation);
};
}
function Embedded() {
return (target, propertyKey) => {
if (typeof propertyKey === 'symbol') {
throw new SymbolTypeNotSupportedException();
}
Column({
name: propertyKey
})(target, propertyKey);
const columns = target.constructor;
const column = columns.Column.get(propertyKey);
Object.assign(column, {
embedded: true
});
columns.Column.set(propertyKey, column);
};
}
function Embeddable() {
return (target) => {
Entity({
embeddable: true
})(target);
};
}
function EntityListeners(...value) {
return (target) => {
if (Object.prototype.hasOwnProperty.call(target, 'EntityListeners') === false) {
Object.assign(target, {
EntityListeners: []
});
}
const entityClass = target;
entityClass.EntityListeners.push(...value);
};
}
function SetCallbackMethod(method) {
return (target, propertyKey, propertyDescriptor) => {
if (typeof propertyKey === 'symbol') {
throw new SymbolTypeNotSupportedException();
}
if (Object.prototype.hasOwnProperty.call(target.constructor, 'CallbackMethods') === false) {
Object.assign(target.constructor, {
CallbackMethods: []
});
}
const entityClass = target.constructor;
entityClass.CallbackMethods.push({
type: method,
name: `${target.constructor.name}.${propertyKey}`,
callback: propertyDescriptor.value
});
};
}
function PreLoad() {
return SetCallbackMethod(PreLoad);
}
function PostLoad() {
return SetCallbackMethod(PostLoad);
}
function PrePersist() {
return SetCallbackMethod(PrePersist);
}
function PostPersist() {
return SetCallbackMethod(PostPersist);
}
function PreUpdate() {
return SetCallbackMethod(PreUpdate);
}
function PostUpdate() {
return SetCallbackMethod(PostUpdate);
}
function PreRemove() {
return SetCallbackMethod(PreRemove);
}
function PostRemove() {
return SetCallbackMethod(PostRemove);
}
function PreInit() {
return SetCallbackMethod(PreInit);
}
function PostInit() {
return SetCallbackMethod(PostInit);
}
function CollectionTable(annotation) {
return (target, propertyKey) => {
if (typeof propertyKey === 'symbol') {
throw new SymbolTypeNotSupportedException();
}
if (Object.prototype.hasOwnProperty.call(target.constructor, 'Column') === false) {
Object.assign(target.constructor, {
Column: new Map()
});
}
const columns = target.constructor;
// get column
let column = columns.Column.get(propertyKey);
if (column == null) {
column = {
name: propertyKey
};
}
// set value property
Object.assign(column, {
joinTable: annotation
});
// finally, set column annotation
columns.Column.set(propertyKey, column);
};
}
function ElementCollection(annotation) {
return (target, propertyKey) => {
if (typeof propertyKey === 'symbol') {
throw new SymbolTypeNotSupportedException();
}
if (Object.prototype.hasOwnProperty.call(target.constructor, 'Column') === false) {
Object.assign(target.constructor, {
Column: new Map()
});
}
const columns = target.constructor;
// get value
const value = Object.assign({
fetchType: exports.FetchType.Lazy,
optional: true
}, annotation);
// get column
let column = columns.Column.get(propertyKey);
if (column == null) {
column = {
name: propertyKey
};
}
// try to find target entity
let targetClass;
if (typeof annotation.targetClass === 'function') {
targetClass = annotation.targetClass.name;
}
else if (typeof annotation.targetClass === 'string') {
targetClass = annotation.targetClass;
}
else {
// get type from reflect metadata
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const r = Reflect.getMetadata('design:type', target, propertyKey);
if (r && r.name) {
targetClass = r.name;
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Permission(annotation.privileges)(value);
// set value property
Object.assign(column, {
elementCollection: value
});
if (targetClass) {
Object.assign(column, {
type: targetClass
});
}
// finally, set column annotation
columns.Column.set(propertyKey, column);
};
}
function tryGetColumn(target, propertyKey) {
if (Object.prototype.hasOwnProperty.call(target.constructor, 'Column') === false) {
Object.assign(target.constructor, {
Column: new Map()
});
}
const columns = target.constructor;
let column = columns.Column.get(propertyKey);
if (column == null) {
column = {
name: propertyKey
};
}
return column;
}
function trySetColumn(target, propertyKey, column) {
if (Object.prototype.hasOwnProperty.call(target.constructor, 'Column') === false) {
Object.assign(target.constructor, {
Column: new Map()
});
}
const columns = target.constructor;
columns.Column.set(propertyKey, column);
}
function Pattern(pattern, patternMessage) {
return (target, propertyKey) => {
if (typeof propertyKey === 'symbol') {
throw new SymbolTypeNotSupportedException();
}
// get column annotation
const column = tryGetColumn(target, propertyKey);
const value = {
pattern,
patternMessage
};
// assign value
Object.assign(column, {
validation: value
});
// set column annotation
trySetColumn(target, propertyKey, column);
};
}
function Size(minLength, maxLength, message) {
return (target, propertyKey) => {
if (typeof propertyKey === 'symbol') {
throw new SymbolTypeNotSupportedException();
}
// get column annotation
const column = tryGetColumn(target, propertyKey);
const value = {
minLength,
maxLength,
message
};
// assign value
Object.assign(column, {
validation: value
});
// set column annotation
trySetColumn(target, propertyKey, column);
};
}
function Min(minValue, message) {
return (target, propertyKey) => {
if (typeof propertyKey === 'symbol') {
throw new SymbolTypeNotSupportedException();
}
// get column annotation
const column = tryGetColumn(target, propertyKey);
const value = {
minValue,
message
};
// assign value
Object.assign(column, {
validation: value
});
// set column annotation
trySetColumn(target, propertyKey, column);
};
}
function Max(maxValue, message) {
return (target, propertyKey) => {
if (typeof propertyKey === 'symbol') {
throw new SymbolTypeNotSupportedException();
}
// get column annotation
const column = tryGetColumn(target, propertyKey);
const value = {
maxValue,
message
};
// assign value
Object.assign(column, {
validation: value
});
// set column annotation
trySetColumn(target, propertyKey, column);
};
}
function Range(minValue, maxValue, message) {
return (target, propertyKey) => {
if (typeof propertyKey === 'symbol') {
throw new SymbolTypeNotSupportedException();
}
// get column annotation
const column = tryGetColumn(target, propertyKey);
const value = {
minValue,
maxValue,
message
};
// assign value
Object.assign(column, {
validation: value
});
// set column annotation
trySetColumn(target, propertyKey, column);
};
}
function Validate(validator, message) {
return (target, propertyKey) => {
if (typeof propertyKey === 'symbol') {
throw new SymbolTypeNotSupportedException();
}
// get column annotation
const column = tryGetColumn(target, propertyKey);
const value = {
validator,
message
};
// assign value
Object.assign(column, {
validation: value
});
// set column annotation
trySetColumn(target, propertyKey, column);
};
}
exports.AttributeOverride = AttributeOverride;
exports.Basic = Basic;
exports.CollectionTable = CollectionTable;
exports.Column = Column;
exports.ColumnDefault = ColumnDefault;
exports.Counter = Counter;
exports.D