Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
Vladimir Spasic authored and Vladimir Spasic committed Mar 30, 2015
1 parent c4033c9 commit 2c71996
Show file tree
Hide file tree
Showing 19 changed files with 671 additions and 119 deletions.
29 changes: 28 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
lib-cov
*.seed
*.log
*.csv
*.dat
*.out
*.pid
*.gz

pids
logs
results

node_modules
vendor
public/dist

# Logs
logs
*.log

# Env data
.env

# Runtime data
pids
*.pid
Expand All @@ -21,8 +41,15 @@ build/Release

# Dependency directory
# Commenting this out is preferred by some people, see
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git-
# https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git
node_modules

# Users Environment Variables
.lock-wscript

#Docs
docs
theme
yuidoc.json

.DS_Store
4 changes: 4 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.jshintrc
yuidoc.json
theme
README.md
191 changes: 191 additions & 0 deletions lib/core.js
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;
63 changes: 63 additions & 0 deletions lib/default-resolver.js
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
});
}
});
28 changes: 28 additions & 0 deletions lib/deserializer.js
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;
}
});
43 changes: 36 additions & 7 deletions lib/index.js
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;
Loading

0 comments on commit 2c71996

Please sign in to comment.