@grouparoo/core
Version:
The Grouparoo Core
683 lines (682 loc) • 31.2 kB
JavaScript
;
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;