service-model
Version:
An object oriented web service framework inspired by Windows Communication Foundation.
92 lines (91 loc) • 3.78 kB
JavaScript
var message_1 = require("../message");
var httpStatusCode_1 = require("../httpStatusCode");
var annotations_1 = require("../annotations");
/**
* @hidden
*/
var RestMessageFormatter = (function () {
function RestMessageFormatter(endpoint, operation) {
if (!endpoint) {
throw new Error("Missing required argument 'endpoint'.");
}
if (!operation) {
throw new Error("Missing required argument 'operation'.");
}
// do not include callback in list of parameters
this._parameters = operation.method.parameters.slice(0, operation.method.parameters.length - 1);
this._cast = new Array(this._parameters.length);
// check parameters
for (var i = 0; i < this._parameters.length; i++) {
var parameter = this._parameters[i];
if (!this._checkForInjectBody(parameter)) {
// setup cast functions if we have a type for the parameter
if (parameter.type && !parameter.type.isString) {
if (parameter.type.isNumber) {
this._cast[i] = parseFloat;
}
else if (parameter.type.isBoolean) {
this._cast[i] = castBoolean;
}
else if (parameter.type.isAssignableTo(Date)) {
this._cast[i] = castDate;
}
else {
throw new Error("Invalid parameter '" + parameter.name + "'. Parameters on REST enabled operations must be of type String, Number, or Boolean unless annotated with @InjectBody.");
}
}
}
}
// then retrieve the url template
var annotation = operation.method.getAnnotations(annotations_1.WebInvokeAnnotation)[0];
if (annotation) {
this._template = annotation.template.prefix(endpoint.address);
}
}
/**
* Checks to see if parameter is annotated with @Body
* @param parameter Parameter to check.
* @hidden
*/
RestMessageFormatter.prototype._checkForInjectBody = function (parameter) {
if (parameter.hasAnnotation(annotations_1.InjectBodyAnnotation)) {
if (this._bodyParameter !== undefined) {
throw new Error("Only one operation parameter can be decorated with @InjectBody.");
}
this._bodyParameter = parameter.index;
return true;
}
return false;
};
RestMessageFormatter.prototype.deserializeRequest = function (message, callback) {
var args = new Array(this._parameters.length);
if (this._template) {
var parsed = this._template.parse(message.url);
for (var i = 0; i < args.length; i++) {
if (i !== this._bodyParameter) {
var cast = this._cast[i], value = parsed.get(this._parameters[i].name);
args[i] = cast ? cast(value) : value;
}
}
}
if (this._bodyParameter !== undefined) {
args[this._bodyParameter] = message.body;
}
callback(null, args);
};
RestMessageFormatter.prototype.serializeReply = function (result, callback) {
callback(null, message_1.Message.createReply(httpStatusCode_1.HttpStatusCode.Ok, result));
};
return RestMessageFormatter;
})();
exports.RestMessageFormatter = RestMessageFormatter;
function castBoolean(text) {
return text === "true";
}
/**
* Converts string in ISO 8601 format to a Date object. Other formats may be accepts but results could be inconsistent.
* @param text Date in ISO 8601 format.
*/
function castDate(text) {
return new Date(text);
}