mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of https://github.com/triAGENS/ArangoDB into devel
This commit is contained in:
commit
988a622b54
|
@ -85,6 +85,29 @@ do the same for all routes of a controller. For this purpose
|
||||||
use the *allRoutes* object of the according controller.
|
use the *allRoutes* object of the according controller.
|
||||||
The following methods are available.
|
The following methods are available.
|
||||||
|
|
||||||
|
*Examples*
|
||||||
|
|
||||||
|
Provide an error response for all routes handled by this controller:
|
||||||
|
|
||||||
|
```js
|
||||||
|
ctrl.allRoutes
|
||||||
|
.errorResponse(Unauthorized, 401, 'Not authenticated.')
|
||||||
|
.errorResponse(NotFound, 404, 'Document not found.')
|
||||||
|
.errorResponse(ImATeapot, 418, 'I\'m a teapot.');
|
||||||
|
|
||||||
|
ctrl.get('/some/route', function (req, res) {
|
||||||
|
// ...
|
||||||
|
throw new NotFound('The document does not exist');
|
||||||
|
// ...
|
||||||
|
}); // no errorResponse needed here
|
||||||
|
|
||||||
|
ctrl.get('/another/route', function (req, res) {
|
||||||
|
// ...
|
||||||
|
throw new NotFound('I made you a cookie but I ated it');
|
||||||
|
// ...
|
||||||
|
}); // no errorResponse needed here either
|
||||||
|
```
|
||||||
|
|
||||||
!SUBSECTION Buffer Error Response
|
!SUBSECTION Buffer Error Response
|
||||||
<!-- js/server/modules/org/arangodb/foxx/request_context.js -->
|
<!-- js/server/modules/org/arangodb/foxx/request_context.js -->
|
||||||
@startDocuBlock JSF_foxx_RequestContextBuffer_errorResponse
|
@startDocuBlock JSF_foxx_RequestContextBuffer_errorResponse
|
||||||
|
|
|
@ -191,7 +191,6 @@ function FILTER (list, examples) {
|
||||||
|
|
||||||
for (i = 0; i < list.length; ++i) {
|
for (i = 0; i < list.length; ++i) {
|
||||||
var element = list[i];
|
var element = list[i];
|
||||||
|
|
||||||
if (MATCHES(element, examples, false)) {
|
if (MATCHES(element, examples, false)) {
|
||||||
result.push(element);
|
result.push(element);
|
||||||
}
|
}
|
||||||
|
@ -3860,7 +3859,6 @@ function MATCHES (element, examples, returnIndex) {
|
||||||
if (! Array.isArray(examples)) {
|
if (! Array.isArray(examples)) {
|
||||||
examples = [ examples ];
|
examples = [ examples ];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (examples.length === 0) {
|
if (examples.length === 0) {
|
||||||
THROW(INTERNAL.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "MATCHES");
|
THROW(INTERNAL.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "MATCHES");
|
||||||
}
|
}
|
||||||
|
@ -3870,7 +3868,6 @@ function MATCHES (element, examples, returnIndex) {
|
||||||
for (i = 0; i < examples.length; ++i) {
|
for (i = 0; i < examples.length; ++i) {
|
||||||
var example = examples[i];
|
var example = examples[i];
|
||||||
var result = true;
|
var result = true;
|
||||||
|
|
||||||
if (TYPEWEIGHT(example) !== TYPEWEIGHT_DOCUMENT) {
|
if (TYPEWEIGHT(example) !== TYPEWEIGHT_DOCUMENT) {
|
||||||
THROW(INTERNAL.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "MATCHES");
|
THROW(INTERNAL.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "MATCHES");
|
||||||
}
|
}
|
||||||
|
@ -5997,6 +5994,11 @@ function GENERAL_GRAPH_NEIGHBORS (graphName,
|
||||||
options.startVertexCollectionRestriction = options.vertexCollectionRestriction;
|
options.startVertexCollectionRestriction = options.vertexCollectionRestriction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (options.neighborExamples) {
|
||||||
|
if (typeof options.neighborExamples === "string") {
|
||||||
|
options.neighborExamples = {_id : options.neighborExamples};
|
||||||
|
}
|
||||||
|
}
|
||||||
var neighbors = [],
|
var neighbors = [],
|
||||||
params = TRAVERSAL_PARAMS(),
|
params = TRAVERSAL_PARAMS(),
|
||||||
factory = TRAVERSAL.generalGraphDatasourceFactory(graphName);
|
factory = TRAVERSAL.generalGraphDatasourceFactory(graphName);
|
||||||
|
@ -6005,14 +6007,12 @@ function GENERAL_GRAPH_NEIGHBORS (graphName,
|
||||||
params.paths = true;
|
params.paths = true;
|
||||||
params.visitor = TRAVERSAL_NEIGHBOR_VISITOR;
|
params.visitor = TRAVERSAL_NEIGHBOR_VISITOR;
|
||||||
var fromVertices = RESOLVE_GRAPH_TO_FROM_VERTICES(graphName, options);
|
var fromVertices = RESOLVE_GRAPH_TO_FROM_VERTICES(graphName, options);
|
||||||
|
|
||||||
if (options.edgeExamples) {
|
if (options.edgeExamples) {
|
||||||
params.followEdges = options.edgeExamples;
|
params.followEdges = options.edgeExamples;
|
||||||
}
|
}
|
||||||
if (options.edgeCollectionRestriction) {
|
if (options.edgeCollectionRestriction) {
|
||||||
params.edgeCollectionRestriction = options.edgeCollectionRestriction;
|
params.edgeCollectionRestriction = options.edgeCollectionRestriction;
|
||||||
}
|
}
|
||||||
|
|
||||||
fromVertices.forEach(function (v) {
|
fromVertices.forEach(function (v) {
|
||||||
var e = TRAVERSAL_FUNC("GRAPH_NEIGHBORS",
|
var e = TRAVERSAL_FUNC("GRAPH_NEIGHBORS",
|
||||||
factory,
|
factory,
|
||||||
|
|
|
@ -346,7 +346,11 @@ extend(Controller.prototype, {
|
||||||
/// The before function takes a *path* on which it should watch and a
|
/// The before function takes a *path* on which it should watch and a
|
||||||
/// function that it should execute before the routing takes place. If you do
|
/// function that it should execute before the routing takes place. If you do
|
||||||
/// omit the path, the function will be executed before each request, no matter
|
/// omit the path, the function will be executed before each request, no matter
|
||||||
/// the path. Your function gets a Request and a Response object.
|
/// the path. Your function gets a Request and a Response object.
|
||||||
|
///
|
||||||
|
/// If your callback returns the Boolean value *false*, the route handling
|
||||||
|
/// will not proceed. You can use this to intercept invalid or unauthorized
|
||||||
|
/// requests and prevent them from being passed to the matching routes.
|
||||||
///
|
///
|
||||||
/// @EXAMPLES
|
/// @EXAMPLES
|
||||||
///
|
///
|
||||||
|
@ -371,8 +375,10 @@ extend(Controller.prototype, {
|
||||||
url: {match: path},
|
url: {match: path},
|
||||||
action: {
|
action: {
|
||||||
callback: function (req, res, opts, next) {
|
callback: function (req, res, opts, next) {
|
||||||
func(req, res, opts);
|
var result = func(req, res, opts);
|
||||||
next();
|
if (result !== false) {
|
||||||
|
next();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -192,13 +192,14 @@ function extendContext (context, app, root) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var cp = context.collectionPrefix;
|
var cp = context.collectionPrefix;
|
||||||
|
var cname = "";
|
||||||
|
|
||||||
if (cp !== "" && cp !== "_") {
|
if (cp !== "") {
|
||||||
cp += "_";
|
cname = cp + "_";
|
||||||
}
|
}
|
||||||
|
|
||||||
context.collectionName = function (name) {
|
context.collectionName = function (name) {
|
||||||
var replaced = ((cp + name).replace(/[^a-zA-Z0-9]/g, '_').replace(/(^_+|_+$)/g, '')).substr(0, 64);
|
var replaced = (cname + name).replace(/[^a-zA-Z0-9]/g, '_').replace(/(^_+|_+$)/g, '').substr(0, 64);
|
||||||
|
|
||||||
if (replaced.length === 0) {
|
if (replaced.length === 0) {
|
||||||
throw new Error("Cannot derive collection name from '" + name + "'");
|
throw new Error("Cannot derive collection name from '" + name + "'");
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
var Repository,
|
var Repository,
|
||||||
|
Model = require("org/arangodb/foxx/model").Model,
|
||||||
_ = require("underscore"),
|
_ = require("underscore"),
|
||||||
extend = require('org/arangodb/extend').extend;
|
extend = require('org/arangodb/extend').extend;
|
||||||
|
|
||||||
|
@ -82,7 +83,7 @@ Repository = function (collection, opts) {
|
||||||
/// @endDocuBlock
|
/// @endDocuBlock
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
this.modelPrototype = this.options.model || require("org/arangodb/foxx/model").Model;
|
this.modelPrototype = this.options.model || Model;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @startDocuBlock JSF_foxx_repository_prefix
|
/// @startDocuBlock JSF_foxx_repository_prefix
|
||||||
|
@ -262,7 +263,7 @@ _.extend(Repository.prototype, {
|
||||||
remove: function (model) {
|
remove: function (model) {
|
||||||
'use strict';
|
'use strict';
|
||||||
var id = model.get('_id');
|
var id = model.get('_id');
|
||||||
this.collection.remove(id);
|
return this.collection.remove(id);
|
||||||
},
|
},
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -281,7 +282,7 @@ _.extend(Repository.prototype, {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
removeById: function (id) {
|
removeById: function (id) {
|
||||||
'use strict';
|
'use strict';
|
||||||
this.collection.remove(id);
|
return this.collection.remove(id);
|
||||||
},
|
},
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -299,7 +300,7 @@ _.extend(Repository.prototype, {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
removeByExample: function (example) {
|
removeByExample: function (example) {
|
||||||
'use strict';
|
'use strict';
|
||||||
this.collection.removeByExample(example);
|
return this.collection.removeByExample(example);
|
||||||
},
|
},
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -311,7 +312,7 @@ _.extend(Repository.prototype, {
|
||||||
/// `FoxxRepository#replace(model)`
|
/// `FoxxRepository#replace(model)`
|
||||||
///
|
///
|
||||||
/// Find the model in the database by its *_id* and replace it with this version.
|
/// Find the model in the database by its *_id* and replace it with this version.
|
||||||
/// Expects a model. Sets the Revision of the model.
|
/// Expects a model. Sets the revision of the model.
|
||||||
/// Returns the model.
|
/// Returns the model.
|
||||||
///
|
///
|
||||||
/// @EXAMPLES
|
/// @EXAMPLES
|
||||||
|
@ -324,7 +325,7 @@ _.extend(Repository.prototype, {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
replace: function (model) {
|
replace: function (model) {
|
||||||
'use strict';
|
'use strict';
|
||||||
var id = model.get("_id"),
|
var id = model.get("_id") || model.get("_key"),
|
||||||
data = model.forDB(),
|
data = model.forDB(),
|
||||||
id_and_rev = this.collection.replace(id, data);
|
id_and_rev = this.collection.replace(id, data);
|
||||||
model.set(id_and_rev);
|
model.set(id_and_rev);
|
||||||
|
@ -333,11 +334,12 @@ _.extend(Repository.prototype, {
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @startDocuBlock JSF_foxx_repository_replaceById
|
/// @startDocuBlock JSF_foxx_repository_replaceById
|
||||||
/// `FoxxRepository#replaceById(id, model)`
|
/// `FoxxRepository#replaceById(id, object)`
|
||||||
///
|
///
|
||||||
/// Find the model in the database by the given ID and replace it with the given.
|
/// Find the item in the database by the given ID and replace it with the
|
||||||
/// model.
|
/// given object's attributes.
|
||||||
/// Sets the ID and Revision of the model and also returns it.
|
///
|
||||||
|
/// If the object is a model, updates the model's revision and returns the model.
|
||||||
///
|
///
|
||||||
/// @EXAMPLES
|
/// @EXAMPLES
|
||||||
///
|
///
|
||||||
|
@ -346,21 +348,22 @@ _.extend(Repository.prototype, {
|
||||||
/// ```
|
/// ```
|
||||||
/// @endDocuBlock
|
/// @endDocuBlock
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
replaceById: function (id, model) {
|
replaceById: function (id, data) {
|
||||||
'use strict';
|
'use strict';
|
||||||
var data = model.forDB(),
|
if (data instanceof Model) {
|
||||||
id_and_rev = this.collection.replace(id, data);
|
var id_and_rev = this.collection.replace(id, data.forDB());
|
||||||
model.set(id_and_rev);
|
data.set(id_and_rev);
|
||||||
return model;
|
return data;
|
||||||
|
}
|
||||||
|
return this.collection.replace(id, data);
|
||||||
},
|
},
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @startDocuBlock JSF_foxx_repository_replaceByExample
|
/// @startDocuBlock JSF_foxx_repository_replaceByExample
|
||||||
/// `FoxxRepository#replaceByExample(example, model)`
|
/// `FoxxRepository#replaceByExample(example, object)`
|
||||||
///
|
///
|
||||||
/// Find the model in the database by the given example and replace it with the given.
|
/// Find every matching item by example and replace it with the attributes in
|
||||||
/// model.
|
/// the provided object.
|
||||||
/// Sets the ID and Revision of the model and also returns it.
|
|
||||||
///
|
///
|
||||||
/// @EXAMPLES
|
/// @EXAMPLES
|
||||||
///
|
///
|
||||||
|
@ -369,24 +372,46 @@ _.extend(Repository.prototype, {
|
||||||
/// ```
|
/// ```
|
||||||
/// @endDocuBlock
|
/// @endDocuBlock
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
replaceByExample: function (example, model) {
|
replaceByExample: function (example, data) {
|
||||||
'use strict';
|
'use strict';
|
||||||
var data = model.forDB(),
|
return this.collection.replaceByExample(example, data);
|
||||||
idAndRev = this.collection.replaceByExample(example, data);
|
|
||||||
model.set(idAndRev);
|
|
||||||
return model;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SUBSECTION-- Updating Entries
|
// --SUBSECTION-- Updating Entries
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @startDocuBlock JSF_foxx_repository_update
|
||||||
|
/// `FoxxRepository#update(model, object)`
|
||||||
|
///
|
||||||
|
/// Find the model in the database by its *_id* and update it with the given object.
|
||||||
|
/// Expects a model. Sets the revision of the model and updates its properties.
|
||||||
|
/// Returns the model.
|
||||||
|
///
|
||||||
|
/// @EXAMPLES
|
||||||
|
///
|
||||||
|
/// ```javascript
|
||||||
|
/// repository.update(myModel, {name: 'Jan Steeman'});
|
||||||
|
/// ```
|
||||||
|
/// @endDocuBlock
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
update: function (model, data) {
|
||||||
|
'use strict';
|
||||||
|
var id = model.get("_id") || model.get("_key"),
|
||||||
|
id_and_rev = this.collection.update(id, data);
|
||||||
|
model.set(data);
|
||||||
|
model.set(id_and_rev);
|
||||||
|
return model;
|
||||||
|
},
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @startDocuBlock JSF_foxx_repository_updateById
|
/// @startDocuBlock JSF_foxx_repository_updateById
|
||||||
/// `FoxxRepository#updateById(id, object)`
|
/// `FoxxRepository#updateById(id, object)`
|
||||||
///
|
///
|
||||||
/// Find an item by ID and update it with the attributes in the provided object.
|
/// Find an item by ID and update it with the attributes in the provided object.
|
||||||
/// Returns the updated model.
|
///
|
||||||
|
/// If the object is a model, updates the model's revision and returns the model.
|
||||||
///
|
///
|
||||||
/// @EXAMPLES
|
/// @EXAMPLES
|
||||||
///
|
///
|
||||||
|
@ -395,17 +420,22 @@ _.extend(Repository.prototype, {
|
||||||
/// ```
|
/// ```
|
||||||
/// @endDocuBlock
|
/// @endDocuBlock
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
updateById: function (id, updates) {
|
updateById: function (id, data) {
|
||||||
'use strict';
|
'use strict';
|
||||||
this.collection.update(id, updates);
|
if (data instanceof Model) {
|
||||||
|
var id_and_rev = this.collection.update(id, data.forDB());
|
||||||
|
data.set(id_and_rev);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
return this.collection.update(id, data);
|
||||||
},
|
},
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @startDocuBlock JSF_foxx_repository_updateByExample
|
/// @startDocuBlock JSF_foxx_repository_updateByExample
|
||||||
/// `FoxxRepository#updateByExample(example, object)`
|
/// `FoxxRepository#updateByExample(example, object)`
|
||||||
///
|
///
|
||||||
/// Find an item by example and update it with the attributes in the provided object.
|
/// Find every matching item by example and update it with the attributes in
|
||||||
/// Returns the updated model.
|
/// the provided object.
|
||||||
///
|
///
|
||||||
/// @EXAMPLES
|
/// @EXAMPLES
|
||||||
///
|
///
|
||||||
|
@ -414,9 +444,9 @@ _.extend(Repository.prototype, {
|
||||||
/// ```
|
/// ```
|
||||||
/// @endDocuBlock
|
/// @endDocuBlock
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
updateByExample: function (example, updates) {
|
updateByExample: function (example, data) {
|
||||||
'use strict';
|
'use strict';
|
||||||
this.collection.updateByExample(example, updates);
|
return this.collection.updateByExample(example, data);
|
||||||
},
|
},
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
|
@ -220,13 +220,23 @@ extend(RequestContext.prototype, {
|
||||||
///
|
///
|
||||||
/// You can also provide a description of this parameter.
|
/// 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
|
/// ```js
|
||||||
/// app.get("/foxx/:id", function {
|
/// app.get("/foxx/:id", function {
|
||||||
/// // Do something
|
/// // Do something
|
||||||
/// }).pathParam("id", {
|
/// }).pathParam("id", {
|
||||||
/// type: joi.number().integer().required().description("Id of the Foxx")
|
/// type: joi.number().integer(),
|
||||||
|
/// required: true,
|
||||||
|
/// description: "Id of the Foxx"
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
/// @endDocuBlock
|
/// @endDocuBlock
|
||||||
|
@ -239,9 +249,16 @@ extend(RequestContext.prototype, {
|
||||||
type = attributes.type,
|
type = attributes.type,
|
||||||
required = attributes.required,
|
required = attributes.required,
|
||||||
description = attributes.description,
|
description = attributes.description,
|
||||||
constraint = type,
|
constraint, regexType, cfg;
|
||||||
regexType = type,
|
|
||||||
cfg;
|
if (attributes.isJoi) {
|
||||||
|
type = attributes;
|
||||||
|
required = undefined;
|
||||||
|
description = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
constraint = type;
|
||||||
|
regexType = type;
|
||||||
|
|
||||||
// deprecated: assume type.describe is always a function
|
// deprecated: assume type.describe is always a function
|
||||||
if (type && typeof type.describe === 'function') {
|
if (type && typeof type.describe === 'function') {
|
||||||
|
@ -306,6 +323,19 @@ extend(RequestContext.prototype, {
|
||||||
/// ```js
|
/// ```js
|
||||||
/// app.get("/foxx", function {
|
/// app.get("/foxx", function {
|
||||||
/// // Do something
|
/// // 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", {
|
/// }).queryParam("id", {
|
||||||
/// type: joi.number().integer().required().description("Id of the Foxx"),
|
/// type: joi.number().integer().required().description("Id of the Foxx"),
|
||||||
/// allowMultiple: false
|
/// allowMultiple: false
|
||||||
|
@ -319,8 +349,17 @@ extend(RequestContext.prototype, {
|
||||||
var type = attributes.type,
|
var type = attributes.type,
|
||||||
required = attributes.required,
|
required = attributes.required,
|
||||||
description = attributes.description,
|
description = attributes.description,
|
||||||
constraint = type,
|
allowMultiple = attributes.allowMultiple,
|
||||||
cfg;
|
constraint, cfg;
|
||||||
|
|
||||||
|
if (attributes.isJoi) {
|
||||||
|
type = attributes;
|
||||||
|
required = undefined;
|
||||||
|
description = undefined;
|
||||||
|
allowMultiple = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
constraint = type;
|
||||||
|
|
||||||
// deprecated: assume type.describe is always a function
|
// deprecated: assume type.describe is always a function
|
||||||
if (type && typeof type.describe === 'function') {
|
if (type && typeof type.describe === 'function') {
|
||||||
|
@ -330,6 +369,9 @@ extend(RequestContext.prototype, {
|
||||||
if (typeof description === 'string') {
|
if (typeof description === 'string') {
|
||||||
constraint = constraint.description(description);
|
constraint = constraint.description(description);
|
||||||
}
|
}
|
||||||
|
if (typeof allowMultiple === 'boolean') {
|
||||||
|
constraint = constraint.meta({allowMultiple: allowMultiple});
|
||||||
|
}
|
||||||
this.constraints.queryParams[paramName] = constraint;
|
this.constraints.queryParams[paramName] = constraint;
|
||||||
cfg = constraint.describe();
|
cfg = constraint.describe();
|
||||||
if (Array.isArray(cfg)) {
|
if (Array.isArray(cfg)) {
|
||||||
|
@ -338,8 +380,18 @@ extend(RequestContext.prototype, {
|
||||||
} else {
|
} else {
|
||||||
type = cfg.type;
|
type = cfg.type;
|
||||||
}
|
}
|
||||||
required = Boolean(cfg.flags && cfg.flags.presense === 'required');
|
required = Boolean(cfg.flags && cfg.flags.presence === 'required');
|
||||||
description = cfg.description;
|
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 (
|
if (
|
||||||
type === 'number' &&
|
type === 'number' &&
|
||||||
_.isArray(cfg.rules) &&
|
_.isArray(cfg.rules) &&
|
||||||
|
@ -356,7 +408,7 @@ extend(RequestContext.prototype, {
|
||||||
description,
|
description,
|
||||||
type,
|
type,
|
||||||
required,
|
required,
|
||||||
attributes.allowMultiple
|
Boolean(allowMultiple)
|
||||||
);
|
);
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
|
@ -288,25 +288,39 @@ describe('Repository Methods', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should replace by example', function () {
|
it('should replace by example', function () {
|
||||||
var model = new Model({}),
|
var example = createSpy('example'),
|
||||||
idAndRev = createSpy('idAndRev'),
|
data = createSpy('data');
|
||||||
example = createSpy('example'),
|
|
||||||
data = createSpy('data'),
|
|
||||||
result;
|
|
||||||
|
|
||||||
spyOn(model, 'forDB').and.returnValue(data);
|
instance.replaceByExample(example, data);
|
||||||
spyOn(model, 'set');
|
|
||||||
collection.replaceByExample.and.returnValue(idAndRev);
|
|
||||||
|
|
||||||
result = instance.replaceByExample(example, model);
|
|
||||||
|
|
||||||
expect(result).toBe(model);
|
|
||||||
expect(model.set.calls.argsFor(0)).toEqual([idAndRev]);
|
|
||||||
expect(collection.replaceByExample.calls.argsFor(0)).toEqual([example, data]);
|
expect(collection.replaceByExample.calls.argsFor(0)).toEqual([example, data]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('for updating entries', function () {
|
describe('for updating entries', function () {
|
||||||
|
it('should allow to update by model', function () {
|
||||||
|
var model = new Model({}),
|
||||||
|
idAndRev = createSpy('idAndRev'),
|
||||||
|
id = createSpy('id'),
|
||||||
|
data = createSpy('data'),
|
||||||
|
updates = createSpy('updates'),
|
||||||
|
result;
|
||||||
|
|
||||||
|
spyOn(model, 'get').and.returnValue(id);
|
||||||
|
spyOn(model, 'forDB').and.returnValue(data);
|
||||||
|
spyOn(model, 'set');
|
||||||
|
collection.update.and.returnValue(idAndRev);
|
||||||
|
|
||||||
|
result = instance.update(model, updates);
|
||||||
|
|
||||||
|
expect(result).toBe(model);
|
||||||
|
expect(model.set.calls.allArgs().length).toEqual(2);
|
||||||
|
expect(model.set.calls.allArgs()).toContain([idAndRev]);
|
||||||
|
expect(model.set.calls.allArgs()).toContain([updates]);
|
||||||
|
expect(collection.update.calls.argsFor(0)).toEqual([id, updates]);
|
||||||
|
expect(model.get.calls.argsFor(0)).toEqual(['_id']);
|
||||||
|
});
|
||||||
|
|
||||||
it('should update by id', function () {
|
it('should update by id', function () {
|
||||||
var id = createSpy('id'),
|
var id = createSpy('id'),
|
||||||
updates = createSpy('updates'),
|
updates = createSpy('updates'),
|
||||||
|
@ -320,13 +334,11 @@ describe('Repository Methods', function () {
|
||||||
|
|
||||||
it('should update by example', function () {
|
it('should update by example', function () {
|
||||||
var example = createSpy('example'),
|
var example = createSpy('example'),
|
||||||
updates = createSpy('updates'),
|
data = createSpy('data');
|
||||||
idAndRev = createSpy('idAndRev');
|
|
||||||
|
|
||||||
collection.updateByExample.and.returnValue(idAndRev);
|
instance.updateByExample(example, data);
|
||||||
instance.updateByExample(example, updates);
|
|
||||||
|
|
||||||
expect(collection.updateByExample.calls.argsFor(0)).toEqual([example, updates]);
|
expect(collection.updateByExample.calls.argsFor(0)).toEqual([example, data]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -514,6 +514,21 @@ function DocumentationAndConstraintsSpec () {
|
||||||
assertEqual(context.constraints.urlParams, {id: constraint});
|
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 () {
|
testDefinePathCaseParam: function () {
|
||||||
var constraint = joi.number().integer().description("Id of the Foxx"),
|
var constraint = joi.number().integer().description("Id of the Foxx"),
|
||||||
context = app.get('/foxx/:idParam', function () {
|
context = app.get('/foxx/:idParam', function () {
|
||||||
|
@ -592,10 +607,56 @@ function DocumentationAndConstraintsSpec () {
|
||||||
context = app.get('/foxx', function () {
|
context = app.get('/foxx', function () {
|
||||||
//nothing
|
//nothing
|
||||||
}).queryParam("a", {
|
}).queryParam("a", {
|
||||||
type: constraint,
|
type: constraint
|
||||||
allowMultiple: 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");
|
||||||
|
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.length, 1);
|
||||||
assertEqual(routes[0].docs.parameters[0].paramType, "query");
|
assertEqual(routes[0].docs.parameters[0].paramType, "query");
|
||||||
assertEqual(routes[0].docs.parameters[0].name, "a");
|
assertEqual(routes[0].docs.parameters[0].name, "a");
|
||||||
|
|
Loading…
Reference in New Issue