UNPKG

@sequelize/core

Version:

Sequelize is a promise-based Node.js ORM tool for Postgres, MySQL, MariaDB, SQLite, Microsoft SQL Server, Amazon Redshift, Snowflake’s Data Cloud, Db2, and IBM i. It features solid transaction support, relations, eager and lazy loading, read replication a

436 lines (435 loc) 18.8 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var model_typescript_exports = {}; __export(model_typescript_exports, { ModelTypeScript: () => ModelTypeScript, initModel: () => initModel }); module.exports = __toCommonJS(model_typescript_exports); var import_utils = require("@sequelize/utils"); var import_node_util = require("node:util"); var import_model = require("./decorators/shared/model.js"); var import_hooks_legacy = require("./hooks-legacy.js"); var import_model_definition = require("./model-definition.js"); var import_model_hooks = require("./model-hooks.js"); var import_model_repository = require("./model-repository.js"); var import_model2 = require("./model.js"); var import_sequelize = require("./sequelize.js"); var import_deprecations = require("./utils/deprecations.js"); var import_object = require("./utils/object.js"); class ModelTypeScript { static get queryInterface() { return this.sequelize.queryInterface; } static get queryGenerator() { return this.sequelize.queryGenerator; } /** * A reference to the sequelize instance. */ get sequelize() { return this.constructor.sequelize; } /** * A reference to the sequelize instance. * * Accessing this property throws if the model has not been registered with a Sequelize instance yet. */ static get sequelize() { return this.modelDefinition.sequelize; } /** * Returns the model definition of this model. * The model definition contains all metadata about this model. */ static get modelDefinition() { return (0, import_model_definition.getModelDefinition)(this); } get modelDefinition() { return this.constructor.modelDefinition; } static get modelRepository() { return (0, import_model_repository.getModelRepository)(this.modelDefinition); } get modelRepository() { return this.constructor.modelRepository; } /** * An object hash from alias to the association object */ static get associations() { return this.modelDefinition.associations; } /** * The name of the primary key attribute (on the JS side). * * @deprecated This property doesn't work for composed primary keys. Use {@link primaryKeyAttributes} instead. */ static get primaryKeyAttribute() { return this.primaryKeyAttributes[0] ?? null; } /** * The name of the primary key attributes (on the JS side). * * @deprecated use {@link modelDefinition}. */ static get primaryKeyAttributes() { return [...this.modelDefinition.primaryKeysAttributeNames]; } /** * The column name of the primary key. * * @deprecated don't use this. It doesn't work with composite PKs. It may be removed in the future to reduce duplication. * Use the. Use {@link Model.primaryKeys} instead. */ static get primaryKeyField() { const primaryKeyAttribute = this.primaryKeyAttribute; if (!primaryKeyAttribute) { return null; } return this.modelDefinition.getColumnName(primaryKeyAttribute); } /** * Like {@link Model.rawAttributes}, but only includes attributes that are part of the Primary Key. */ static get primaryKeys() { const out = /* @__PURE__ */ Object.create(null); const definition = this.modelDefinition; for (const primaryKey of definition.primaryKeysAttributeNames) { out[primaryKey] = definition.attributes.get(primaryKey); } return out; } /** * The options that the model was initialized with */ static get options() { return this.modelDefinition.options; } /** * The name of the database table * * @deprecated use {@link modelDefinition} or {@link table}. */ static get tableName() { (0, import_deprecations.noModelTableName)(); return this.modelDefinition.table.tableName; } static get table() { return this.modelDefinition.table; } /** * @deprecated use {@link modelDefinition}'s {@link ModelDefinition#rawAttributes} or {@link ModelDefinition#attributes} instead. */ static get rawAttributes() { throw new Error(`${this.name}.rawAttributes has been removed, as it has been split in two: - If you only need to read the final attributes, use ${this.name}.modelDefinition.attributes - If you need to modify the attributes, mutate ${this.name}.modelDefinition.rawAttributes, then call ${this.name}.modelDefinition.refreshAttributes()`); } /** * @deprecated use {@link modelDefinition}'s {@link ModelDefinition#rawAttributes} or {@link ModelDefinition#attributes} instead. */ get rawAttributes() { return this.constructor.rawAttributes; } /** * @deprecated use {@link modelDefinition}'s {@link ModelDefinition#columns}. */ static get fieldRawAttributesMap() { return (0, import_object.getObjectFromMap)(this.modelDefinition.columns); } /** * @deprecated use {@link modelDefinition}'s {@link ModelDefinition#physicalAttributes}. */ static get tableAttributes() { return (0, import_object.getObjectFromMap)(this.modelDefinition.physicalAttributes); } /** * A mapping of column name to attribute name * * @private */ static get fieldAttributeMap() { const out = /* @__PURE__ */ Object.create(null); const attributes = this.modelDefinition.attributes; for (const attribute of attributes.values()) { out[attribute.columnName] = attribute.attributeName; } return out; } static get hooks() { return this.modelDefinition.hooks; } static addHook = (0, import_hooks_legacy.legacyBuildAddAnyHook)(import_model_hooks.staticModelHooks); static hasHook = (0, import_hooks_legacy.legacyBuildHasHook)(import_model_hooks.staticModelHooks); static hasHooks = (0, import_hooks_legacy.legacyBuildHasHook)(import_model_hooks.staticModelHooks); static removeHook = (0, import_hooks_legacy.legacyBuildRemoveHook)(import_model_hooks.staticModelHooks); static runHooks = (0, import_hooks_legacy.legacyBuildRunHook)(import_model_hooks.staticModelHooks); static beforeValidate = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "beforeValidate"); static afterValidate = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "afterValidate"); static validationFailed = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "validationFailed"); static beforeCreate = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "beforeCreate"); static afterCreate = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "afterCreate"); static beforeDestroy = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "beforeDestroy"); static afterDestroy = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "afterDestroy"); static beforeRestore = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "beforeRestore"); static afterRestore = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "afterRestore"); static beforeUpdate = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "beforeUpdate"); static afterUpdate = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "afterUpdate"); static beforeUpsert = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "beforeUpsert"); static afterUpsert = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "afterUpsert"); static beforeSave = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "beforeSave"); static afterSave = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "afterSave"); static beforeBulkCreate = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "beforeBulkCreate"); static afterBulkCreate = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "afterBulkCreate"); static beforeBulkDestroy = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "beforeBulkDestroy"); static afterBulkDestroy = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "afterBulkDestroy"); static beforeBulkRestore = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "beforeBulkRestore"); static afterBulkRestore = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "afterBulkRestore"); static beforeBulkUpdate = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "beforeBulkUpdate"); static afterBulkUpdate = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "afterBulkUpdate"); static beforeCount = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "beforeCount"); static beforeFind = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "beforeFind"); static beforeFindAfterExpandIncludeAll = (0, import_hooks_legacy.legacyBuildAddHook)( import_model_hooks.staticModelHooks, "beforeFindAfterExpandIncludeAll" ); static beforeFindAfterOptions = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "beforeFindAfterOptions"); static afterFind = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "afterFind"); static beforeSync = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "beforeSync"); static afterSync = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "afterSync"); static beforeAssociate = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "beforeAssociate"); static afterAssociate = (0, import_hooks_legacy.legacyBuildAddHook)(import_model_hooks.staticModelHooks, "afterAssociate"); /** * Initialize a model, representing a table in the DB, with attributes and options. * * The table columns are defined by the hash that is given as the first argument. * Each attribute of the hash represents a column. * * @example * ```javascript * Project.init({ * columnA: { * type: DataTypes.BOOLEAN, * validate: { * is: ['[a-z]','i'], // will only allow letters * max: 23, // only allow values <= 23 * isIn: { * args: [['en', 'zh']], * msg: "Must be English or Chinese" * } * }, * field: 'column_a' * // Other attributes here * }, * columnB: DataTypes.STRING, * columnC: 'MY VERY OWN COLUMN TYPE' * }, {sequelize}) * ``` * * sequelize.models.modelName // The model will now be available in models under the class name * * @see https://sequelize.org/docs/v7/core-concepts/model-basics/ * @see https://sequelize.org/docs/v7/core-concepts/validations-and-constraints/ * * @param attributes An object, where each attribute is a column of the table. Each column can be either a * DataType, a string or a type-description object. * @param options These options are merged with the default define options provided to the Sequelize constructor */ static init(attributes, options) { if ((0, import_model.isDecoratedModel)(this)) { throw new Error( `Model.init cannot be used if the model uses one of Sequelize's decorators. You must pass your model to the Sequelize constructor using the "models" option instead.` ); } if (!options.sequelize) { throw new Error( "Model.init expects a Sequelize instance to be passed through the option bag, which is the second parameter." ); } initModel(this, attributes, options); return this; } static getIndexes() { return this.modelDefinition.getIndexes(); } /** * Unique indexes that can be declared as part of a CREATE TABLE query. * * @deprecated prefer using {@link getIndexes}, this will eventually be removed. */ static get uniqueKeys() { const indexes = this.getIndexes(); const uniqueKeys = /* @__PURE__ */ Object.create(null); const supportedOptions = ["unique", "fields", "column", "name"]; for (const index of indexes) { if (!index.unique) { continue; } if (!index.name) { continue; } if (!index.fields) { continue; } if (!index.fields.every((field) => typeof field === "string")) { continue; } if (!Object.keys(index).every((optionName) => supportedOptions.includes(optionName))) { continue; } uniqueKeys[index.name] = index; } return uniqueKeys; } // TODO [>7]: Remove this static get _indexes() { throw new Error("Model._indexes has been replaced with Model.getIndexes()"); } /** * Refreshes the Model's attribute definition. * * @deprecated use {@link modelDefinition}. */ static refreshAttributes() { this.modelDefinition.refreshAttributes(); } static assertIsInitialized() { if (!this.isInitialized()) { throw new Error( `Model "${this.name}" has not been initialized yet. You can check whether a model has been initialized by calling its isInitialized method.` ); } } static isInitialized() { return (0, import_model_definition.hasModelDefinition)(this); } /** * Get the table name of the model, taking schema into account. The method will an object with `tableName`, `schema` and `delimiter` properties. * * @deprecated use {@link modelDefinition} or {@link table}. */ static getTableName() { (0, import_deprecations.noModelTableName)(); const queryGenerator = this.sequelize.queryGenerator; return { ...this.table, /** * @deprecated This should not be relied upon! */ // @ts-expect-error -- This toString is a hacky property that must be removed toString() { return queryGenerator.quoteTable(this); } }; } /** * Works like the {@link Model#destroy} instance method, but is capable of deleting multiple instances in one query. * Unlike {@link Model.destroy}, this method takes instances, not a `where` option. * * @param instances The instances to delete. * @param options Options. */ static async _UNSTABLE_destroyMany(instances, options) { return this.modelRepository._UNSTABLE_destroy(instances, options); } /** * Search for a single instance by its primary key. * * This applies LIMIT 1, only a single instance will be returned. * * Returns the model with the matching primary key. * If not found, returns null or throws an error if {@link FindOptions.rejectOnEmpty} is set. * * If the model has a composite primary key, pass an object with the primary key attributes. * * @param identifier The value of the desired instance's primary key. * @param options find options */ static async findByPk(identifier, options) { if (identifier == null) { throw new Error(`${identifier} is not a valid primary key`); } const primaryKeyAttributeNames = this.modelDefinition.primaryKeysAttributeNames; if (primaryKeyAttributeNames.size === 0) { throw new Error( `Model ${this.name} does not have a primary key attribute, so findByPk cannot be used` ); } const pkWhere = /* @__PURE__ */ Object.create(null); if (primaryKeyAttributeNames.size === 1) { pkWhere[primaryKeyAttributeNames.firstValue()] = identifier; } else { if (!(0, import_utils.isPlainObject)(identifier)) { throw new TypeError( `Model ${this.name} has a composite primary key. Please pass all primary keys in an object like { pk1: value1, pk2: value2 }. Received: ${(0, import_node_util.inspect)(identifier)}` ); } for (const attributeName of primaryKeyAttributeNames) { if (identifier[attributeName] === void 0) { throw new TypeError( `Part of the composite primary key, ${attributeName}, is missing. Please pass all primary key attributes. Received: ${(0, import_node_util.inspect)(identifier)}` ); } pkWhere[attributeName] = identifier[attributeName]; } } return import_model2.Model.findOne.call(this, { ...options, where: options?.where ? (0, import_sequelize.and)(options?.where, pkWhere) : pkWhere }); } } function initModel(model, attributes, options) { options.modelName ||= model.name; const modelDefinition = new import_model_definition.ModelDefinition(attributes, options, model); Object.defineProperty(model, "name", { value: modelDefinition.modelName }); (0, import_model_definition.registerModelDefinition)(model, modelDefinition); model._scope = model.options.defaultScope; model._scopeNames = ["defaultScope"]; model.sequelize.hooks.runSync("afterDefine", model); addAttributeGetterAndSetters(model); model.hooks.addListener("afterDefinitionRefresh", () => { addAttributeGetterAndSetters(model); }); } function addAttributeGetterAndSetters(model) { const modelDefinition = model.modelDefinition; const { Model: TmpModel } = require("./model.js"); for (const attribute of modelDefinition.attributes.values()) { const attributeName = attribute.attributeName; if (attributeName in TmpModel.prototype) { model.sequelize.log( `Attribute ${attributeName} in model ${model.name} is shadowing a built-in property of the Model prototype. This is not recommended. Consider renaming your attribute.` ); continue; } const attributeProperty = { configurable: true, get() { return this.get(attributeName); }, set(value) { return this.set(attributeName, value); } }; Object.defineProperty(model.prototype, attributeName, attributeProperty); } } //# sourceMappingURL=model-typescript.js.map