UNPKG

2.07 kBJavaScriptView Raw
1// Copyright IBM Corp. 2014,2019. All Rights Reserved.
2// Node module: loopback-datasource-juggler
3// This file is licensed under the MIT License.
4// License text available at https://opensource.org/licenses/MIT
5
6'use strict';
7
8const debug = require('debug')('loopback:mixin');
9const assert = require('assert');
10const DefaultModelBaseClass = require('./model.js');
11
12function isModelClass(cls) {
13 if (!cls) {
14 return false;
15 }
16 return cls.prototype instanceof DefaultModelBaseClass;
17}
18
19module.exports = MixinProvider;
20
21function MixinProvider(modelBuilder) {
22 this.modelBuilder = modelBuilder;
23 this.mixins = {};
24}
25
26/**
27 * Apply named mixin to the model class
28 * @param {Model} modelClass
29 * @param {String} name
30 * @param {Object} options
31 */
32MixinProvider.prototype.applyMixin = function applyMixin(modelClass, name, options) {
33 const fn = this.mixins[name];
34 if (typeof fn === 'function') {
35 if (modelClass.dataSource) {
36 fn(modelClass, options || {});
37 } else {
38 modelClass.once('dataSourceAttached', function() {
39 fn(modelClass, options || {});
40 });
41 }
42 } else {
43 // Try model name
44 const model = this.modelBuilder.getModel(name);
45 if (model) {
46 debug('Mixin is resolved to a model: %s', name);
47 modelClass.mixin(model, options);
48 } else {
49 const errMsg = 'Model "' + modelClass.modelName + '" uses unknown mixin: ' + name;
50 debug(errMsg);
51 throw new Error(errMsg);
52 }
53 }
54};
55
56/**
57 * Define a mixin with name
58 * @param {String} name Name of the mixin
59 * @param {*) mixin The mixin function or a model
60 */
61MixinProvider.prototype.define = function defineMixin(name, mixin) {
62 assert(typeof mixin === 'function', 'The mixin must be a function or model class');
63 if (this.mixins[name]) {
64 debug('Duplicate mixin: %s', name);
65 } else {
66 debug('Defining mixin: %s', name);
67 }
68 if (isModelClass(mixin)) {
69 this.mixins[name] = function(Model, options) {
70 Model.mixin(mixin, options);
71 };
72 } else if (typeof mixin === 'function') {
73 this.mixins[name] = mixin;
74 }
75};