UNPKG

nexorm

Version:

A powerful TypeScript ORM with advanced features.

1,342 lines 108 kB
"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}