nexorm
Version:
A powerful TypeScript ORM with advanced features.
1,342 lines • 108 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ModelEngine = exports.Nexorm = exports.models = void 0;
exports.AllowNull = AllowNull;
exports.UUID = UUID;
exports.Enum = Enum;
exports.AutoIncrement = AutoIncrement;
exports.Default = Default;
exports.Required = Required;
exports.Unique = Unique;
exports.Index = Index;
exports.PrimaryKey = PrimaryKey;
exports.ForeignKey = ForeignKey;
exports.Comment = Comment;
exports.Hash = Hash;
exports.Encrypt = Encrypt;
exports.Decrypt = Decrypt;
exports.Reference = Reference;
exports.OneToMany = OneToMany;
exports.OneToOne = OneToOne;
exports.ManyToOne = ManyToOne;
exports.ManyToMany = ManyToMany;
exports.CreatedAt = CreatedAt;
exports.UpdatedAt = UpdatedAt;
exports.DeletedAt = DeletedAt;
exports.IdColumn = IdColumn;
exports.Column = Column;
exports.Paranoid = Paranoid;
exports.Debug = Debug;
exports.Provider = Provider;
exports.Roles = Roles;
exports.Scopes = Scopes;
exports.Model = Model;
require("reflect-metadata");
const node_schedule_1 = require("node-schedule");
const uuid_1 = require("uuid");
const lodash_1 = __importDefault(require("lodash"));
const fileInspector_1 = require("./fileInspector");
const errorHandler_1 = __importDefault(require("./errorHandler"));
const cacheManager_1 = require("./util/cacheManager");
var schema = {};
var havePrimaryKey = false;
var haveAutoIncrement = {};
var primaryKeyCount = {};
var isWarned = false;
var models = [];
exports.models = models;
const export_1 = require("./functions/export");
const chalk_1 = __importDefault(require("chalk"));
const modelBuilder_1 = require("./modelBuilder");
const connectionManager_1 = require("./util/connectionManager");
/**
* @name AllowNull
* @description This decorator is used to define a column in the database.
* @example @AllowNull
* @public
* @returns {void}
*/
function AllowNull(target, key) {
if (!Reflect.hasMetadata(`allowNull-${target.name}`, target)) {
Reflect.defineMetadata(`allowNull-${target.name}`, [], target);
}
const allowNullFields = Reflect.getMetadata(`allowNull-${target.name}`, target);
allowNullFields.push(key);
Reflect.defineMetadata(`allowNull-${target.name}`, allowNullFields, target);
}
;
/**
* @name UUID
* @description This decorator is used to define a column in the database.
* @example @UUID(4)
* @public
* @param v
* @returns {Function}
*/
function UUID(v) {
return function (target, key) {
var selectedUUID = { key: 'v4' };
if (v instanceof Object) {
if (v.v1)
selectedUUID = { key: 'v1' };
if (v.v4)
selectedUUID = { key: 'v4' };
if (v.v3)
selectedUUID = { key: 'v3', namespace: v.v3.namespace, name: v.v3.name };
if (v.v5)
selectedUUID = { key: 'v5', namespace: v.v5.namespace, name: v.v5.name };
if (v.v6)
selectedUUID = { key: 'v6' };
if (v.v7)
selectedUUID = { key: 'v7' };
}
else {
if (v == 1)
selectedUUID = { key: 'v1' };
if (v == 4)
selectedUUID = { key: 'v4' };
if (v == 6)
selectedUUID = { key: 'v6' };
if (v == 7)
selectedUUID = { key: 'v7' };
}
;
var uuidVersionList = {
v1: () => (0, uuid_1.v1)(),
v3: (namespace, name) => (0, uuid_1.v3)(namespace, name),
v4: () => (0, uuid_1.v4)(),
v5: (namespace, name) => (0, uuid_1.v5)(namespace, name),
v6: () => (0, uuid_1.v6)(),
v7: () => (0, uuid_1.v7)(),
};
if (!Reflect.hasMetadata(`defaults-${target.name}`, target)) {
Reflect.defineMetadata(`defaults-${target.name}`, {}, target);
}
const defaults = Reflect.getMetadata(`defaults-${target.name}`, target);
defaults[key] = uuidVersionList[selectedUUID.key](selectedUUID.namespace || 'nexorm', selectedUUID.name || 'nexorm');
Reflect.defineMetadata(`defaults-${target.name}`, defaults, target);
};
}
/**
* @name Enum
* @description This decorator is used to define a column in the database.
* @example @Enum
* @public
* @param values
* @returns {Function}
*/
function Enum(values) {
return function (target, key) {
if (!Reflect.hasMetadata(`enum-${target.name}`, target)) {
Reflect.defineMetadata(`enum-${target.name}`, {}, target);
}
const enums = Reflect.getMetadata(`enum-${target.name}`, target);
enums[key] = values;
Reflect.defineMetadata(`enum-${target.name}`, enums, target);
};
}
;
/**
* @name AutoIncrement
* @description This decorator is used to define a column in the database.
* @example @AutoIncrement
* @public
* @returns {void}
*/
function AutoIncrement(target, key) {
if (!Reflect.hasMetadata(`autoIncrement-${target.name}`, target)) {
Reflect.defineMetadata(`autoIncrement-${target.name}`, [], target);
}
;
if (!Reflect.hasMetadata(`primaryKey-${target.name}`, target)) {
Reflect.defineMetadata(`primaryKey-${target.name}`, [], target);
}
;
if (!Reflect.hasMetadata(`defaults-${target.name}`, target)) {
Reflect.defineMetadata(`defaults-${target.name}`, {}, target);
}
;
const autoIncrements = Reflect.getMetadata(`autoIncrement-${target.name}`, target);
const primaryKey = Reflect.getMetadata(`primaryKey-${target.name}`, target);
const defaults = Reflect.getMetadata(`defaults-${target.name}`, target);
autoIncrements.push(key);
primaryKey.push(key);
defaults[key] = 0;
Reflect.defineMetadata(`autoIncrement-${target.name}`, autoIncrements, target);
}
;
/**
* @name Default
* @description This decorator is used to define a column in the database.
* @example @Default
* @public
* @param value
* @returns {Function}
*/
function Default(value) {
return function (target, key) {
if (!Reflect.hasMetadata(`defaults-${target.name}`, target)) {
Reflect.defineMetadata(`defaults-${target.name}`, {}, target);
}
const defaults = Reflect.getMetadata(`defaults-${target.name}`, target);
defaults[key] = value;
Reflect.defineMetadata(`defaults-${target.name}`, defaults, target);
};
}
;
/**
* @name Required
* @description This decorator is used to define a column in the database.
* @example @Required
* @public
* @returns {void}
*/
function Required(target, key) {
if (!Reflect.hasMetadata(`required-${target.name}`, target)) {
Reflect.defineMetadata(`required-${target.name}`, [], target);
}
const requiredFields = Reflect.getMetadata(`required-${target.name}`, target);
requiredFields.push(key);
Reflect.defineMetadata(`required-${target.name}`, requiredFields, target);
}
;
/**
* @name Unique
* @description This decorator is used to define a column in the database.
* @example @Unique
* @public
* @returns {void}
*/
function Unique(target, key) {
if (!Reflect.hasMetadata(`unique-${target.name}`, target)) {
Reflect.defineMetadata(`unique-${target.name}`, [], target);
}
const uniqueFields = Reflect.getMetadata(`unique-${target.name}`, target);
uniqueFields.push(key);
Reflect.defineMetadata(`unique-${target.name}`, uniqueFields, target);
}
;
/**
* @name Index
* @description This decorator is used to define a column in the database.
* @example @Index
* @public
* @returns {void}
*/
function Index(target, key) {
if (!Reflect.hasMetadata(`index-${target.name}`, target)) {
Reflect.defineMetadata(`index-${target.name}`, [], target);
}
const indexFields = Reflect.getMetadata(`index-${target.name}`, target);
indexFields.push(key);
Reflect.defineMetadata(`index-${target.name}`, indexFields, target);
}
;
/**
* @name PrimaryKey
* @description This decorator is used to define a column in the database.
* @example @PrimaryKey
* @public
* @returns {void}
*/
function PrimaryKey(target, key) {
if (!Reflect.hasMetadata(`primaryKey-${target.name}`, target)) {
Reflect.defineMetadata(`primaryKey-${target.name}`, [], target);
}
const primaryKeyFields = Reflect.getMetadata(`primaryKey-${target.name}`, target);
primaryKeyFields.push(key);
if (primaryKeyCount[target.name] == undefined) {
primaryKeyCount[target.name] = 1;
}
else {
primaryKeyCount[target.name]++;
}
;
Reflect.defineMetadata(`primaryKey-${target.name}`, primaryKeyFields, target);
}
;
/**
* @name ForeignKey
* @description This decorator is used to define a foreign key in the database.
* @example @ForeignKey
* @public
* @param target
* @param key
* @returns {void}
* @throws {Error}
**/
function ForeignKey(relatedModel) {
return function (target, key) {
if (!Reflect.hasMetadata(`foreignKey-${target.name}`, target)) {
Reflect.defineMetadata(`foreignKey-${target.name}`, {}, target);
}
const foreignKeyFields = Reflect.getMetadata(`foreignKey-${target.name}`, target);
foreignKeyFields['key'] = key;
foreignKeyFields['relatedModel'] = relatedModel;
Reflect.defineMetadata(`foreignKey-${target.name}`, foreignKeyFields, target);
};
}
;
/**
* @name Comment
* @description This decorator is used to define a column in the database.
* @example @Comment
* @public
* @param comment
* @returns {Function}
*/
function Comment(comment) {
return function (target, key) {
if (!Reflect.hasMetadata(`comments-${target.name}`, target)) {
Reflect.defineMetadata(`comments-${target.name}`, {}, target);
}
const comments = Reflect.getMetadata(`comments-${target.name}`, target);
comments[key] = comment;
Reflect.defineMetadata(`comments-${target.name}`, comments, target);
};
}
;
/**
* @name Hash
* @description This decorator is used to define a column in the database.
* @example @Hash
* @public
* @param method
* @param digest
* @returns {Function}
*/
function Hash(method, digest) {
if (!method) {
throw new errorHandler_1.default('Method is required', '#FF0000');
}
;
if (!digest)
digest = 'hex';
return function (target, key) {
if (!Reflect.hasMetadata(`hash-${target.name}`, target)) {
Reflect.defineMetadata(`hash-${target.name}`, {}, target);
}
const hash = Reflect.getMetadata(`hash-${target.name}`, target);
hash[key] = { method, digest };
Reflect.defineMetadata(`hash-${target.name}`, hash, target);
};
}
;
/**
* @name Encrypt
* @description This decorator is used to define a column in the database.
* @example @Encrypt
* @public
* @param method
* @param cipherKey
* @param iv
* @returns {Function}
* @throws {Error}
*/
function Encrypt(method, cipherKey, iv) {
if (!method) {
throw new errorHandler_1.default('Method is required', '#FF0000');
}
;
if (!cipherKey) {
throw new errorHandler_1.default('Cipher Key is required', '#FF0000');
}
;
if (!iv) {
throw new errorHandler_1.default('IV is required', '#FF0000');
}
;
return function (target, key) {
if (!Reflect.hasMetadata(`encrypt-${target.name}`, target)) {
Reflect.defineMetadata(`encrypt-${target.name}`, {}, target);
}
;
const encrypt = Reflect.getMetadata(`encrypt-${target.name}`, target);
encrypt[key] = { method, cipherKey, iv };
Reflect.defineMetadata(`encrypt-${target.name}`, encrypt, target);
};
}
;
/**
* @name Decrypt
* @description This decorator is used to define a column in the database.
* @example @Decrypt
* @public
* @param method
* @param cipherKey
* @param iv
* @returns {Function}
* @throws {Error}
*/
function Decrypt(method, cipherKey, iv) {
if (!method) {
throw new errorHandler_1.default('Method is required', '#FF0000');
}
;
if (!cipherKey) {
throw new errorHandler_1.default('Cipher Key is required', '#FF0000');
}
;
if (!iv) {
throw new errorHandler_1.default('IV is required', '#FF0000');
}
;
return function (target, key) {
if (!Reflect.hasMetadata(`decrypt-${target.name}`, target)) {
Reflect.defineMetadata(`decrypt-${target.name}`, {}, target);
}
;
const decrypt = Reflect.getMetadata(`decrypt-${target.name}`, target);
decrypt[key] = { method, cipherKey, iv };
Reflect.defineMetadata(`decrypt-${target.name}`, decrypt, target);
};
}
;
/**
* @name Reference
* @description This decorator is used to define a column in the database.
* @example @Reference
* @public
* @param value
* @returns {Function}
*/
function Reference(value) {
return function (target, key) {
if (!Reflect.hasMetadata(`references-${target.name}`, target)) {
Reflect.defineMetadata(`references-${target.name}`, {}, target);
}
const references = Reflect.getMetadata(`references-${target.name}`, target);
references[key] = value;
Reflect.defineMetadata(`references-${target.name}`, references, target);
};
}
;
;
;
;
;
/* Relationship */
function OneToMany(relatedModel, inverse, options) {
return function (target, propertyKey) {
if (!propertyKey) {
throw new errorHandler_1.default('Property key is required for OneToMany relationship', '#FF0000');
}
if (!Reflect.hasMetadata(`oneToMany-${target.name}`, target)) {
Reflect.defineMetadata(`oneToMany-${target.name}`, {}, target);
}
const oneToMany = Reflect.getMetadata(`oneToMany-${target.name}`, target);
oneToMany[propertyKey] = { relatedModel, inverse, options, sourcePop: String(propertyKey) };
Reflect.defineMetadata(`oneToMany-${target.name}`, oneToMany, target);
};
}
function OneToOne(relatedModel, inverse, options) {
return function (target, propertyKey) {
if (!propertyKey) {
throw new errorHandler_1.default('Property key is required for OneToOne relationship', '#FF0000');
}
if (!Reflect.hasMetadata(`oneToOne-${target.name}`, target)) {
Reflect.defineMetadata(`oneToOne-${target.name}`, {}, target);
}
const oneToOne = Reflect.getMetadata(`oneToOne-${target.name}`, target);
oneToOne[propertyKey] = { relatedModel, inverse, options, sourcePop: String(propertyKey) };
Reflect.defineMetadata(`oneToOne-${target.name}`, oneToOne, target);
};
}
function ManyToOne(relatedModel, inverse, options) {
return function (target, propertyKey) {
if (!propertyKey) {
throw new errorHandler_1.default('Property key is required for ManyToOne relationship', '#FF0000');
}
if (!Reflect.hasMetadata(`manyToOne-${target.name}`, target)) {
Reflect.defineMetadata(`manyToOne-${target.name}`, {}, target);
}
const manyToOne = Reflect.getMetadata(`manyToOne-${target.name}`, target);
manyToOne[propertyKey] = { relatedModel, inverse, options, sourcePop: String(propertyKey) };
Reflect.defineMetadata(`manyToOne-${target.name}`, manyToOne, target);
};
}
function ManyToMany(relatedModel, inverse, options) {
return function (target, propertyKey) {
if (!propertyKey) {
throw new errorHandler_1.default('Property key is required for ManyToMany relationship', '#FF0000');
}
if (!Reflect.hasMetadata(`manyToMany-${target.name}`, target)) {
Reflect.defineMetadata(`manyToMany-${target.name}`, {}, target);
}
const manyToMany = Reflect.getMetadata(`manyToMany-${target.name}`, target);
manyToMany[propertyKey] = { relatedModel, inverse, options, sourcePop: String(propertyKey) };
Reflect.defineMetadata(`manyToMany-${target.name}`, manyToMany, target);
};
}
/* */
function CreatedAt(target, key) {
if (!String(target[key]).includes('Date'))
throw new errorHandler_1.default(`The column "${key}" is not a Date type. Please ensure that the column type is correct and follows the expected naming conventions.`, '#FF0000');
Reflect.defineMetadata(`createdAt-${target.name}`, key, target);
}
;
function UpdatedAt(target, key) {
if (!String(target[key]).includes('Date'))
throw new errorHandler_1.default(`The column "${key}" is not a Date type. Please ensure that the column type is correct and follows the expected naming conventions.`, '#FF0000');
Reflect.defineMetadata(`updatedAt-${target.name}`, key, target);
}
;
function DeletedAt(target, key) {
if (!String(target[key]).includes('Date'))
throw new errorHandler_1.default(`The column "${key}" is not a Date type. Please ensure that the column type is correct and follows the expected naming conventions.`, '#FF0000');
Reflect.defineMetadata(`deletedAt-${target.name}`, key, target);
}
;
function IdColumn(target, key) {
/* Push to rows */
if (['name'].includes(String(key)))
throw new errorHandler_1.default(`The column name "${key}" is invalid. Please ensure that the column name is correct and follows the expected naming conventions.`, '#FF0000');
if (!Reflect.hasMetadata(`rows-${target.name}`, target)) {
Reflect.defineMetadata(`rows-${target.name}`, [], target);
}
const rows = Reflect.getMetadata(`rows-${target.name}`, target);
rows.push({ key, keyType: target[key] });
Reflect.defineMetadata(`rows-${target.name}`, rows, target);
/* Define AutoIncrement */
if (!Reflect.hasMetadata(`autoIncrement-${target.name}`, target)) {
Reflect.defineMetadata(`autoIncrement-${target.name}`, [], target);
}
;
if (!Reflect.hasMetadata(`primaryKey-${target.name}`, target)) {
Reflect.defineMetadata(`primaryKey-${target.name}`, [], target);
}
;
if (!Reflect.hasMetadata(`defaults-${target.name}`, target)) {
Reflect.defineMetadata(`defaults-${target.name}`, {}, target);
}
;
const autoIncrements = Reflect.getMetadata(`autoIncrement-${target.name}`, target);
const primaryKey = Reflect.getMetadata(`primaryKey-${target.name}`, target);
const defaults = Reflect.getMetadata(`defaults-${target.name}`, target);
autoIncrements.push(key);
primaryKey.push(key);
defaults[key] = 0;
Reflect.defineMetadata(`autoIncrement-${target.name}`, autoIncrements, target);
}
;
function Column(target, key) {
if (['name'].includes(String(key)))
throw new errorHandler_1.default(`The column name "${key}" is invalid. Please ensure that the column name is correct and follows the expected naming conventions.`, '#FF0000');
if (!Reflect.hasMetadata(`rows-${target.name}`, target)) {
Reflect.defineMetadata(`rows-${target.name}`, [], target);
}
const rows = Reflect.getMetadata(`rows-${target.name}`, target);
rows.push({ key, keyType: target[key] });
Reflect.defineMetadata(`rows-${target.name}`, rows, target);
}
;
function Paranoid(target) {
Reflect.defineMetadata(`paranoid-${target.name}`, true, target);
}
;
function Debug(target) {
Reflect.defineMetadata(`debug-${target.name}`, true, target);
}
;
function Provider(providerName) {
return function (target) {
Reflect.defineMetadata(`databaseName-${target.name}`, providerName, target);
};
}
;
function Roles(roles) {
return function (target) {
Reflect.defineMetadata(`roles-${target.name}`, roles, target);
};
}
;
function Scopes(scopes) {
return function (target) {
Reflect.defineMetadata(`scopes-${target.name}`, scopes, target);
};
}
;
;
;
;
;
;
;
;
/**
* Nexorm
* @description Nexorm Main Class
* @class Nexorm
* @public
* @async
* @type {Class}
* @example import Nexorm from 'nexorm';
* @returns {Class}
*/
class Nexorm {
/**
* Nexorm Config
* @type {NexormConfig}
* @public
* @static
* @example Nexorm.$config
*/
static $configs = fileInspector_1.cachedConfig;
/**
* Nexorm Providers
* @type {string[]}
* @public
* @static
* @example Nexorm.$providers
*/
static $providers = fileInspector_1.sequelizes.map(x => x.name);
/**
* Nexorm Scheduled Jobs
* @static
* @public
* @example Nexorm.$crons
* @description Get All Scheduled Jobs
* @example Nexorm.$crons.$every()
* @example Nexorm.$crons.$get('jobName')
* @returns {Object}
*/
static $crons = {
/**
* Get All Scheduled Jobs
* @returns {Job[]}
* @example Nexorm.$crons.$every()
* @description Get All Scheduled Jobs
*/
$every: () => {
return Object.values(node_schedule_1.scheduledJobs);
},
/**
* Get Scheduled Job by Name
* @param {string} name - Job Name
* @returns {Job | undefined}
* @example Nexorm.$crons.$get('jobName')
* @description Get Scheduled Job by Name
*/
$get: (name) => {
return node_schedule_1.scheduledJobs[name];
},
/**
* Add a Scheduled Job
* @param {string} name - Job Name
* @param {string} cron - Cron Expression
* @param {() => void} callback - Callback Function
* @returns {Job}
* @example Nexorm.$crons.$addSchedule('jobName', '0 0 * * *', () => { console.log('Job executed'); })
* @description Add a Scheduled Job
*/
$addSchedule: (name, cron, callback) => {
if (node_schedule_1.scheduledJobs[name]) {
throw new errorHandler_1.default(`Cron Job with name ${name} already exists`, '#FF0000');
}
;
if (!cron || !callback) {
throw new errorHandler_1.default('Cron Job name, cron expression and callback function are required', '#FF0000');
}
;
if (typeof cron !== 'string') {
throw new errorHandler_1.default('Cron Job cron expression must be a string', '#FF0000');
}
;
if (typeof callback !== 'function') {
throw new errorHandler_1.default('Cron Job callback must be a function', '#FF0000');
}
;
(0, node_schedule_1.scheduleJob)(name, cron, callback);
return node_schedule_1.scheduledJobs[name];
},
/**
* Cancel a Scheduled Job
* @param {string} name - Job Name
* @returns {boolean}
* @example Nexorm.$crons.$cancel('jobName')
* @description Cancel a Scheduled Job
*/
$cancel: (name) => {
if (node_schedule_1.scheduledJobs[name]) {
node_schedule_1.scheduledJobs[name].cancel();
delete node_schedule_1.scheduledJobs[name];
return true;
}
;
return false;
},
/**
* Cancel All Scheduled Jobs
* @returns {boolean}
* @example Nexorm.$crons.$cancelAll()
* @description Cancel All Scheduled Jobs
*/
$cancelAll: () => {
Object.keys(node_schedule_1.scheduledJobs).forEach((name) => {
node_schedule_1.scheduledJobs[name].cancel();
delete node_schedule_1.scheduledJobs[name];
});
return true;
},
};
/**
* Nexorm Connections
* @type {Object}
* @public
* @static
* @example Nexorm.$connections.$size
* @example Nexorm.$connections.$list
* @returns {Object}
* @description Get All Connections
* @example Nexorm.$connections
*/
static $connections = { $size: fileInspector_1.connections.length, $list: fileInspector_1.connections };
/**
* Connect To Database
* @param providerName Provider Name
* @returns Promise<void>
* @example await Nexorm.$connect('nexorm')
*/
static async $connect(providerName) {
if (!providerName)
providerName = 'nexorm';
if (fileInspector_1.connections.find(x => x == providerName)) {
throw new errorHandler_1.default('Connection Already Exists, Try Again by Trying Other Providers Or You\'re Already Connected', '#FF0000');
}
;
return await (0, fileInspector_1.connect)(providerName);
}
;
/**
* Disconnect From Database
* @param providerName Provider Name
* @returns Promise<void>
* @example await Nexorm.$disconnect('nexorm')
*/
static async $disconnect(providerName) {
if (!providerName)
providerName = 'nexorm';
if (!fileInspector_1.connections.find(x => x == providerName)) {
throw new errorHandler_1.default('Connection Not Found, Try Again by Trying Other Providers Or You\'re Already Disconnected', '#FF0000');
}
;
await (0, fileInspector_1.closeConnection)(providerName);
}
;
/**
* Drop Database
* @param providerName Provider Name
* @returns Promise<void>
* @example await Nexorm.$drop('nexorm')
*/
static async $drop(providerName) {
if (!providerName)
providerName = 'nexorm';
if (!fileInspector_1.connections.find(x => x == providerName)) {
throw new errorHandler_1.default('Connection Not Found, Try Again by Trying Other Providers Or You\'re Already Disconnected', '#FF0000');
}
;
await (0, fileInspector_1.dropProvider)(providerName);
}
;
/**
* Close All Connections
* @returns Promise<void>
* @example await Nexorm.$closeAllConnections()
* @description Close All Connections
*/
static async $closeAllConnections() {
for (var i = 0; i < fileInspector_1.connections.length; i++) {
await (0, fileInspector_1.closeConnection)(fileInspector_1.connections[i]);
}
;
}
;
/**
* Connect All Providers
* @returns Promise<void>
* @example await Nexorm.$connectAll()
* @description Connect All Providers
*/
static async $connectAll() {
await (0, fileInspector_1.connectAll)();
}
;
/**
* Transaction
* @param providerName Provider Name
* @returns Promise<Transaction>
* @example await Nexorm.$transaction('nexorm')
* @description Create a Transaction
*/
static async $transaction(providerName) {
if (!providerName)
providerName = 'nexorm';
await connectionManager_1.ConnectionManager.waitUntilConnected(providerName);
const sequelize = fileInspector_1.sequelizes.find(x => x.name === providerName);
if (!sequelize || !sequelize.sequelize) {
throw new errorHandler_1.default(`Sequelize provider "${providerName}" not found.`, '#FF0000');
}
;
const trx = await sequelize.sequelize.transaction();
const wrapped = returnTransaction(trx, providerName);
return wrapped;
}
;
}
exports.Nexorm = Nexorm;
;
function returnTransaction(transaction, providerName) {
const DynamicClass = class {
trx;
$id;
$provider;
$commit;
$rollback;
$afterCommit;
constructor() {
this.trx = transaction;
this.$id = transaction.id;
this.$provider = providerName;
this.$commit = () => transaction.commit();
this.$rollback = () => transaction.rollback();
this.$afterCommit = (callback) => {
if (typeof callback !== 'function') {
throw new errorHandler_1.default('Callback must be a function', '#FF0000');
}
;
transaction.afterCommit(callback);
};
Object.defineProperty(this, 'trx', {
enumerable: false,
writable: false,
configurable: false,
});
}
};
Object.defineProperty(DynamicClass, 'name', { value: 'Transaction' });
return new DynamicClass();
}
;
async function getConfigByProvider(providerName) {
const config = await (0, fileInspector_1.readConfig)().catch((err) => { return undefined; });
if (!config) {
throw new errorHandler_1.default('Nexorm Config Not Found, Please Create a Config File', '#FF0000');
}
;
var providerConfig = config.find((x) => x.$provider == providerName);
if (!providerConfig) {
throw new errorHandler_1.default(`Nexorm Config Not Found For Provider: ${providerName}, Please Create a Config File`, '#FF0000');
}
;
return providerConfig;
}
;
;
function Model(Schema) {
const modelEngine = new ModelEngine(Schema);
const engine = modelEngine.initialize();
const DynamicModel = class {
#isNew = false;
constructor(dataValue) {
this.#isNew = true;
/* Define Properties */
if (dataValue) {
Object.keys(dataValue)
.filter((key) => !['length', 'name', 'prototype'].includes(key))
.forEach((key) => {
this[key] = dataValue ? dataValue[key] : undefined;
});
}
;
/* Hide Properties */
Object.defineProperty(this, '$toObject', { enumerable: false, configurable: false, writable: false });
Object.defineProperty(this, '$save', { enumerable: false, configurable: false, writable: false });
Object.defineProperty(this, '$get', { enumerable: false, configurable: false, writable: false });
Object.defineProperty(this, '$set', { enumerable: false, configurable: false, writable: false });
Object.defineProperty(this, '$clear', { enumerable: false, configurable: false, writable: false });
Object.defineProperty(this, '$toJSON', { enumerable: false, configurable: false, writable: false });
Object.defineProperty(this, '$toStringify', { enumerable: false, configurable: false, writable: false });
Object.defineProperty(this, '$isNew', { enumerable: false, configurable: false, writable: false });
}
;
/* Initialize Engine */
$get = (property) => {
var value = this[property];
if (value) {
return value;
}
;
return null;
};
$set = (property, value) => {
this[property] = value;
return this[property];
};
$clear = () => {
Object.keys(this).forEach((key) => {
if (String(key).startsWith('$') ||
String(key) == 'length' ||
String(key) == 'name' ||
String(key) == 'prototype' ||
String(key) == 'constructor' ||
['toObject', 'save', 'toJSON', 'toStringify', 'clear', 'get', 'set', 'isNew'].includes(String(key)))
return;
delete this[key];
});
};
$toJSON = () => {
try {
return JSON.parse(JSON.stringify(this.$toObject()));
}
catch (error) {
return {};
}
};
$toStringify = () => {
try {
return JSON.stringify(this.$toObject());
}
catch (error) {
return '';
}
};
$toObject = () => Object.assign({}, this);
$isNew = () => {
return this.#isNew;
};
$save = async (dataValue) => {
if (!dataValue)
dataValue = {};
await this.#constructorInitialize();
await connectionManager_1.ConnectionManager.connectIfNotConnected(engine.$provider);
if (engine.$config && engine.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(engine.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(engine.$provider);
}
;
if (engine.$debugMode)
debugLog(`Saving Data: ${engine.$schema.name} - dataValue: ${JSON.stringify(dataValue)}`);
var dataValues = this.#isNew ?
await engine.$build({ ...this.$toObject(), ...dataValue }) :
await engine.$update({ $where: { ObjectId: this?.ObjectId }, $update: { $set: { ...this.$toObject(), ...dataValue } } });
if (this.#isNew)
this.#isNew = false;
if (dataValues) {
Object.keys(dataValues).forEach((key) => {
if (String(key).startsWith('$') ||
String(key) == 'length' ||
String(key) == 'name' ||
String(key) == 'prototype' ||
String(key) == 'constructor' ||
['toObject', 'save', 'toJSON', 'toStringify', 'clear', 'get', 'set', 'isNew'].includes(String(key)))
return;
this[key] = dataValues[key];
});
}
;
return dataValues;
};
/* */
static $search = async (values) => {
await this.#initialize();
if (engine.$config && engine.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(engine.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(engine.$provider);
}
;
return engine.$search(values);
};
static $searchFirst = async () => {
await this.#initialize();
if (engine.$config && engine.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(engine.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(engine.$provider);
}
;
return engine.$searchFirst();
};
static $searchOne = async (values) => {
await this.#initialize();
if (engine.$config && engine.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(engine.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(engine.$provider);
}
;
return engine.$searchOne(values);
};
static $searchById = async (values) => {
await this.#initialize();
if (engine.$config && engine.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(engine.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(engine.$provider);
}
;
return engine.$searchById(values);
};
static $searchByIds = async (values) => {
await this.#initialize();
if (engine.$config && engine.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(engine.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(engine.$provider);
}
;
return engine.$searchByIds(values);
};
static $searchAndCount = async (values) => {
await this.#initialize();
if (engine.$config && engine.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(engine.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(engine.$provider);
}
;
return engine.$searchAndCount(values);
};
static $everything = async () => {
await this.#initialize();
if (engine.$config && engine.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(engine.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(engine.$provider);
}
;
return engine.$everything();
};
static $count = async (values) => {
await this.#initialize();
if (engine.$config && engine.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(engine.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(engine.$provider);
}
;
return engine.$count(values);
};
static $query = async (values) => {
await this.#initialize();
if (engine.$config && engine.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(engine.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(engine.$provider);
}
;
return engine.$query(values);
};
static $distinct = async (values) => {
await this.#initialize();
if (engine.$config && engine.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(engine.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(engine.$provider);
}
;
return engine.$distinct(values);
};
static $scope = (scope, values) => {
return engine.$scope(scope, values);
};
static $build = async (values) => {
await this.#initialize();
if (engine.$config && engine.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(engine.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(engine.$provider);
}
;
return engine.$build(values);
};
static $buildMany = async (values) => {
await this.#initialize();
if (engine.$config && engine.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(engine.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(engine.$provider);
}
;
return engine.$buildMany(values);
};
static $searchAndReplace = async (values) => {
await this.#initialize();
if (engine.$config && engine.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(engine.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(engine.$provider);
}
;
return engine.$searchAndReplace(values);
};
static $update = async (values) => {
await this.#initialize();
if (engine.$config && engine.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(engine.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(engine.$provider);
}
;
return engine.$update(values);
};
static $updateMany = async (values) => {
await this.#initialize();
if (engine.$config && engine.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(engine.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(engine.$provider);
}
;
return engine.$updateMany(values);
};
static $upsert = async (values) => {
await this.#initialize();
if (engine.$config && engine.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(engine.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(engine.$provider);
}
;
return engine.$upsert(values);
};
static $delete = async (values) => {
await this.#initialize();
if (engine.$config && engine.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(engine.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(engine.$provider);
}
;
return engine.$delete(values);
};
static $deleteMany = async (values) => {
await this.#initialize();
if (engine.$config && engine.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(engine.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(engine.$provider);
}
;
return engine.$deleteMany(values);
};
static $restore = async (values) => {
await this.#initialize();
if (engine.$config && engine.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(engine.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(engine.$provider);
}
;
return engine.$restore(values);
};
static $softDelete = async (values) => {
await this.#initialize();
if (engine.$config && engine.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(engine.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(engine.$provider);
}
;
return engine.$softDelete(values);
};
static $softDeleteMany = async (values) => {
await this.#initialize();
if (engine.$config && engine.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(engine.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(engine.$provider);
}
;
return engine.$softDeleteMany(values);
};
static $truncate = async () => {
await this.#initialize();
if (engine.$config && engine.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(engine.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(engine.$provider);
}
;
return engine.$truncate();
};
static $cache = engine.$cache;
static $debugMode = engine.$debugMode;
static $hooks = engine.$hooks;
static $middlewares = engine.$middlewares;
static $model = engine.$model;
static $schema = engine.$schema;
static $provider = engine.$provider;
static $config = engine.$config;
/* Initialize */
/**
* Initialize the model
* @returns Promise<boolean>
* @private
*/
/********/
static async #initialize() {
if (this.$config)
return true;
var config = await getConfigByProvider(engine.$provider).catch((err) => { });
if (!config)
return false;
engine.$config = config;
this.$config = config;
return true;
}
;
async #constructorInitialize() {
if (engine.$config)
return true;
var config = await getConfigByProvider(engine.$provider).catch((err) => { });
if (!config)
return false;
engine.$config = config;
}
;
};
Object.defineProperty(DynamicModel, 'name', { value: Schema.name });
return DynamicModel;
}
;
;
class ModelEngine {
Schema;
$type;
$model;
$middlewares = [];
$cache = new cacheManager_1.CacheManager();
$config;
;
$debugMode = false;
$schema;
$provider;
constructor(Schema) {
this.Schema = Schema;
this.$provider = Reflect.getMetadata(`databaseName-${Schema.name}`, Schema) || 'nexorm';
this.$schema = Schema;
this.$middlewares = [];
if (!String(Schema).includes("class"))
throw new errorHandler_1.default('Schema Must Be A Static Class', '#FF0000');
var debug = Reflect.getMetadata(`debug-${this.$schema.name}`, this.$schema) || false;
this.$debugMode = debug;
}
;
initialize() {
return this;
}
;
/**
* Scope
*
*/
$scope(scopes, ...args) {
var scope = {};
if (typeof scopes === 'string') {
var getScopes = Reflect.getMetadata(`scopes-${this.$schema.name}`, this.$schema) || {};
if (!getScopes[scopes]) {
throw new errorHandler_1.default(`Scope ${scopes} Not Found`, '#FF0000');
}
;
if (typeof getScopes[scopes] == 'function') {
scope = getScopes[scopes](...args);
}
else {
scope = getScopes[scopes];
}
}
else if (lodash_1.default.isArray(scopes)) {
var getScopes = Reflect.getMetadata(`scopes-${this.$schema.name}`, this.$schema) || {};
for (var i = 0; i < scopes.length; i++) {
if (!getScopes[scopes[i]]) {
throw new errorHandler_1.default(`Scope ${scopes[i]} Not Found`, '#FF0000');
}
;
if (typeof getScopes[scopes[i]] == 'function') {
scope = { ...scope, ...getScopes[scopes[i]](...args) };
}
else {
scope = { ...scope, ...getScopes[scopes[i]] };
}
}
;
}
;
if (Object.keys(scope).length === 0) {
throw new errorHandler_1.default('Scope Not Found', '#FF0000');
}
;
return {
/* İnitalize yapılcak ModelEngine Kımsındaki gibi wait untilli yer gibi */
$searchOne: async (query) => {
var searchQuery = { ...scope?.$where, ...query?.$where };
var optionsQuery = { ...scope?.$options, ...query?.$options };
if (this.$config && this.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(this.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(this.$provider);
}
;
if (this.$debugMode)
debugLog(`Searching One Data: ${this.$schema.name} - $where: ${JSON.stringify(searchQuery)} - $options: ${JSON.stringify(optionsQuery)}`);
const dataValues = await this.$searchOne({ $where: searchQuery, $options: optionsQuery });
return dataValues;
},
$search: async (query) => {
var searchQuery = { ...scope?.$where, ...query?.$where };
var optionsQuery = { ...scope?.$options, ...query?.$options };
if (this.$config && this.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(this.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(this.$provider);
}
;
if (this.$debugMode)
debugLog(`Searching Data: ${this.$schema.name} - $where: ${JSON.stringify(searchQuery)} - $options: ${JSON.stringify(optionsQuery)}`);
const dataValues = await this.$search({ $where: searchQuery, $options: optionsQuery });
return dataValues;
},
$update: async (query) => {
var updateQuery = { ...scope?.$where, ...query?.$where };
var updateOptions = { ...query?.$update };
var rulesQuery = { ...query?.$rules };
if (this.$config && this.$config.$autoConnect) {
await connectionManager_1.ConnectionManager.connectIfNotConnected(this.$provider);
}
else {
await connectionManager_1.ConnectionManager.waitUntilConnected(this.$provider);
}
;
if (this.$debugMode)
debugLog(`Updating Data: ${this.$schema.name}