poseidon
Version:
Simplify Node Callback APIs with an optimized promise layer that doesnt compromise on performance.
136 lines (126 loc) • 8 kB
JavaScript
// Generated by CoffeeScript 1.6.3
var Poseidon, Promise, escodegen, esprima, fs;
esprima = require('esprima');
escodegen = require('escodegen');
Promise = require('bluebird');
fs = require('fs');
Poseidon = (function() {
function Poseidon(configuration) {
if (configuration == null) {
configuration = {};
}
this.configuration = configuration;
return;
}
Poseidon.prototype.generate = function(path) {
var castValues, className, classSchema, code, codeLines, constructorName, dependencies, dependency, dependencyPath, err, file, files, functionName, functionSchema, hunk, index, instanceIdentifier, write, _ref, _ref1, _ref2, _ref3, _ref4;
files = [];
_ref = this.configuration;
for (className in _ref) {
classSchema = _ref[className];
file = {};
file.name = "" + (className.toLowerCase()) + ".js";
code = file.code = [];
dependencies = ["var Promise = require('bluebird');"];
_ref1 = classSchema.require;
for (dependency in _ref1) {
dependencyPath = _ref1[dependency];
dependencies.push("var " + dependency + " = require('" + dependencyPath + "');");
}
code.push("function " + className + "(" + (classSchema.constructor.params.join(", ")) + ") {\n " + classSchema.constructor.body + "\n}");
_ref2 = classSchema.functions;
for (functionName in _ref2) {
functionSchema = _ref2[functionName];
if (functionSchema.wrap == null) {
functionSchema.wrap = true;
}
if (functionSchema.params == null) {
functionSchema.params = [];
}
hunk = ["" + className + ".prototype." + functionName + " = function (" + (functionSchema.body != null ? "" + (functionSchema.params.join(", ")) + "){\n" : "){\n var args = arguments;")];
if (classSchema.type === 'promise') {
instanceIdentifier = "instanceValue";
} else {
instanceIdentifier = "this.instance";
}
if (functionSchema.body != null) {
hunk.push(functionSchema.body);
} else {
if (functionSchema.wrap || classSchema.type === 'promise') {
hunk.push("var deferred = Promise.pending();");
}
if (!functionSchema.wrap) {
hunk.push("var result;");
}
if (classSchema.type === 'promise') {
hunk.push("this.instance.catch(function(err){\n deferred.reject(err);\n return deferred.promise;\n}).then(function (instanceValue) {");
}
if (functionSchema.wrap) {
castValues = [];
if (functionSchema["return"] != null) {
_ref3 = functionSchema["return"];
for (index in _ref3) {
constructorName = _ref3[index];
if (constructorName !== null) {
if (constructorName instanceof Object) {
if (constructorName.array != null) {
castValues.push("arguments[" + (parseInt(index) + 1) + "] = arguments[" + (parseInt(index) + 1) + "].map(function(item) { return new " + constructorName.name + "(item); });");
}
} else {
castValues.push("arguments[" + (parseInt(index) + 1) + "] = new " + constructorName + "(arguments[" + (parseInt(index) + 1) + "]);");
}
}
}
}
hunk.push("var callback = function () {\n if (arguments[0]) {\n if (arguments.length === 1 || arguments[1] == null) {\n deferred.reject(arguments[0]);\n } else {\n deferred.reject(Array.prototype.slice.call(arguments, 0));\n }\n } else {\n " + (castValues.join("\n")) + "\n switch(arguments.length) {\n case 0:\n deferred.resolve();\n break;\n case 2:\n deferred.resolve(arguments[1]);\n break;\n case 3:\n deferred.resolve([arguments[1], arguments[2]]);\n break;\n case 4:\n deferred.resolve([arguments[1], arguments[2], arguments[3]]);\n break;\n case 5:\n deferred.resolve([arguments[1], arguments[2], arguments[3], arguments[4]]);\n break;\n case 6:\n deferred.resolve([arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]]);\n break;\n default:\n deferred.resolve(Array.prototype.slice.call(null, arguments, 1));\n break;\n }\n }\n};");
}
hunk.push("switch(args.length) {\n case 0:\n " + (functionSchema.wrap ? "" : "result = ") + instanceIdentifier + "." + functionName + "(" + (functionSchema.wrap ? "callback" : "") + ");\n break;\n case 1:\n " + (functionSchema.wrap ? "" : "result = ") + instanceIdentifier + "." + functionName + "(args[0]" + (functionSchema.wrap ? ", callback" : "") + ");\n break;\n case 2:\n " + (functionSchema.wrap ? "" : "result = ") + instanceIdentifier + "." + functionName + "(args[0], args[1]" + (functionSchema.wrap ? ", callback" : "") + ");\n break;\n case 3:\n " + (functionSchema.wrap ? "" : "result = ") + instanceIdentifier + "." + functionName + "(args[0], args[1], args[2]" + (functionSchema.wrap ? ", callback" : "") + ");\n break;\n case 4:\n " + (functionSchema.wrap ? "" : "result = ") + instanceIdentifier + "." + functionName + "(args[0], args[1], args[2], args[3]" + (functionSchema.wrap ? ", callback" : "") + ");\n break;\n case 5:\n " + (functionSchema.wrap ? "" : "result = ") + instanceIdentifier + "." + functionName + "(args[0], args[1], args[2], args[3], args[4]" + (functionSchema.wrap ? ", callback" : "") + ");\n break;\n default:\n " + (functionSchema.wrap ? "" : "result = ") + instanceIdentifier + "." + functionName + ".apply(" + instanceIdentifier + ", " + (functionSchema.wrap ? "Array.prototype.slice.call(null, args).concat(callback)" : "args") + ");\n break;\n}\n" + (!functionSchema.wrap && classSchema.type === 'promise' && (functionSchema["return"] != null) ? "result = new " + functionSchema["return"][0] + "(result);" : "") + "\n" + (!functionSchema.wrap && classSchema.type === 'promise' ? "deferred.resolve(result);" : ""));
if (classSchema.type === 'promise') {
hunk.push("});");
}
if (functionSchema.wrap || classSchema.type === 'promise') {
if (!functionSchema.wrap && ((_ref4 = functionSchema["return"]) != null ? _ref4.length : void 0) > 1) {
throw new Error("Only 1 return value allowed when no callback is present");
}
hunk.push("return deferred.promise;");
} else {
if (functionSchema["return"] != null) {
if (functionSchema["return"].length > 1) {
throw new Error("Only 1 return value allowed when no callback is present");
}
hunk.push("return new " + functionSchema["return"][0] + "(result);");
} else if (functionSchema.chain) {
hunk.push("return this;");
} else {
hunk.push("return result;");
}
}
}
hunk.push("};");
code.push(hunk.join("\n"));
}
code.push("module.exports = " + className + ";");
try {
code = "" + (dependencies.join("\n")) + "\n" + (code.join("\n"));
file.code = escodegen.generate(esprima.parse(code));
files.push(file);
} catch (_error) {
err = _error;
codeLines = code.split("\n");
throw new Error("Error generating class " + className + "\n" + err.message + "\n" + codeLines[err.lineNumber - 1]);
}
}
if (path != null) {
write = Promise.promisify(fs.writeFile, fs);
return Promise.map(files, function(file) {
return write("" + path + "/" + file.name, file.code);
}).then(function() {
return Promise.resolve(files);
});
} else {
return files;
}
};
return Poseidon;
})();
module.exports = Poseidon;