2019-05-08 15:45:37 +00:00
|
|
|
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
|
2016-04-01 22:25:16 +00:00
|
|
|
// Node module: loopback-datasource-juggler
|
|
|
|
// This file is licensed under the MIT License.
|
|
|
|
// License text available at https://opensource.org/licenses/MIT
|
2019-05-08 15:45:37 +00:00
|
|
|
|
2016-08-22 19:55:22 +00:00
|
|
|
'use strict';
|
2016-04-01 22:25:16 +00:00
|
|
|
|
2018-12-07 14:54:29 +00:00
|
|
|
const debug = require('debug')('loopback:mixin');
|
|
|
|
const assert = require('assert');
|
|
|
|
const DefaultModelBaseClass = require('./model.js');
|
2014-08-06 11:26:47 +00:00
|
|
|
|
2014-08-08 08:20:57 +00:00
|
|
|
function isModelClass(cls) {
|
|
|
|
if (!cls) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return cls.prototype instanceof DefaultModelBaseClass;
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = MixinProvider;
|
2014-08-06 11:26:47 +00:00
|
|
|
|
2014-08-08 08:20:57 +00:00
|
|
|
function MixinProvider(modelBuilder) {
|
|
|
|
this.modelBuilder = modelBuilder;
|
|
|
|
this.mixins = {};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Apply named mixin to the model class
|
|
|
|
* @param {Model} modelClass
|
|
|
|
* @param {String} name
|
|
|
|
* @param {Object} options
|
|
|
|
*/
|
|
|
|
MixinProvider.prototype.applyMixin = function applyMixin(modelClass, name, options) {
|
2018-12-07 14:54:29 +00:00
|
|
|
const fn = this.mixins[name];
|
2014-08-06 11:26:47 +00:00
|
|
|
if (typeof fn === 'function') {
|
|
|
|
if (modelClass.dataSource) {
|
|
|
|
fn(modelClass, options || {});
|
|
|
|
} else {
|
|
|
|
modelClass.once('dataSourceAttached', function() {
|
|
|
|
fn(modelClass, options || {});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
} else {
|
2014-08-08 08:20:57 +00:00
|
|
|
// Try model name
|
2018-12-07 14:54:29 +00:00
|
|
|
const model = this.modelBuilder.getModel(name);
|
2016-04-01 11:48:17 +00:00
|
|
|
if (model) {
|
2014-08-08 08:20:57 +00:00
|
|
|
debug('Mixin is resolved to a model: %s', name);
|
|
|
|
modelClass.mixin(model, options);
|
2014-08-06 11:26:47 +00:00
|
|
|
} else {
|
2018-12-07 14:54:29 +00:00
|
|
|
const errMsg = 'Model "' + modelClass.modelName + '" uses unknown mixin: ' + name;
|
2016-05-24 17:58:21 +00:00
|
|
|
debug(errMsg);
|
|
|
|
throw new Error(errMsg);
|
2014-08-06 11:26:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2014-08-08 08:20:57 +00:00
|
|
|
/**
|
|
|
|
* Define a mixin with name
|
|
|
|
* @param {String} name Name of the mixin
|
|
|
|
* @param {*) mixin The mixin function or a model
|
|
|
|
*/
|
|
|
|
MixinProvider.prototype.define = function defineMixin(name, mixin) {
|
|
|
|
assert(typeof mixin === 'function', 'The mixin must be a function or model class');
|
|
|
|
if (this.mixins[name]) {
|
|
|
|
debug('Duplicate mixin: %s', name);
|
|
|
|
} else {
|
|
|
|
debug('Defining mixin: %s', name);
|
2014-08-06 11:26:47 +00:00
|
|
|
}
|
2014-08-08 08:20:57 +00:00
|
|
|
if (isModelClass(mixin)) {
|
2016-04-01 11:48:17 +00:00
|
|
|
this.mixins[name] = function(Model, options) {
|
2014-08-08 08:20:57 +00:00
|
|
|
Model.mixin(mixin, options);
|
|
|
|
};
|
|
|
|
} else if (typeof mixin === 'function') {
|
|
|
|
this.mixins[name] = mixin;
|
2014-08-06 11:26:47 +00:00
|
|
|
}
|
|
|
|
};
|