2016-02-21 12:02:18 -05:00
|
|
|
/*
|
|
|
|
|
AdaptableController.js
|
|
|
|
|
|
|
|
|
|
AdaptableController is the base class for all controllers
|
2016-03-07 00:30:21 -08:00
|
|
|
that support adapter,
|
2016-02-21 12:02:18 -05:00
|
|
|
The super class takes care of creating the right instance for the adapter
|
|
|
|
|
based on the parameters passed
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
2016-02-22 14:12:51 -05:00
|
|
|
// _adapter is private, use Symbol
|
|
|
|
|
var _adapter = Symbol();
|
2016-02-27 10:51:12 -05:00
|
|
|
import Config from '../Config';
|
2016-02-22 14:12:51 -05:00
|
|
|
|
2016-02-21 12:02:18 -05:00
|
|
|
export class AdaptableController {
|
2016-02-22 14:12:51 -05:00
|
|
|
|
2016-02-27 10:51:12 -05:00
|
|
|
constructor(adapter, appId, options) {
|
|
|
|
|
this.options = options;
|
2016-02-25 19:04:27 -05:00
|
|
|
this.appId = appId;
|
2016-02-28 00:15:59 -05:00
|
|
|
this.adapter = adapter;
|
2016-02-21 23:47:07 -05:00
|
|
|
}
|
2016-02-22 14:12:51 -05:00
|
|
|
|
|
|
|
|
set adapter(adapter) {
|
2016-02-21 23:47:07 -05:00
|
|
|
this.validateAdapter(adapter);
|
2016-02-22 14:12:51 -05:00
|
|
|
this[_adapter] = adapter;
|
|
|
|
|
}
|
2016-03-07 00:30:21 -08:00
|
|
|
|
2016-02-22 14:12:51 -05:00
|
|
|
get adapter() {
|
|
|
|
|
return this[_adapter];
|
2016-02-21 12:02:18 -05:00
|
|
|
}
|
2016-03-07 00:30:21 -08:00
|
|
|
|
2016-02-25 19:04:27 -05:00
|
|
|
get config() {
|
2016-02-27 10:51:12 -05:00
|
|
|
return new Config(this.appId);
|
2016-02-25 19:04:27 -05:00
|
|
|
}
|
2016-03-07 00:30:21 -08:00
|
|
|
|
2016-02-21 23:47:07 -05:00
|
|
|
expectedAdapterType() {
|
|
|
|
|
throw new Error("Subclasses should implement expectedAdapterType()");
|
2016-02-21 16:54:30 -05:00
|
|
|
}
|
2016-03-07 00:30:21 -08:00
|
|
|
|
2016-02-21 23:47:07 -05:00
|
|
|
validateAdapter(adapter) {
|
|
|
|
|
if (!adapter) {
|
2017-01-11 12:31:40 -08:00
|
|
|
throw new Error(this.constructor.name + " requires an adapter");
|
2016-02-21 23:47:07 -05:00
|
|
|
}
|
2016-03-07 00:30:21 -08:00
|
|
|
|
2016-12-07 15:17:05 -08:00
|
|
|
const Type = this.expectedAdapterType();
|
2016-02-21 23:47:07 -05:00
|
|
|
// Allow skipping for testing
|
2016-03-07 00:30:21 -08:00
|
|
|
if (!Type) {
|
2016-02-21 23:47:07 -05:00
|
|
|
return;
|
|
|
|
|
}
|
2016-03-07 00:30:21 -08:00
|
|
|
|
2016-02-21 23:47:07 -05:00
|
|
|
// Makes sure the prototype matches
|
2016-12-07 15:17:05 -08:00
|
|
|
const mismatches = Object.getOwnPropertyNames(Type.prototype).reduce((obj, key) => {
|
2016-11-24 15:47:41 -05:00
|
|
|
const adapterType = typeof adapter[key];
|
|
|
|
|
const expectedType = typeof Type.prototype[key];
|
|
|
|
|
if (adapterType !== expectedType) {
|
|
|
|
|
obj[key] = {
|
|
|
|
|
expected: expectedType,
|
|
|
|
|
actual: adapterType
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return obj;
|
2016-02-21 23:47:07 -05:00
|
|
|
}, {});
|
2016-03-07 00:30:21 -08:00
|
|
|
|
2016-02-21 23:47:07 -05:00
|
|
|
if (Object.keys(mismatches).length > 0) {
|
2016-02-28 00:15:59 -05:00
|
|
|
throw new Error("Adapter prototype don't match expected prototype", adapter, mismatches);
|
2016-02-21 23:47:07 -05:00
|
|
|
}
|
2016-02-21 16:54:30 -05:00
|
|
|
}
|
2016-02-21 12:02:18 -05:00
|
|
|
}
|
|
|
|
|
|
2016-03-01 07:35:28 -08:00
|
|
|
export default AdaptableController;
|