This commit is contained in:
thosakwe 2017-01-25 18:03:45 -05:00
parent c7698c2087
commit 1104cd7a82
5 changed files with 55 additions and 9 deletions

View file

@ -1,5 +1,5 @@
# validate # validate
[![version 1.0.0-beta](https://img.shields.io/badge/pub-v1.0.0--beta-red.svg)](https://pub.dartlang.org/packages/angel_validate) [![version 1.0.0](https://img.shields.io/badge/pub-v1.0.0-red.svg)](https://pub.dartlang.org/packages/angel_validate)
[![build status](https://travis-ci.org/angel-dart/validate.svg)](https://travis-ci.org/angel-dart/validate) [![build status](https://travis-ci.org/angel-dart/validate.svg)](https://travis-ci.org/angel-dart/validate)
(Still missing several tests) (Still missing several tests)
@ -23,6 +23,7 @@ For convenience's sake, this library also exports `matcher`.
* [Default Values](#default-values) * [Default Values](#default-values)
* [Custom Validator Functions](#custom-validator-functions) * [Custom Validator Functions](#custom-validator-functions)
* [Auto-parsing Numbers](#autoparse) * [Auto-parsing Numbers](#autoparse)
* [Filtering Maps](#filter)
* [Custom Error Messages](#custom-error-messages) * [Custom Error Messages](#custom-error-messages)
* [Extending Validators](#extending-validators) * [Extending Validators](#extending-validators)
* [Bundled Matchers](#bundled-matchers) * [Bundled Matchers](#bundled-matchers)
@ -166,6 +167,16 @@ main() {
You can also call `checkParsed` or `enforceParsed` as a shorthand. You can also call `checkParsed` or `enforceParsed` as a shorthand.
# filter
This is a helper function to extract only the desired keys from a `Map`.
```dart
var inputData = {'foo': 'bar', 'a': 'b', '1': 2};
var only = filter(inputData, ['foo']);
print(only); // { foo: bar }
```
# Extending Validators # Extending Validators
You can add situation-specific rules within a child validator. You can add situation-specific rules within a child validator.
You can also use `extend` to mark fields as required or forbidden that originally You can also use `extend` to mark fields as required or forbidden that originally
@ -257,12 +268,14 @@ main() {
# Use with Angel # Use with Angel
`server.dart` exposes five helper middleware: `server.dart` exposes seven helper middleware:
* `validate(validator)`: Validates and filters `req.body`, and throws an `AngelHttpException.BadRequest` if data is invalid. * `validate(validator)`: Validates and filters `req.body`, and throws an `AngelHttpException.BadRequest` if data is invalid.
* `validateEvent(validator)`: Sets `e.data` to the result of validation on a service event. * `validateEvent(validator)`: Sets `e.data` to the result of validation on a service event.
* `validateQuery(validator)`: Same as `validate`, but operates on `req.query`. * `validateQuery(validator)`: Same as `validate`, but operates on `req.query`.
* `autoParseBody(fields)`: Auto-parses numbers in `req.body`. * `autoParseBody(fields)`: Auto-parses numbers in `req.body`.
* `autoParseQuery(fields)`: Same as `autoParseBody`, but operates on `req.query`. * `autoParseQuery(fields)`: Same as `autoParseBody`, but operates on `req.query`.
* `filterBody(only)`: Filters unwanted data out of `req.body`.
* `filterQuery(only)`: Same as `filterBody`, but operates on `req.query`.
```dart ```dart
import 'package:angel_framework/angel_framework.dart'; import 'package:angel_framework/angel_framework.dart';

View file

@ -21,6 +21,28 @@ RequestMiddleware autoParseQuery(List<String> fields) {
}; };
} }
/// Filters unwanted data out of `req.body`.
RequestMiddleware filterBody(Iterable<String> only) {
return (RequestContext req, res) async {
var filtered = filter(req.body, only);
req.body
..clear()
..addAll(filtered);
return true;
};
}
/// Filters unwanted data out of `req.query`.
RequestMiddleware filterQuery(Iterable<String> only) {
return (RequestContext req, res) async {
var filtered = filter(req.query, only);
req.query
..clear()
..addAll(filtered);
return true;
};
}
/// Validates the data in `req.body`, and sets the body to /// Validates the data in `req.body`, and sets the body to
/// filtered data before continuing the response. /// filtered data before continuing the response.
RequestMiddleware validate(Validator validator, RequestMiddleware validate(Validator validator,

View file

@ -14,7 +14,7 @@ typedef String CustomErrorMessageFunction(item);
typedef bool Filter(value); typedef bool Filter(value);
/// Converts the desired fields to their numeric representations, if present. /// Converts the desired fields to their numeric representations, if present.
Map<String, dynamic> autoParse(Map inputData, List<String> fields) { Map<String, dynamic> autoParse(Map inputData, Iterable<String> fields) {
Map<String, dynamic> data = {}; Map<String, dynamic> data = {};
for (var key in inputData.keys) { for (var key in inputData.keys) {
@ -33,6 +33,14 @@ Map<String, dynamic> autoParse(Map inputData, List<String> fields) {
return data; return data;
} }
/// Removes undesired fields from a `Map`.
Map<String, dynamic> filter(Map inputData, Iterable<String> only) {
return inputData.keys.fold(<String, dynamic>{}, (map, key) {
if (only.contains(key)) map[key] = inputData[key];
return map;
});
}
/// Enforces the validity of input data, according to [Matcher]s. /// Enforces the validity of input data, according to [Matcher]s.
class Validator extends Matcher { class Validator extends Matcher {
/// Pre-defined error messages for certain fields. /// Pre-defined error messages for certain fields.

View file

@ -1,6 +1,6 @@
name: angel_validate name: angel_validate
description: Cross-platform validation library based on `matcher`. description: Cross-platform validation library based on `matcher`.
version: 1.0.0-beta version: 1.0.0
author: Tobe O <thosakwe@gmail.com> author: Tobe O <thosakwe@gmail.com>
homepage: https://github.com/angel-dart/validate homepage: https://github.com/angel-dart/validate
environment: environment:

View file

@ -1,11 +1,8 @@
import 'package:angel_validate/angel_validate.dart'; import 'package:angel_validate/angel_validate.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
final Validator emailSchema = new Validator({ final Validator emailSchema = new Validator({'to': isEmail},
'to': isEmail customErrorMessages: {'to': 'Hello, world!'});
}, customErrorMessages: {
'to': 'Hello, world!'
});
final Validator todoSchema = new Validator({ final Validator todoSchema = new Validator({
'id': [isInt, isPositive], 'id': [isInt, isPositive],
@ -30,4 +27,10 @@ main() {
.enforce({'id': 'fool', 'text': 'Hello, world!', 'completed': 4}); .enforce({'id': 'fool', 'text': 'Hello, world!', 'completed': 4});
}, throwsA(new isInstanceOf<ValidationException>())); }, throwsA(new isInstanceOf<ValidationException>()));
}); });
test('filter', () {
var inputData = {'foo': 'bar', 'a': 'b', '1': 2};
var only = filter(inputData, ['foo']);
expect(only, equals({'foo': 'bar'}));
});
} }