Splits Adapter loading from AdaptableController
- Adds dynamic prototype conformance check upon setting adapter - Throws when adapter is undefined, invalid in controller
This commit is contained in:
@@ -8,8 +8,6 @@ based on the parameters passed
|
||||
|
||||
*/
|
||||
|
||||
const DefaultAdapters = {};
|
||||
|
||||
export class AdaptableController {
|
||||
/**
|
||||
* Check whether the api call has master key or not.
|
||||
@@ -22,51 +20,49 @@ export class AdaptableController {
|
||||
* - object: a plain javascript object (options.constructor === Object), if options.adapter is set, we'll try to load it with the same mechanics.
|
||||
* - function: we'll create a new instance from that function, and pass the options object
|
||||
*/
|
||||
constructor(options) {
|
||||
|
||||
let adapter;
|
||||
|
||||
// We have options and options have adapter key
|
||||
if (options) {
|
||||
// Pass an adapter as a module name, a function or an instance
|
||||
if (typeof options == "string" || typeof options == "function" || options.constructor != Object) {
|
||||
adapter = options;
|
||||
}
|
||||
if (options.adapter) {
|
||||
adapter = options.adapter;
|
||||
}
|
||||
}
|
||||
|
||||
if (!adapter) {
|
||||
adapter = this.defaultAdapter();
|
||||
}
|
||||
|
||||
// This is a string, require the module
|
||||
if (typeof adapter === "string") {
|
||||
adapter = require(adapter);
|
||||
// If it's define as a module, get the default
|
||||
if (adapter.default) {
|
||||
adapter = adapter.default;
|
||||
}
|
||||
}
|
||||
// From there it's either a function or an object
|
||||
// if it's an function, instanciate and pass the options
|
||||
if (typeof adapter === "function") {
|
||||
var Adapter = adapter;
|
||||
adapter = new Adapter(options);
|
||||
}
|
||||
|
||||
constructor(adapter, options) {
|
||||
this.setAdapter(adapter, options);
|
||||
}
|
||||
|
||||
setAdapter(adapter, options) {
|
||||
this.validateAdapter(adapter);
|
||||
this.adapter = adapter;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
defaultAdapter() {
|
||||
return DefaultAdapters[this.constructor.name];
|
||||
expectedAdapterType() {
|
||||
throw new Error("Subclasses should implement expectedAdapterType()");
|
||||
}
|
||||
|
||||
// Sets the default adapter for that Class
|
||||
static setDefaultAdapter(defaultAdapter) {
|
||||
DefaultAdapters[this.name] = defaultAdapter;
|
||||
validateAdapter(adapter) {
|
||||
|
||||
if (!adapter) {
|
||||
throw new Error(this.constructor.name+" requires an adapter");
|
||||
}
|
||||
|
||||
let Type = this.expectedAdapterType();
|
||||
// Allow skipping for testing
|
||||
if (!Type) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Makes sure the prototype matches
|
||||
let mismatches = Object.getOwnPropertyNames(Type.prototype).reduce( (obj, key) => {
|
||||
const adapterType = typeof adapter[key];
|
||||
const expectedType = typeof Type.prototype[key];
|
||||
if (adapterType !== expectedType) {
|
||||
obj[key] = {
|
||||
expected: expectedType,
|
||||
actual: adapterType
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}, {});
|
||||
|
||||
if (Object.keys(mismatches).length > 0) {
|
||||
console.error(adapter, mismatches);
|
||||
throw new Error("Adapter prototype don't match expected prototype");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import { Parse } from 'parse/node';
|
||||
import { randomHexString } from '../cryptoUtils';
|
||||
import AdaptableController from './AdaptableController';
|
||||
import { FilesAdapter } from '../Adapters/Files/FilesAdapter';
|
||||
|
||||
export class FilesController extends AdaptableController {
|
||||
|
||||
@@ -29,7 +30,7 @@ export class FilesController extends AdaptableController {
|
||||
* with the current mount point and app id.
|
||||
* Object may be a single object or list of REST-format objects.
|
||||
*/
|
||||
expandFilesInObject(config, object) {
|
||||
expandFilesInObject(config, object) {
|
||||
if (object instanceof Array) {
|
||||
object.map((obj) => this.expandFilesInObject(config, obj));
|
||||
return;
|
||||
@@ -52,6 +53,10 @@ export class FilesController extends AdaptableController {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expectedAdapterType() {
|
||||
return FilesAdapter;
|
||||
}
|
||||
}
|
||||
|
||||
export default FilesController;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Parse } from 'parse/node';
|
||||
import PromiseRouter from '../PromiseRouter';
|
||||
import AdaptableController from './AdaptableController';
|
||||
import { LoggerAdapter } from '../Adapters/Logger/LoggerAdapter';
|
||||
|
||||
const Promise = Parse.Promise;
|
||||
const MILLISECONDS_IN_A_DAY = 24 * 60 * 60 * 1000;
|
||||
@@ -70,6 +71,10 @@ export class LoggerController extends AdaptableController {
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
|
||||
expectedAdapterType() {
|
||||
return LoggerAdapter;
|
||||
}
|
||||
}
|
||||
|
||||
export default LoggerController;
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Parse } from 'parse/node';
|
||||
import PromiseRouter from '../PromiseRouter';
|
||||
import rest from '../rest';
|
||||
import AdaptableController from './AdaptableController';
|
||||
import { PushAdapter } from '../Adapters/Push/PushAdapter';
|
||||
|
||||
export class PushController extends AdaptableController {
|
||||
|
||||
@@ -25,7 +26,7 @@ export class PushController extends AdaptableController {
|
||||
deviceType + ' is not supported push type.');
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the api call has master key or not.
|
||||
@@ -53,7 +54,8 @@ export class PushController extends AdaptableController {
|
||||
rest.find(config, auth, '_Installation', where).then(function(response) {
|
||||
return pushAdapter.send(body, response.results);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get expiration time from the request body.
|
||||
* @param {Object} request A request object
|
||||
@@ -80,7 +82,11 @@ export class PushController extends AdaptableController {
|
||||
body['expiration_time'] + ' is not valid time.');
|
||||
}
|
||||
return expirationTime.valueOf();
|
||||
};
|
||||
}
|
||||
|
||||
expectedAdapterType() {
|
||||
return PushAdapter;
|
||||
}
|
||||
};
|
||||
|
||||
export default PushController;
|
||||
|
||||
Reference in New Issue
Block a user