diff --git a/js/server/modules/org/arangodb/foxx/request_context.js b/js/server/modules/org/arangodb/foxx/request_context.js index abd2c8cfe0..4af90b3ff9 100644 --- a/js/server/modules/org/arangodb/foxx/request_context.js +++ b/js/server/modules/org/arangodb/foxx/request_context.js @@ -220,13 +220,23 @@ extend(RequestContext.prototype, { /// /// You can also provide a description of this parameter. /// -/// @EXAMPLES +/// *Examples* +/// +/// ```js +/// app.get("/foxx/:id", function { +/// // Do something +/// }).pathParam("id", type: joi.number().integer().required().description("Id of the Foxx")); +/// ``` +/// +/// You can also pass in a configuration object instead: /// /// ```js /// app.get("/foxx/:id", function { /// // Do something /// }).pathParam("id", { -/// type: joi.number().integer().required().description("Id of the Foxx") +/// type: joi.number().integer(), +/// required: true, +/// description: "Id of the Foxx" /// }); /// ``` /// @endDocuBlock @@ -239,9 +249,16 @@ extend(RequestContext.prototype, { type = attributes.type, required = attributes.required, description = attributes.description, - constraint = type, - regexType = type, - cfg; + constraint, regexType, cfg; + + if (attributes.isJoi) { + type = attributes; + required = undefined; + description = undefined; + } + + constraint = type; + regexType = type; // deprecated: assume type.describe is always a function if (type && typeof type.describe === 'function') { @@ -306,6 +323,19 @@ extend(RequestContext.prototype, { /// ```js /// app.get("/foxx", function { /// // Do something +/// }).queryParam("id", +/// joi.number().integer() +/// .required() +/// .description("Id of the Foxx") +/// .meta({allowMultiple: false}) +/// }); +/// ``` +/// +/// You can also pass in a configuration object instead: +/// +/// ```js +/// app.get("/foxx", function { +/// // Do something /// }).queryParam("id", { /// type: joi.number().integer().required().description("Id of the Foxx"), /// allowMultiple: false @@ -319,8 +349,17 @@ extend(RequestContext.prototype, { var type = attributes.type, required = attributes.required, description = attributes.description, - constraint = type, - cfg; + allowMultiple = attributes.allowMultiple, + constraint, cfg; + + if (attributes.isJoi) { + type = attributes; + required = undefined; + description = undefined; + allowMultiple = undefined; + } + + constraint = type; // deprecated: assume type.describe is always a function if (type && typeof type.describe === 'function') { @@ -330,6 +369,9 @@ extend(RequestContext.prototype, { if (typeof description === 'string') { constraint = constraint.description(description); } + if (typeof allowMultiple === 'boolean') { + constraint = constraint.meta({allowMultiple: allowMultiple}); + } this.constraints.queryParams[paramName] = constraint; cfg = constraint.describe(); if (Array.isArray(cfg)) { @@ -338,8 +380,18 @@ extend(RequestContext.prototype, { } else { type = cfg.type; } - required = Boolean(cfg.flags && cfg.flags.presense === 'required'); + required = Boolean(cfg.flags && cfg.flags.presence === 'required'); description = cfg.description; + if (cfg.meta) { + if (!Array.isArray(cfg.meta)) { + cfg.meta = [cfg.meta]; + } + _.each(cfg.meta, function (meta) { + if (meta && typeof meta.allowMultiple === 'boolean') { + allowMultiple = meta.allowMultiple; + } + }); + } if ( type === 'number' && _.isArray(cfg.rules) && @@ -356,7 +408,7 @@ extend(RequestContext.prototype, { description, type, required, - attributes.allowMultiple + Boolean(allowMultiple) ); return this; }, diff --git a/js/server/tests/shell-foxx.js b/js/server/tests/shell-foxx.js index feb926e3a6..6abd9dc2fb 100644 --- a/js/server/tests/shell-foxx.js +++ b/js/server/tests/shell-foxx.js @@ -514,6 +514,21 @@ function DocumentationAndConstraintsSpec () { assertEqual(context.constraints.urlParams, {id: constraint}); }, + testDefinePathParamShorthand: function () { + var constraint = joi.number().integer().description("Id of the Foxx"), + context = app.get('/foxx/:id', function () { + //nothing + }).pathParam("id", constraint); + + assertEqual(routes.length, 1); + assertEqual(routes[0].url.constraint.id, "/[0-9]+/"); + assertEqual(routes[0].docs.parameters[0].paramType, "path"); + assertEqual(routes[0].docs.parameters[0].name, "id"); + assertEqual(routes[0].docs.parameters[0].description, "Id of the Foxx"); + assertEqual(routes[0].docs.parameters[0].dataType, "integer"); + assertEqual(context.constraints.urlParams, {id: constraint}); + }, + testDefinePathCaseParam: function () { var constraint = joi.number().integer().description("Id of the Foxx"), context = app.get('/foxx/:idParam', function () { @@ -592,10 +607,56 @@ function DocumentationAndConstraintsSpec () { context = app.get('/foxx', function () { //nothing }).queryParam("a", { - type: constraint, - allowMultiple: true + type: constraint }); + assertEqual(routes.length, 1); + assertEqual(routes[0].docs.parameters[0].paramType, "query"); + assertEqual(routes[0].docs.parameters[0].name, "a"); + assertEqual(routes[0].docs.parameters[0].description, "The value of an a"); + assertEqual(routes[0].docs.parameters[0].dataType, "integer"); + assertEqual(routes[0].docs.parameters[0].required, false); + assertEqual(routes[0].docs.parameters[0].allowMultiple, false); + assertEqual(context.constraints.queryParams, {a: constraint}); + }, + + testDefineQueryParamWithOverrides: function () { + var constraint = joi.number().integer(), + context = app.get('/foxx', function () { + //nothing + }).queryParam("a", { + type: constraint, + description: "The value of an a", + allowMultiple: true, + required: true + }); + + assertEqual(routes.length, 1); + assertEqual(routes[0].docs.parameters[0].paramType, "query"); + assertEqual(routes[0].docs.parameters[0].name, "a"); + assertEqual(routes[0].docs.parameters[0].description, "The value of an a"); + assertEqual(routes[0].docs.parameters[0].dataType, "integer"); + print(0) + assertEqual(routes[0].docs.parameters[0].required, true); + print(1) + assertEqual(routes[0].docs.parameters[0].allowMultiple, true); + print(2) + assertEqual(context.constraints.queryParams, { + a: constraint + .description("The value of an a") + .meta({allowMultiple: true}) + .required() + }); + }, + + testDefineQueryParamShorthand: function () { + var constraint = joi.number().integer() + .description("The value of an a") + .meta({allowMultiple: true}), + context = app.get('/foxx', function () { + //nothing + }).queryParam("a", constraint); + assertEqual(routes.length, 1); assertEqual(routes[0].docs.parameters[0].paramType, "query"); assertEqual(routes[0].docs.parameters[0].name, "a");