123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596 |
- 'use strict';
- const _ = require('lodash');
- const { logger } = require('./utils/logger');
- const debug = logger.debugContext('hooks');
- const hookTypes = {
- beforeValidate: { params: 2 },
- afterValidate: { params: 2 },
- validationFailed: { params: 3 },
- beforeCreate: { params: 2 },
- afterCreate: { params: 2 },
- beforeDestroy: { params: 2 },
- afterDestroy: { params: 2 },
- beforeRestore: { params: 2 },
- afterRestore: { params: 2 },
- beforeUpdate: { params: 2 },
- afterUpdate: { params: 2 },
- beforeSave: { params: 2, proxies: ['beforeUpdate', 'beforeCreate'] },
- afterSave: { params: 2, proxies: ['afterUpdate', 'afterCreate'] },
- beforeUpsert: { params: 2 },
- afterUpsert: { params: 2 },
- beforeBulkCreate: { params: 2 },
- afterBulkCreate: { params: 2 },
- beforeBulkDestroy: { params: 1 },
- afterBulkDestroy: { params: 1 },
- beforeBulkRestore: { params: 1 },
- afterBulkRestore: { params: 1 },
- beforeBulkUpdate: { params: 1 },
- afterBulkUpdate: { params: 1 },
- beforeFind: { params: 1 },
- beforeFindAfterExpandIncludeAll: { params: 1 },
- beforeFindAfterOptions: { params: 1 },
- afterFind: { params: 2 },
- beforeCount: { params: 1 },
- beforeDefine: { params: 2, sync: true, noModel: true },
- afterDefine: { params: 1, sync: true, noModel: true },
- beforeInit: { params: 2, sync: true, noModel: true },
- afterInit: { params: 1, sync: true, noModel: true },
- beforeAssociate: { params: 2, sync: true },
- afterAssociate: { params: 2, sync: true },
- beforeConnect: { params: 1, noModel: true },
- afterConnect: { params: 2, noModel: true },
- beforeDisconnect: { params: 1, noModel: true },
- afterDisconnect: { params: 1, noModel: true },
- beforeSync: { params: 1 },
- afterSync: { params: 1 },
- beforeBulkSync: { params: 1 },
- afterBulkSync: { params: 1 },
- beforeQuery: { params: 2 },
- afterQuery: { params: 2 }
- };
- exports.hooks = hookTypes;
- /**
- * get array of current hook and its proxies combined
- *
- * @param {string} hookType any hook type @see {@link hookTypes}
- *
- * @private
- */
- const getProxiedHooks = hookType =>
- hookTypes[hookType].proxies
- ? hookTypes[hookType].proxies.concat(hookType)
- : [hookType]
- ;
- function getHooks(hooked, hookType) {
- return (hooked.options.hooks || {})[hookType] || [];
- }
- const Hooks = {
- /**
- * Process user supplied hooks definition
- *
- * @param {object} hooks hooks definition
- *
- * @private
- * @memberof Sequelize
- * @memberof Sequelize.Model
- */
- _setupHooks(hooks) {
- this.options.hooks = {};
- _.map(hooks || {}, (hooksArray, hookName) => {
- if (!Array.isArray(hooksArray)) hooksArray = [hooksArray];
- hooksArray.forEach(hookFn => this.addHook(hookName, hookFn));
- });
- },
- async runHooks(hooks, ...hookArgs) {
- if (!hooks) throw new Error('runHooks requires at least 1 argument');
- let hookType;
- if (typeof hooks === 'string') {
- hookType = hooks;
- hooks = getHooks(this, hookType);
- if (this.sequelize) {
- hooks = hooks.concat(getHooks(this.sequelize, hookType));
- }
- }
- if (!Array.isArray(hooks)) {
- hooks = [hooks];
- }
- // synchronous hooks
- if (hookTypes[hookType] && hookTypes[hookType].sync) {
- for (let hook of hooks) {
- if (typeof hook === 'object') {
- hook = hook.fn;
- }
- debug(`running hook(sync) ${hookType}`);
- hook.apply(this, hookArgs);
- }
- return;
- }
- // asynchronous hooks (default)
- for (let hook of hooks) {
- if (typeof hook === 'object') {
- hook = hook.fn;
- }
- debug(`running hook ${hookType}`);
- await hook.apply(this, hookArgs);
- }
- },
- /**
- * Add a hook to the model
- *
- * @param {string} hookType hook name @see {@link hookTypes}
- * @param {string|Function} [name] Provide a name for the hook function. It can be used to remove the hook later or to order hooks based on some sort of priority system in the future.
- * @param {Function} fn The hook function
- *
- * @memberof Sequelize
- * @memberof Sequelize.Model
- */
- addHook(hookType, name, fn) {
- if (typeof name === 'function') {
- fn = name;
- name = null;
- }
- debug(`adding hook ${hookType}`);
- // check for proxies, add them too
- hookType = getProxiedHooks(hookType);
- hookType.forEach(type => {
- const hooks = getHooks(this, type);
- hooks.push(name ? { name, fn } : fn);
- this.options.hooks[type] = hooks;
- });
- return this;
- },
- /**
- * Remove hook from the model
- *
- * @param {string} hookType @see {@link hookTypes}
- * @param {string|Function} name name of hook or function reference which was attached
- *
- * @memberof Sequelize
- * @memberof Sequelize.Model
- */
- removeHook(hookType, name) {
- const isReference = typeof name === 'function' ? true : false;
- if (!this.hasHook(hookType)) {
- return this;
- }
- debug(`removing hook ${hookType}`);
- // check for proxies, add them too
- hookType = getProxiedHooks(hookType);
- for (const type of hookType) {
- this.options.hooks[type] = this.options.hooks[type].filter(hook => {
- if (isReference && typeof hook === 'function') {
- return hook !== name; // check if same method
- }
- if (!isReference && typeof hook === 'object') {
- return hook.name !== name;
- }
- return true;
- });
- }
- return this;
- },
- /**
- * Check whether the mode has any hooks of this type
- *
- * @param {string} hookType @see {@link hookTypes}
- *
- * @alias hasHooks
- *
- * @memberof Sequelize
- * @memberof Sequelize.Model
- */
- hasHook(hookType) {
- return this.options.hooks[hookType] && !!this.options.hooks[hookType].length;
- }
- };
- Hooks.hasHooks = Hooks.hasHook;
- function applyTo(target, isModel = false) {
- _.mixin(target, Hooks);
- for (const hook of Object.keys(hookTypes)) {
- if (isModel && hookTypes[hook].noModel) {
- continue;
- }
- target[hook] = function(name, callback) {
- return this.addHook(hook, name, callback);
- };
- }
- }
- exports.applyTo = applyTo;
- /**
- * A hook that is run before validation
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with instance, options
- * @name beforeValidate
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run after validation
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with instance, options
- * @name afterValidate
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run when validation fails
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with instance, options, error. Error is the
- * SequelizeValidationError. If the callback throws an error, it will replace the original validation error.
- * @name validationFailed
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run before creating a single instance
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with attributes, options
- * @name beforeCreate
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run after creating a single instance
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with attributes, options
- * @name afterCreate
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run before creating or updating a single instance, It proxies `beforeCreate` and `beforeUpdate`
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with attributes, options
- * @name beforeSave
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run before upserting
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with attributes, options
- * @name beforeUpsert
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run after upserting
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with the result of upsert(), options
- * @name afterUpsert
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run after creating or updating a single instance, It proxies `afterCreate` and `afterUpdate`
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with attributes, options
- * @name afterSave
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run before destroying a single instance
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with instance, options
- *
- * @name beforeDestroy
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run after destroying a single instance
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with instance, options
- *
- * @name afterDestroy
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run before restoring a single instance
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with instance, options
- *
- * @name beforeRestore
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run after restoring a single instance
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with instance, options
- *
- * @name afterRestore
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run before updating a single instance
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with instance, options
- * @name beforeUpdate
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run after updating a single instance
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with instance, options
- * @name afterUpdate
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run before creating instances in bulk
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with instances, options
- * @name beforeBulkCreate
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run after creating instances in bulk
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with instances, options
- * @name afterBulkCreate
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run before destroying instances in bulk
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with options
- *
- * @name beforeBulkDestroy
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run after destroying instances in bulk
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with options
- *
- * @name afterBulkDestroy
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run before restoring instances in bulk
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with options
- *
- * @name beforeBulkRestore
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run after restoring instances in bulk
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with options
- *
- * @name afterBulkRestore
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run before updating instances in bulk
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with options
- * @name beforeBulkUpdate
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run after updating instances in bulk
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with options
- * @name afterBulkUpdate
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run before a find (select) query
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with options
- * @name beforeFind
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run before a find (select) query, after any { include: {all: ...} } options are expanded
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with options
- * @name beforeFindAfterExpandIncludeAll
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run before a find (select) query, after all option parsing is complete
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with options
- * @name beforeFindAfterOptions
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run after a find (select) query
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with instance(s), options
- * @name afterFind
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run before a count query
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with options
- * @name beforeCount
- * @memberof Sequelize.Model
- */
- /**
- * A hook that is run before a define call
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with attributes, options
- * @name beforeDefine
- * @memberof Sequelize
- */
- /**
- * A hook that is run after a define call
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with factory
- * @name afterDefine
- * @memberof Sequelize
- */
- /**
- * A hook that is run before Sequelize() call
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with config, options
- * @name beforeInit
- * @memberof Sequelize
- */
- /**
- * A hook that is run after Sequelize() call
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with sequelize
- * @name afterInit
- * @memberof Sequelize
- */
- /**
- * A hook that is run before a connection is created
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with config passed to connection
- * @name beforeConnect
- * @memberof Sequelize
- */
- /**
- * A hook that is run after a connection is created
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with the connection object and the config passed to connection
- * @name afterConnect
- * @memberof Sequelize
- */
- /**
- * A hook that is run before a connection is disconnected
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with the connection object
- * @name beforeDisconnect
- * @memberof Sequelize
- */
- /**
- * A hook that is run after a connection is disconnected
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with the connection object
- * @name afterDisconnect
- * @memberof Sequelize
- */
- /**
- * A hook that is run before Model.sync call
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with options passed to Model.sync
- * @name beforeSync
- * @memberof Sequelize
- */
- /**
- * A hook that is run after Model.sync call
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with options passed to Model.sync
- * @name afterSync
- * @memberof Sequelize
- */
- /**
- * A hook that is run before sequelize.sync call
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with options passed to sequelize.sync
- * @name beforeBulkSync
- * @memberof Sequelize
- */
- /**
- * A hook that is run after sequelize.sync call
- *
- * @param {string} name
- * @param {Function} fn A callback function that is called with options passed to sequelize.sync
- * @name afterBulkSync
- * @memberof Sequelize
- */
|