trader-server
Version:
OData server for testing strategies, simulating and real trading.
579 lines • 24.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
require("reflect-metadata");
const edm_1 = require("./edm");
const utils_1 = require("./utils");
class ODataMethodType {
}
ODataMethodType.GET = "GET";
ODataMethodType.POST = "POST";
ODataMethodType.PUT = "PUT";
ODataMethodType.PATCH = "PATCH";
ODataMethodType.DELETE = "DELETE";
exports.ODataMethodType = ODataMethodType;
const ODataEntitySets = "odata:entitysets";
const ODataMethod = "odata:method";
const ODataKeyParameters = "odata:keyparameters";
const ODataLinkParameters = "odata:linkparameters";
const ODataQueryParameter = "odata:queryparameter";
const ODataFilterParameter = "odata:filterparameter";
const ODataBodyParameter = "odata:bodyparameter";
const ODataContextParameter = "odata:contextparameter";
const ODataStreamParameter = "odata:streamparameter";
const ODataResultParameter = "odata:resultparameter";
const ODataIdParameter = "odata:idparameter";
const ODataTypeParameter = "odata:typeparameter";
const ODataNamespace = "odata:namespace";
function type(elementType, targetKey, parameterIndex) {
if (typeof parameterIndex == "number") {
let target = elementType;
let parameterNames = utils_1.getFunctionParameters(target, targetKey);
let paramName = parameterNames[parameterIndex];
Reflect.defineMetadata(ODataTypeParameter, paramName, target, targetKey);
}
else {
return function (constructor) {
constructor.prototype.elementType = elementType;
};
}
}
exports.type = type;
/** Set namespace
* @param namespace Namespace to be set
*/
function namespace(namespace) {
return function (target, targetKey) {
if (targetKey) {
if (target[targetKey]) {
target[targetKey].namespace = namespace;
}
else {
Reflect.defineMetadata(ODataNamespace, namespace, target, targetKey);
}
}
else
target.namespace = namespace;
};
}
exports.namespace = namespace;
function getNamespace(target, targetKey) {
return Reflect.getMetadata(ODataNamespace, target.prototype, targetKey) || (target[targetKey] || target).namespace;
}
exports.getNamespace = getNamespace;
/** Set container
* @param name Name of the container
*/
function container(name) {
return function (target, targetKey) {
if (targetKey)
target[targetKey].containerName = name;
else
target.containerName = name;
};
}
exports.container = container;
/** Set parser
* @param parser Parser to use (odata-v4-parser compatible functional parser)
*/
function parser(parser) {
return function (target) {
target.parser = parser;
};
}
exports.parser = parser;
/** Attach connector
* @param connector Connector to use
*/
function connector(connector) {
return function (target) {
target.connector = connector;
};
}
exports.connector = connector;
/** Attach validator
* @param connector Connector to use
*/
function validation(validator, options) {
return function (target) {
target.validator = function (odataQuery) {
return validator.validate(odataQuery, options);
};
};
}
exports.validation = validation;
/** Set error handler
* @param errorHandler Error request handler to use
*/
function error(errorHandler) {
return function (target) {
target.errorHandler = errorHandler;
};
}
exports.error = error;
/** Class decorator for server that binds the given controller to the server.
* @param controller Controller to be bind to the server.
* @param entitySetName The name of the entity set.
* @param elementType Type of the element.
*/
function controller(controller, entitySetName, elementType) {
return function (server) {
server.prototype[controller.name] = controller;
entitySetName = (typeof entitySetName == "string" ? entitySetName : "") || controller.prototype.entitySetName || (entitySetName === true ? controller.name.replace("Controller", "") : false);
if (entitySetName) {
let entitySets = Reflect.getOwnMetadata(ODataEntitySets, server) || {};
entitySets[entitySetName] = controller;
Reflect.defineMetadata(ODataEntitySets, entitySets, server);
}
if (elementType) {
controller.prototype.elementType = elementType;
}
if (!controller.prototype.elementType) {
controller.prototype.elementType = Object;
}
edm_1.EntityType(controller.prototype.elementType)(server.prototype, controller.name);
};
}
exports.controller = controller;
/** Gives the public controllers of the given server
* @param server
*/
function getPublicControllers(server) {
return Reflect.getOwnMetadata(ODataEntitySets, server) || {};
}
exports.getPublicControllers = getPublicControllers;
/** Enables CORS on your server
* @param server The server where you turn the CORS on
* */
exports.cors = (function cors() {
return function (server) {
server.cors = true;
};
})();
function odataMethodFactory(type, navigationProperty) {
if (type.indexOf("/") < 0)
type = type.toLowerCase();
let decorator = function (target, targetKey) {
let existingMethods = Reflect.getMetadata(ODataMethod, target, targetKey) || [];
existingMethods.unshift(type);
Reflect.defineMetadata(ODataMethod, existingMethods, target, targetKey);
};
let createRefFn = function (navigationProperty) {
let fn = odataMethodFactory(`${type}/${navigationProperty}`);
fn.$ref = function (target, targetKey) {
let existingMethods = Reflect.getMetadata(ODataMethod, target, targetKey) || [];
existingMethods.unshift(`${type}/${navigationProperty}/$ref`);
Reflect.defineMetadata(ODataMethod, existingMethods, target, targetKey);
};
return fn;
};
if (typeof navigationProperty == "string")
return createRefFn(navigationProperty);
let fn = function (target, targetKey) {
if (typeof target == "string")
return createRefFn(target);
if (arguments.length == 0)
return fn;
else
decorator(target, targetKey);
};
fn.$value = function (target, targetKey) {
let existingMethods = Reflect.getMetadata(ODataMethod, target, targetKey) || [];
existingMethods.unshift(`${type}/$value`);
Reflect.defineMetadata(ODataMethod, existingMethods, target, targetKey);
};
return fn;
}
/** Annotate function for OData GET operation */
exports.GET = odataMethodFactory("GET");
/** Annotate function for OData POST operation */
exports.POST = odataMethodFactory("POST");
/** Annotate function for OData PUT operation */
exports.PUT = odataMethodFactory("PUT");
/** Annotate function for OData PATCH operation */
exports.PATCH = odataMethodFactory("PATCH");
/** Annotate function for OData DELETE operation */
exports.DELETE = odataMethodFactory("DELETE");
/** Create reference for OData POST operation
* @param navigationProperty Navigation property name to handle
*/
function createRef(navigationProperty) {
return exports.POST(navigationProperty).$ref;
}
exports.createRef = createRef;
/** Update reference for OData PUT operation
* @param navigationProperty Navigation property name to handle
*/
function updateRef(navigationProperty) {
return exports.PUT(navigationProperty).$ref;
}
exports.updateRef = updateRef;
/** Delete reference for OData DELETE operation
* @param navigationProperty Navigation property name to handle
*/
function deleteRef(navigationProperty) {
return exports.DELETE(navigationProperty).$ref;
}
exports.deleteRef = deleteRef;
/** Annotate function for a specified OData method operation */
function method(method, navigationProperty) {
return odataMethodFactory(method.toUpperCase(), navigationProperty);
}
exports.method = method;
/** get metadata value of ODataMethod on the prototype chain of target or targetKey
* @param target The prototype of the class for an instance member
* @param targetKey The name of the class method
*/
function getMethod(target, targetKey) {
return Reflect.getMetadata(ODataMethod, target.prototype, targetKey);
}
exports.getMethod = getMethod;
/** Gives the entity key
* @param target The prototype of the class for an instance member
* @param targetKey The name of the class method
* @param parameterIndex The ordinal index of the parameter in the function’s parameter list
*/
function key(target, targetKey, parameterIndex) {
let name;
let decorator = function (target, targetKey, parameterIndex) {
let parameterNames = utils_1.getFunctionParameters(target, targetKey);
let existingParameters = Reflect.getOwnMetadata(ODataKeyParameters, target, targetKey) || [];
let paramName = parameterNames[parameterIndex];
existingParameters.push({
from: name || paramName,
to: paramName
});
Reflect.defineMetadata(ODataKeyParameters, existingParameters, target, targetKey);
};
if (typeof target == "string" || typeof target == "undefined" || !target) {
name = target;
return decorator;
}
else
return decorator(target, targetKey, parameterIndex);
}
exports.key = key;
/** Gives the decorated key parameter.
* @param target The prototype of the class for an instance member
* @param targetKey The name of the class method
*/
function getKeys(target, targetKey) {
return Reflect.getMetadata(ODataKeyParameters, target.prototype, targetKey) || [];
}
exports.getKeys = getKeys;
/** Gives the identifier of the referenced entity.
* @param target The prototype of the class for an instance member
* @param targetKey The name of the class method
* @param parameterIndex The ordinal index of the parameter in the function’s parameter list
*/
function link(target, targetKey, parameterIndex) {
let name;
let decorator = function (target, targetKey, parameterIndex) {
let parameterNames = utils_1.getFunctionParameters(target, targetKey);
let existingParameters = Reflect.getOwnMetadata(ODataLinkParameters, target, targetKey) || [];
let paramName = parameterNames[parameterIndex];
existingParameters.push({
from: name || paramName,
to: paramName
});
Reflect.defineMetadata(ODataLinkParameters, existingParameters, target, targetKey);
};
if (typeof target == "string" || typeof target == "undefined" || !target) {
name = target;
return decorator;
}
else
return decorator(target, targetKey, parameterIndex);
}
exports.link = link;
/** Gives the decorated link parameter.
* @param target The prototype of the class for an instance member
* @param targetKey The name of the class method
*/
function getLinks(target, targetKey) {
return Reflect.getMetadata(ODataLinkParameters, target.prototype, targetKey) || [];
}
exports.getLinks = getLinks;
/** Finds the given OData method
* @param {any} target
* @param {any} method
* @param {any} keys
*/
function findODataMethod(target, method, keys) {
keys = keys || [];
let propNames = utils_1.getAllPropertyNames(target.prototype);
for (let prop of propNames) {
if (getMethod(target, prop) && getMethod(target, prop).indexOf(method) >= 0) {
let fnKeys = getKeys(target, prop);
if (keys.length == fnKeys.length) {
return {
call: prop,
key: fnKeys,
link: getLinks(target, prop)
};
}
}
}
for (let prop of propNames) {
if (prop == method.toLowerCase()) {
let fnKeys = getKeys(target, prop);
if (keys.length == fnKeys.length) {
return {
call: prop,
key: fnKeys,
link: getLinks(target, prop)
};
}
}
}
for (let prop of propNames) {
if (getMethod(target, prop) && getMethod(target, prop).indexOf(method) >= 0) {
return {
call: prop,
key: [],
link: getLinks(target, prop)
};
}
}
for (let prop of propNames) {
if (prop == method.toLowerCase()) {
return {
call: prop,
key: [],
link: getLinks(target, prop)
};
}
}
return null;
}
exports.findODataMethod = findODataMethod;
/** Provides access to all OData query options.
* @param target The prototype of the class for an instance member
* @param targetKey The name of the class method
* @param parameterIndex The ordinal index of the parameter in the function’s parameter list
*/
exports.query = (function query() {
return function (target, targetKey, parameterIndex) {
let parameterNames = utils_1.getFunctionParameters(target, targetKey);
let paramName = parameterNames[parameterIndex];
Reflect.defineMetadata(ODataQueryParameter, paramName, target, targetKey);
};
})();
/** Gives the decorated query parameter.
* @param target The prototype of the class for an instance member
* @param targetKey The name of the class method
*/
function getQueryParameter(target, targetKey) {
return Reflect.getMetadata(ODataQueryParameter, target.prototype, targetKey);
}
exports.getQueryParameter = getQueryParameter;
/** Gives filter information and provides the AST tree of the OData $filter.
* @param target The prototype of the class for an instance member
* @param targetKey The name of the class method
* @param parameterIndex The ordinal index of the parameter in the function’s parameter list
*/
exports.filter = (function filter() {
return function (target, targetKey, parameterIndex) {
let parameterNames = utils_1.getFunctionParameters(target, targetKey);
let paramName = parameterNames[parameterIndex];
Reflect.defineMetadata(ODataFilterParameter, paramName, target, targetKey);
};
})();
/** Gives the decorated filter parameter.
* @param target The prototype of the class for an instance member
* @param targetKey The name of the class method
*/
function getFilterParameter(target, targetKey) {
return Reflect.getMetadata(ODataFilterParameter, target.prototype, targetKey);
}
exports.getFilterParameter = getFilterParameter;
/** Gives the body of the OData request.
* @param target The prototype of the class for an instance member
* @param targetKey The name of the class method
* @param parameterIndex The ordinal index of the parameter in the function’s parameter list
*/
exports.body = (function body() {
return function (target, targetKey, parameterIndex) {
let parameterNames = utils_1.getFunctionParameters(target, targetKey);
let paramName = parameterNames[parameterIndex];
Reflect.defineMetadata(ODataBodyParameter, paramName, target, targetKey);
};
})();
/** Gives the decorated body parameter.
* @param target The prototype of the class for an instance member
* @param targetKey The name of the class method
*/
function getBodyParameter(target, targetKey) {
return Reflect.getMetadata(ODataBodyParameter, target.prototype, targetKey);
}
exports.getBodyParameter = getBodyParameter;
/** Gives the current execution context.
* @param target The prototype of the class for an instance member
* @param targetKey The name of the class method
* @param parameterIndex The ordinal index of the parameter in the function’s parameter list
*/
exports.context = (function context() {
return function (target, targetKey, parameterIndex) {
let parameterNames = utils_1.getFunctionParameters(target, targetKey);
let paramName = parameterNames[parameterIndex];
Reflect.defineMetadata(ODataContextParameter, paramName, target, targetKey);
};
})();
/** Gives the decorated context parameter.
* @param target The prototype of the class for an instance member
* @param targetKey The name of the class method
*/
function getContextParameter(target, targetKey) {
return Reflect.getMetadata(ODataContextParameter, target.prototype, targetKey);
}
exports.getContextParameter = getContextParameter;
/** Gives a writable stream that will perform OData result transformation on the result and then sends it forward to your response stream.
* @param target The prototype of the class for an instance member
* @param targetKey The name of the class method
* @param parameterIndex The ordinal index of the parameter in the function’s parameter list
*/
exports.stream = (function stream() {
return function (target, targetKey, parameterIndex) {
let parameterNames = utils_1.getFunctionParameters(target, targetKey);
let paramName = parameterNames[parameterIndex];
Reflect.defineMetadata(ODataStreamParameter, paramName, target, targetKey);
};
})();
/** Gives the decorated stream parameter.
* @param target The prototype of the class for an instance member
* @param targetKey The name of the class method
*/
function getStreamParameter(target, targetKey) {
return Reflect.getMetadata(ODataStreamParameter, target.prototype, targetKey);
}
exports.getStreamParameter = getStreamParameter;
/** Gives the result from the last part from the resource path of the OData URL. This ensures the access to an entity in context of your action or function.
* @param target The prototype of the class for an instance member
* @param targetKey The name of the class method
* @param parameterIndex The ordinal index of the parameter in the function’s parameter list
*/
exports.result = (function result() {
return function (target, targetKey, parameterIndex) {
let parameterNames = utils_1.getFunctionParameters(target, targetKey);
let paramName = parameterNames[parameterIndex];
Reflect.defineMetadata(ODataResultParameter, paramName, target, targetKey);
};
})();
/** Gives the decorated result parameter.
* @param target The prototype of the class for an instance member
* @param targetKey The name of the class method
*/
function getResultParameter(target, targetKey) {
return Reflect.getMetadata(ODataResultParameter, target.prototype, targetKey);
}
exports.getResultParameter = getResultParameter;
/** Gives the url that was provided either in request body as @odata.id or in query parameters as $id.
* @param target The prototype of the class for an instance member
* @param targetKey The name of the class method
* @param parameterIndex The ordinal index of the parameter in the function’s parameter list
*/
exports.id = (function id() {
return function (target, targetKey, parameterIndex) {
let parameterNames = utils_1.getFunctionParameters(target, targetKey);
let paramName = parameterNames[parameterIndex];
Reflect.defineMetadata(ODataIdParameter, paramName, target, targetKey);
};
})();
/** Gives the decorated id parameter.
* @param target The prototype of the class for an instance member
* @param targetKey The name of the class method
*/
function getIdParameter(target, targetKey) {
return Reflect.getMetadata(ODataIdParameter, target.prototype, targetKey);
}
exports.getIdParameter = getIdParameter;
/** Gives the decorated type parameter.
* @param target The prototype of the class for an instance member
* @param targetKey The name of the class method
*/
function getTypeParameter(target, targetKey) {
return Reflect.getMetadata(ODataTypeParameter, target.prototype, targetKey);
}
exports.getTypeParameter = getTypeParameter;
/** Sets a parameter decorator for the given parameter.
* @param name The name of the parameter.
* @param type OData decorator type.
*/
function parameter(name, type) {
return function (target, targetKey) {
let parameterNames = utils_1.getFunctionParameters(target, targetKey);
let parameterIndex = parameterNames.indexOf(name);
if (parameterIndex >= 0) {
type(target, targetKey, parameterIndex);
}
};
}
exports.parameter = parameter;
/** Sets parameter decorators for the given parameters.
* @param parameters Object that contains the name of the parameter as key and the type of the parameter as value.
*/
function parameters(parameters) {
return function (target, targetKey) {
for (let prop in parameters) {
parameter(prop, parameters[prop])(target, targetKey);
}
};
}
exports.parameters = parameters;
function ODataBase(Base) {
class ODataBaseClass extends Base {
/** Define class, properties and parameters with decorators */
static define(...decorators) {
decorators.forEach(decorator => {
if (typeof decorator == 'function') {
decorator(this);
}
else if (typeof decorator == 'object') {
let props = Object.keys(decorator);
props.forEach(prop => {
let propDecorators = decorator[prop];
if (!Array.isArray(propDecorators))
propDecorators = [propDecorators];
propDecorators.forEach(propDecorator => {
if (typeof propDecorator == 'function') {
propDecorator(this.prototype, prop);
}
else if (typeof propDecorator == 'object') {
let params = Object.keys(propDecorator);
let parameterNames = utils_1.getFunctionParameters(this.prototype[prop]);
params.forEach(param => {
let paramDecorators = propDecorator[param];
if (!Array.isArray(paramDecorators))
paramDecorators = [paramDecorators];
paramDecorators.forEach(paramDecorator => {
if (typeof paramDecorator == 'function') {
paramDecorator(this.prototype, prop, parameterNames.indexOf(param));
}
else {
throw new Error(`Unsupported parameter decorator on ${this.name || this} at ${prop}.${param} using ${paramDecorator}`);
}
});
});
}
else {
throw new Error(`Unsupported member decorator on ${this.name || this} at ${prop} using ${propDecorator}`);
}
});
});
}
else {
throw new Error(`Unsupported decorator on ${this.name || this} using ${decorator}`);
}
});
return this;
}
}
return ODataBaseClass;
}
exports.ODataBase = ODataBase;
class ODataEntityBase {
}
exports.ODataEntityBase = ODataEntityBase;
class ODataEntity extends ODataBase(ODataEntityBase) {
}
exports.ODataEntity = ODataEntity;
//# sourceMappingURL=odata.js.map