{ "version": 3, "sources": ["../../src/associations/has-one.js"], "sourcesContent": ["'use strict';\n\nconst Utils = require('./../utils');\nconst Helpers = require('./helpers');\nconst _ = require('lodash');\nconst Association = require('./base');\nconst Op = require('../operators');\n\n/**\n * One-to-one association\n *\n * In the API reference below, add the name of the association to the method, e.g. for `User.hasOne(Project)` the getter will be `user.getProject()`.\n * This is almost the same as `belongsTo` with one exception - The foreign key will be defined on the target model.\n *\n * @see {@link Model.hasOne}\n */\nclass HasOne extends Association {\n constructor(source, target, options) {\n super(source, target, options);\n\n this.associationType = 'HasOne';\n this.isSingleAssociation = true;\n this.foreignKeyAttribute = {};\n\n if (this.as) {\n this.isAliased = true;\n this.options.name = {\n singular: this.as\n };\n } else {\n this.as = this.target.options.name.singular;\n this.options.name = this.target.options.name;\n }\n\n if (_.isObject(this.options.foreignKey)) {\n this.foreignKeyAttribute = this.options.foreignKey;\n this.foreignKey = this.foreignKeyAttribute.name || this.foreignKeyAttribute.fieldName;\n } else if (this.options.foreignKey) {\n this.foreignKey = this.options.foreignKey;\n }\n\n if (!this.foreignKey) {\n this.foreignKey = Utils.camelize(\n [\n Utils.singularize(this.options.as || this.source.name),\n this.source.primaryKeyAttribute\n ].join('_')\n );\n }\n\n if (\n this.options.sourceKey\n && !this.source.rawAttributes[this.options.sourceKey]\n ) {\n throw new Error(`Unknown attribute \"${this.options.sourceKey}\" passed as sourceKey, define this attribute on model \"${this.source.name}\" first`);\n }\n\n this.sourceKey = this.sourceKeyAttribute = this.options.sourceKey || this.source.primaryKeyAttribute;\n this.sourceKeyField = this.source.rawAttributes[this.sourceKey].field || this.sourceKey;\n this.sourceKeyIsPrimary = this.sourceKey === this.source.primaryKeyAttribute;\n\n this.associationAccessor = this.as;\n this.options.useHooks = options.useHooks;\n\n if (this.target.rawAttributes[this.foreignKey]) {\n this.identifierField = this.target.rawAttributes[this.foreignKey].field || this.foreignKey;\n }\n\n // Get singular name, trying to uppercase the first letter, unless the model forbids it\n const singular = _.upperFirst(this.options.name.singular);\n\n this.accessors = {\n get: `get${singular}`,\n set: `set${singular}`,\n create: `create${singular}`\n };\n }\n\n // the id is in the target table\n _injectAttributes() {\n const newAttributes = {\n [this.foreignKey]: {\n type: this.options.keyType || this.source.rawAttributes[this.sourceKey].type,\n allowNull: true,\n ...this.foreignKeyAttribute\n }\n };\n\n if (this.options.constraints !== false) {\n const target = this.target.rawAttributes[this.foreignKey] || newAttributes[this.foreignKey];\n this.options.onDelete = this.options.onDelete || (target.allowNull ? 'SET NULL' : 'CASCADE');\n this.options.onUpdate = this.options.onUpdate || 'CASCADE';\n }\n\n Helpers.addForeignKeyConstraints(newAttributes[this.foreignKey], this.source, this.target, this.options, this.sourceKeyField);\n Utils.mergeDefaults(this.target.rawAttributes, newAttributes);\n\n this.target.refreshAttributes();\n\n this.identifierField = this.target.rawAttributes[this.foreignKey].field || this.foreignKey;\n\n Helpers.checkNamingCollision(this);\n\n return this;\n }\n\n mixin(obj) {\n const methods = ['get', 'set', 'create'];\n\n Helpers.mixinMethods(this, obj, methods);\n }\n\n /**\n * Get the associated instance.\n *\n * @param {Model|Array} instances source instances\n * @param {object} [options] find options\n * @param {string|boolean} [options.scope] Apply a scope on the related model, or remove its default scope by passing false\n * @param {string} [options.schema] Apply a schema on the related model\n *\n * @see\n * {@link Model.findOne} for a full explanation of options\n *\n * @returns {Promise}\n */\n async get(instances, options) {\n const where = {};\n\n let Target = this.target;\n let instance;\n\n options = Utils.cloneDeep(options);\n\n if (Object.prototype.hasOwnProperty.call(options, 'scope')) {\n if (!options.scope) {\n Target = Target.unscoped();\n } else {\n Target = Target.scope(options.scope);\n }\n }\n\n if (Object.prototype.hasOwnProperty.call(options, 'schema')) {\n Target = Target.schema(options.schema, options.schemaDelimiter);\n }\n\n if (!Array.isArray(instances)) {\n instance = instances;\n instances = undefined;\n }\n\n if (instances) {\n where[this.foreignKey] = {\n [Op.in]: instances.map(_instance => _instance.get(this.sourceKey))\n };\n } else {\n where[this.foreignKey] = instance.get(this.sourceKey);\n }\n\n if (this.scope) {\n Object.assign(where, this.scope);\n }\n\n options.where = options.where ?\n { [Op.and]: [where, options.where] } :\n where;\n\n if (instances) {\n const results = await Target.findAll(options);\n const result = {};\n for (const _instance of instances) {\n result[_instance.get(this.sourceKey, { raw: true })] = null;\n }\n\n for (const _instance of results) {\n result[_instance.get(this.foreignKey, { raw: true })] = _instance;\n }\n\n return result;\n }\n\n return Target.findOne(options);\n }\n\n /**\n * Set the associated model.\n *\n * @param {Model} sourceInstance the source instance\n * @param {?Model|string|number} [associatedInstance] An persisted instance or the primary key of an instance to associate with this. Pass `null` or `undefined` to remove the association.\n * @param {object} [options] Options passed to getAssociation and `target.save`\n *\n * @returns {Promise}\n */\n async set(sourceInstance, associatedInstance, options) {\n options = { ...options, scope: false };\n\n const oldInstance = await sourceInstance[this.accessors.get](options);\n // TODO Use equals method once #5605 is resolved\n const alreadyAssociated = oldInstance && associatedInstance && this.target.primaryKeyAttributes.every(attribute =>\n oldInstance.get(attribute, { raw: true }) === (associatedInstance.get ? associatedInstance.get(attribute, { raw: true }) : associatedInstance)\n );\n\n if (oldInstance && !alreadyAssociated) {\n oldInstance[this.foreignKey] = null;\n\n await oldInstance.save({\n ...options,\n fields: [this.foreignKey],\n allowNull: [this.foreignKey],\n association: true\n });\n }\n if (associatedInstance && !alreadyAssociated) {\n if (!(associatedInstance instanceof this.target)) {\n const tmpInstance = {};\n tmpInstance[this.target.primaryKeyAttribute] = associatedInstance;\n associatedInstance = this.target.build(tmpInstance, {\n isNewRecord: false\n });\n }\n\n Object.assign(associatedInstance, this.scope);\n associatedInstance.set(this.foreignKey, sourceInstance.get(this.sourceKeyAttribute));\n\n return associatedInstance.save(options);\n }\n\n return null;\n }\n\n /**\n * Create a new instance of the associated model and associate it with this.\n *\n * @param {Model} sourceInstance the source instance\n * @param {object} [values={}] values to create associated model instance with\n * @param {object} [options] Options passed to `target.create` and setAssociation.\n *\n * @see\n * {@link Model#create} for a full explanation of options\n *\n * @returns {Promise} The created target model\n */\n async create(sourceInstance, values, options) {\n values = values || {};\n options = options || {};\n\n if (this.scope) {\n for (const attribute of Object.keys(this.scope)) {\n values[attribute] = this.scope[attribute];\n if (options.fields) {\n options.fields.push(attribute);\n }\n }\n }\n\n values[this.foreignKey] = sourceInstance.get(this.sourceKeyAttribute);\n if (options.fields) {\n options.fields.push(this.foreignKey);\n }\n\n return await this.target.create(values, options);\n }\n\n verifyAssociationAlias(alias) {\n if (typeof alias === 'string') {\n return this.as === alias;\n }\n\n if (alias && alias.singular) {\n return this.as === alias.singular;\n }\n\n return !this.isAliased;\n }\n}\n\nmodule.exports = HasOne;\n"], "mappings": "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", "names": [] }