This commit is contained in:
2025-10-24 17:06:14 -05:00
parent 12d0690b91
commit df8c75603f
11289 changed files with 1209053 additions and 318 deletions

View File

@@ -0,0 +1,33 @@
"use strict";
const { AssociationError } = require("./../errors");
class Association {
constructor(source, target, options = {}) {
this.source = source;
this.target = target;
this.options = options;
this.scope = options.scope;
this.isSelfAssociation = this.source === this.target;
this.as = options.as;
this.associationType = "";
if (source.hasAlias(options.as)) {
throw new AssociationError(`You have used the alias ${options.as} in two separate associations. Aliased associations must have unique aliases.`);
}
}
toInstanceArray(input) {
if (!Array.isArray(input)) {
input = [input];
}
return input.map((element) => {
if (element instanceof this.target)
return element;
const tmpInstance = {};
tmpInstance[this.target.primaryKeyAttribute] = element;
return this.target.build(tmpInstance, { isNewRecord: false });
});
}
[Symbol.for("nodejs.util.inspect.custom")]() {
return this.as;
}
}
module.exports = Association;
//# sourceMappingURL=base.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,566 @@
"use strict";
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
const Utils = require("./../utils");
const Helpers = require("./helpers");
const _ = require("lodash");
const Association = require("./base");
const BelongsTo = require("./belongs-to");
const HasMany = require("./has-many");
const HasOne = require("./has-one");
const AssociationError = require("../errors").AssociationError;
const EmptyResultError = require("../errors").EmptyResultError;
const Op = require("../operators");
class BelongsToMany extends Association {
constructor(source, target, options) {
super(source, target, options);
if (this.options.through === void 0 || this.options.through === true || this.options.through === null) {
throw new AssociationError(`${source.name}.belongsToMany(${target.name}) requires through option, pass either a string or a model`);
}
if (!this.options.through.model) {
this.options.through = {
model: options.through
};
}
this.associationType = "BelongsToMany";
this.targetAssociation = null;
this.sequelize = source.sequelize;
this.through = __spreadValues({}, this.options.through);
this.isMultiAssociation = true;
this.doubleLinked = false;
if (!this.as && this.isSelfAssociation) {
throw new AssociationError("'as' must be defined for many-to-many self-associations");
}
if (this.as) {
this.isAliased = true;
if (_.isPlainObject(this.as)) {
this.options.name = this.as;
this.as = this.as.plural;
} else {
this.options.name = {
plural: this.as,
singular: Utils.singularize(this.as)
};
}
} else {
this.as = this.target.options.name.plural;
this.options.name = this.target.options.name;
}
this.combinedTableName = Utils.combineTableNames(this.source.tableName, this.isSelfAssociation ? this.as || this.target.tableName : this.target.tableName);
if (this.isSelfAssociation) {
this.targetAssociation = this;
}
_.each(this.target.associations, (association) => {
if (association.associationType !== "BelongsToMany")
return;
if (association.target !== this.source)
return;
if (this.options.through.model === association.options.through.model) {
this.paired = association;
association.paired = this;
}
});
this.sourceKey = this.options.sourceKey || this.source.primaryKeyAttribute;
this.sourceKeyField = this.source.rawAttributes[this.sourceKey].field || this.sourceKey;
if (this.options.targetKey) {
this.targetKey = this.options.targetKey;
this.targetKeyField = this.target.rawAttributes[this.targetKey].field || this.targetKey;
} else {
this.targetKeyDefault = true;
this.targetKey = this.target.primaryKeyAttribute;
this.targetKeyField = this.target.rawAttributes[this.targetKey].field || this.targetKey;
}
this._createForeignAndOtherKeys();
if (typeof this.through.model === "string") {
if (!this.sequelize.isDefined(this.through.model)) {
this.through.model = this.sequelize.define(this.through.model, {}, Object.assign(this.options, {
tableName: this.through.model,
indexes: [],
paranoid: this.through.paranoid ? this.through.paranoid : false,
validate: {}
}));
} else {
this.through.model = this.sequelize.model(this.through.model);
}
}
Object.assign(this.options, _.pick(this.through.model.options, [
"timestamps",
"createdAt",
"updatedAt",
"deletedAt",
"paranoid"
]));
if (this.paired) {
let needInjectPaired = false;
if (this.targetKeyDefault) {
this.targetKey = this.paired.sourceKey;
this.targetKeyField = this.paired.sourceKeyField;
this._createForeignAndOtherKeys();
}
if (this.paired.targetKeyDefault) {
if (this.paired.targetKey !== this.sourceKey) {
delete this.through.model.rawAttributes[this.paired.otherKey];
this.paired.targetKey = this.sourceKey;
this.paired.targetKeyField = this.sourceKeyField;
this.paired._createForeignAndOtherKeys();
needInjectPaired = true;
}
}
if (this.otherKeyDefault) {
this.otherKey = this.paired.foreignKey;
}
if (this.paired.otherKeyDefault) {
if (this.paired.otherKey !== this.foreignKey) {
delete this.through.model.rawAttributes[this.paired.otherKey];
this.paired.otherKey = this.foreignKey;
needInjectPaired = true;
}
}
if (needInjectPaired) {
this.paired._injectAttributes();
}
}
if (this.through) {
this.throughModel = this.through.model;
}
this.options.tableName = this.combinedName = this.through.model === Object(this.through.model) ? this.through.model.tableName : this.through.model;
this.associationAccessor = this.as;
const plural = _.upperFirst(this.options.name.plural);
const singular = _.upperFirst(this.options.name.singular);
this.accessors = {
get: `get${plural}`,
set: `set${plural}`,
addMultiple: `add${plural}`,
add: `add${singular}`,
create: `create${singular}`,
remove: `remove${singular}`,
removeMultiple: `remove${plural}`,
hasSingle: `has${singular}`,
hasAll: `has${plural}`,
count: `count${plural}`
};
}
_createForeignAndOtherKeys() {
if (_.isObject(this.options.foreignKey)) {
this.foreignKeyAttribute = this.options.foreignKey;
this.foreignKey = this.foreignKeyAttribute.name || this.foreignKeyAttribute.fieldName;
} else {
this.foreignKeyAttribute = {};
this.foreignKey = this.options.foreignKey || Utils.camelize([
this.source.options.name.singular,
this.sourceKey
].join("_"));
}
if (_.isObject(this.options.otherKey)) {
this.otherKeyAttribute = this.options.otherKey;
this.otherKey = this.otherKeyAttribute.name || this.otherKeyAttribute.fieldName;
} else {
if (!this.options.otherKey) {
this.otherKeyDefault = true;
}
this.otherKeyAttribute = {};
this.otherKey = this.options.otherKey || Utils.camelize([
this.isSelfAssociation ? Utils.singularize(this.as) : this.target.options.name.singular,
this.targetKey
].join("_"));
}
}
_injectAttributes() {
this.identifier = this.foreignKey;
this.foreignIdentifier = this.otherKey;
_.each(this.through.model.rawAttributes, (attribute, attributeName) => {
if (attribute.primaryKey === true && attribute._autoGenerated === true) {
if ([this.foreignKey, this.otherKey].includes(attributeName)) {
attribute.primaryKey = false;
} else {
delete this.through.model.rawAttributes[attributeName];
}
this.primaryKeyDeleted = true;
}
});
const sourceKey = this.source.rawAttributes[this.sourceKey];
const sourceKeyType = sourceKey.type;
const sourceKeyField = this.sourceKeyField;
const targetKey = this.target.rawAttributes[this.targetKey];
const targetKeyType = targetKey.type;
const targetKeyField = this.targetKeyField;
const sourceAttribute = __spreadValues({ type: sourceKeyType }, this.foreignKeyAttribute);
const targetAttribute = __spreadValues({ type: targetKeyType }, this.otherKeyAttribute);
if (this.primaryKeyDeleted === true) {
targetAttribute.primaryKey = sourceAttribute.primaryKey = true;
} else if (this.through.unique !== false) {
let uniqueKey;
if (typeof this.options.uniqueKey === "string" && this.options.uniqueKey !== "") {
uniqueKey = this.options.uniqueKey;
} else {
uniqueKey = [this.through.model.tableName, this.foreignKey, this.otherKey, "unique"].join("_");
}
targetAttribute.unique = sourceAttribute.unique = uniqueKey;
}
if (!this.through.model.rawAttributes[this.foreignKey]) {
this.through.model.rawAttributes[this.foreignKey] = {
_autoGenerated: true
};
}
if (!this.through.model.rawAttributes[this.otherKey]) {
this.through.model.rawAttributes[this.otherKey] = {
_autoGenerated: true
};
}
if (this.options.constraints !== false) {
sourceAttribute.references = {
model: this.source.getTableName(),
key: sourceKeyField
};
sourceAttribute.onDelete = this.options.onDelete || this.through.model.rawAttributes[this.foreignKey].onDelete;
sourceAttribute.onUpdate = this.options.onUpdate || this.through.model.rawAttributes[this.foreignKey].onUpdate;
if (!sourceAttribute.onDelete)
sourceAttribute.onDelete = "CASCADE";
if (!sourceAttribute.onUpdate)
sourceAttribute.onUpdate = "CASCADE";
targetAttribute.references = {
model: this.target.getTableName(),
key: targetKeyField
};
targetAttribute.onDelete = this.through.model.rawAttributes[this.otherKey].onDelete || this.options.onDelete;
targetAttribute.onUpdate = this.through.model.rawAttributes[this.otherKey].onUpdate || this.options.onUpdate;
if (!targetAttribute.onDelete)
targetAttribute.onDelete = "CASCADE";
if (!targetAttribute.onUpdate)
targetAttribute.onUpdate = "CASCADE";
}
Object.assign(this.through.model.rawAttributes[this.foreignKey], sourceAttribute);
Object.assign(this.through.model.rawAttributes[this.otherKey], targetAttribute);
this.through.model.refreshAttributes();
this.identifierField = this.through.model.rawAttributes[this.foreignKey].field || this.foreignKey;
this.foreignIdentifierField = this.through.model.rawAttributes[this.otherKey].field || this.otherKey;
if (this.options.sequelize.options.dialect === "db2" && this.source.rawAttributes[this.sourceKey].primaryKey !== true) {
this.source.rawAttributes[this.sourceKey].unique = true;
}
if (this.paired && !this.paired.foreignIdentifierField) {
this.paired.foreignIdentifierField = this.through.model.rawAttributes[this.paired.otherKey].field || this.paired.otherKey;
}
this.toSource = new BelongsTo(this.through.model, this.source, {
foreignKey: this.foreignKey
});
this.manyFromSource = new HasMany(this.source, this.through.model, {
foreignKey: this.foreignKey
});
this.oneFromSource = new HasOne(this.source, this.through.model, {
foreignKey: this.foreignKey,
sourceKey: this.sourceKey,
as: this.through.model.name
});
this.toTarget = new BelongsTo(this.through.model, this.target, {
foreignKey: this.otherKey
});
this.manyFromTarget = new HasMany(this.target, this.through.model, {
foreignKey: this.otherKey
});
this.oneFromTarget = new HasOne(this.target, this.through.model, {
foreignKey: this.otherKey,
sourceKey: this.targetKey,
as: this.through.model.name
});
if (this.paired && this.paired.otherKeyDefault) {
this.paired.toTarget = new BelongsTo(this.paired.through.model, this.paired.target, {
foreignKey: this.paired.otherKey
});
this.paired.oneFromTarget = new HasOne(this.paired.target, this.paired.through.model, {
foreignKey: this.paired.otherKey,
sourceKey: this.paired.targetKey,
as: this.paired.through.model.name
});
}
Helpers.checkNamingCollision(this);
return this;
}
mixin(obj) {
const methods = ["get", "count", "hasSingle", "hasAll", "set", "add", "addMultiple", "remove", "removeMultiple", "create"];
const aliases = {
hasSingle: "has",
hasAll: "has",
addMultiple: "add",
removeMultiple: "remove"
};
Helpers.mixinMethods(this, obj, methods, aliases);
}
async get(instance, options) {
options = Utils.cloneDeep(options) || {};
const through = this.through;
let scopeWhere;
let throughWhere;
if (this.scope) {
scopeWhere = __spreadValues({}, this.scope);
}
options.where = {
[Op.and]: [
scopeWhere,
options.where
]
};
if (Object(through.model) === through.model) {
throughWhere = {};
throughWhere[this.foreignKey] = instance.get(this.sourceKey);
if (through.scope) {
Object.assign(throughWhere, through.scope);
}
if (options.through && options.through.where) {
throughWhere = {
[Op.and]: [throughWhere, options.through.where]
};
}
options.include = options.include || [];
options.include.push({
association: this.oneFromTarget,
attributes: options.joinTableAttributes,
required: true,
paranoid: _.get(options.through, "paranoid", true),
where: throughWhere
});
}
let model = this.target;
if (Object.prototype.hasOwnProperty.call(options, "scope")) {
if (!options.scope) {
model = model.unscoped();
} else {
model = model.scope(options.scope);
}
}
if (Object.prototype.hasOwnProperty.call(options, "schema")) {
model = model.schema(options.schema, options.schemaDelimiter);
}
return model.findAll(options);
}
async count(instance, options) {
const sequelize = this.target.sequelize;
options = Utils.cloneDeep(options);
options.attributes = [
[sequelize.fn("COUNT", sequelize.col([this.target.name, this.targetKeyField].join("."))), "count"]
];
options.joinTableAttributes = [];
options.raw = true;
options.plain = true;
const result = await this.get(instance, options);
return parseInt(result.count, 10);
}
async has(sourceInstance, instances, options) {
if (!Array.isArray(instances)) {
instances = [instances];
}
options = __spreadProps(__spreadValues({
raw: true
}, options), {
scope: false,
attributes: [this.targetKey],
joinTableAttributes: []
});
const instancePrimaryKeys = instances.map((instance) => {
if (instance instanceof this.target) {
return instance.where();
}
return {
[this.targetKey]: instance
};
});
options.where = {
[Op.and]: [
{ [Op.or]: instancePrimaryKeys },
options.where
]
};
const associatedObjects = await this.get(sourceInstance, options);
return _.differenceWith(instancePrimaryKeys, associatedObjects, (a, b) => _.isEqual(a[this.targetKey], b[this.targetKey])).length === 0;
}
async set(sourceInstance, newAssociatedObjects, options) {
options = options || {};
const sourceKey = this.sourceKey;
const targetKey = this.targetKey;
const identifier = this.identifier;
const foreignIdentifier = this.foreignIdentifier;
if (newAssociatedObjects === null) {
newAssociatedObjects = [];
} else {
newAssociatedObjects = this.toInstanceArray(newAssociatedObjects);
}
const where = __spreadValues({
[identifier]: sourceInstance.get(sourceKey)
}, this.through.scope);
const updateAssociations = (currentRows) => {
const obsoleteAssociations = [];
const promises = [];
const defaultAttributes = options.through || {};
const unassociatedObjects = newAssociatedObjects.filter((obj) => !currentRows.some((currentRow) => currentRow[foreignIdentifier] === obj.get(targetKey)));
for (const currentRow of currentRows) {
const newObj = newAssociatedObjects.find((obj) => currentRow[foreignIdentifier] === obj.get(targetKey));
if (!newObj) {
obsoleteAssociations.push(currentRow);
} else {
let throughAttributes = newObj[this.through.model.name];
if (throughAttributes instanceof this.through.model) {
throughAttributes = {};
}
const attributes = __spreadValues(__spreadValues({}, defaultAttributes), throughAttributes);
if (Object.keys(attributes).length) {
promises.push(this.through.model.update(attributes, Object.assign(options, {
where: {
[identifier]: sourceInstance.get(sourceKey),
[foreignIdentifier]: newObj.get(targetKey)
}
})));
}
}
}
if (obsoleteAssociations.length > 0) {
promises.push(this.through.model.destroy(__spreadProps(__spreadValues({}, options), {
where: __spreadValues({
[identifier]: sourceInstance.get(sourceKey),
[foreignIdentifier]: obsoleteAssociations.map((obsoleteAssociation) => obsoleteAssociation[foreignIdentifier])
}, this.through.scope)
})));
}
if (unassociatedObjects.length > 0) {
const bulk = unassociatedObjects.map((unassociatedObject) => {
return __spreadValues(__spreadProps(__spreadValues(__spreadValues({}, defaultAttributes), unassociatedObject[this.through.model.name]), {
[identifier]: sourceInstance.get(sourceKey),
[foreignIdentifier]: unassociatedObject.get(targetKey)
}), this.through.scope);
});
promises.push(this.through.model.bulkCreate(bulk, __spreadValues({ validate: true }, options)));
}
return Promise.all(promises);
};
try {
const currentRows = await this.through.model.findAll(__spreadProps(__spreadValues({}, options), { where, raw: true }));
return await updateAssociations(currentRows);
} catch (error) {
if (error instanceof EmptyResultError)
return updateAssociations([]);
throw error;
}
}
async add(sourceInstance, newInstances, options) {
if (!newInstances)
return Promise.resolve();
options = __spreadValues({}, options);
const association = this;
const sourceKey = association.sourceKey;
const targetKey = association.targetKey;
const identifier = association.identifier;
const foreignIdentifier = association.foreignIdentifier;
const defaultAttributes = options.through || {};
newInstances = association.toInstanceArray(newInstances);
const where = __spreadValues({
[identifier]: sourceInstance.get(sourceKey),
[foreignIdentifier]: newInstances.map((newInstance) => newInstance.get(targetKey))
}, association.through.scope);
const updateAssociations = (currentRows) => {
const promises = [];
const unassociatedObjects = [];
const changedAssociations = [];
for (const obj of newInstances) {
const existingAssociation = currentRows && currentRows.find((current) => current[foreignIdentifier] === obj.get(targetKey));
if (!existingAssociation) {
unassociatedObjects.push(obj);
} else {
const throughAttributes = obj[association.through.model.name];
const attributes = __spreadValues(__spreadValues({}, defaultAttributes), throughAttributes);
if (Object.keys(attributes).some((attribute) => attributes[attribute] !== existingAssociation[attribute])) {
changedAssociations.push(obj);
}
}
}
if (unassociatedObjects.length > 0) {
const bulk = unassociatedObjects.map((unassociatedObject) => {
const throughAttributes = unassociatedObject[association.through.model.name];
const attributes = __spreadValues(__spreadValues({}, defaultAttributes), throughAttributes);
attributes[identifier] = sourceInstance.get(sourceKey);
attributes[foreignIdentifier] = unassociatedObject.get(targetKey);
Object.assign(attributes, association.through.scope);
return attributes;
});
promises.push(association.through.model.bulkCreate(bulk, __spreadValues({ validate: true }, options)));
}
for (const assoc of changedAssociations) {
let throughAttributes = assoc[association.through.model.name];
const attributes = __spreadValues(__spreadValues({}, defaultAttributes), throughAttributes);
if (throughAttributes instanceof association.through.model) {
throughAttributes = {};
}
promises.push(association.through.model.update(attributes, Object.assign(options, { where: {
[identifier]: sourceInstance.get(sourceKey),
[foreignIdentifier]: assoc.get(targetKey)
} })));
}
return Promise.all(promises);
};
try {
const currentRows = await association.through.model.findAll(__spreadProps(__spreadValues({}, options), { where, raw: true }));
const [associations] = await updateAssociations(currentRows);
return associations;
} catch (error) {
if (error instanceof EmptyResultError)
return updateAssociations();
throw error;
}
}
remove(sourceInstance, oldAssociatedObjects, options) {
const association = this;
options = options || {};
oldAssociatedObjects = association.toInstanceArray(oldAssociatedObjects);
const where = {
[association.identifier]: sourceInstance.get(association.sourceKey),
[association.foreignIdentifier]: oldAssociatedObjects.map((newInstance) => newInstance.get(association.targetKey))
};
return association.through.model.destroy(__spreadProps(__spreadValues({}, options), { where }));
}
async create(sourceInstance, values, options) {
const association = this;
options = options || {};
values = values || {};
if (Array.isArray(options)) {
options = {
fields: options
};
}
if (association.scope) {
Object.assign(values, association.scope);
if (options.fields) {
options.fields = options.fields.concat(Object.keys(association.scope));
}
}
const newAssociatedObject = await association.target.create(values, options);
await sourceInstance[association.accessors.add](newAssociatedObject, _.omit(options, ["fields"]));
return newAssociatedObject;
}
verifyAssociationAlias(alias) {
if (typeof alias === "string") {
return this.as === alias;
}
if (alias && alias.plural) {
return this.as === alias.plural;
}
return !this.isAliased;
}
}
module.exports = BelongsToMany;
module.exports.BelongsToMany = BelongsToMany;
module.exports.default = BelongsToMany;
//# sourceMappingURL=belongs-to-many.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,172 @@
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
const Utils = require("./../utils");
const Helpers = require("./helpers");
const _ = require("lodash");
const Association = require("./base");
const Op = require("../operators");
class BelongsTo extends Association {
constructor(source, target, options) {
super(source, target, options);
this.associationType = "BelongsTo";
this.isSingleAssociation = true;
this.foreignKeyAttribute = {};
if (this.as) {
this.isAliased = true;
this.options.name = {
singular: this.as
};
} else {
this.as = this.target.options.name.singular;
this.options.name = this.target.options.name;
}
if (_.isObject(this.options.foreignKey)) {
this.foreignKeyAttribute = this.options.foreignKey;
this.foreignKey = this.foreignKeyAttribute.name || this.foreignKeyAttribute.fieldName;
} else if (this.options.foreignKey) {
this.foreignKey = this.options.foreignKey;
}
if (!this.foreignKey) {
this.foreignKey = Utils.camelize([
this.as,
this.target.primaryKeyAttribute
].join("_"));
}
this.identifier = this.foreignKey;
if (this.source.rawAttributes[this.identifier]) {
this.identifierField = this.source.rawAttributes[this.identifier].field || this.identifier;
}
if (this.options.targetKey && !this.target.rawAttributes[this.options.targetKey]) {
throw new Error(`Unknown attribute "${this.options.targetKey}" passed as targetKey, define this attribute on model "${this.target.name}" first`);
}
this.targetKey = this.options.targetKey || this.target.primaryKeyAttribute;
this.targetKeyField = this.target.rawAttributes[this.targetKey].field || this.targetKey;
this.targetKeyIsPrimary = this.targetKey === this.target.primaryKeyAttribute;
this.targetIdentifier = this.targetKey;
this.associationAccessor = this.as;
this.options.useHooks = options.useHooks;
const singular = _.upperFirst(this.options.name.singular);
this.accessors = {
get: `get${singular}`,
set: `set${singular}`,
create: `create${singular}`
};
}
_injectAttributes() {
const newAttributes = {
[this.foreignKey]: __spreadValues({
type: this.options.keyType || this.target.rawAttributes[this.targetKey].type,
allowNull: true
}, this.foreignKeyAttribute)
};
if (this.options.constraints !== false) {
const source = this.source.rawAttributes[this.foreignKey] || newAttributes[this.foreignKey];
this.options.onDelete = this.options.onDelete || (source.allowNull ? "SET NULL" : "NO ACTION");
this.options.onUpdate = this.options.onUpdate || "CASCADE";
}
Helpers.addForeignKeyConstraints(newAttributes[this.foreignKey], this.target, this.source, this.options, this.targetKeyField);
Utils.mergeDefaults(this.source.rawAttributes, newAttributes);
this.source.refreshAttributes();
this.identifierField = this.source.rawAttributes[this.foreignKey].field || this.foreignKey;
Helpers.checkNamingCollision(this);
return this;
}
mixin(obj) {
const methods = ["get", "set", "create"];
Helpers.mixinMethods(this, obj, methods);
}
async get(instances, options) {
const where = {};
let Target = this.target;
let instance;
options = Utils.cloneDeep(options);
if (Object.prototype.hasOwnProperty.call(options, "scope")) {
if (!options.scope) {
Target = Target.unscoped();
} else {
Target = Target.scope(options.scope);
}
}
if (Object.prototype.hasOwnProperty.call(options, "schema")) {
Target = Target.schema(options.schema, options.schemaDelimiter);
}
if (!Array.isArray(instances)) {
instance = instances;
instances = void 0;
}
if (instances) {
where[this.targetKey] = {
[Op.in]: instances.map((_instance) => _instance.get(this.foreignKey))
};
} else {
if (this.targetKeyIsPrimary && !options.where) {
return Target.findByPk(instance.get(this.foreignKey), options);
}
where[this.targetKey] = instance.get(this.foreignKey);
options.limit = null;
}
options.where = options.where ? { [Op.and]: [where, options.where] } : where;
if (instances) {
const results = await Target.findAll(options);
const result = {};
for (const _instance of instances) {
result[_instance.get(this.foreignKey, { raw: true })] = null;
}
for (const _instance of results) {
result[_instance.get(this.targetKey, { raw: true })] = _instance;
}
return result;
}
return Target.findOne(options);
}
async set(sourceInstance, associatedInstance, options = {}) {
let value = associatedInstance;
if (associatedInstance instanceof this.target) {
value = associatedInstance[this.targetKey];
}
sourceInstance.set(this.foreignKey, value);
if (options.save === false)
return;
options = __spreadValues({
fields: [this.foreignKey],
allowNull: [this.foreignKey],
association: true
}, options);
return await sourceInstance.save(options);
}
async create(sourceInstance, values, options) {
values = values || {};
options = options || {};
const newAssociatedObject = await this.target.create(values, options);
await sourceInstance[this.accessors.set](newAssociatedObject, options);
return newAssociatedObject;
}
verifyAssociationAlias(alias) {
if (typeof alias === "string") {
return this.as === alias;
}
if (alias && alias.singular) {
return this.as === alias.singular;
}
return !this.isAliased;
}
}
module.exports = BelongsTo;
module.exports.BelongsTo = BelongsTo;
module.exports.default = BelongsTo;
//# sourceMappingURL=belongs-to.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,316 @@
"use strict";
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
const Utils = require("./../utils");
const Helpers = require("./helpers");
const _ = require("lodash");
const Association = require("./base");
const Op = require("../operators");
class HasMany extends Association {
constructor(source, target, options) {
super(source, target, options);
this.associationType = "HasMany";
this.targetAssociation = null;
this.sequelize = source.sequelize;
this.isMultiAssociation = true;
this.foreignKeyAttribute = {};
if (this.options.through) {
throw new Error("N:M associations are not supported with hasMany. Use belongsToMany instead");
}
if (this.isSelfAssociation) {
this.targetAssociation = this;
}
if (this.as) {
this.isAliased = true;
if (_.isPlainObject(this.as)) {
this.options.name = this.as;
this.as = this.as.plural;
} else {
this.options.name = {
plural: this.as,
singular: Utils.singularize(this.as)
};
}
} else {
this.as = this.target.options.name.plural;
this.options.name = this.target.options.name;
}
if (_.isObject(this.options.foreignKey)) {
this.foreignKeyAttribute = this.options.foreignKey;
this.foreignKey = this.foreignKeyAttribute.name || this.foreignKeyAttribute.fieldName;
} else if (this.options.foreignKey) {
this.foreignKey = this.options.foreignKey;
}
if (!this.foreignKey) {
this.foreignKey = Utils.camelize([
this.source.options.name.singular,
this.source.primaryKeyAttribute
].join("_"));
}
if (this.target.rawAttributes[this.foreignKey]) {
this.identifierField = this.target.rawAttributes[this.foreignKey].field || this.foreignKey;
this.foreignKeyField = this.target.rawAttributes[this.foreignKey].field || this.foreignKey;
}
this.sourceKey = this.options.sourceKey || this.source.primaryKeyAttribute;
if (this.source.rawAttributes[this.sourceKey]) {
this.sourceKeyAttribute = this.sourceKey;
this.sourceKeyField = this.source.rawAttributes[this.sourceKey].field || this.sourceKey;
} else {
this.sourceKeyAttribute = this.source.primaryKeyAttribute;
this.sourceKeyField = this.source.primaryKeyField;
}
const plural = _.upperFirst(this.options.name.plural);
const singular = _.upperFirst(this.options.name.singular);
this.associationAccessor = this.as;
this.accessors = {
get: `get${plural}`,
set: `set${plural}`,
addMultiple: `add${plural}`,
add: `add${singular}`,
create: `create${singular}`,
remove: `remove${singular}`,
removeMultiple: `remove${plural}`,
hasSingle: `has${singular}`,
hasAll: `has${plural}`,
count: `count${plural}`
};
}
_injectAttributes() {
const newAttributes = {
[this.foreignKey]: __spreadValues({
type: this.options.keyType || this.source.rawAttributes[this.sourceKeyAttribute].type,
allowNull: true
}, this.foreignKeyAttribute)
};
const constraintOptions = __spreadValues({}, this.options);
if (this.options.constraints !== false) {
const target = this.target.rawAttributes[this.foreignKey] || newAttributes[this.foreignKey];
constraintOptions.onDelete = constraintOptions.onDelete || (target.allowNull ? "SET NULL" : "CASCADE");
constraintOptions.onUpdate = constraintOptions.onUpdate || "CASCADE";
}
Helpers.addForeignKeyConstraints(newAttributes[this.foreignKey], this.source, this.target, constraintOptions, this.sourceKeyField);
Utils.mergeDefaults(this.target.rawAttributes, newAttributes);
this.target.refreshAttributes();
this.source.refreshAttributes();
this.identifierField = this.target.rawAttributes[this.foreignKey].field || this.foreignKey;
this.foreignKeyField = this.target.rawAttributes[this.foreignKey].field || this.foreignKey;
this.sourceKeyField = this.source.rawAttributes[this.sourceKey].field || this.sourceKey;
Helpers.checkNamingCollision(this);
return this;
}
mixin(obj) {
const methods = ["get", "count", "hasSingle", "hasAll", "set", "add", "addMultiple", "remove", "removeMultiple", "create"];
const aliases = {
hasSingle: "has",
hasAll: "has",
addMultiple: "add",
removeMultiple: "remove"
};
Helpers.mixinMethods(this, obj, methods, aliases);
}
async get(instances, options = {}) {
const where = {};
let Model = this.target;
let instance;
let values;
if (!Array.isArray(instances)) {
instance = instances;
instances = void 0;
}
options = __spreadValues({}, options);
if (this.scope) {
Object.assign(where, this.scope);
}
if (instances) {
values = instances.map((_instance) => _instance.get(this.sourceKey, { raw: true }));
if (options.limit && instances.length > 1) {
options.groupedLimit = {
limit: options.limit,
on: this,
values
};
delete options.limit;
} else {
where[this.foreignKey] = {
[Op.in]: values
};
delete options.groupedLimit;
}
} else {
where[this.foreignKey] = instance.get(this.sourceKey, { raw: true });
}
options.where = options.where ? { [Op.and]: [where, options.where] } : where;
if (Object.prototype.hasOwnProperty.call(options, "scope")) {
if (!options.scope) {
Model = Model.unscoped();
} else {
Model = Model.scope(options.scope);
}
}
if (Object.prototype.hasOwnProperty.call(options, "schema")) {
Model = Model.schema(options.schema, options.schemaDelimiter);
}
const results = await Model.findAll(options);
if (instance)
return results;
const result = {};
for (const _instance of instances) {
result[_instance.get(this.sourceKey, { raw: true })] = [];
}
for (const _instance of results) {
result[_instance.get(this.foreignKey, { raw: true })].push(_instance);
}
return result;
}
async count(instance, options) {
options = Utils.cloneDeep(options);
options.attributes = [
[
this.sequelize.fn("COUNT", this.sequelize.col(`${this.target.name}.${this.target.primaryKeyField}`)),
"count"
]
];
options.raw = true;
options.plain = true;
const result = await this.get(instance, options);
return parseInt(result.count, 10);
}
async has(sourceInstance, targetInstances, options) {
const where = {};
if (!Array.isArray(targetInstances)) {
targetInstances = [targetInstances];
}
options = __spreadProps(__spreadValues({}, options), {
scope: false,
attributes: [this.target.primaryKeyAttribute],
raw: true
});
where[Op.or] = targetInstances.map((instance) => {
if (instance instanceof this.target) {
return instance.where();
}
return {
[this.target.primaryKeyAttribute]: instance
};
});
options.where = {
[Op.and]: [
where,
options.where
]
};
const associatedObjects = await this.get(sourceInstance, options);
return associatedObjects.length === targetInstances.length;
}
async set(sourceInstance, targetInstances, options) {
if (targetInstances === null) {
targetInstances = [];
} else {
targetInstances = this.toInstanceArray(targetInstances);
}
const oldAssociations = await this.get(sourceInstance, __spreadProps(__spreadValues({}, options), { scope: false, raw: true }));
const promises = [];
const obsoleteAssociations = oldAssociations.filter((old) => !targetInstances.find((obj) => obj[this.target.primaryKeyAttribute] === old[this.target.primaryKeyAttribute]));
const unassociatedObjects = targetInstances.filter((obj) => !oldAssociations.find((old) => obj[this.target.primaryKeyAttribute] === old[this.target.primaryKeyAttribute]));
let updateWhere;
let update;
if (obsoleteAssociations.length > 0) {
update = {};
update[this.foreignKey] = null;
updateWhere = {
[this.target.primaryKeyAttribute]: obsoleteAssociations.map((associatedObject) => associatedObject[this.target.primaryKeyAttribute])
};
promises.push(this.target.unscoped().update(update, __spreadProps(__spreadValues({}, options), {
where: updateWhere
})));
}
if (unassociatedObjects.length > 0) {
updateWhere = {};
update = {};
update[this.foreignKey] = sourceInstance.get(this.sourceKey);
Object.assign(update, this.scope);
updateWhere[this.target.primaryKeyAttribute] = unassociatedObjects.map((unassociatedObject) => unassociatedObject[this.target.primaryKeyAttribute]);
promises.push(this.target.unscoped().update(update, __spreadProps(__spreadValues({}, options), {
where: updateWhere
})));
}
await Promise.all(promises);
return sourceInstance;
}
async add(sourceInstance, targetInstances, options = {}) {
if (!targetInstances)
return Promise.resolve();
targetInstances = this.toInstanceArray(targetInstances);
const update = __spreadValues({
[this.foreignKey]: sourceInstance.get(this.sourceKey)
}, this.scope);
const where = {
[this.target.primaryKeyAttribute]: targetInstances.map((unassociatedObject) => unassociatedObject.get(this.target.primaryKeyAttribute))
};
await this.target.unscoped().update(update, __spreadProps(__spreadValues({}, options), { where }));
return sourceInstance;
}
async remove(sourceInstance, targetInstances, options = {}) {
const update = {
[this.foreignKey]: null
};
targetInstances = this.toInstanceArray(targetInstances);
const where = {
[this.foreignKey]: sourceInstance.get(this.sourceKey),
[this.target.primaryKeyAttribute]: targetInstances.map((targetInstance) => targetInstance.get(this.target.primaryKeyAttribute))
};
await this.target.unscoped().update(update, __spreadProps(__spreadValues({}, options), { where }));
return this;
}
async create(sourceInstance, values, options = {}) {
if (Array.isArray(options)) {
options = {
fields: options
};
}
if (values === void 0) {
values = {};
}
if (this.scope) {
for (const attribute of Object.keys(this.scope)) {
values[attribute] = this.scope[attribute];
if (options.fields)
options.fields.push(attribute);
}
}
values[this.foreignKey] = sourceInstance.get(this.sourceKey);
if (options.fields)
options.fields.push(this.foreignKey);
return await this.target.create(values, options);
}
verifyAssociationAlias(alias) {
if (typeof alias === "string") {
return this.as === alias;
}
if (alias && alias.plural) {
return this.as === alias.plural;
}
return !this.isAliased;
}
}
module.exports = HasMany;
module.exports.HasMany = HasMany;
module.exports.default = HasMany;
//# sourceMappingURL=has-many.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,191 @@
"use strict";
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
const Utils = require("./../utils");
const Helpers = require("./helpers");
const _ = require("lodash");
const Association = require("./base");
const Op = require("../operators");
class HasOne extends Association {
constructor(source, target, options) {
super(source, target, options);
this.associationType = "HasOne";
this.isSingleAssociation = true;
this.foreignKeyAttribute = {};
if (this.as) {
this.isAliased = true;
this.options.name = {
singular: this.as
};
} else {
this.as = this.target.options.name.singular;
this.options.name = this.target.options.name;
}
if (_.isObject(this.options.foreignKey)) {
this.foreignKeyAttribute = this.options.foreignKey;
this.foreignKey = this.foreignKeyAttribute.name || this.foreignKeyAttribute.fieldName;
} else if (this.options.foreignKey) {
this.foreignKey = this.options.foreignKey;
}
if (!this.foreignKey) {
this.foreignKey = Utils.camelize([
Utils.singularize(this.options.as || this.source.name),
this.source.primaryKeyAttribute
].join("_"));
}
if (this.options.sourceKey && !this.source.rawAttributes[this.options.sourceKey]) {
throw new Error(`Unknown attribute "${this.options.sourceKey}" passed as sourceKey, define this attribute on model "${this.source.name}" first`);
}
this.sourceKey = this.sourceKeyAttribute = this.options.sourceKey || this.source.primaryKeyAttribute;
this.sourceKeyField = this.source.rawAttributes[this.sourceKey].field || this.sourceKey;
this.sourceKeyIsPrimary = this.sourceKey === this.source.primaryKeyAttribute;
this.associationAccessor = this.as;
this.options.useHooks = options.useHooks;
if (this.target.rawAttributes[this.foreignKey]) {
this.identifierField = this.target.rawAttributes[this.foreignKey].field || this.foreignKey;
}
const singular = _.upperFirst(this.options.name.singular);
this.accessors = {
get: `get${singular}`,
set: `set${singular}`,
create: `create${singular}`
};
}
_injectAttributes() {
const newAttributes = {
[this.foreignKey]: __spreadValues({
type: this.options.keyType || this.source.rawAttributes[this.sourceKey].type,
allowNull: true
}, this.foreignKeyAttribute)
};
if (this.options.constraints !== false) {
const target = this.target.rawAttributes[this.foreignKey] || newAttributes[this.foreignKey];
this.options.onDelete = this.options.onDelete || (target.allowNull ? "SET NULL" : "CASCADE");
this.options.onUpdate = this.options.onUpdate || "CASCADE";
}
Helpers.addForeignKeyConstraints(newAttributes[this.foreignKey], this.source, this.target, this.options, this.sourceKeyField);
Utils.mergeDefaults(this.target.rawAttributes, newAttributes);
this.target.refreshAttributes();
this.identifierField = this.target.rawAttributes[this.foreignKey].field || this.foreignKey;
Helpers.checkNamingCollision(this);
return this;
}
mixin(obj) {
const methods = ["get", "set", "create"];
Helpers.mixinMethods(this, obj, methods);
}
async get(instances, options) {
const where = {};
let Target = this.target;
let instance;
options = Utils.cloneDeep(options);
if (Object.prototype.hasOwnProperty.call(options, "scope")) {
if (!options.scope) {
Target = Target.unscoped();
} else {
Target = Target.scope(options.scope);
}
}
if (Object.prototype.hasOwnProperty.call(options, "schema")) {
Target = Target.schema(options.schema, options.schemaDelimiter);
}
if (!Array.isArray(instances)) {
instance = instances;
instances = void 0;
}
if (instances) {
where[this.foreignKey] = {
[Op.in]: instances.map((_instance) => _instance.get(this.sourceKey))
};
} else {
where[this.foreignKey] = instance.get(this.sourceKey);
}
if (this.scope) {
Object.assign(where, this.scope);
}
options.where = options.where ? { [Op.and]: [where, options.where] } : where;
if (instances) {
const results = await Target.findAll(options);
const result = {};
for (const _instance of instances) {
result[_instance.get(this.sourceKey, { raw: true })] = null;
}
for (const _instance of results) {
result[_instance.get(this.foreignKey, { raw: true })] = _instance;
}
return result;
}
return Target.findOne(options);
}
async set(sourceInstance, associatedInstance, options) {
options = __spreadProps(__spreadValues({}, options), { scope: false });
const oldInstance = await sourceInstance[this.accessors.get](options);
const alreadyAssociated = oldInstance && associatedInstance && this.target.primaryKeyAttributes.every((attribute) => oldInstance.get(attribute, { raw: true }) === (associatedInstance.get ? associatedInstance.get(attribute, { raw: true }) : associatedInstance));
if (oldInstance && !alreadyAssociated) {
oldInstance[this.foreignKey] = null;
await oldInstance.save(__spreadProps(__spreadValues({}, options), {
fields: [this.foreignKey],
allowNull: [this.foreignKey],
association: true
}));
}
if (associatedInstance && !alreadyAssociated) {
if (!(associatedInstance instanceof this.target)) {
const tmpInstance = {};
tmpInstance[this.target.primaryKeyAttribute] = associatedInstance;
associatedInstance = this.target.build(tmpInstance, {
isNewRecord: false
});
}
Object.assign(associatedInstance, this.scope);
associatedInstance.set(this.foreignKey, sourceInstance.get(this.sourceKeyAttribute));
return associatedInstance.save(options);
}
return null;
}
async create(sourceInstance, values, options) {
values = values || {};
options = options || {};
if (this.scope) {
for (const attribute of Object.keys(this.scope)) {
values[attribute] = this.scope[attribute];
if (options.fields) {
options.fields.push(attribute);
}
}
}
values[this.foreignKey] = sourceInstance.get(this.sourceKeyAttribute);
if (options.fields) {
options.fields.push(this.foreignKey);
}
return await this.target.create(values, options);
}
verifyAssociationAlias(alias) {
if (typeof alias === "string") {
return this.as === alias;
}
if (alias && alias.singular) {
return this.as === alias.singular;
}
return !this.isAliased;
}
}
module.exports = HasOne;
//# sourceMappingURL=has-one.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,34 @@
"use strict";
function checkNamingCollision(association) {
if (Object.prototype.hasOwnProperty.call(association.source.rawAttributes, association.as)) {
throw new Error(`Naming collision between attribute '${association.as}' and association '${association.as}' on model ${association.source.name}. To remedy this, change either foreignKey or as in your association definition`);
}
}
exports.checkNamingCollision = checkNamingCollision;
function addForeignKeyConstraints(newAttribute, source, target, options, key) {
if (options.foreignKeyConstraint || options.onDelete || options.onUpdate) {
const primaryKeys = Object.keys(source.primaryKeys).map((primaryKeyAttribute) => source.rawAttributes[primaryKeyAttribute].field || primaryKeyAttribute);
if (primaryKeys.length === 1 || !primaryKeys.includes(key)) {
newAttribute.references = {
model: source.getTableName(),
key: key || primaryKeys[0]
};
newAttribute.onDelete = options.onDelete;
newAttribute.onUpdate = options.onUpdate;
}
}
}
exports.addForeignKeyConstraints = addForeignKeyConstraints;
function mixinMethods(association, obj, methods, aliases) {
aliases = aliases || {};
for (const method of methods) {
if (!Object.prototype.hasOwnProperty.call(obj, association.accessors[method])) {
const realMethod = aliases[method] || method;
obj[association.accessors[method]] = function() {
return association[realMethod](this, ...Array.from(arguments));
};
}
}
}
exports.mixinMethods = mixinMethods;
//# sourceMappingURL=helpers.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/associations/helpers.js"],
"sourcesContent": ["'use strict';\n\nfunction checkNamingCollision(association) {\n if (Object.prototype.hasOwnProperty.call(association.source.rawAttributes, association.as)) {\n throw new Error(\n `Naming collision between attribute '${association.as}'` +\n ` and association '${association.as}' on model ${association.source.name}` +\n '. To remedy this, change either foreignKey or as in your association definition'\n );\n }\n}\nexports.checkNamingCollision = checkNamingCollision;\n\nfunction addForeignKeyConstraints(newAttribute, source, target, options, key) {\n // FK constraints are opt-in: users must either set `foreignKeyConstraints`\n // on the association, or request an `onDelete` or `onUpdate` behavior\n\n if (options.foreignKeyConstraint || options.onDelete || options.onUpdate) {\n // Find primary keys: composite keys not supported with this approach\n const primaryKeys = Object.keys(source.primaryKeys)\n .map(primaryKeyAttribute => source.rawAttributes[primaryKeyAttribute].field || primaryKeyAttribute);\n\n if (primaryKeys.length === 1 || !primaryKeys.includes(key)) {\n newAttribute.references = {\n model: source.getTableName(),\n key: key || primaryKeys[0]\n };\n\n newAttribute.onDelete = options.onDelete;\n newAttribute.onUpdate = options.onUpdate;\n }\n }\n}\nexports.addForeignKeyConstraints = addForeignKeyConstraints;\n\n/**\n * Mixin (inject) association methods to model prototype\n *\n * @private\n *\n * @param {object} association instance\n * @param {object} obj Model prototype\n * @param {Array} methods Method names to inject\n * @param {object} aliases Mapping between model and association method names\n *\n */\nfunction mixinMethods(association, obj, methods, aliases) {\n aliases = aliases || {};\n\n for (const method of methods) {\n // don't override custom methods\n if (!Object.prototype.hasOwnProperty.call(obj, association.accessors[method])) {\n const realMethod = aliases[method] || method;\n\n obj[association.accessors[method]] = function() {\n return association[realMethod](this, ...Array.from(arguments));\n };\n }\n }\n}\nexports.mixinMethods = mixinMethods;\n"],
"mappings": ";AAEA,8BAA8B,aAAa;AACzC,MAAI,OAAO,UAAU,eAAe,KAAK,YAAY,OAAO,eAAe,YAAY,KAAK;AAC1F,UAAM,IAAI,MACR,uCAAuC,YAAY,wBAC9B,YAAY,gBAAgB,YAAY,OAAO;AAAA;AAAA;AAK1E,QAAQ,uBAAuB;AAE/B,kCAAkC,cAAc,QAAQ,QAAQ,SAAS,KAAK;AAI5E,MAAI,QAAQ,wBAAwB,QAAQ,YAAY,QAAQ,UAAU;AAExE,UAAM,cAAc,OAAO,KAAK,OAAO,aACpC,IAAI,yBAAuB,OAAO,cAAc,qBAAqB,SAAS;AAEjF,QAAI,YAAY,WAAW,KAAK,CAAC,YAAY,SAAS,MAAM;AAC1D,mBAAa,aAAa;AAAA,QACxB,OAAO,OAAO;AAAA,QACd,KAAK,OAAO,YAAY;AAAA;AAG1B,mBAAa,WAAW,QAAQ;AAChC,mBAAa,WAAW,QAAQ;AAAA;AAAA;AAAA;AAItC,QAAQ,2BAA2B;AAanC,sBAAsB,aAAa,KAAK,SAAS,SAAS;AACxD,YAAU,WAAW;AAErB,aAAW,UAAU,SAAS;AAE5B,QAAI,CAAC,OAAO,UAAU,eAAe,KAAK,KAAK,YAAY,UAAU,UAAU;AAC7E,YAAM,aAAa,QAAQ,WAAW;AAEtC,UAAI,YAAY,UAAU,WAAW,WAAW;AAC9C,eAAO,YAAY,YAAY,MAAM,GAAG,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAK3D,QAAQ,eAAe;",
"names": []
}

