loopback-datasource-juggler/lib/jutil.js

108 lines
3.2 KiB
JavaScript
Raw Normal View History

2013-05-29 17:03:01 +00:00
var util = require('util');
2013-05-28 05:20:30 +00:00
/**
*
* @param newClass
* @param baseClass
*/
2013-05-29 17:03:01 +00:00
exports.inherits = function (newClass, baseClass, options) {
util.inherits(newClass, baseClass);
options = options || {
staticProperties: true,
override: false
};
if (options.staticProperties) {
Object.keys(baseClass).forEach(function (classProp) {
if (classProp !== 'super_' && (!newClass.hasOwnProperty(classProp) || options.override)) {
var pd = Object.getOwnPropertyDescriptor(baseClass, classProp);
Object.defineProperty(newClass, classProp, pd);
}
});
}
2011-10-10 13:22:51 +00:00
};
2013-05-28 05:20:30 +00:00
/**
* Mix in the a class into the new class
* @param newClass The target class to receive the mixin
* @param mixinClass The class to be mixed in
2013-05-28 05:20:30 +00:00
* @param options
*/
exports.mixin = function (newClass, mixinClass, options) {
if (Array.isArray(newClass._mixins)) {
if(newClass._mixins.indexOf(mixinClass) !== -1) {
return;
}
newClass._mixins.push(mixinClass);
} else {
newClass._mixins = [mixinClass];
}
2013-05-28 05:20:30 +00:00
options = options || {
staticProperties: true,
instanceProperties: true,
2013-12-04 21:44:25 +00:00
override: false,
proxyFunctions: false
2013-05-28 05:20:30 +00:00
};
2013-12-04 21:44:25 +00:00
if(options.staticProperties === undefined) {
options.staticProperties = true;
}
if(options.instanceProperties === undefined) {
options.instanceProperties = true;
}
2013-05-28 05:20:30 +00:00
if (options.staticProperties) {
var staticProxies = [];
Object.keys(mixinClass).forEach(function (classProp) {
if (classProp !== 'super_' && classProp !== '_mixins' && (!newClass.hasOwnProperty(classProp) || options.override)) {
var pd = Object.getOwnPropertyDescriptor(mixinClass, classProp);
2013-12-04 21:44:25 +00:00
if(options.proxyFunctions && pd.writable && typeof pd.value === 'function') {
pd.value = exports.proxy(pd.value, staticProxies);
}
2013-05-28 20:50:59 +00:00
Object.defineProperty(newClass, classProp, pd);
2013-05-28 05:20:30 +00:00
}
});
}
if (options.instanceProperties) {
if (mixinClass.prototype) {
var instanceProxies = [];
Object.keys(mixinClass.prototype).forEach(function (instanceProp) {
2013-10-12 01:37:45 +00:00
if (!newClass.prototype.hasOwnProperty(instanceProp) || options.override) {
var pd = Object.getOwnPropertyDescriptor(mixinClass.prototype, instanceProp);
2013-12-04 21:44:25 +00:00
if(options.proxyFunctions && pd.writable && typeof pd.value === 'function') {
pd.value = exports.proxy(pd.value, instanceProxies);
}
2013-05-28 20:50:59 +00:00
Object.defineProperty(newClass.prototype, instanceProp, pd);
}
2013-05-28 05:20:30 +00:00
});
}
}
2013-05-28 20:50:59 +00:00
return newClass;
2013-05-28 05:20:30 +00:00
};
exports.proxy = function(fn, proxies) {
// Make sure same methods referenced by different properties have the same proxy
// For example, deleteById is an alias of removeById
proxies = proxies || [];
for(var i = 0; i<proxies.length; i++) {
if(proxies[i]._delegate === fn) {
return proxies[i];
}
}
var f = function() {
return fn.apply(this, arguments);
};
f._delegate = fn;
proxies.push(f);
Object.keys(fn).forEach(function(x) {
f[x] = fn[x];
});
return f;
};