loopback-datasource-juggler/lib/mixins.js

76 lines
2.0 KiB
JavaScript
Raw Normal View History

// Copyright IBM Corp. 2014,2019. 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-08 08:20:57 +00:00
function isModelClass(cls) {
if (!cls) {
return false;
}
return cls.prototype instanceof DefaultModelBaseClass;
}
module.exports = MixinProvider;
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];
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);
} else {
2018-12-07 14:54:29 +00:00
const errMsg = 'Model "' + modelClass.modelName + '" uses unknown mixin: ' + name;
debug(errMsg);
throw new Error(errMsg);
}
}
};
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-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;
}
};