View File

@@ -0,0 +1,10 @@
"use strict";
const Association = require("./base");
Association.BelongsTo = require("./belongs-to");
Association.HasOne = require("./has-one");
Association.HasMany = require("./has-many");
Association.BelongsToMany = require("./belongs-to-many");
module.exports = Association;
module.exports.default = Association;
module.exports.Association = Association;
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/associations/index.js"],
"sourcesContent": ["'use strict';\n\nconst Association = require('./base');\n\nAssociation.BelongsTo = require('./belongs-to');\nAssociation.HasOne = require('./has-one');\nAssociation.HasMany = require('./has-many');\nAssociation.BelongsToMany = require('./belongs-to-many');\n\nmodule.exports = Association;\nmodule.exports.default = Association;\nmodule.exports.Association = Association;\n"],
"mappings": ";AAEA,MAAM,cAAc,QAAQ;AAE5B,YAAY,YAAY,QAAQ;AAChC,YAAY,SAAS,QAAQ;AAC7B,YAAY,UAAU,QAAQ;AAC9B,YAAY,gBAAgB,QAAQ;AAEpC,OAAO,UAAU;AACjB,OAAO,QAAQ,UAAU;AACzB,OAAO,QAAQ,cAAc;",
"names": []
}

View File

@@ -0,0 +1,85 @@
"use strict";
const _ = require("lodash");
const HasOne = require("./has-one");
const HasMany = require("./has-many");
const BelongsToMany = require("./belongs-to-many");
const BelongsTo = require("./belongs-to");
function isModel(model, sequelize) {
return model && model.prototype && model.prototype instanceof sequelize.Sequelize.Model;
}
const Mixin = {
hasMany(target, options = {}) {
if (!isModel(target, this.sequelize)) {
throw new Error(`${this.name}.hasMany called with something that's not a subclass of Sequelize.Model`);
}
const source = this;
options.hooks = options.hooks === void 0 ? false : Boolean(options.hooks);
options.useHooks = options.hooks;
Object.assign(options, _.omit(source.options, ["hooks"]));
if (options.useHooks) {
this.runHooks("beforeAssociate", { source, target, type: HasMany }, options);
}
const association = new HasMany(source, target, options);
source.associations[association.associationAccessor] = association;
association._injectAttributes();
association.mixin(source.prototype);
if (options.useHooks) {
this.runHooks("afterAssociate", { source, target, type: HasMany, association }, options);
}
return association;
},
belongsToMany(target, options = {}) {
if (!isModel(target, this.sequelize)) {
throw new Error(`${this.name}.belongsToMany called with something that's not a subclass of Sequelize.Model`);
}
const source = this;
options.hooks = options.hooks === void 0 ? false : Boolean(options.hooks);
options.useHooks = options.hooks;
options.timestamps = options.timestamps === void 0 ? this.sequelize.options.timestamps : options.timestamps;
Object.assign(options, _.omit(source.options, ["hooks", "timestamps", "scopes", "defaultScope"]));
if (options.useHooks) {
this.runHooks("beforeAssociate", { source, target, type: BelongsToMany }, options);
}
const association = new BelongsToMany(source, target, options);
source.associations[association.associationAccessor] = association;
association._injectAttributes();
association.mixin(source.prototype);
if (options.useHooks) {
this.runHooks("afterAssociate", { source, target, type: BelongsToMany, association }, options);
}
return association;
},
getAssociations(target) {
return Object.values(this.associations).filter((association) => association.target.name === target.name);
},
getAssociationForAlias(target, alias) {
return this.getAssociations(target).find((association) => association.verifyAssociationAlias(alias)) || null;
}
};
function singleLinked(Type) {
return function(target, options = {}) {
const source = this;
if (!isModel(target, source.sequelize)) {
throw new Error(`${source.name}.${_.lowerFirst(Type.name)} called with something that's not a subclass of Sequelize.Model`);
}
options.hooks = options.hooks === void 0 ? false : Boolean(options.hooks);
options.useHooks = options.hooks;
if (options.useHooks) {
source.runHooks("beforeAssociate", { source, target, type: Type }, options);
}
const association = new Type(source, target, Object.assign(options, source.options));
source.associations[association.associationAccessor] = association;
association._injectAttributes();
association.mixin(source.prototype);
if (options.useHooks) {
source.runHooks("afterAssociate", { source, target, type: Type, association }, options);
}
return association;
};
}
Mixin.hasOne = singleLinked(HasOne);
Mixin.belongsTo = singleLinked(BelongsTo);
module.exports = Mixin;
module.exports.Mixin = Mixin;
module.exports.default = Mixin;
//# sourceMappingURL=mixin.js.map

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/associations/mixin.js"],
"sourcesContent": ["'use strict';\n\nconst _ = require('lodash');\nconst HasOne = require('./has-one');\nconst HasMany = require('./has-many');\nconst BelongsToMany = require('./belongs-to-many');\nconst BelongsTo = require('./belongs-to');\n\nfunction isModel(model, sequelize) {\n return model\n && model.prototype\n && model.prototype instanceof sequelize.Sequelize.Model;\n}\n\nconst Mixin = {\n hasMany(target, options = {}) {\n if (!isModel(target, this.sequelize)) {\n throw new Error(`${this.name}.hasMany called with something that's not a subclass of Sequelize.Model`);\n }\n\n const source = this;\n\n // Since this is a mixin, we'll need a unique letiable name for hooks (since Model will override our hooks option)\n options.hooks = options.hooks === undefined ? false : Boolean(options.hooks);\n options.useHooks = options.hooks;\n\n Object.assign(options, _.omit(source.options, ['hooks']));\n\n if (options.useHooks) {\n this.runHooks('beforeAssociate', { source, target, type: HasMany }, options);\n }\n\n // the id is in the foreign table or in a connecting table\n const association = new HasMany(source, target, options);\n source.associations[association.associationAccessor] = association;\n\n association._injectAttributes();\n association.mixin(source.prototype);\n\n if (options.useHooks) {\n this.runHooks('afterAssociate', { source, target, type: HasMany, association }, options);\n }\n\n return association;\n },\n\n belongsToMany(target, options = {}) {\n if (!isModel(target, this.sequelize)) {\n throw new Error(`${this.name}.belongsToMany called with something that's not a subclass of Sequelize.Model`);\n }\n\n const source = this;\n\n // Since this is a mixin, we'll need a unique letiable name for hooks (since Model will override our hooks option)\n options.hooks = options.hooks === undefined ? false : Boolean(options.hooks);\n options.useHooks = options.hooks;\n options.timestamps = options.timestamps === undefined ? this.sequelize.options.timestamps : options.timestamps;\n Object.assign(options, _.omit(source.options, ['hooks', 'timestamps', 'scopes', 'defaultScope']));\n\n if (options.useHooks) {\n this.runHooks('beforeAssociate', { source, target, type: BelongsToMany }, options);\n }\n // the id is in the foreign table or in a connecting table\n const association = new BelongsToMany(source, target, options);\n source.associations[association.associationAccessor] = association;\n\n association._injectAttributes();\n association.mixin(source.prototype);\n\n if (options.useHooks) {\n this.runHooks('afterAssociate', { source, target, type: BelongsToMany, association }, options);\n }\n\n return association;\n },\n\n getAssociations(target) {\n return Object.values(this.associations).filter(association => association.target.name === target.name);\n },\n\n getAssociationForAlias(target, alias) {\n // Two associations cannot have the same alias, so we can use find instead of filter\n return this.getAssociations(target).find(association => association.verifyAssociationAlias(alias)) || null;\n }\n};\n\n// The logic for hasOne and belongsTo is exactly the same\nfunction singleLinked(Type) {\n return function(target, options = {}) {\n // eslint-disable-next-line no-invalid-this\n const source = this;\n if (!isModel(target, source.sequelize)) {\n throw new Error(`${source.name}.${_.lowerFirst(Type.name)} called with something that's not a subclass of Sequelize.Model`);\n }\n\n\n // Since this is a mixin, we'll need a unique letiable name for hooks (since Model will override our hooks option)\n options.hooks = options.hooks === undefined ? false : Boolean(options.hooks);\n options.useHooks = options.hooks;\n\n if (options.useHooks) {\n source.runHooks('beforeAssociate', { source, target, type: Type }, options);\n }\n // the id is in the foreign table\n const association = new Type(source, target, Object.assign(options, source.options));\n source.associations[association.associationAccessor] = association;\n\n association._injectAttributes();\n association.mixin(source.prototype);\n\n if (options.useHooks) {\n source.runHooks('afterAssociate', { source, target, type: Type, association }, options);\n }\n\n return association;\n };\n}\n\nMixin.hasOne = singleLinked(HasOne);\nMixin.belongsTo = singleLinked(BelongsTo);\n\nmodule.exports = Mixin;\nmodule.exports.Mixin = Mixin;\nmodule.exports.default = Mixin;\n"],
"mappings": ";AAEA,MAAM,IAAI,QAAQ;AAClB,MAAM,SAAS,QAAQ;AACvB,MAAM,UAAU,QAAQ;AACxB,MAAM,gBAAgB,QAAQ;AAC9B,MAAM,YAAY,QAAQ;AAE1B,iBAAiB,OAAO,WAAW;AACjC,SAAO,SACF,MAAM,aACN,MAAM,qBAAqB,UAAU,UAAU;AAAA;AAGtD,MAAM,QAAQ;AAAA,EACZ,QAAQ,QAAQ,UAAU,IAAI;AAC5B,QAAI,CAAC,QAAQ,QAAQ,KAAK,YAAY;AACpC,YAAM,IAAI,MAAM,GAAG,KAAK;AAAA;AAG1B,UAAM,SAAS;AAGf,YAAQ,QAAQ,QAAQ,UAAU,SAAY,QAAQ,QAAQ,QAAQ;AACtE,YAAQ,WAAW,QAAQ;AAE3B,WAAO,OAAO,SAAS,EAAE,KAAK,OAAO,SAAS,CAAC;AAE/C,QAAI,QAAQ,UAAU;AACpB,WAAK,SAAS,mBAAmB,EAAE,QAAQ,QAAQ,MAAM,WAAW;AAAA;AAItE,UAAM,cAAc,IAAI,QAAQ,QAAQ,QAAQ;AAChD,WAAO,aAAa,YAAY,uBAAuB;AAEvD,gBAAY;AACZ,gBAAY,MAAM,OAAO;AAEzB,QAAI,QAAQ,UAAU;AACpB,WAAK,SAAS,kBAAkB,EAAE,QAAQ,QAAQ,MAAM,SAAS,eAAe;AAAA;AAGlF,WAAO;AAAA;AAAA,EAGT,cAAc,QAAQ,UAAU,IAAI;AAClC,QAAI,CAAC,QAAQ,QAAQ,KAAK,YAAY;AACpC,YAAM,IAAI,MAAM,GAAG,KAAK;AAAA;AAG1B,UAAM,SAAS;AAGf,YAAQ,QAAQ,QAAQ,UAAU,SAAY,QAAQ,QAAQ,QAAQ;AACtE,YAAQ,WAAW,QAAQ;AAC3B,YAAQ,aAAa,QAAQ,eAAe,SAAY,KAAK,UAAU,QAAQ,aAAa,QAAQ;AACpG,WAAO,OAAO,SAAS,EAAE,KAAK,OAAO,SAAS,CAAC,SAAS,cAAc,UAAU;AAEhF,QAAI,QAAQ,UAAU;AACpB,WAAK,SAAS,mBAAmB,EAAE,QAAQ,QAAQ,MAAM,iBAAiB;AAAA;AAG5E,UAAM,cAAc,IAAI,cAAc,QAAQ,QAAQ;AACtD,WAAO,aAAa,YAAY,uBAAuB;AAEvD,gBAAY;AACZ,gBAAY,MAAM,OAAO;AAEzB,QAAI,QAAQ,UAAU;AACpB,WAAK,SAAS,kBAAkB,EAAE,QAAQ,QAAQ,MAAM,eAAe,eAAe;AAAA;AAGxF,WAAO;AAAA;AAAA,EAGT,gBAAgB,QAAQ;AACtB,WAAO,OAAO,OAAO,KAAK,cAAc,OAAO,iBAAe,YAAY,OAAO,SAAS,OAAO;AAAA;AAAA,EAGnG,uBAAuB,QAAQ,OAAO;AAEpC,WAAO,KAAK,gBAAgB,QAAQ,KAAK,iBAAe,YAAY,uBAAuB,WAAW;AAAA;AAAA;AAK1G,sBAAsB,MAAM;AAC1B,SAAO,SAAS,QAAQ,UAAU,IAAI;AAEpC,UAAM,SAAS;AACf,QAAI,CAAC,QAAQ,QAAQ,OAAO,YAAY;AACtC,YAAM,IAAI,MAAM,GAAG,OAAO,QAAQ,EAAE,WAAW,KAAK;AAAA;AAKtD,YAAQ,QAAQ,QAAQ,UAAU,SAAY,QAAQ,QAAQ,QAAQ;AACtE,YAAQ,WAAW,QAAQ;AAE3B,QAAI,QAAQ,UAAU;AACpB,aAAO,SAAS,mBAAmB,EAAE,QAAQ,QAAQ,MAAM,QAAQ;AAAA;AAGrE,UAAM,cAAc,IAAI,KAAK,QAAQ,QAAQ,OAAO,OAAO,SAAS,OAAO;AAC3E,WAAO,aAAa,YAAY,uBAAuB;AAEvD,gBAAY;AACZ,gBAAY,MAAM,OAAO;AAEzB,QAAI,QAAQ,UAAU;AACpB,aAAO,SAAS,kBAAkB,EAAE,QAAQ,QAAQ,MAAM,MAAM,eAAe;AAAA;AAGjF,WAAO;AAAA;AAAA;AAIX,MAAM,SAAS,aAAa;AAC5B,MAAM,YAAY,aAAa;AAE/B,OAAO,UAAU;AACjB,OAAO,QAAQ,QAAQ;AACvB,OAAO,QAAQ,UAAU;",
"names": []
}