UNPKG

@grouparoo/core

Version:
683 lines (682 loc) 31.2 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Group = exports.GROUP_RULE_LIMIT = void 0; const actionhero_1 = require("actionhero"); const moment_1 = __importDefault(require("moment")); const sequelize_1 = __importStar(require("sequelize")); const sequelize_typescript_1 = require("sequelize-typescript"); const apiData_1 = require("../modules/apiData"); const configWriter_1 = require("../modules/configWriter"); const lockableHelper_1 = require("../modules/lockableHelper"); const group_1 = require("../modules/ops/group"); const ruleOpsDictionary_1 = require("../modules/ruleOpsDictionary"); const topLevelGroupRules_1 = require("../modules/topLevelGroupRules"); const stateMachine_1 = require("./../modules/stateMachine"); const Destination_1 = require("./Destination"); const DestinationGroupMembership_1 = require("./DestinationGroupMembership"); const GroupMember_1 = require("./GroupMember"); const GrouparooRecord_1 = require("./GrouparooRecord"); const GroupRule_1 = require("./GroupRule"); const RecordProperty_1 = require("./RecordProperty"); const Property_1 = require("./Property"); const Run_1 = require("./Run"); const Setting_1 = require("./Setting"); const GrouparooModel_1 = require("./GrouparooModel"); const Source_1 = require("./Source"); const runs_1 = require("../modules/ops/runs"); const modelGuard_1 = require("../modules/modelGuard"); const runMode_1 = require("../modules/runMode"); const commonModel_1 = require("../classes/commonModel"); const propertiesCache_1 = require("../modules/caches/propertiesCache"); exports.GROUP_RULE_LIMIT = 10; const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; const matchTypes = ["any", "all"]; const STATES = [ "draft", "ready", "initializing", "updating", "deleted", ]; // we have no checks, as those are managed by the lifecycle methods below (and tasks) const STATE_TRANSITIONS = [ { from: "draft", to: "ready", checks: [] }, { from: "draft", to: "initializing", checks: [] }, { from: "draft", to: "deleted", checks: [] }, { from: "draft", to: "updating", checks: [] }, { from: "ready", to: "initializing", checks: [] }, { from: "initializing", to: "ready", checks: [] }, { from: "initializing", to: "updating", checks: [] }, { from: "initializing", to: "deleted", checks: [] }, { from: "ready", to: "updating", checks: [] }, { from: "updating", to: "ready", checks: [] }, { from: "updating", to: "initializing", checks: [] }, { from: "updating", to: "deleted", checks: [] }, { from: "ready", to: "deleted", checks: [] }, { from: "deleted", to: "ready", checks: [] }, ]; let Group = class Group extends commonModel_1.CommonModel { idPrefix() { return "grp"; } async recordsCount(options = {}) { let queryOptions = { where: { groupId: this.id } }; if (options) { queryOptions = Object.assign(queryOptions, options); } return this.$count("groupMembers", queryOptions); } async getRules() { // We won't be deleting the model for GroupRule until the group is really deleted (to validate other models) // But we want to be sure that all membership matching will fail if (this.state === "deleted") return []; const rulesWithKey = []; const rules = this.groupRules ? this.groupRules.sort((a, b) => a.position - b.position) : await this.$get("groupRules", { order: [["position", "asc"]], }); for (const i in rules) { const rule = rules[i]; const property = await propertiesCache_1.PropertiesCache.findOneWithCache(rule.propertyId, this.modelId, "ready"); const type = property ? property.type : topLevelGroupRules_1.TopLevelGroupRules.find((tlgr) => tlgr.key === rule.recordColumn) .type; rulesWithKey.push({ key: property ? property.key : rule.recordColumn, topLevel: property ? false : true, type: type, operation: { op: rule.op, description: ruleOpsDictionary_1.PropertyOpsDictionary[type].find((operation) => operation.op === rule.op).description, }, match: rule.match, relativeMatchNumber: rule.relativeMatchNumber, relativeMatchUnit: rule.relativeMatchUnit, relativeMatchDirection: rule.relativeMatchDirection, }); } return this.fromConvenientRules(rulesWithKey); } async setRules(rules) { if (Object.keys(rules).length > exports.GROUP_RULE_LIMIT) { throw new Error("too many group rules"); } const topLevelRuleKeys = topLevelGroupRules_1.TopLevelGroupRules.map((tlr) => tlr.key); const existingRules = await this.getRules(); const rulesAreEqual = group_1.GroupOps.rulesAreEqual(existingRules, rules); if (rulesAreEqual) return; await GroupRule_1.GroupRule.destroy({ where: { groupId: this.id }, }); for (const i in rules) { const rule = rules[i]; const key = rule.key; const property = await Property_1.Property.findOne({ where: { key }, include: [Source_1.Source], }); if (!property && !topLevelRuleKeys.includes(key)) { throw new Error(`cannot find property ${key}`); } let type = property === null || property === void 0 ? void 0 : property.type; if (topLevelRuleKeys.includes(key)) { type = topLevelGroupRules_1.TopLevelGroupRules.find((tlgr) => tlgr.key === key).type; } const dictionaryEntries = ruleOpsDictionary_1.PropertyOpsDictionary[type].filter((operation) => operation.op === rule.operation.op); if (!dictionaryEntries || dictionaryEntries.length === 0) { throw new Error(`invalid group rule operation "${rule.operation.op}" for property of type ${property.type}`); } if (property && this.modelId !== property.source.modelId) { throw new Error(`${property.key} does not belong to the ${this.modelId} model`); } await GroupRule_1.GroupRule.create({ position: parseInt(i) + 1, groupId: this.id, propertyId: property ? property.id : null, recordColumn: property ? null : key, op: rule.operation.op, match: rule.match, relativeMatchNumber: rule.relativeMatchNumber, relativeMatchUnit: rule.relativeMatchUnit, relativeMatchDirection: rule.relativeMatchDirection, }); } // test the rules const savedRules = await this.getRules(); await this.countPotentialMembers(savedRules, null); if (this.state !== "deleted" && rules.length > 0) { this.state = (0, runMode_1.getGrouparooRunMode)() === "cli:config" ? "ready" : "initializing"; this.changed("updatedAt", true); await this.save(); return this.run(); } } async apiData() { const model = await this.$get("model"); const recordsCount = await this.recordsCount(null); const rules = await this.getRules(); const nextCalculatedAt = await this.nextCalculatedAt(); return { id: this.id, name: this.name, modelId: this.modelId, modelName: model.name, rules, matchType: this.matchType, state: this.state, locked: this.locked, recordsCount, createdAt: apiData_1.APIData.formatDate(this.createdAt), updatedAt: apiData_1.APIData.formatDate(this.updatedAt), nextCalculatedAt: apiData_1.APIData.formatDate(nextCalculatedAt), calculatedAt: apiData_1.APIData.formatDate(this.calculatedAt), }; } fromConvenientRules(rules) { const convenientRules = ruleOpsDictionary_1.PropertyOpsDictionary._convenientRules; for (const i in rules) { //@ts-ignore if (convenientRules[rules[i].operation.op]) { //@ts-ignore const convenientRule = convenientRules[rules[i].operation.op]; if (convenientRule.operation.op) rules[i].operation.op = convenientRule.operation.op; if (convenientRule.relativeMatchDirection) rules[i].relativeMatchDirection = convenientRule.relativeMatchDirection; if (convenientRule.match) rules[i].match = convenientRule.match; } else if (rules[i].relativeMatchNumber && rules[i].operation.op.match(/^relative_/)) { rules[i].operation.op = rules[i].operation.op.replace(/^relative_/, ""); } } return rules; } toConvenientRules(rules) { const convenientRules = ruleOpsDictionary_1.PropertyOpsDictionary._convenientRules; for (const i in rules) { for (const k in convenientRules) { if (!rules[i].relativeMatchNumber && //@ts-ignore convenientRules[k].operation.op === rules[i].operation.op && //@ts-ignore convenientRules[k].match === rules[i].match) { rules[i] = Object.assign(rules[i], { operation: { op: k }, match: undefined, }); } } if (rules[i].relativeMatchNumber && !rules[i].operation.op.match(/^relative_/)) { rules[i].operation.op = `relative_${rules[i].operation.op}`; rules[i].operation.description = ruleOpsDictionary_1.PropertyOpsDictionary[rules[i].type].filter((operation) => operation.op === rules[i].operation.op)[0].description; delete rules[i].relativeMatchDirection; } } return rules; } async nextCalculatedAt() { let hasRelativeRule = false; const rules = await this.getRules(); for (const rule of rules) { if (rule.relativeMatchDirection) hasRelativeRule = true; } if (!hasRelativeRule) return null; if (!this.calculatedAt) return (0, moment_1.default)().toDate(); const setting = await Setting_1.Setting.findOne({ where: { pluginName: "core", key: "groups-calculation-delay-minutes" }, }); const delayMinutes = parseInt(setting.value); return (0, moment_1.default)(this.calculatedAt).add(delayMinutes, "minutes").toDate(); } async run(destinationId) { return runs_1.RunOps.run(this, destinationId); } async stopPreviousRuns() { return runs_1.RunOps.stopPreviousRuns(this); } async runAddGroupMembers(run, limit = 1000, offset = 0, highWaterMark = null, destinationId) { return group_1.GroupOps.runAddGroupMembers(this, run, limit, offset, highWaterMark, destinationId); } async runRemoveGroupMembers(run, limit = 1000, destinationId) { return group_1.GroupOps.runRemoveGroupMembers(this, run, limit, destinationId); } async removePreviousRunGroupMembers(run, limit = 100) { return group_1.GroupOps.removePreviousRunGroupMembers(this, run, limit); } async updateRecordsMembership(records) { return group_1.GroupOps.updateRecordsMembership(this, records); } async countPotentialMembers(rules, matchType = this.matchType) { return group_1.GroupOps.countPotentialMembers(this, rules, matchType); } /** * Take the rules for the group and check how many group members there would have been both individually for each single rule, and then by building up the query step-by-step */ async countComponentMembersFromRules(rules) { return group_1.GroupOps.countComponentMembersFromRules(this, rules); } /** * Build the where-clause for the query to determine Group membership */ async _buildGroupMemberQueryParts(rules, matchType = this.matchType, recordState) { if (!rules) rules = await this.getRules(); const include = []; const wheres = []; const localNumbers = [].concat(numbers); for (const i in rules) { const rule = rules[i]; const number = localNumbers.pop(); const alias = `RecordProperties_${number}`; const { key, operation, type, topLevel, relativeMatchNumber, relativeMatchDirection, relativeMatchUnit, } = rule; let { match } = rule; const localWhereGroup = {}; let rawValueMatch = {}; const property = await propertiesCache_1.PropertiesCache.findOneWithCache(key, this.modelId, "ready", "key"); if (!property && !topLevel) { throw new Error(`cannot find type for Property ${key}`); } if (match !== null && match !== undefined) { // special cases for dialects if (actionhero_1.config.sequelize.dialect === "sqlite") { if ((property === null || property === void 0 ? void 0 : property.type) === "boolean") { if (match === "1") match = "true"; if (match === "0") match = "false"; } } // rewrite null matches // @ts-ignore rawValueMatch[sequelize_1.Op[operation.op]] = match.toString().toLocaleLowerCase() === "null" ? null : match; // in the case of Array property negation, we also want to consider those records with the property never set if (!topLevel && property.isArray && ["ne", "notLike", "notILike"].includes(operation.op)) { rawValueMatch = { [sequelize_1.Op.or]: [rawValueMatch, { [sequelize_1.Op.eq]: null }] }; } } else if (relativeMatchNumber && !match) { const now = (0, moment_1.default)(); const timestamp = now[relativeMatchDirection](relativeMatchNumber, relativeMatchUnit) // i.e.: Moment().add(3, 'days') .toDate() .getTime(); // @ts-ignore rawValueMatch[sequelize_1.Op[operation.op]] = timestamp; } else { throw new Error("either match or relativeMatch is required"); } if (!topLevel) { // when we are considering a record property // @ts-ignore localWhereGroup[sequelize_1.Op.and] = [ sequelize_1.default.where(sequelize_1.default.cast(sequelize_1.default.col(`${alias}.rawValue`), (0, Property_1.propertyJSToSQLType)(property.type)), rawValueMatch), ]; } else { // when we are considering a column on the records table const topLevelGroupRule = topLevelGroupRules_1.TopLevelGroupRules.find((tlgr) => tlgr.key === key); if (!topLevelGroupRule) throw new Error(`cannot find TopLevelGroupRule where for key ${key}`); // @ts-ignore if (rawValueMatch[sequelize_1.Op[operation.op]] && type === "date") { // @ts-ignore rawValueMatch[sequelize_1.Op[operation.op]] = new Date( // @ts-ignore parseInt(rawValueMatch[sequelize_1.Op[operation.op]])).getTime(); } const topLevelWhere = { [topLevelGroupRule.column]: rawValueMatch, modelId: this.modelId, }; // @ts-ignore localWhereGroup[sequelize_1.Op.and] = [topLevelWhere]; } // also upper/lower bound against 'now' in the relative date case (ie: if we want 'in the past month', that means a) greater than one month ago and B) less than now) // this is not needed in the topLevel case as the timestamps cannot be in the future if (relativeMatchNumber && !match && !topLevel) { const todayBoundWhereGroup = {}; const todayBoundMatch = {}; // @ts-ignore todayBoundMatch[sequelize_1.Op[operation.op === "gt" ? "lte" : "gte"]] = new Date().getTime(); // @ts-ignore todayBoundWhereGroup[sequelize_1.Op.and] = sequelize_1.default.where(sequelize_1.default.cast(sequelize_1.default.col(`${alias}.rawValue`), (0, Property_1.propertyJSToSQLType)(property.type)), todayBoundMatch); // @ts-ignore localWhereGroup[sequelize_1.Op.and].push(todayBoundWhereGroup); } // in the case of Array property negation, we also need to do a sub-query to subtract the records which would match the affirmative match for this match if (!topLevel && match !== null && match !== undefined && property.isArray && ["ne", "notLike", "notILike"].includes(operation.op)) { let reverseMatchWhere = { [sequelize_1.Op.and]: [{ propertyId: property.id }], }; const castedValue = sequelize_1.default.cast(sequelize_1.default.col(`rawValue`), (0, Property_1.propertyJSToSQLType)(property.type)); const nullCheckedMatch = match.toString().toLocaleLowerCase() === "null" ? null : match; switch (operation.op) { case "ne": reverseMatchWhere[sequelize_1.Op.and].push(sequelize_1.default.where(castedValue, nullCheckedMatch === null || nullCheckedMatch === void 0 ? void 0 : nullCheckedMatch.toString())); break; case "notLike": reverseMatchWhere[sequelize_1.Op.and].push(sequelize_1.default.where(castedValue, { [sequelize_1.Op.like]: nullCheckedMatch, })); break; case "notILike": reverseMatchWhere[sequelize_1.Op.and].push(sequelize_1.default.where(castedValue, { [sequelize_1.Op.iLike]: nullCheckedMatch, })); break; } const whereClause = //@ts-ignore actionhero_1.api.sequelize.queryInterface.queryGenerator.getWhereConditions(reverseMatchWhere); const affirmativeArrayMatch = sequelize_1.default.literal(`"RecordMultipleAssociationShim"."id" NOT IN (SELECT "recordId" FROM "recordProperties" WHERE ${whereClause})`); // @ts-ignore localWhereGroup[sequelize_1.Op.and].push(affirmativeArrayMatch); } wheres.push(localWhereGroup); if (!topLevel) { include.push({ // $_$ wrapping is an option with eager loading // https://sequelize.org/master/manual/models-usage.html#eager-loading where: { [`$${alias}.propertyId$`]: property.id, }, attributes: [], model: RecordProperty_1.RecordProperty, as: alias, }); } } if (rules.length === 0) wheres.push({ id: "" }); const joinType = matchType === "all" ? sequelize_1.Op.and : sequelize_1.Op.or; const whereContainer = {}; if (recordState) whereContainer.state = recordState; // @ts-ignore whereContainer[joinType] = wheres; return { where: whereContainer, include }; } getConfigId() { return this.idIsDefault() ? configWriter_1.ConfigWriter.generateId(this.name) : this.id; } async getConfigObject() { var _a; const { name } = this; this.model = await this.$get("model"); const modelId = (_a = this.model) === null || _a === void 0 ? void 0 : _a.getConfigId(); if (!name || !modelId) return; const rules = []; const groupRules = await this.getRules(); const convenientRules = this.toConvenientRules(groupRules); for (const rule of convenientRules) { const property = await propertiesCache_1.PropertiesCache.findOneWithCache(rule.key, modelId, "ready", "key"); rules.push({ propertyId: rule.topLevel ? rule.key : property.getConfigId(), op: rule.operation.op, match: rule.match, relativeMatchNumber: rule.relativeMatchNumber, relativeMatchUnit: rule.relativeMatchUnit, relativeMatchDirection: rule.relativeMatchDirection, }); } const configObject = { class: "Group", id: this.getConfigId(), modelId, name, rules, }; return configObject; } // --- Class Methods --- // static async ensureModel(instance) { return modelGuard_1.ModelGuard.check(instance); } static async updateState(instance) { await stateMachine_1.StateMachine.transition(instance, STATE_TRANSITIONS); } static async noUpdateIfLocked(instance) { await lockableHelper_1.LockableHelper.beforeSave(instance, ["state", "calculatedAt"]); } static async checkGroupMembers(instance) { const count = await instance.$count("groupMembers"); if (count > 0) { throw new Error(`this group still has ${count} members, cannot delete`); } } static async ensureNotInUse(instance) { const count = await instance.$count("destinations", { scope: "notDraft" }); if (count > 0) { throw new Error(`this group still in use by ${count} destinations, cannot delete`); } } static async noDestroyIfLocked(instance) { await lockableHelper_1.LockableHelper.beforeDestroy(instance); } static async destroyDestinationGroupTracking(instance) { const destinations = await instance.$get("destinations", { scope: null, }); for (const i in destinations) { await destinations[i].update({ groupId: null }); } } static async destroyDestinationGroupMembership(instance) { const destinationGroupMemberships = await DestinationGroupMembership_1.DestinationGroupMembership.findAll({ where: { groupId: instance.id }, }); for (const i in destinationGroupMemberships) { const destination = await destinationGroupMemberships[i].$get("destination"); await destinationGroupMemberships[i].destroy(); if (destination) await destination.exportMembers(); } } static async destroyGroupRules(instance) { return GroupRule_1.GroupRule.destroy({ where: { groupId: instance.id, }, }); } static async stopRuns(instance) { const runs = await Run_1.Run.findAll({ where: { creatorId: instance.id, state: "running" }, }); for (const i in runs) { await runs[i].update({ state: "stopped" }); } } }; __decorate([ (0, sequelize_typescript_1.Length)({ min: 0, max: 191 }), (0, sequelize_typescript_1.Default)(""), sequelize_typescript_1.Column, __metadata("design:type", String) ], Group.prototype, "name", void 0); __decorate([ (0, sequelize_typescript_1.AllowNull)(false), (0, sequelize_typescript_1.Default)("all"), (0, sequelize_typescript_1.Is)("ofValidMatchType", (value) => { if (value && !matchTypes.includes(value)) { throw new Error(`matchType must be one of: ${matchTypes.join(",")}`); } }), (0, sequelize_typescript_1.Column)(sequelize_typescript_1.DataType.ENUM(...matchTypes)), __metadata("design:type", Object) ], Group.prototype, "matchType", void 0); __decorate([ (0, sequelize_typescript_1.AllowNull)(false), (0, sequelize_typescript_1.Default)("draft"), (0, sequelize_typescript_1.Column)(sequelize_typescript_1.DataType.ENUM(...STATES)), __metadata("design:type", Object) ], Group.prototype, "state", void 0); __decorate([ sequelize_typescript_1.Column, __metadata("design:type", String) ], Group.prototype, "locked", void 0); __decorate([ sequelize_typescript_1.Column, __metadata("design:type", Date) ], Group.prototype, "calculatedAt", void 0); __decorate([ (0, sequelize_typescript_1.AllowNull)(false), (0, sequelize_typescript_1.ForeignKey)(() => GrouparooModel_1.GrouparooModel), sequelize_typescript_1.Column, __metadata("design:type", String) ], Group.prototype, "modelId", void 0); __decorate([ (0, sequelize_typescript_1.HasMany)(() => GroupMember_1.GroupMember), __metadata("design:type", Array) ], Group.prototype, "groupMembers", void 0); __decorate([ (0, sequelize_typescript_1.HasMany)(() => GroupRule_1.GroupRule), __metadata("design:type", Array) ], Group.prototype, "groupRules", void 0); __decorate([ (0, sequelize_typescript_1.HasMany)(() => Destination_1.Destination), __metadata("design:type", Array) ], Group.prototype, "destinations", void 0); __decorate([ (0, sequelize_typescript_1.BelongsToMany)(() => GrouparooRecord_1.GrouparooRecord, () => GroupMember_1.GroupMember), __metadata("design:type", Array) ], Group.prototype, "records", void 0); __decorate([ (0, sequelize_typescript_1.BelongsTo)(() => GrouparooModel_1.GrouparooModel), __metadata("design:type", GrouparooModel_1.GrouparooModel) ], Group.prototype, "model", void 0); __decorate([ sequelize_typescript_1.BeforeCreate, sequelize_typescript_1.BeforeSave, __metadata("design:type", Function), __metadata("design:paramtypes", [Group]), __metadata("design:returntype", Promise) ], Group, "ensureModel", null); __decorate([ sequelize_typescript_1.BeforeSave, __metadata("design:type", Function), __metadata("design:paramtypes", [Group]), __metadata("design:returntype", Promise) ], Group, "updateState", null); __decorate([ sequelize_typescript_1.BeforeSave, __metadata("design:type", Function), __metadata("design:paramtypes", [Group]), __metadata("design:returntype", Promise) ], Group, "noUpdateIfLocked", null); __decorate([ sequelize_typescript_1.BeforeDestroy, __metadata("design:type", Function), __metadata("design:paramtypes", [Group]), __metadata("design:returntype", Promise) ], Group, "checkGroupMembers", null); __decorate([ sequelize_typescript_1.BeforeDestroy, __metadata("design:type", Function), __metadata("design:paramtypes", [Group]), __metadata("design:returntype", Promise) ], Group, "ensureNotInUse", null); __decorate([ sequelize_typescript_1.BeforeDestroy, __metadata("design:type", Function), __metadata("design:paramtypes", [Group]), __metadata("design:returntype", Promise) ], Group, "noDestroyIfLocked", null); __decorate([ sequelize_typescript_1.AfterDestroy, __metadata("design:type", Function), __metadata("design:paramtypes", [Group]), __metadata("design:returntype", Promise) ], Group, "destroyDestinationGroupTracking", null); __decorate([ sequelize_typescript_1.AfterDestroy, __metadata("design:type", Function), __metadata("design:paramtypes", [Group]), __metadata("design:returntype", Promise) ], Group, "destroyDestinationGroupMembership", null); __decorate([ sequelize_typescript_1.AfterDestroy, __metadata("design:type", Function), __metadata("design:paramtypes", [Group]), __metadata("design:returntype", Promise) ], Group, "destroyGroupRules", null); __decorate([ sequelize_typescript_1.AfterDestroy, __metadata("design:type", Function), __metadata("design:paramtypes", [Group]), __metadata("design:returntype", Promise) ], Group, "stopRuns", null); Group = __decorate([ (0, sequelize_typescript_1.DefaultScope)(() => ({ where: { state: { [sequelize_1.Op.notIn]: ["draft", "deleted"] }, }, })), (0, sequelize_typescript_1.Scopes)(() => ({ notDraft: { where: { state: { [sequelize_1.Op.notIn]: ["draft"] }, }, }, })), (0, sequelize_typescript_1.Table)({ tableName: "groups", paranoid: false }) ], Group); exports.Group = Group;