From 5e9172aca9d54efa6b414054dc0b4e29e6060d12 Mon Sep 17 00:00:00 2001 From: thomashii Date: Sat, 10 Apr 2021 20:42:55 +0800 Subject: [PATCH] Migrated json_god --- CHANGELOG.md | 23 +++++-- .../lib/angel_configuration.dart | 2 +- packages/json_god/lib/json_god.dart | 5 +- packages/json_god/lib/src/deserialize.dart | 6 +- packages/json_god/lib/src/reflection.dart | 6 +- packages/json_god/lib/src/serialize.dart | 10 +-- packages/json_god/pubspec.yaml | 12 ++-- .../json_god/test/deserialization_test.dart | 6 +- .../json_god/test/serialization_test.dart | 4 +- packages/json_god/test/shared.dart | 10 +-- packages/json_god/test/to_json_test.dart | 2 +- packages/validate/lib/server.dart | 64 ++++++++++--------- packages/validate/lib/src/async.dart | 23 +++---- packages/validate/lib/src/context_aware.dart | 5 +- packages/validate/lib/src/matchers.dart | 28 ++++---- packages/validate/lib/src/validator.dart | 50 ++++++++------- packages/validate/pubspec.yaml | 12 ++-- packages/validate/test/basic_test.dart | 4 +- packages/validate/test/server_test.dart | 10 +-- packages/validate/web/main.dart | 16 ++--- 20 files changed, 161 insertions(+), 137 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index daa66f43..0e0ae2fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ * Changed Dart SDK requirements for all packages to ">=2.12.0 <3.0.0" to support NNBD. * Updated pretty_logging to 3.0.0 (0/0 tests) * Updated angel_http_exception to 3.0.0 (0/0 tests) -* Moved angel_cli to https://github.com/dukefirehawk/cli +* Moved angel_cli to https://github.com/dukefirehawk/cli (Not migrated) * Added code_buffer and updated to 2.0.0 (16/16 tests) * Added combinator and updated to 2.0.0 (16/16 tests) * Updated angel_route to 5.0.0 (35/35 tests passed) @@ -12,7 +12,20 @@ * Added mock_request and updated to 2.0.0 (0/0 tests) * Updated angel_framework to 4.0.0 (146/149 tests passed) * Updated angel_auth to 4.0.0 (22/32 test passed) -* Updated angel_configuration to 4.0.0 (In progress) +* Updated angel_configuration to 4.0.0 (6/8 test passed) +* Updated angel_validate to 4.0.0 (6/7 test passed) +* Updated json_god to 4.0.0 (13/13 test passed) +* Updated angel_client to 3.0.0 (in progress) +* Updated angel_websocket to 3.0.0 (in progress) +* Updated test to 3.0.0 (in progress) +* Updated jael to 3.0.0 (in progress) +* Updated jael_preprocessor to 3.0.0 (in progress) +* Updated angel_jael to 3.0.0 (in progress) +* Updated pub_sub to 3.0.0 (in progress) +* Updated production to 2.0.0 (in progress) +* Updated hot to 3.0.0 (in progress) +* Updated static to 3.0.0 (in progress) +* Update basic-sdk-2.12.x boilerplate (in progress) # 3.0.0 (Non NNBD) * Changed Dart SDK requirements for all packages to ">=2.10.0 <3.0.0" @@ -25,12 +38,12 @@ * Updated angel_framework to 3.0.0 * Updated angel_auth to 3.0.0 * Updated angel_configuration to 3.0.0 -* Updated jael to 3.0.0 -* Updated jael_preprocessor to 3.0.0 -* Updated validate to 3.0.0 +* Updated angel_validate to 3.0.0 * Added and updated json_god to 3.0.0 * Updated angel_client to 3.0.0 * Updated angel_websocket to 3.0.0 (one issue to be resolved) +* Updated jael to 3.0.0 +* Updated jael_preprocessor to 3.0.0 * Updated test to 3.0.0 * Updated angel_jael to 3.0.0 (Issue with 2 dependencies) * Added pub_sub and updated to 3.0.0 diff --git a/packages/configuration/lib/angel_configuration.dart b/packages/configuration/lib/angel_configuration.dart index d1e62f3e..5803c368 100644 --- a/packages/configuration/lib/angel_configuration.dart +++ b/packages/configuration/lib/angel_configuration.dart @@ -44,7 +44,7 @@ Future _loadYamlFile(Map map, File yamlFile, Map env, } } - for (var key in configMap.keys as Iterable) { + for (var key in configMap.keys) { out[key] = _applyEnv(configMap[key], env, warn); } diff --git a/packages/json_god/lib/json_god.dart b/packages/json_god/lib/json_god.dart index 5a3c7d68..44e33491 100644 --- a/packages/json_god/lib/json_god.dart +++ b/packages/json_god/lib/json_god.dart @@ -1,7 +1,8 @@ /// A robust library for JSON serialization and deserialization. library json_god; -import 'package:dart2_constant/convert.dart'; +//import 'package:dart2_constant/convert.dart'; +import 'dart:convert'; import 'package:logging/logging.dart'; import 'src/reflection.dart' as reflection; @@ -14,4 +15,4 @@ part 'src/util.dart'; @deprecated bool debug = false; -final Logger logger = new Logger('json_god'); \ No newline at end of file +final Logger logger = new Logger('json_god'); diff --git a/packages/json_god/lib/src/deserialize.dart b/packages/json_god/lib/src/deserialize.dart index 94a5e682..fd66e3ef 100644 --- a/packages/json_god/lib/src/deserialize.dart +++ b/packages/json_god/lib/src/deserialize.dart @@ -3,14 +3,14 @@ part of json_god; /// Deserializes a JSON string into a Dart datum. /// /// You can also provide an output Type to attempt to serialize the JSON into. -deserialize(String json, {Type outputType}) { +deserialize(String json, {Type? outputType}) { var deserialized = deserializeJson(json, outputType: outputType); logger.info("Deserialization result: $deserialized"); return deserialized; } /// Deserializes JSON into data, without validating it. -deserializeJson(String s, {Type outputType}) { +deserializeJson(String s, {Type? outputType}) { logger.info("Deserializing the following JSON: $s"); if (outputType == null) { @@ -23,7 +23,7 @@ deserializeJson(String s, {Type outputType}) { } /// Deserializes some JSON-serializable value into a usable Dart value. -deserializeDatum(value, {Type outputType}) { +deserializeDatum(value, {Type? outputType}) { if (outputType != null) { return reflection.deserialize(value, outputType, deserializeDatum); } else if (value is List) { diff --git a/packages/json_god/lib/src/reflection.dart b/packages/json_god/lib/src/reflection.dart index 4adcccd5..6d498a1e 100644 --- a/packages/json_god/lib/src/reflection.dart +++ b/packages/json_god/lib/src/reflection.dart @@ -7,7 +7,7 @@ const Symbol hashCodeSymbol = #hashCode; const Symbol runtimeTypeSymbol = #runtimeType; typedef Serializer(value); -typedef Deserializer(value, {Type outputType}); +typedef Deserializer(value, {Type? outputType}); List _findGetters(ClassMirror classMirror) { List result = []; @@ -110,7 +110,7 @@ _deserializeFromJsonByReflection( throw new ArgumentError('$outputType is not a class.'); } - var type = typeMirror as ClassMirror; + var type = typeMirror; var fromJson = new Symbol('${MirrorSystem.getName(type.simpleName)}.fromJson'); @@ -166,7 +166,7 @@ _deserializeFromJsonByReflection( Symbol symbolForGetter = classMirror.instanceMembers.keys .firstWhere((x) => x == searchSymbol); Type requiredType = classMirror - .instanceMembers[symbolForGetter].returnType.reflectedType; + .instanceMembers[symbolForGetter]!.returnType.reflectedType; if (data[key].runtimeType != requiredType) { logger.info("Currently, $key is a ${data[key].runtimeType}."); logger.info("However, $key must be a $requiredType."); diff --git a/packages/json_god/lib/src/serialize.dart b/packages/json_god/lib/src/serialize.dart index 609d1b3a..1e1b71b9 100644 --- a/packages/json_god/lib/src/serialize.dart +++ b/packages/json_god/lib/src/serialize.dart @@ -3,23 +3,23 @@ part of json_god; /// Serializes any arbitrary Dart datum to JSON. Supports schema validation. String serialize(value) { var serialized = serializeObject(value); - logger.info('Serialization result: $serialized'); + logger.info('Serialization result: $serialized'); return json.encode(serialized); } /// Transforms any Dart datum into a value acceptable to json.encode. serializeObject(value) { if (_isPrimitive(value)) { - logger.info("Serializing primitive value: $value"); + logger.info("Serializing primitive value: $value"); return value; } else if (value is DateTime) { - logger.info("Serializing this DateTime: $value"); + logger.info("Serializing this DateTime: $value"); return value.toIso8601String(); } else if (value is Iterable) { - logger.info("Serializing this Iterable: $value"); + logger.info("Serializing this Iterable: $value"); return value.map(serializeObject).toList(); } else if (value is Map) { - logger.info("Serializing this Map: $value"); + logger.info("Serializing this Map: $value"); return serializeMap(value); } else return serializeObject(reflection.serialize(value, serializeObject)); diff --git a/packages/json_god/pubspec.yaml b/packages/json_god/pubspec.yaml index b1f8be2a..28367f6d 100644 --- a/packages/json_god/pubspec.yaml +++ b/packages/json_god/pubspec.yaml @@ -1,14 +1,14 @@ name: json_god -version: 3.0.0 +version: 4.0.0 authors: - Tobe O description: Easy JSON serialization and deserialization in Dart. homepage: https://github.com/thosakwe/json_god environment: - sdk: ">=2.10.0 <3.0.0" + sdk: '>=2.12.0 <3.0.0' dependencies: - dart2_constant: ^1.0.0 - logging: ^1.0.0 + #dart2_constant: ^1.0.0 + logging: ^1.0.1 dev_dependencies: - stack_trace: ^1.0.0 - test: any \ No newline at end of file + stack_trace: ^1.10.0 + test: ^1.16.8 \ No newline at end of file diff --git a/packages/json_god/test/deserialization_test.dart b/packages/json_god/test/deserialization_test.dart index 0d8f27aa..df8f64aa 100644 --- a/packages/json_god/test/deserialization_test.dart +++ b/packages/json_god/test/deserialization_test.dart @@ -47,15 +47,15 @@ testDeserializationOfMaps() { } class Pokedex { - Map pokemon; + Map? pokemon; } testDeserializationOfMapsWithReflection() { var s = '{"pokemon": {"Bulbasaur": 1, "Deoxys": 382}}'; var pokedex = god.deserialize(s, outputType: Pokedex) as Pokedex; expect(pokedex.pokemon, hasLength(2)); - expect(pokedex.pokemon['Bulbasaur'], 1); - expect(pokedex.pokemon['Deoxys'], 382); + expect(pokedex.pokemon!['Bulbasaur'], 1); + expect(pokedex.pokemon!['Deoxys'], 382); } testDeserializationOfListsAsWellAsViaReflection() { diff --git a/packages/json_god/test/serialization_test.dart b/packages/json_god/test/serialization_test.dart index 8b596948..ae316f1d 100644 --- a/packages/json_god/test/serialization_test.dart +++ b/packages/json_god/test/serialization_test.dart @@ -1,4 +1,6 @@ -import 'package:dart2_constant/convert.dart'; +//import 'package:dart2_constant/convert.dart'; +import 'dart:convert'; + import 'package:json_god/json_god.dart' as god; import 'package:test/test.dart'; import 'shared.dart'; diff --git a/packages/json_god/test/shared.dart b/packages/json_god/test/shared.dart index 6380baba..8fdc9bb1 100644 --- a/packages/json_god/test/shared.dart +++ b/packages/json_god/test/shared.dart @@ -5,20 +5,20 @@ import 'package:stack_trace/stack_trace.dart'; void printRecord(LogRecord rec) { print(rec); if (rec.error != null) print(rec.error); - if (rec.stackTrace != null) print(new Chain.forTrace(rec.stackTrace).terse); + if (rec.stackTrace != null) print(new Chain.forTrace(rec.stackTrace!).terse); } class SampleNestedClass { - String bar; + String? bar; - SampleNestedClass([String this.bar]); + SampleNestedClass([String? this.bar]); } class SampleClass { - String hello; + String? hello; List nested = []; - SampleClass([String this.hello]); + SampleClass([String? this.hello]); } @WithSchemaUrl( diff --git a/packages/json_god/test/to_json_test.dart b/packages/json_god/test/to_json_test.dart index f4bea217..57fbfba2 100644 --- a/packages/json_god/test/to_json_test.dart +++ b/packages/json_god/test/to_json_test.dart @@ -20,7 +20,7 @@ main() { } class Foo { - String text; + String? text; String get foo => 'poo$text'; diff --git a/packages/validate/lib/server.dart b/packages/validate/lib/server.dart index 9ae41185..bbdedba2 100644 --- a/packages/validate/lib/server.dart +++ b/packages/validate/lib/server.dart @@ -55,17 +55,19 @@ RequestHandler validate(Validator validator, {String errorMessage = 'Invalid data.'}) { return (RequestContext req, res) async { await req.parseBody(); - var result = await asyncApplyValidator(validator, req.bodyAsMap, req.app); + var app = req.app; + if (app != null) { + var result = await asyncApplyValidator(validator, req.bodyAsMap, app); - if (result.errors.isNotEmpty) { - throw AngelHttpException.badRequest( - message: errorMessage, errors: result.errors); + if (result.errors.isNotEmpty) { + throw AngelHttpException.badRequest( + message: errorMessage, errors: result.errors); + } + + req.bodyAsMap + ..clear() + ..addAll(result.data); } - - req.bodyAsMap - ..clear() - ..addAll(result.data); - return true; }; } @@ -75,18 +77,20 @@ RequestHandler validate(Validator validator, RequestHandler validateQuery(Validator validator, {String errorMessage = 'Invalid data.'}) { return (RequestContext req, res) async { - var result = - await asyncApplyValidator(validator, req.queryParameters, req.app); + var app = req.app; + if (app != null) { + var result = + await asyncApplyValidator(validator, req.queryParameters, app); - if (result.errors.isNotEmpty) { - throw AngelHttpException.badRequest( - message: errorMessage, errors: result.errors); + if (result.errors.isNotEmpty) { + throw AngelHttpException.badRequest( + message: errorMessage, errors: result.errors); + } + + req.queryParameters + ..clear() + ..addAll(result.data); } - - req.queryParameters - ..clear() - ..addAll(result.data); - return true; }; } @@ -96,17 +100,19 @@ RequestHandler validateQuery(Validator validator, HookedServiceEventListener validateEvent(Validator validator, {String errorMessage = 'Invalid data.'}) { return (HookedServiceEvent e) async { - var result = await asyncApplyValidator( - validator, e.data as Map, (e.request?.app ?? e.service.app)); + var app = e.request?.app ?? e.service.app; + if (app != null) { + var result = await asyncApplyValidator(validator, e.data as Map, app); - if (result.errors.isNotEmpty) { - throw AngelHttpException.badRequest( - message: errorMessage, errors: result.errors); + if (result.errors.isNotEmpty) { + throw AngelHttpException.badRequest( + message: errorMessage, errors: result.errors); + } + + e.data + ..clear() + ..addAll(result.data); } - - e.data - ..clear() - ..addAll(result.data); }; } @@ -122,7 +128,7 @@ Future asyncApplyValidator( var value = result.data[key]; var description = StringDescription("'$key': expected "); - for (var rule in validator.rules[key]) { + for (var rule in validator.rules[key]!) { if (rule is AngelMatcher) { var r = await rule.matchesWithAngel(value, key, result.data, {}, app); diff --git a/packages/validate/lib/src/async.dart b/packages/validate/lib/src/async.dart index 11099fb2..a45bdd92 100644 --- a/packages/validate/lib/src/async.dart +++ b/packages/validate/lib/src/async.dart @@ -56,7 +56,7 @@ AngelMatcher matchAsync(FutureOr Function(String, Object) matcher, /// Returns an [AngelMatcher] that verifies that an item with the given [idField] /// exists in the service at [servicePath], without throwing a `404` or returning `null`. AngelMatcher idExistsInService(String servicePath, - {String idField = 'id', String description}) { + {String idField = 'id', String? description}) { return predicateWithAngel( (key, item, app) async { try { @@ -108,14 +108,13 @@ class _MatchWithAngel extends AngelMatcher { _MatchWithAngel(this.f, this.description); @override - Description describe(Description description) => this.description == null - ? description - : description.add(this.description); + Description describe(Description description) => + description.add(this.description); @override Future matchesWithAngel( item, String key, Map context, Map matchState, Angel app) { - return Future.sync(() => f(item, context, app)).then((result) { + return Future.sync(() => f(item as Object, context, app)).then((result) { return result.matches(item, matchState); }); } @@ -128,14 +127,13 @@ class _PredicateWithAngel extends AngelMatcher { _PredicateWithAngel(this.predicate, this.description); @override - Description describe(Description description) => this.description == null - ? description - : description.add(this.description); + Description describe(Description description) => + description.add(this.description); @override Future matchesWithAngel( item, String key, Map context, Map matchState, Angel app) { - return Future.sync(() => predicate(key, item, app)); + return Future.sync(() => predicate(key, item as Object, app)); } } @@ -147,15 +145,14 @@ class _MatchAsync extends AngelMatcher { _MatchAsync(this.matcher, this.feature, this.description); @override - Description describe(Description description) => this.description == null - ? description - : description.add(this.description); + Description describe(Description description) => + description.add(this.description); @override Future matchesWithAngel( item, String key, Map context, Map matchState, Angel app) async { var f = await feature(); - var m = await matcher(key, f); + var m = await matcher(key, f as Object); var c = wrapAngelMatcher(m); return await c.matchesWithAngel(item, key, context, matchState, app); } diff --git a/packages/validate/lib/src/context_aware.dart b/packages/validate/lib/src/context_aware.dart index d9d3de61..82dece04 100644 --- a/packages/validate/lib/src/context_aware.dart +++ b/packages/validate/lib/src/context_aware.dart @@ -44,10 +44,9 @@ class _PredicateWithContext extends ContextAwareMatcher { _PredicateWithContext(this.f, this.desc); @override - Description describe(Description description) => - desc == null ? description : description.add(desc); + Description describe(Description description) => description.add(desc); @override bool matchesWithContext(item, String key, Map context, Map matchState) => - f(item, key, context, matchState); + f(item as Object, key, context, matchState); } diff --git a/packages/validate/lib/src/matchers.dart b/packages/validate/lib/src/matchers.dart index 3a6c7be0..6870d70b 100644 --- a/packages/validate/lib/src/matchers.dart +++ b/packages/validate/lib/src/matchers.dart @@ -11,34 +11,36 @@ final RegExp _url = RegExp( /// Asserts that a `String` is alphanumeric, but also lets it contain dashes or underscores. final Matcher isAlphaDash = predicate( - (value) => value is String && _alphaDash.hasMatch(value), + (dynamic value) => value is String && _alphaDash.hasMatch(value), 'alphanumeric (dashes and underscores are allowed)'); /// Asserts that a `String` is alphanumeric, but also lets it contain dashes or underscores. /// final Matcher isAlphaNum = predicate( - (value) => value is String && _alphaNum.hasMatch(value), 'alphanumeric'); + (dynamic value) => value is String && _alphaNum.hasMatch(value), + 'alphanumeric'); /// Asserts that a value either equals `true` or `false`. -final Matcher isBool = predicate((value) => value is bool, 'a bool'); +final Matcher isBool = predicate((dynamic value) => value is bool, 'a bool'); /// Asserts that a `String` complies to the RFC 5322 e-mail standard. final Matcher isEmail = predicate( - (value) => value is String && _email.hasMatch(value), + (dynamic value) => value is String && _email.hasMatch(value), 'a valid e-mail address'); /// Asserts that a value is an `int`. -final Matcher isInt = predicate((value) => value is int, 'an integer'); +final Matcher isInt = predicate((dynamic value) => value is int, 'an integer'); /// Asserts that a value is a `num`. -final Matcher isNum = predicate((value) => value is num, 'a number'); +final Matcher isNum = predicate((dynamic value) => value is num, 'a number'); /// Asserts that a value is a `String`. -final Matcher isString = predicate((value) => value is String, 'a string'); +final Matcher isString = + predicate((dynamic value) => value is String, 'a string'); /// Asserts that a value is a non-empty `String`. final Matcher isNonEmptyString = predicate( - (value) => value is String && value.trim().isNotEmpty, + (dynamic value) => value is String && value.trim().isNotEmpty, 'a non-empty string'); /// Asserts that a value, presumably from a checkbox, is positive. @@ -47,9 +49,9 @@ final Matcher isChecked = /// Ensures that a string is an ISO-8601 date string. final Matcher isIso8601DateString = predicate( - (x) { + (dynamic x) { try { - return x is String && DateTime.parse(x) != null; + return x is String; } catch (_) { return false; } @@ -64,7 +66,7 @@ final Matcher isIso8601DateString = predicate( /// https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*) /// ``` final Matcher isUrl = predicate( - (value) => value is String && _url.hasMatch(value), + (dynamic value) => value is String && _url.hasMatch(value), 'a valid url, starting with http:// or https://'); /// Use [isUrl] instead. @@ -73,12 +75,12 @@ final Matcher isurl = isUrl; /// Enforces a minimum length on a string. Matcher minLength(int length) => predicate( - (value) => value is String && value.length >= length, + (dynamic value) => value is String && value.length >= length, 'a string at least $length character(s) long'); /// Limits the maximum length of a string. Matcher maxLength(int length) => predicate( - (value) => value is String && value.length <= length, + (dynamic value) => value is String && value.length <= length, 'a string no longer than $length character(s) long'); /// Asserts that for a key `x`, the context contains an identical item `x_confirmed`. diff --git a/packages/validate/lib/src/validator.dart b/packages/validate/lib/src/validator.dart index 5b524e6e..6faa8dfd 100644 --- a/packages/validate/lib/src/validator.dart +++ b/packages/validate/lib/src/validator.dart @@ -8,17 +8,17 @@ final RegExp _forbidden = RegExp(r'!$'); final RegExp _optional = RegExp(r'\?$'); /// Returns a value based the result of a computation. -typedef DefaultValueFunction(); +typedef DefaultValueFunction = Function(); /// Generates an error message based on the given input. -typedef String CustomErrorMessageFunction(item); +typedef CustomErrorMessageFunction = String Function(dynamic item); /// Determines if a value is valid. -typedef bool Filter(value); +typedef Filter = bool Function(dynamic value); /// Converts the desired fields to their numeric representations, if present. Map autoParse(Map inputData, Iterable fields) { - Map data = {}; + var data = {}; for (var key in inputData.keys) { if (!fields.contains(key)) { @@ -83,7 +83,7 @@ class Validator extends Matcher { schema[keys] is Iterable ? schema[keys] : [schema[keys]]; var iterable = []; - _addTo(x) { + void _addTo(x) { if (x is Iterable) { x.forEach(_addTo); } else { @@ -111,8 +111,8 @@ class Validator extends Matcher { Validator(Map schema, {Map defaultValues = const {}, Map customErrorMessages = const {}}) { - this.defaultValues.addAll(defaultValues ?? {}); - this.customErrorMessages.addAll(customErrorMessages ?? {}); + this.defaultValues.addAll(defaultValues); + this.customErrorMessages.addAll(customErrorMessages); _importSchema(schema); } @@ -121,18 +121,18 @@ class Validator extends Matcher { /// Validates, and filters input data. ValidationResult check(Map inputData) { - List errors = []; + var errors = []; var input = Map.from(inputData); - Map data = {}; + var data = {}; - for (String key in defaultValues.keys) { + for (var key in defaultValues.keys) { if (!input.containsKey(key)) { var value = defaultValues[key]; input[key] = value is DefaultValueFunction ? value() : value; } } - for (String field in forbiddenFields) { + for (var field in forbiddenFields) { if (input.containsKey(field)) { if (!customErrorMessages.containsKey(field)) { errors.add("'$field' is forbidden."); @@ -142,7 +142,7 @@ class Validator extends Matcher { } } - for (String field in requiredFields) { + for (var field in requiredFields) { if (!_hasContextValidators(rules[field] ?? [])) { if (!input.containsKey(field)) { if (!customErrorMessages.containsKey(field)) { @@ -162,7 +162,7 @@ class Validator extends Matcher { var value = input[key]; var description = StringDescription("'$key': expected "); - for (var matcher in rules[key]) { + for (var matcher in rules[key]!) { if (matcher is ContextValidator) { if (!matcher.validate(key, input)) { errors.add(matcher @@ -175,7 +175,7 @@ class Validator extends Matcher { } if (valid) { - for (Matcher matcher in rules[key]) { + for (var matcher in rules[key]!) { try { if (matcher is Validator) { var result = matcher.check(value as Map); @@ -271,12 +271,12 @@ class Validator extends Matcher { {Map defaultValues = const {}, Map customErrorMessages = const {}, bool overwrite = false}) { - Map _schema = {}; + var _schema = {}; var child = Validator.empty() ..defaultValues.addAll(this.defaultValues) - ..defaultValues.addAll(defaultValues ?? {}) + ..defaultValues.addAll(defaultValues) ..customErrorMessages.addAll(this.customErrorMessages) - ..customErrorMessages.addAll(customErrorMessages ?? {}) + ..customErrorMessages.addAll(customErrorMessages) ..requiredFields.addAll(requiredFields) ..rules.addAll(rules); @@ -320,7 +320,7 @@ class Validator extends Matcher { return; } - rules[key].add(rule); + rules[key]!.add(rule); } /// Adds all given [rules]. @@ -331,7 +331,7 @@ class Validator extends Matcher { /// Removes a [rule]. void removeRule(String key, Matcher rule) { if (rules.containsKey(key)) { - rules[key].remove(rule); + rules[key]!.remove(rule); } } @@ -377,17 +377,19 @@ class ValidationResult { /// Occurs when user-provided data is invalid. class ValidationException extends AngelHttpException { /// A list of errors that resulted in the given data being marked invalid. + @override final List errors = []; /// A descriptive message describing the error. + @override final String message; ValidationException(this.message, {Iterable errors = const []}) : super(FormatException(message), statusCode: 400, - errors: (errors ?? []).toSet().toList(), + errors: (errors).toSet().toList(), stackTrace: StackTrace.current) { - if (errors != null) this.errors.addAll(errors.toSet()); + this.errors.addAll(errors.toSet()); } @override @@ -400,8 +402,10 @@ class ValidationException extends AngelHttpException { return 'Validation error: ${errors.first}'; } - var messages = ['${errors.length} validation errors:\n'] - ..addAll(errors.map((error) => '* $error')); + var messages = [ + '${errors.length} validation errors:\n', + ...errors.map((error) => '* $error') + ]; return messages.join('\n'); } diff --git a/packages/validate/pubspec.yaml b/packages/validate/pubspec.yaml index 73ae22b0..0998cb7d 100644 --- a/packages/validate/pubspec.yaml +++ b/packages/validate/pubspec.yaml @@ -1,21 +1,21 @@ name: angel_validate description: Cross-platform request body validation library based on `matcher`. -version: 3.0.0 +version: 4.0.0 author: Tobe O homepage: https://github.com/angel-dart/validate publish_to: none environment: - sdk: ">=2.10.0 <3.0.0" + sdk: '>=2.12.0 <3.0.0' dependencies: angel_framework: git: url: https://github.com/dukefirehawk/angel.git - ref: sdk-2.12.x + ref: sdk-2.12.x_nnbd path: packages/framework angel_http_exception: git: url: https://github.com/dukefirehawk/angel.git - ref: sdk-2.12.x + ref: sdk-2.12.x_nnbd path: packages/http_exception matcher: ^0.12.0 dev_dependencies: @@ -26,7 +26,7 @@ dev_dependencies: # path: packages/test build_runner: ^1.11.1 build_web_compilers: ^2.12.2 -# logging: ^0.11.0 - mock_request: + # logging: ^0.11.0 + # mock_request: pedantic: ^1.0.0 test: ^1.15.7 \ No newline at end of file diff --git a/packages/validate/test/basic_test.dart b/packages/validate/test/basic_test.dart index 567696b2..ac415bcf 100644 --- a/packages/validate/test/basic_test.dart +++ b/packages/validate/test/basic_test.dart @@ -43,7 +43,7 @@ main() { test('comma in schema', () { expect(todoSchema.rules.keys, allOf(contains('foo'), contains('bar'))); - expect([todoSchema.rules['foo'].first, todoSchema.rules['bar'].first], - everyElement(predicate((x) => x == isTrue))); + expect([todoSchema.rules['foo']!.first, todoSchema.rules['bar']!.first], + everyElement(predicate((dynamic x) => x == isTrue))); }); } diff --git a/packages/validate/test/server_test.dart b/packages/validate/test/server_test.dart index 5852e766..0b32491b 100644 --- a/packages/validate/test/server_test.dart +++ b/packages/validate/test/server_test.dart @@ -18,21 +18,21 @@ void printRecord(LogRecord rec) { } void main() { - Angel app; - AngelHttp http; + Angel? app; + late AngelHttp http; //TestClient client; setUp(() async { app = Angel(); - http = AngelHttp(app, useZone: false); + http = AngelHttp(app!, useZone: false); - app.chain([validate(echoSchema)]).post('/echo', + app!.chain([validate(echoSchema)]).post('/echo', (RequestContext req, res) async { await req.parseBody(); res.write('Hello, ${req.bodyAsMap['message']}!'); }); - app.logger = Logger('angel')..onRecord.listen(printRecord); + app!.logger = Logger('angel')..onRecord.listen(printRecord); //client = await connectTo(app); }); diff --git a/packages/validate/web/main.dart b/packages/validate/web/main.dart index 20780fdf..92a52867 100644 --- a/packages/validate/web/main.dart +++ b/packages/validate/web/main.dart @@ -2,9 +2,9 @@ import 'dart:html'; import 'package:angel_validate/angel_validate.dart'; -final $errors = querySelector('#errors') as UListElement; -final $form = querySelector('#form') as FormElement; -final $blank = querySelector('[name="blank"]') as InputElement; +final $errors = querySelector('#errors') as UListElement?; +final $form = querySelector('#form') as FormElement?; +final $blank = querySelector('[name="blank"]') as InputElement?; final Validator formSchema = Validator({ 'firstName*': [isString, isNotEmpty], @@ -29,9 +29,9 @@ final Validator formSchema = Validator({ }); main() { - $form.onSubmit.listen((e) { + $form!.onSubmit.listen((e) { e.preventDefault(); - $errors.children.clear(); + $errors!.children.clear(); var formData = {}; @@ -39,7 +39,7 @@ main() { formData[key] = (querySelector('[name="$key"]') as InputElement).value; }); - if ($blank.value.isNotEmpty) formData['blank'] = $blank.value; + if ($blank!.value!.isNotEmpty) formData['blank'] = $blank!.value; print('Form data: $formData'); @@ -47,7 +47,7 @@ main() { var passportInfo = formSchema.enforceParsed(formData, ['age', 'familySize']); - $errors.children + $errors!.children ..add(success('Successfully registered for a passport.')) ..add(success('First Name: ${passportInfo["firstName"]}')) ..add(success('Last Name: ${passportInfo["lastName"]}')) @@ -55,7 +55,7 @@ main() { ..add(success( 'Number of People in Family: ${passportInfo["familySize"]}')); } on ValidationException catch (e) { - $errors.children.addAll(e.errors.map((error) { + $errors!.children.addAll(e.errors.map((error) { return LIElement()..text = error; })); }