-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Vladimir Spasic
authored and
Vladimir Spasic
committed
Mar 30, 2015
1 parent
c4033c9
commit 2c71996
Showing
19 changed files
with
671 additions
and
119 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
.jshintrc | ||
yuidoc.json | ||
theme | ||
README.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
var _ = require('lodash'); | ||
|
||
/** | ||
* Base Object Class for all classes inside the Rest Sequelize Registry. | ||
* | ||
* @class Object | ||
* @namespace RestSequelize | ||
*/ | ||
var CoreObject = function() { | ||
|
||
}; | ||
|
||
function extend(protoProps, staticProps) { | ||
var parent = this; | ||
var child, hasFunction = false; | ||
|
||
if (protoProps && _.has(protoProps, 'constructor')) { | ||
child = protoProps.constructor; | ||
} else { | ||
child = function(){ | ||
if(this.init) { | ||
this.init.apply(this, arguments); | ||
} else { | ||
parent.apply(this, arguments); | ||
} | ||
}; | ||
} | ||
|
||
_.extend(child, parent); | ||
|
||
var Class = function() { | ||
this.constructor = child; | ||
}; | ||
|
||
Class.prototype = parent.prototype; | ||
child.prototype = new Class(); | ||
|
||
if (protoProps) { | ||
_.each(protoProps, function(value, key) { | ||
|
||
if ('function' !== typeof value) { | ||
protoProps[key] = value; | ||
} else { | ||
hasFunction = true; | ||
protoProps[key] = giveMethodSuper(child.prototype, key, value, parent.prototype); | ||
} | ||
|
||
}); | ||
|
||
_.extend(child.prototype, protoProps); | ||
} | ||
|
||
_.each(staticProps || {}, function(prop, key) { | ||
Object.defineProperty(child.prototype, key, { | ||
value: prop, | ||
writable: false, | ||
configurable: false, | ||
enumerable: false | ||
}); | ||
}); | ||
|
||
child.toString = function() { | ||
return '(subclass of ' + parent.toString() + ')'; | ||
}; | ||
|
||
if (hasFunction) { | ||
child.prototype._super = superFunction; | ||
} | ||
|
||
child.__super__ = parent.prototype; | ||
|
||
return child; | ||
} | ||
|
||
/** | ||
* Extends the current class with an new subclass. | ||
* | ||
* @example | ||
var MyClass = RestSequelize.Object.extend({ | ||
method: function(arg) { | ||
console.log(arg); | ||
} | ||
}); | ||
* | ||
* When defining a subclass, you can override methods but | ||
* still access the implementation of your parent class by | ||
* calling the special _super() method: | ||
* | ||
* @example | ||
var MyOtherClass = MyClass.extend({ | ||
init: function() { | ||
this._super('New argument'); | ||
} | ||
}); | ||
* | ||
* @static | ||
* @method extend | ||
* @param {Object} props Object of new methods | ||
* @return {Object} a new subclass | ||
*/ | ||
CoreObject.extend = extend; | ||
|
||
|
||
function giveMethodSuper(obj, key, method, proto) { | ||
var superMethod = proto[key] || obj[key]; | ||
|
||
if ('function' !== typeof superMethod) { | ||
return method; | ||
} | ||
|
||
return wrap(method, superMethod); | ||
} | ||
|
||
function wrap(func, superFunc) { | ||
function superWrapper() { | ||
var ret, sup = this && this.__nextSuper; | ||
|
||
if(this) { | ||
this.__nextSuper = superFunc; | ||
} | ||
|
||
ret = func.apply(this, arguments); | ||
|
||
if(this) { | ||
this.__nextSuper = sup; | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
return superWrapper; | ||
} | ||
|
||
function superFunction() { | ||
var ret, func = this.__nextSuper; | ||
if (func) { | ||
this.__nextSuper = null; | ||
ret = func.apply(this, arguments); | ||
this.__nextSuper = func; | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
/** | ||
* Initializer function for each class, | ||
* invoked by the all subclasses when they are | ||
* created / instantiated. | ||
* | ||
* @method init | ||
*/ | ||
CoreObject.prototype.init = function() { | ||
|
||
}; | ||
|
||
/** | ||
* Creates a new instance of the class. | ||
* | ||
* @example | ||
var instance = RestSequelize.Object.create({ | ||
method: function(arg) { | ||
console.log(arg); | ||
} | ||
}); | ||
instance.method('My object'); | ||
* | ||
* @method create | ||
* @static | ||
* @param {Object} props Defines new properties on the newly created object | ||
* @param {Object} statics Defines read only values for the object | ||
* @return {Function} a new Object Class function | ||
*/ | ||
CoreObject.create = function create(props, statics) { | ||
var C = this.extend(props, statics); | ||
|
||
return new C(); | ||
}; | ||
|
||
/** | ||
* Extends the class prototype | ||
* | ||
* @method reopen | ||
* @static | ||
* @param {Object} protoProps new properties for the prototype | ||
*/ | ||
CoreObject.reopen = function reopen(protoProps) { | ||
_.extend(this.prototype, protoProps); | ||
}; | ||
|
||
module.exports = CoreObject; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
var _ = require('lodash'), | ||
Resolver = require('./resolver'), | ||
DefaultService = require('./rest-service'), | ||
DefaultSerializer = require('./serializer'), | ||
DefaultDeserializer = require('./deserializer'); | ||
|
||
/** | ||
* Default implementation of the Resolver. | ||
* | ||
* This class can only resiolve the default modules. | ||
* | ||
* @class DefaultResolver | ||
* @extends RestSequelize.Resolver | ||
* @namespace RestSequelize | ||
*/ | ||
module.exports = Resolver.extend({ | ||
|
||
init: function() { | ||
this.defaults = { | ||
services: DefaultService, | ||
deserializers: DefaultDeserializer, | ||
serializers: DefaultSerializer | ||
}; | ||
|
||
this._cache = {}; | ||
}, | ||
|
||
/** | ||
* Resolves the model from the sequelize instance. | ||
* | ||
* By default it searches through all the sequelize models. | ||
* | ||
* @method resolveModel | ||
* @param {String} name | ||
* @return {Model} | ||
*/ | ||
resolveModel: function(name) { | ||
return _.find(this.sequelize.models, function(model) { | ||
var modelName = model.options.name.plural; | ||
|
||
return modelName.toLowerCase() === name.toLowerCase(); | ||
}); | ||
}, | ||
|
||
/** | ||
* Returns a default module for a given type. | ||
* | ||
* @method resolve | ||
* @param {String} type | ||
* @return {*} | ||
*/ | ||
resolve: function(type, name) { | ||
var Factory = this.defaults[type]; | ||
|
||
if (!Factory) { | ||
throw new Error('Can not resolve factory module for `' + type + '` with name `' + name + '`.'); | ||
} | ||
|
||
return Factory.create({ | ||
sequelize: this.sequelize | ||
}); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
var CoreObject = require('./core'); | ||
|
||
/** | ||
* Deserializer Class used for deserialization | ||
* of incoming payloads. | ||
* | ||
* @class Deserializer | ||
* @extends RestSequelize.Object | ||
* @namespace RestSequelize | ||
*/ | ||
module.exports = CoreObject.extend({ | ||
/** | ||
* Deserializes the incoming payload to a | ||
* data that will later be used to populate | ||
* Sequelize Model attributes. | ||
* | ||
* By default raw payload is returned. | ||
* | ||
* @method deserialize | ||
* @param {RestAdapter} adapter | ||
* @param {String} type | ||
* @param {Object} payload | ||
* @return {Object} | ||
*/ | ||
deserialize: function(adapter, type, payload) { | ||
return payload; | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,39 @@ | ||
var _ = require('lodash'), | ||
RestAdapter = require('./rest-adapter'); | ||
RestService = require('./rest-service'), | ||
Resolver = require('./resolver'), | ||
RestAdapter = require('./rest-adapter'), | ||
Serializer = require('./serializer'), | ||
Deserializer = require('./deserializer'); | ||
|
||
module.exports = function(sequelize, options) { | ||
options = _.defaults(options || {}, { | ||
services: {} | ||
}); | ||
/** | ||
* Rest Sequelize namespace | ||
* | ||
* @module rest-sequelize | ||
* @namespace RestSequelize | ||
* @param {Sequelize} sequelize Sequelize instance | ||
* @param {Object} options Container used by the `DefaultResolver` | ||
* to resolve modules needed by the `RestAdapter` | ||
*/ | ||
var RestSequelize = {}; | ||
|
||
return new RestAdapter(sequelize, options.services); | ||
}; | ||
// Expose Classes to the Namespace | ||
RestSequelize.RestService = RestService; | ||
RestSequelize.RestAdapter = RestAdapter; | ||
RestSequelize.Serializer = Serializer; | ||
RestSequelize.Deserializer = Deserializer; | ||
RestSequelize.Resolver = Resolver; | ||
|
||
RestAdapter.create({ | ||
sequelize: {} | ||
}); | ||
|
||
// Give a nice toString method :) | ||
(function giveToString(keys) { | ||
_.each(keys, function(name) { | ||
this[name].toString = function() { | ||
return 'RestSequelize.' + name; | ||
}; | ||
}, this); | ||
}).call(RestSequelize, _.keys(RestSequelize) ); | ||
|
||
module.exports = RestSequelize; |
Oops, something went wrong.