From 15926ff45dc03af51b3c1a311970ac9cf5f31891 Mon Sep 17 00:00:00 2001 From: "thomashii@dukefirehawk.com" Date: Sun, 9 May 2021 19:16:15 +0800 Subject: [PATCH] Fixed null safety issues --- CHANGELOG.md | 2 +- packages/auth/lib/src/auth_token.dart | 11 +- packages/auth/lib/src/configuration.dart | 34 +++--- .../auth/lib/src/middleware/require_auth.dart | 28 +++-- packages/auth/lib/src/plugin.dart | 100 +++++++++--------- packages/auth/lib/src/strategies/local.dart | 23 ++-- packages/auth/pubspec.yaml | 5 + packages/auth/test/auth_token_test.dart | 16 +-- packages/auth/test/config_test.dart | 2 + packages/auth/test/local_test.dart | 11 +- packages/auth/test/protect_cookie_test.dart | 2 +- packages/combinator/example/basic_auth.dart | 2 +- packages/combinator/example/calculator.dart | 2 +- .../lib/src/combinator/advance.dart | 2 +- .../combinator/lib/src/combinator/any.dart | 2 +- .../combinator/lib/src/combinator/cache.dart | 4 +- .../combinator/lib/src/combinator/chain.dart | 20 ++-- .../combinator/lib/src/combinator/check.dart | 2 +- .../lib/src/combinator/combinator.dart | 38 ++++--- .../lib/src/combinator/compare.dart | 4 +- .../lib/src/combinator/fold_errors.dart | 2 +- .../combinator/lib/src/combinator/index.dart | 21 +++- .../lib/src/combinator/longest.dart | 8 +- .../combinator/lib/src/combinator/map.dart | 10 +- .../lib/src/combinator/max_depth.dart | 2 +- .../combinator/lib/src/combinator/negate.dart | 2 +- .../combinator/lib/src/combinator/opt.dart | 6 +- .../combinator/lib/src/combinator/reduce.dart | 4 +- .../lib/src/combinator/reference.dart | 4 +- .../combinator/lib/src/combinator/repeat.dart | 6 +- .../combinator/lib/src/combinator/safe.dart | 2 +- .../combinator/lib/src/combinator/value.dart | 4 +- packages/framework/lib/src/core/driver.dart | 4 +- .../lib/src/core/hostname_router.dart | 2 +- packages/framework/lib/src/core/routable.dart | 2 +- packages/framework/lib/src/core/server.dart | 6 +- packages/route/lib/browser.dart | 21 ++-- packages/route/lib/src/grammar.dart | 12 +-- .../route/lib/src/middleware_pipeline.dart | 6 +- packages/route/lib/src/router.dart | 6 +- packages/route/lib/src/routing_result.dart | 8 +- packages/route/pubspec.yaml | 1 + 42 files changed, 242 insertions(+), 207 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 551ca807..d3b48c93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ * Added merge_map and migrated to 2.0.0 (6/6 tests passed) * Added mock_request and migrated to 2.0.0 (0/0 tests) * Migrated angel_framework to 4.0.0 (146/149 tests passed) -* Migrated angel_auth to 4.0.0 (22/32 tests passed) +* Migrated angel_auth to 4.0.0 (21/30 tests passed) * Migrated angel_configuration to 4.0.0 (6/8 testspassed) * Migrated angel_validate to 4.0.0 (6/7 tests passed) * Migrated json_god to 4.0.0 (13/13 tests passed) diff --git a/packages/auth/lib/src/auth_token.dart b/packages/auth/lib/src/auth_token.dart index 8c6b9c9b..9da2e7d7 100644 --- a/packages/auth/lib/src/auth_token.dart +++ b/packages/auth/lib/src/auth_token.dart @@ -30,7 +30,7 @@ class AuthToken { String? ipAddress; late DateTime issuedAt; - num? lifeSpan; + num lifeSpan; var userId; Map payload = {}; @@ -41,12 +41,17 @@ class AuthToken { DateTime? issuedAt, Map payload = const {}}) { this.issuedAt = issuedAt ?? DateTime.now(); + this.payload.addAll(payload.keys + .fold({}, ((out, k) => out?..[k.toString()] = payload[k])) ?? + {}); + /* this.payload.addAll(payload.keys.fold( {}, ((out, k) => out..[k.toString()] = payload[k]) as Map? Function( Map?, dynamic)) ?? {}); + */ } factory AuthToken.fromJson(String jsons) => @@ -55,10 +60,10 @@ class AuthToken { factory AuthToken.fromMap(Map data) { return AuthToken( ipAddress: data['aud'].toString(), - lifeSpan: data['exp'] as num?, + lifeSpan: data['exp'] as num, issuedAt: DateTime.parse(data['iat'].toString()), userId: data['sub'], - payload: data['pld'] as Map? ?? {}); + payload: data['pld'] as Map); } factory AuthToken.parse(String jwt) { diff --git a/packages/auth/lib/src/configuration.dart b/packages/auth/lib/src/configuration.dart index d2529440..4f49e677 100644 --- a/packages/auth/lib/src/configuration.dart +++ b/packages/auth/lib/src/configuration.dart @@ -5,10 +5,10 @@ import 'package:quiver/core.dart'; /// A common class containing parsing and validation logic for third-party authentication configuration. class ExternalAuthOptions { /// The user's identifier, otherwise known as an "application id". - final String? clientId; + final String clientId; /// The user's secret, other known as an "application secret". - final String? clientSecret; + final String clientSecret; /// The user's redirect URI. final Uri redirectUri; @@ -17,17 +17,11 @@ class ExternalAuthOptions { final Set scopes; ExternalAuthOptions._( - this.clientId, this.clientSecret, this.redirectUri, this.scopes) { - if (clientId == null) { - throw ArgumentError.notNull('clientId'); - } else if (clientSecret == null) { - throw ArgumentError.notNull('clientSecret'); - } - } + this.clientId, this.clientSecret, this.redirectUri, this.scopes); factory ExternalAuthOptions( - {required String? clientId, - required String? clientSecret, + {required String clientId, + required String clientSecret, required redirectUri, Iterable scopes = const []}) { if (redirectUri is String) { @@ -50,8 +44,8 @@ class ExternalAuthOptions { /// * `redirect_uri` factory ExternalAuthOptions.fromMap(Map map) { return ExternalAuthOptions( - clientId: map['client_id'] as String?, - clientSecret: map['client_secret'] as String?, + clientId: map['client_id'] as String, + clientSecret: map['client_secret'] as String, redirectUri: map['redirect_uri'], scopes: map['scopes'] is Iterable ? ((map['scopes'] as Iterable).map((x) => x.toString())) @@ -72,15 +66,15 @@ class ExternalAuthOptions { /// Creates a copy of this object, with the specified changes. ExternalAuthOptions copyWith( - {String? clientId, - String? clientSecret, + {String clientId = '', + String clientSecret = '', redirectUri, - Iterable? scopes}) { + Iterable scopes = const []}) { return ExternalAuthOptions( - clientId: clientId ?? this.clientId, - clientSecret: clientSecret ?? this.clientSecret, + clientId: clientId, + clientSecret: clientSecret, redirectUri: redirectUri ?? this.redirectUri, - scopes: (scopes ??= []).followedBy(this.scopes), + scopes: (scopes).followedBy(this.scopes), ); } @@ -117,7 +111,7 @@ class ExternalAuthOptions { secret = clientSecret; } else { var codeUnits = - List.filled(asteriskCount ?? clientSecret!.length, $asterisk); + List.filled(asteriskCount ?? clientSecret.length, $asterisk); secret = String.fromCharCodes(codeUnits); } diff --git a/packages/auth/lib/src/middleware/require_auth.dart b/packages/auth/lib/src/middleware/require_auth.dart index 35b7c164..35bfa998 100644 --- a/packages/auth/lib/src/middleware/require_auth.dart +++ b/packages/auth/lib/src/middleware/require_auth.dart @@ -6,11 +6,14 @@ import 'package:angel_framework/angel_framework.dart'; /// [realm] defaults to `'angel_auth'`. RequestHandler forceBasicAuth({String? realm}) { return (RequestContext req, ResponseContext res) async { - if (req.container!.has()) { - return true; - } else if (req.container!.has>()) { - await req.container!.makeAsync(); - return true; + if (req.container != null) { + var reqContainer = req.container!; + if (reqContainer.has()) { + return true; + } else if (reqContainer.has>()) { + await reqContainer.makeAsync(); + return true; + } } res.headers['www-authenticate'] = 'Basic realm="${realm ?? 'angel_auth'}"'; @@ -31,11 +34,16 @@ RequestHandler requireAuthentication() { } } - if (req.container!.has() || req.method == 'OPTIONS') { - return true; - } else if (req.container!.has>()) { - await req.container!.makeAsync(); - return true; + if (req.container != null) { + var reqContainer = req.container!; + if (reqContainer.has() || req.method == 'OPTIONS') { + return true; + } else if (reqContainer.has>()) { + await reqContainer.makeAsync(); + return true; + } else { + return _reject(res); + } } else { return _reject(res); } diff --git a/packages/auth/lib/src/plugin.dart b/packages/auth/lib/src/plugin.dart index f09da924..0c39e944 100644 --- a/packages/auth/lib/src/plugin.dart +++ b/packages/auth/lib/src/plugin.dart @@ -1,6 +1,6 @@ import 'dart:async'; import 'dart:io'; -import 'dart:math' as Math; +import 'dart:math'; import 'package:angel_framework/angel_framework.dart'; import 'package:crypto/crypto.dart'; import 'auth_token.dart'; @@ -9,11 +9,11 @@ import 'strategy.dart'; /// Handles authentication within an Angel application. class AngelAuth { - Hmac? _hs256; - int? _jwtLifeSpan; - final StreamController _onLogin = StreamController(), + late Hmac _hs256; + late int _jwtLifeSpan; + final StreamController _onLogin = StreamController(), _onLogout = StreamController(); - final Math.Random _random = Math.Random.secure(); + final Random _random = Random.secure(); final RegExp _rgxBearer = RegExp(r'^Bearer'); /// If `true` (default), then JWT's will be stored and retrieved from a `token` cookie. @@ -51,23 +51,25 @@ class AngelAuth { FutureOr Function(User)? serializer; /// Deserializes a unique identifier into its associated identity. In most cases, this is a user object or model instance. - FutureOr Function(Object?)? deserializer; + FutureOr Function(Object)? deserializer; /// Fires the result of [deserializer] whenever a user signs in to the application. - Stream get onLogin => _onLogin.stream; + Stream get onLogin => _onLogin.stream; /// Fires `req.user`, which is usually the result of [deserializer], whenever a user signs out of the application. - Stream get onLogout => _onLogout.stream; + Stream get onLogout => _onLogout.stream; /// The [Hmac] being used to encode JWT's. - Hmac? get hmac => _hs256; + Hmac get hmac => _hs256; String _randomString( {int length = 32, String validChars = - "ABCDEFHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"}) { + 'ABCDEFHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_'}) { var chars = []; - while (chars.length < length) chars.add(_random.nextInt(validChars.length)); + while (chars.length < length) { + chars.add(_random.nextInt(validChars.length)); + } return String.fromCharCodes(chars); } @@ -83,7 +85,7 @@ class AngelAuth { this.cookieDomain, this.cookiePath = '/', this.secureCookies = true, - this.reviveTokenEndpoint = "/auth/token"}) + this.reviveTokenEndpoint = '/auth/token'}) : super() { _hs256 = Hmac(sha256, (jwtKey ?? _randomString()).codeUnits); _jwtLifeSpan = jwtLifeSpan?.toInt() ?? -1; @@ -110,7 +112,7 @@ class AngelAuth { app.container! .registerLazySingleton>>((container) async { var req = container.make()!; - var res = container.make(); + var res = container.make()!; var result = await _decodeJwt(req, res); if (result != null) { return result; @@ -148,8 +150,8 @@ class AngelAuth { req.container!.registerSingleton(token); } - if (allowCookie == true) { - _addProtectedCookie(res!, 'token', token.serialize(_hs256!)); + if (allowCookie) { + _addProtectedCookie(res!, 'token', token.serialize(_hs256)); } } @@ -185,29 +187,29 @@ class AngelAuth { } Future<_AuthResult?> _decodeJwt( - RequestContext req, ResponseContext? res) async { + RequestContext req, ResponseContext res) async { var jwt = getJwt(req); if (jwt != null) { - var token = AuthToken.validate(jwt, _hs256!); + var token = AuthToken.validate(jwt, _hs256); if (enforceIp) { if (req.ip != token.ipAddress) { throw AngelHttpException.forbidden( - message: "JWT cannot be accessed from this IP address."); + message: 'JWT cannot be accessed from this IP address.'); } } - if (token.lifeSpan! > -1) { + if (token.lifeSpan > -1) { var expiry = - token.issuedAt.add(Duration(milliseconds: token.lifeSpan!.toInt())); + token.issuedAt.add(Duration(milliseconds: token.lifeSpan.toInt())); if (!expiry.isAfter(DateTime.now())) { - throw AngelHttpException.forbidden(message: "Expired JWT."); + throw AngelHttpException.forbidden(message: 'Expired JWT.'); } } - var user = await deserializer!(token.userId); + var user = await deserializer!(token.userId as Object); _apply(req, res, token, user); return _AuthResult(user, token); } @@ -217,7 +219,7 @@ class AngelAuth { /// Retrieves a JWT from a request, if any was sent at all. String? getJwt(RequestContext req) { - if (req.headers!.value('Authorization') != null) { + if (req.headers?.value('Authorization') != null) { final authHeader = req.headers!.value('Authorization')!; // Allow Basic auth to fall through @@ -228,7 +230,7 @@ class AngelAuth { req.cookies.any((cookie) => cookie.name == 'token')) { return req.cookies.firstWhere((cookie) => cookie.name == 'token').value; } else if (allowTokenInQuery && - req.uri!.queryParameters['token'] is String) { + req.uri?.queryParameters['token'] is String) { return req.uri!.queryParameters['token']?.toString(); } @@ -248,10 +250,10 @@ class AngelAuth { cookie.secure = true; } - if (_jwtLifeSpan! > 0) { - cookie.maxAge ??= _jwtLifeSpan! < 0 ? -1 : _jwtLifeSpan! ~/ 1000; - cookie.expires ??= - DateTime.now().add(Duration(milliseconds: _jwtLifeSpan!)); + var lifeSpan = _jwtLifeSpan; + if (lifeSpan > 0) { + cookie.maxAge ??= lifeSpan < 0 ? -1 : lifeSpan ~/ 1000; + cookie.expires ??= DateTime.now().add(Duration(milliseconds: lifeSpan)); } cookie.domain ??= cookieDomain; @@ -270,19 +272,19 @@ class AngelAuth { jwt = body['token']?.toString(); } if (jwt == null) { - throw AngelHttpException.forbidden(message: "No JWT provided"); + throw AngelHttpException.forbidden(message: 'No JWT provided'); } else { - var token = AuthToken.validate(jwt, _hs256!); + var token = AuthToken.validate(jwt, _hs256); if (enforceIp) { if (req.ip != token.ipAddress) { throw AngelHttpException.forbidden( - message: "JWT cannot be accessed from this IP address."); + message: 'JWT cannot be accessed from this IP address.'); } } - if (token.lifeSpan! > -1) { + if (token.lifeSpan > -1) { var expiry = token.issuedAt - .add(Duration(milliseconds: token.lifeSpan!.toInt())); + .add(Duration(milliseconds: token.lifeSpan.toInt())); if (!expiry.isAfter(DateTime.now())) { //print( @@ -293,15 +295,15 @@ class AngelAuth { } if (allowCookie) { - _addProtectedCookie(res, 'token', token.serialize(_hs256!)); + _addProtectedCookie(res, 'token', token.serialize(_hs256)); } - final data = await deserializer!(token.userId); - return {'data': data, 'token': token.serialize(_hs256!)}; + final data = await deserializer!(token.userId as Object); + return {'data': data, 'token': token.serialize(_hs256)}; } } catch (e) { if (e is AngelHttpException) rethrow; - throw AngelHttpException.badRequest(message: "Malformed JWT"); + throw AngelHttpException.badRequest(message: 'Malformed JWT'); } } @@ -347,7 +349,7 @@ class AngelAuth { // Create JWT var token = AuthToken( userId: userId, lifeSpan: _jwtLifeSpan, ipAddress: req.ip); - var jwt = token.serialize(_hs256!); + var jwt = token.serialize(_hs256); if (options?.tokenCallback != null) { if (!req.container!.has()) { @@ -356,7 +358,7 @@ class AngelAuth { var r = await options!.tokenCallback!(req, res, token, result); if (r != null) return r; - jwt = token.serialize(_hs256!); + jwt = token.serialize(_hs256); } _apply(req, res, token, result); @@ -376,7 +378,7 @@ class AngelAuth { req.accepts('application/json')) { var user = hasExisting ? result - : await deserializer!(await serializer!(result)); + : await deserializer!((await serializer!(result)) as Object); _onLogin.add(user); return {"data": user, "token": jwt}; } @@ -402,38 +404,40 @@ class AngelAuth { /// Log a user in on-demand. Future login(AuthToken token, RequestContext req, ResponseContext res) async { - var user = await deserializer!(token.userId); + var user = await deserializer!(token.userId as Object); _apply(req, res, token, user); _onLogin.add(user); if (allowCookie) { - _addProtectedCookie(res, 'token', token.serialize(_hs256!)); + _addProtectedCookie(res, 'token', token.serialize(_hs256)); } } /// Log a user in on-demand. Future loginById(userId, RequestContext req, ResponseContext res) async { - var user = await deserializer!(userId); + var user = await deserializer!(userId as Object); var token = AuthToken(userId: userId, lifeSpan: _jwtLifeSpan, ipAddress: req.ip); _apply(req, res, token, user); _onLogin.add(user); if (allowCookie) { - _addProtectedCookie(res, 'token', token.serialize(_hs256!)); + _addProtectedCookie(res, 'token', token.serialize(_hs256)); } } /// Log an authenticated user out. RequestHandler logout([AngelAuthOptions? options]) { return (RequestContext req, ResponseContext res) async { - if (req.container!.has()) { - var user = req.container!.make(); - _onLogout.add(user); + if (req.container?.has() == true) { + var user = req.container?.make(); + if (user != null) { + _onLogout.add(user); + } } if (allowCookie == true) { - res.cookies.removeWhere((cookie) => cookie.name == "token"); + res.cookies.removeWhere((cookie) => cookie.name == 'token'); _addProtectedCookie(res, 'token', '""'); } diff --git a/packages/auth/lib/src/strategies/local.dart b/packages/auth/lib/src/strategies/local.dart index eb118512..4c0873d0 100644 --- a/packages/auth/lib/src/strategies/local.dart +++ b/packages/auth/lib/src/strategies/local.dart @@ -38,10 +38,13 @@ class LocalAuthStrategy extends AuthStrategy { User? verificationResult; if (allowBasic) { - var authHeader = req.headers!.value('authorization') ?? ''; + var authHeader = req.headers?.value('authorization') ?? ''; if (_rgxBasic.hasMatch(authHeader)) { - var base64AuthString = _rgxBasic.firstMatch(authHeader)!.group(1)!; + var base64AuthString = _rgxBasic.firstMatch(authHeader)?.group(1); + if (base64AuthString == null) { + return null; + } var authString = String.fromCharCodes(base64.decode(base64AuthString)); if (_rgxUsrPass.hasMatch(authString)) { Match usrPassMatch = _rgxUsrPass.firstMatch(authString)!; @@ -51,7 +54,7 @@ class LocalAuthStrategy extends AuthStrategy { throw AngelHttpException.badRequest(errors: [invalidMessage]); } - if (verificationResult == false || verificationResult == null) { + if (verificationResult == null) { res ..statusCode = 401 ..headers['www-authenticate'] = 'Basic realm="$realm"'; @@ -68,16 +71,16 @@ class LocalAuthStrategy extends AuthStrategy { .parseBody() .then((_) => req.bodyAsMap) .catchError((_) => {}); - if (body != null) { - if (_validateString(body[usernameField]?.toString()) && - _validateString(body[passwordField]?.toString())) { - verificationResult = await verifier( - body[usernameField]?.toString(), body[passwordField]?.toString()); - } + //if (body != null) { + if (_validateString(body[usernameField].toString()) && + _validateString(body[passwordField].toString())) { + verificationResult = await verifier( + body[usernameField].toString(), body[passwordField].toString()); } + //} } - if (verificationResult == false || verificationResult == null) { + if (verificationResult == null) { if (options.failureRedirect != null && options.failureRedirect!.isNotEmpty) { await res.redirect(options.failureRedirect, code: 401); diff --git a/packages/auth/pubspec.yaml b/packages/auth/pubspec.yaml index d7113fe0..e79c3e6b 100644 --- a/packages/auth/pubspec.yaml +++ b/packages/auth/pubspec.yaml @@ -7,6 +7,7 @@ environment: sdk: '>=2.12.0 <3.0.0' dependencies: angel_framework: +# path: ../framework git: url: https://github.com/dukefirehawk/angel.git ref: sdk-2.12.x_nnbd @@ -23,3 +24,7 @@ dev_dependencies: logging: ^1.0.0 pedantic: ^1.11.0 test: ^1.17.3 + +#dependency_overrides: +# angel_container: +# path: ../container/angel_container \ No newline at end of file diff --git a/packages/auth/test/auth_token_test.dart b/packages/auth/test/auth_token_test.dart index 7bdbf6b0..c677016e 100644 --- a/packages/auth/test/auth_token_test.dart +++ b/packages/auth/test/auth_token_test.dart @@ -1,12 +1,12 @@ -import "package:angel_auth/src/auth_token.dart"; -import "package:crypto/crypto.dart"; -import "package:test/test.dart"; +import 'package:angel_auth/src/auth_token.dart'; +import 'package:crypto/crypto.dart'; +import 'package:test/test.dart'; -main() async { - final Hmac hmac = Hmac(sha256, "angel_auth".codeUnits); +void main() async { + final hmac = Hmac(sha256, 'angel_auth'.codeUnits); - test("sample serialization", () { - var token = AuthToken(ipAddress: "localhost", userId: "thosakwe"); + test('sample serialization', () { + var token = AuthToken(ipAddress: 'localhost', userId: 'thosakwe'); var jwt = token.serialize(hmac); print(jwt); @@ -17,7 +17,7 @@ main() async { }); test('custom payload', () { - var token = AuthToken(ipAddress: "localhost", userId: "thosakwe", payload: { + var token = AuthToken(ipAddress: 'localhost', userId: 'thosakwe', payload: { "foo": "bar", "baz": { "one": 1, diff --git a/packages/auth/test/config_test.dart b/packages/auth/test/config_test.dart index e5b90ce8..14bab026 100644 --- a/packages/auth/test/config_test.dart +++ b/packages/auth/test/config_test.dart @@ -70,6 +70,7 @@ void main() { ); }); +/* Deprecated as clientId and clientSecret cannot be null test('ensures id not null', () { expect( () => ExternalAuthOptions( @@ -89,6 +90,7 @@ void main() { throwsArgumentError, ); }); + */ }); group('fromMap()', () { diff --git a/packages/auth/test/local_test.dart b/packages/auth/test/local_test.dart index 04e9c655..74d6a002 100644 --- a/packages/auth/test/local_test.dart +++ b/packages/auth/test/local_test.dart @@ -7,7 +7,7 @@ import 'package:http/http.dart' as http; import 'package:logging/logging.dart'; import 'package:test/test.dart'; -final AngelAuth?> auth = AngelAuth?>(); +final AngelAuth> auth = AngelAuth>(); var headers = {'accept': 'application/json'}; var localOpts = AngelAuthOptions>( failureRedirect: '/failure', successRedirect: '/success'); @@ -113,12 +113,13 @@ void main() async { auth.strategies.clear(); auth.strategies['local'] = LocalAuthStrategy(verifier, forceBasic: true, realm: 'test'); - var response = await client!.get(Uri.parse('$url/hello'), headers: { + var response = await client?.get(Uri.parse('$url/hello'), headers: { 'accept': 'application/json', 'content-type': 'application/json' }); - print(response.headers); - print('Body <${response.body}>'); - expect(response.headers['www-authenticate'], equals('Basic realm="test"')); + print('Header = ${response?.headers}'); + print('Body <${response?.body}>'); + var head = response?.headers['www-authenticate']; + expect(head, equals('Basic realm="test"')); }); } diff --git a/packages/auth/test/protect_cookie_test.dart b/packages/auth/test/protect_cookie_test.dart index 283af961..df42aff1 100644 --- a/packages/auth/test/protect_cookie_test.dart +++ b/packages/auth/test/protect_cookie_test.dart @@ -3,7 +3,7 @@ import 'dart:io'; import 'package:angel_auth/angel_auth.dart'; import 'package:test/test.dart'; -const Duration threeDays = const Duration(days: 3); +const Duration threeDays = Duration(days: 3); void main() { late Cookie defaultCookie; diff --git a/packages/combinator/example/basic_auth.dart b/packages/combinator/example/basic_auth.dart index ec3784a8..67cd8e7a 100644 --- a/packages/combinator/example/basic_auth.dart +++ b/packages/combinator/example/basic_auth.dart @@ -18,7 +18,7 @@ final Parser> credentials = chain([ match(':'), string.opt(), ]).map>( - (r) => {'username': r.value![0], 'password': r.value![2]}); + (r) => {'username': r.value![0]!, 'password': r.value![2]!}); /// We can actually embed a parser within another parser. /// diff --git a/packages/combinator/example/calculator.dart b/packages/combinator/example/calculator.dart index 7f8607b7..d3074509 100644 --- a/packages/combinator/example/calculator.dart +++ b/packages/combinator/example/calculator.dart @@ -24,7 +24,7 @@ Parser calculatorGrammar() { expr.space(), match(op).space() as Parser, expr.space(), - ]).map((r) => f(r.value![0], r.value![2])), + ]).map((r) => f(r.value![0]!, r.value![2]!)), ); } diff --git a/packages/combinator/lib/src/combinator/advance.dart b/packages/combinator/lib/src/combinator/advance.dart index 01506dc2..e480123c 100644 --- a/packages/combinator/lib/src/combinator/advance.dart +++ b/packages/combinator/lib/src/combinator/advance.dart @@ -7,7 +7,7 @@ class _Advance extends Parser { _Advance(this.parser, this.amount); @override - ParseResult __parse(ParseArgs args) { + ParseResult __parse(ParseArgs args) { var result = parser._parse(args.increaseDepth()).change(parser: this); if (result.successful) args.scanner.position += amount; return result; diff --git a/packages/combinator/lib/src/combinator/any.dart b/packages/combinator/lib/src/combinator/any.dart index 616bf29d..f5511458 100644 --- a/packages/combinator/lib/src/combinator/any.dart +++ b/packages/combinator/lib/src/combinator/any.dart @@ -21,7 +21,7 @@ class _Any extends Parser { _Any(this.parsers, this.backtrack, this.errorMessage, this.severity); @override - ParseResult _parse(ParseArgs args) { + ParseResult _parse(ParseArgs args) { var inactive = parsers .where((p) => !args.trampoline.isActive(p, args.scanner.position)); diff --git a/packages/combinator/lib/src/combinator/cache.dart b/packages/combinator/lib/src/combinator/cache.dart index b07b38e0..309a4c24 100644 --- a/packages/combinator/lib/src/combinator/cache.dart +++ b/packages/combinator/lib/src/combinator/cache.dart @@ -1,13 +1,13 @@ part of lex.src.combinator; class _Cache extends Parser { - final Map> _cache = {}; + final Map> _cache = {}; final Parser parser; _Cache(this.parser); @override - ParseResult __parse(ParseArgs args) { + ParseResult __parse(ParseArgs args) { return _cache.putIfAbsent(args.scanner.position, () { return parser._parse(args.increaseDepth()); }).change(parser: this); diff --git a/packages/combinator/lib/src/combinator/chain.dart b/packages/combinator/lib/src/combinator/chain.dart index c7d094aa..be07fa59 100644 --- a/packages/combinator/lib/src/combinator/chain.dart +++ b/packages/combinator/lib/src/combinator/chain.dart @@ -3,9 +3,9 @@ part of lex.src.combinator; /// Expects to parse a sequence of [parsers]. /// /// If [failFast] is `true` (default), then the first failure to parse will abort the parse. -ListParser chain(Iterable> parsers, +ListParser chain(Iterable> parsers, {bool failFast: true, SyntaxErrorSeverity? severity}) { - return _Chain( + return _Chain( parsers, failFast != false, severity ?? SyntaxErrorSeverity.error); } @@ -17,7 +17,7 @@ class _Alt extends Parser { _Alt(this.parser, this.errorMessage, this.severity); @override - ParseResult __parse(ParseArgs args) { + ParseResult __parse(ParseArgs args) { var result = parser._parse(args.increaseDepth()); return result.successful ? result @@ -33,7 +33,7 @@ class _Alt extends Parser { } } -class _Chain extends ListParser { +class _Chain extends ListParser { final Iterable> parsers; final bool failFast; final SyntaxErrorSeverity severity; @@ -41,9 +41,9 @@ class _Chain extends ListParser { _Chain(this.parsers, this.failFast, this.severity); @override - ParseResult> __parse(ParseArgs args) { + ParseResult?> __parse(ParseArgs args) { var errors = []; - var results = []; + var results = []; var spans = []; bool successful = true; @@ -61,9 +61,7 @@ class _Chain extends ListParser { successful = false; } - if (result.value != null) { - results.add(result.value!); - } + results.add(result.value); if (result.span != null) { spans.add(result.span!); @@ -76,14 +74,14 @@ class _Chain extends ListParser { span = spans.reduce((a, b) => a.expand(b)); } - return ParseResult>( + return ParseResult?>( args.trampoline, args.scanner, this, successful, errors, span: span, - value: List.unmodifiable(results), + value: List.unmodifiable(results), ); } diff --git a/packages/combinator/lib/src/combinator/check.dart b/packages/combinator/lib/src/combinator/check.dart index c15d7051..a87d5f69 100644 --- a/packages/combinator/lib/src/combinator/check.dart +++ b/packages/combinator/lib/src/combinator/check.dart @@ -9,7 +9,7 @@ class _Check extends Parser { _Check(this.parser, this.matcher, this.errorMessage, this.severity); @override - ParseResult __parse(ParseArgs args) { + ParseResult __parse(ParseArgs args) { var matchState = {}; var result = parser._parse(args.increaseDepth()).change(parser: this); if (!result.successful) diff --git a/packages/combinator/lib/src/combinator/combinator.dart b/packages/combinator/lib/src/combinator/combinator.dart index 4511467a..f50df785 100644 --- a/packages/combinator/lib/src/combinator/combinator.dart +++ b/packages/combinator/lib/src/combinator/combinator.dart @@ -67,9 +67,9 @@ class ParseArgs { /// A parser combinator, which can parse very complicated grammars in a manageable manner. abstract class Parser { - ParseResult __parse(ParseArgs args); + ParseResult __parse(ParseArgs args); - ParseResult _parse(ParseArgs args) { + ParseResult _parse(ParseArgs args) { var pos = args.scanner.position; if (args.trampoline.hasMemoized(this, pos)) @@ -86,7 +86,7 @@ abstract class Parser { } /// Parses text from a [SpanScanner]. - ParseResult parse(SpanScanner scanner, [int depth = 1]) { + ParseResult parse(SpanScanner scanner, [int depth = 1]) { var args = ParseArgs(Trampoline(), scanner, depth); return _parse(args); } @@ -105,7 +105,7 @@ abstract class Parser { // TODO: Type issue /// Runs the given function, which changes the returned [ParseResult] into one relating to a [U] object. - Parser change(ParseResult Function(ParseResult) f) { + Parser change(ParseResult Function(ParseResult) f) { return _Change(this, f); } @@ -128,7 +128,7 @@ abstract class Parser { } /// Transforms the parse result using a unary function. - Parser map(U Function(ParseResult) f) { + Parser map(U Function(ParseResult) f) { return _Map(this, f); } @@ -192,20 +192,18 @@ abstract class Parser { Parser> separatedBy(Parser other) { var suffix = other.then(this).index(1).cast(); return this.then(suffix.star()).map((r) { - List? v = r.value; - if (v != null) { - var preceding = - v.isEmpty ? [] : (r.value?[0] == null ? [] : [r.value?[0]]); - var out = List.from(preceding); - if (r.value?[1] != null) { - r.value?[1].forEach((element) { - out.add(element as T); - }); - } - return out; - } else { - return List.empty(growable: true); + var v = r.value; + if (v == null || v.length < 2) { + return []; } + var preceding = v.isEmpty ? [] : (v[0] == null ? [] : [v[0]]); + var out = List.from(preceding); + if (v[1] != null) { + v[1].forEach((element) { + out.add(element as T); + }); + } + return out; }); } @@ -278,7 +276,7 @@ abstract class Parser { Parser opt({bool backtrack: true}) => _Opt(this, backtrack); /// Sets the value of the [ParseResult]. - Parser value(T Function(ParseResult) f) { + Parser value(T Function(ParseResult) f) { return _Value(this, f); } @@ -379,7 +377,7 @@ class ParseResult { scanner, parser ?? this.parser, successful ?? this.successful, - errors, + errors.isNotEmpty ? errors : this.errors, span: span ?? this.span, value: value ?? this.value, ); diff --git a/packages/combinator/lib/src/combinator/compare.dart b/packages/combinator/lib/src/combinator/compare.dart index 4ee0b813..b26e719c 100644 --- a/packages/combinator/lib/src/combinator/compare.dart +++ b/packages/combinator/lib/src/combinator/compare.dart @@ -7,8 +7,8 @@ class _Compare extends ListParser { _Compare(this.parser, this.compare); @override - ParseResult> __parse(ParseArgs args) { - ParseResult> result = parser._parse(args.increaseDepth()); + ParseResult?> __parse(ParseArgs args) { + ParseResult?> result = parser._parse(args.increaseDepth()); if (!result.successful) return result; result = result.change( diff --git a/packages/combinator/lib/src/combinator/fold_errors.dart b/packages/combinator/lib/src/combinator/fold_errors.dart index 6d15c69a..6d3be765 100644 --- a/packages/combinator/lib/src/combinator/fold_errors.dart +++ b/packages/combinator/lib/src/combinator/fold_errors.dart @@ -7,7 +7,7 @@ class _FoldErrors extends Parser { _FoldErrors(this.parser, this.equal); @override - ParseResult __parse(ParseArgs args) { + ParseResult __parse(ParseArgs args) { var result = parser._parse(args.increaseDepth()).change(parser: this); var errors = result.errors.fold>([], (out, e) { if (!out.any((b) => equal(e, b))) out.add(e); diff --git a/packages/combinator/lib/src/combinator/index.dart b/packages/combinator/lib/src/combinator/index.dart index 89a6177c..a92561e7 100644 --- a/packages/combinator/lib/src/combinator/index.dart +++ b/packages/combinator/lib/src/combinator/index.dart @@ -8,11 +8,26 @@ class _Index extends Parser { @override ParseResult __parse(ParseArgs args) { - ParseResult> result = parser._parse(args.increaseDepth()); + ParseResult?> result = parser._parse(args.increaseDepth()); Object? value; - if (result.successful) - value = index == -1 ? result.value!.last : result.value!.elementAt(index); + if (result.successful) { + var vList = result.value; + if (vList == null) { + throw ArgumentError("ParseResult is null"); + } + if (index == -1) { + value = vList.last; + } else { + if (index < vList.length) { + //TODO: Look at this +// print(">>>>Index: $index, Size: ${vList.length}"); +// value = +// index == -1 ? result.value!.last : result.value!.elementAt(index); + value = result.value!.elementAt(index); + } + } + } return ParseResult( args.trampoline, diff --git a/packages/combinator/lib/src/combinator/longest.dart b/packages/combinator/lib/src/combinator/longest.dart index fa9124e7..65a907bc 100644 --- a/packages/combinator/lib/src/combinator/longest.dart +++ b/packages/combinator/lib/src/combinator/longest.dart @@ -16,7 +16,7 @@ class _Longest extends Parser { _Longest(this.parsers, this.errorMessage, this.severity); @override - ParseResult _parse(ParseArgs args) { + ParseResult _parse(ParseArgs args) { var inactive = parsers .toList() .where((p) => !args.trampoline.isActive(p, args.scanner.position)); @@ -27,7 +27,7 @@ class _Longest extends Parser { int replay = args.scanner.position; var errors = []; - var results = >[]; + var results = >[]; for (var parser in inactive) { var result = parser._parse(args.increaseDepth()); @@ -59,10 +59,10 @@ class _Longest extends Parser { } @override - ParseResult __parse(ParseArgs args) { + ParseResult __parse(ParseArgs args) { int replay = args.scanner.position; var errors = []; - var results = >[]; + var results = >[]; for (var parser in parsers) { var result = parser._parse(args.increaseDepth()); diff --git a/packages/combinator/lib/src/combinator/map.dart b/packages/combinator/lib/src/combinator/map.dart index 4dfb326d..638afbb6 100644 --- a/packages/combinator/lib/src/combinator/map.dart +++ b/packages/combinator/lib/src/combinator/map.dart @@ -2,14 +2,14 @@ part of lex.src.combinator; class _Map extends Parser { final Parser parser; - final U Function(ParseResult) f; + final U Function(ParseResult) f; _Map(this.parser, this.f); @override - ParseResult __parse(ParseArgs args) { + ParseResult __parse(ParseArgs args) { var result = parser._parse(args.increaseDepth()); - return ParseResult( + return ParseResult( args.trampoline, args.scanner, this, @@ -34,12 +34,12 @@ class _Map extends Parser { class _Change extends Parser { final Parser parser; - final ParseResult Function(ParseResult) f; + final ParseResult Function(ParseResult) f; _Change(this.parser, this.f); @override - ParseResult __parse(ParseArgs args) { + ParseResult __parse(ParseArgs args) { return f(parser._parse(args.increaseDepth())).change(parser: this); } diff --git a/packages/combinator/lib/src/combinator/max_depth.dart b/packages/combinator/lib/src/combinator/max_depth.dart index 42befcff..2475262c 100644 --- a/packages/combinator/lib/src/combinator/max_depth.dart +++ b/packages/combinator/lib/src/combinator/max_depth.dart @@ -7,7 +7,7 @@ class _MaxDepth extends Parser { _MaxDepth(this.parser, this.cap); @override - ParseResult __parse(ParseArgs args) { + ParseResult __parse(ParseArgs args) { if (args.depth > cap) { return ParseResult(args.trampoline, args.scanner, this, false, []); } diff --git a/packages/combinator/lib/src/combinator/negate.dart b/packages/combinator/lib/src/combinator/negate.dart index b507bdcc..bb956287 100644 --- a/packages/combinator/lib/src/combinator/negate.dart +++ b/packages/combinator/lib/src/combinator/negate.dart @@ -8,7 +8,7 @@ class _Negate extends Parser { _Negate(this.parser, this.errorMessage, this.severity); @override - ParseResult __parse(ParseArgs args) { + ParseResult __parse(ParseArgs args) { var result = parser._parse(args.increaseDepth()).change(parser: this); if (!result.successful) { diff --git a/packages/combinator/lib/src/combinator/opt.dart b/packages/combinator/lib/src/combinator/opt.dart index 12083ed7..dc1d7d15 100644 --- a/packages/combinator/lib/src/combinator/opt.dart +++ b/packages/combinator/lib/src/combinator/opt.dart @@ -7,7 +7,7 @@ class _Opt extends Parser { _Opt(this.parser, this.backtrack); @override - ParseResult __parse(ParseArgs args) { + ParseResult __parse(ParseArgs args) { var replay = args.scanner.position; var result = parser._parse(args.increaseDepth()); @@ -35,9 +35,9 @@ class _ListOpt extends ListParser { _ListOpt(this.parser, this.backtrack); @override - ParseResult> __parse(ParseArgs args) { + ParseResult?> __parse(ParseArgs args) { var replay = args.scanner.position; - ParseResult> result = parser._parse(args.increaseDepth()); + ParseResult?> result = parser._parse(args.increaseDepth()); if (!result.successful) args.scanner.position = replay; diff --git a/packages/combinator/lib/src/combinator/reduce.dart b/packages/combinator/lib/src/combinator/reduce.dart index 29f1f1f3..e14c6390 100644 --- a/packages/combinator/lib/src/combinator/reduce.dart +++ b/packages/combinator/lib/src/combinator/reduce.dart @@ -7,8 +7,8 @@ class _Reduce extends Parser { _Reduce(this.parser, this.combine); @override - ParseResult __parse(ParseArgs args) { - ParseResult> result = parser._parse(args.increaseDepth()); + ParseResult __parse(ParseArgs args) { + ParseResult?> result = parser._parse(args.increaseDepth()); if (!result.successful) return ParseResult( diff --git a/packages/combinator/lib/src/combinator/reference.dart b/packages/combinator/lib/src/combinator/reference.dart index 737b94d4..2c6a58be 100644 --- a/packages/combinator/lib/src/combinator/reference.dart +++ b/packages/combinator/lib/src/combinator/reference.dart @@ -15,14 +15,14 @@ class Reference extends Parser { } @override - ParseResult __parse(ParseArgs args) { + ParseResult __parse(ParseArgs args) { if (_parser == null) throw StateError('There is no parser assigned to this reference.'); return _parser!._parse(args); } @override - ParseResult _parse(ParseArgs args) { + ParseResult _parse(ParseArgs args) { if (_parser == null) throw StateError('There is no parser assigned to this reference.'); return _parser!._parse(args); diff --git a/packages/combinator/lib/src/combinator/repeat.dart b/packages/combinator/lib/src/combinator/repeat.dart index 2ee452bd..12ebb22a 100644 --- a/packages/combinator/lib/src/combinator/repeat.dart +++ b/packages/combinator/lib/src/combinator/repeat.dart @@ -12,12 +12,12 @@ class _Repeat extends ListParser { this.backtrack, this.severity); @override - ParseResult> __parse(ParseArgs args) { + ParseResult?> __parse(ParseArgs args) { var errors = []; var results = []; var spans = []; int success = 0, replay = args.scanner.position; - ParseResult? result; + ParseResult result; do { result = parser._parse(args.increaseDepth()); @@ -51,7 +51,7 @@ class _Repeat extends ListParser { } else if (success > count && exact) { if (backtrack) args.scanner.position = replay; - return ParseResult>(args.trampoline, args.scanner, this, false, [ + return ParseResult?>(args.trampoline, args.scanner, this, false, [ SyntaxError( severity, tooMany, diff --git a/packages/combinator/lib/src/combinator/safe.dart b/packages/combinator/lib/src/combinator/safe.dart index a2542295..35083120 100644 --- a/packages/combinator/lib/src/combinator/safe.dart +++ b/packages/combinator/lib/src/combinator/safe.dart @@ -10,7 +10,7 @@ class _Safe extends Parser { _Safe(this.parser, this.backtrack, this.errorMessage, this.severity); @override - ParseResult __parse(ParseArgs args) { + ParseResult __parse(ParseArgs args) { var replay = args.scanner.position; try { diff --git a/packages/combinator/lib/src/combinator/value.dart b/packages/combinator/lib/src/combinator/value.dart index b0612073..51fc9218 100644 --- a/packages/combinator/lib/src/combinator/value.dart +++ b/packages/combinator/lib/src/combinator/value.dart @@ -2,12 +2,12 @@ part of lex.src.combinator; class _Value extends Parser { final Parser parser; - final T Function(ParseResult) f; + final T Function(ParseResult) f; _Value(this.parser, this.f); @override - ParseResult __parse(ParseArgs args) { + ParseResult __parse(ParseArgs args) { var result = parser._parse(args.increaseDepth()).change(parser: this); return result.successful ? result.change(value: f(result)) : result; } diff --git a/packages/framework/lib/src/core/driver.dart b/packages/framework/lib/src/core/driver.dart index 15b71170..0cec0133 100644 --- a/packages/framework/lib/src/core/driver.dart +++ b/packages/framework/lib/src/core/driver.dart @@ -136,7 +136,7 @@ abstract class Driver< r.resolveAbsolute(path, method: req.method, strip: false); var pipeline = MiddlewarePipeline(resolved); return Tuple4( - pipeline.handlers!, + pipeline.handlers, resolved.fold>( {}, (out, r) => out..addAll(r.allParams)), (resolved.isEmpty ? null : resolved.first.parseResult)!, @@ -164,7 +164,7 @@ abstract class Driver< ..registerSingleton(tuple.item3); if (app.environment.isProduction && app.logger != null) { - req.container!.registerSingleton(Stopwatch()..start()); + req.container?.registerSingleton(Stopwatch()..start()); } return runPipeline(it, req, res, app) diff --git a/packages/framework/lib/src/core/hostname_router.dart b/packages/framework/lib/src/core/hostname_router.dart index 06cbe9be..16b28290 100644 --- a/packages/framework/lib/src/core/hostname_router.dart +++ b/packages/framework/lib/src/core/hostname_router.dart @@ -96,7 +96,7 @@ class HostnameRouter { var resolved = r.resolveAbsolute(req.path, method: req.method); var pipeline = MiddlewarePipeline(resolved); // print('Pipeline: $pipeline'); - for (var handler in pipeline.handlers!) { + for (var handler in pipeline.handlers) { // print(handler); // Avoid stack overflow. if (handler == handleRequest) { diff --git a/packages/framework/lib/src/core/routable.dart b/packages/framework/lib/src/core/routable.dart index 17ee7e57..a0f93e65 100644 --- a/packages/framework/lib/src/core/routable.dart +++ b/packages/framework/lib/src/core/routable.dart @@ -95,7 +95,7 @@ class Routable extends Router { @override Route addRoute( String method, String path, RequestHandler handler, - {Iterable? middleware}) { + {Iterable middleware = const {}}) { final handlers = []; // Merge @Middleware declaration, if any var reflector = _container?.reflector; diff --git a/packages/framework/lib/src/core/server.dart b/packages/framework/lib/src/core/server.dart index 24e4af51..ac328cc4 100644 --- a/packages/framework/lib/src/core/server.dart +++ b/packages/framework/lib/src/core/server.dart @@ -36,7 +36,7 @@ class Angel extends Routable { final List _children = []; final Map< String, - Tuple4, ParseResult?, + Tuple4, ParseResult, MiddlewarePipeline>> handlerCache = HashMap(); Router? _flattened; @@ -150,8 +150,8 @@ class Angel extends Routable { @override Route addRoute( String method, String path, RequestHandler handler, - {Iterable? middleware}) { - middleware ??= []; + {Iterable middleware = const []}) { + //middleware ??= []; if (_flattened != null) { logger?.warning( 'WARNING: You added a route ($method $path) to the router, after it had been optimized.'); diff --git a/packages/route/lib/browser.dart b/packages/route/lib/browser.dart index e73bc227..2ba3844d 100644 --- a/packages/route/lib/browser.dart +++ b/packages/route/lib/browser.dart @@ -11,10 +11,10 @@ final RegExp _straySlashes = RegExp(r'(^/+)|(/+$)'); /// A variation of the [Router] support both hash routing and push state. abstract class BrowserRouter extends Router { /// Fires whenever the active route changes. Fires `null` if none is selected (404). - Stream> get onResolve; + Stream> get onResolve; /// Fires whenever the active route changes. Fires `null` if none is selected (404). - Stream> get onRoute; + Stream> get onRoute; /// Set `hash` to true to use hash routing instead of push state. /// `listen` as `true` will call `listen` after initialization. @@ -48,17 +48,17 @@ abstract class _BrowserRouterImpl extends Router implements BrowserRouter { bool _listening = false; Route? _current; - final StreamController> _onResolve = - StreamController>(); - final StreamController> _onRoute = StreamController>(); + final StreamController> _onResolve = + StreamController>(); + final StreamController> _onRoute = StreamController>(); Route? get currentRoute => _current; @override - Stream> get onResolve => _onResolve.stream; + Stream> get onResolve => _onResolve.stream; @override - Stream> get onRoute => _onRoute.stream; + Stream> get onRoute => _onRoute.stream; _BrowserRouterImpl({bool listen = false}) : super() { if (listen != false) this.listen(); @@ -69,8 +69,7 @@ abstract class _BrowserRouterImpl extends Router void go(Iterable linkParams) => _goTo(navigate(linkParams)); @override - Route on(String path, T handler, - {Iterable middleware = const Iterable.empty()}) => + Route on(String path, T handler, {Iterable middleware = const []}) => all(path, handler, middleware: middleware); void prepareAnchors() { @@ -108,7 +107,9 @@ abstract class _BrowserRouterImpl extends Router class _HashRouter extends _BrowserRouterImpl { _HashRouter({required bool listen}) : super(listen: listen) { - if (listen) this.listen(); + if (listen) { + this.listen(); + } } @override diff --git a/packages/route/lib/src/grammar.dart b/packages/route/lib/src/grammar.dart index a0628056..59fab6ec 100644 --- a/packages/route/lib/src/grammar.dart +++ b/packages/route/lib/src/grammar.dart @@ -6,13 +6,13 @@ class RouteGrammar { static final Parser notSlash = match(RegExp(notSlashRgx)).value((r) => r.span?.text ?? ''); - static final Parser regExp = - match(RegExp(r'\(([^\n)]+)\)([^/]+)?')) - .value((r) => r.scanner.lastMatch); + static final Parser regExp = + match(RegExp(r'\(([^\n)]+)\)([^/]+)?')) + .value((r) => r.scanner.lastMatch!); - static final Parser parameterName = - match(RegExp('$notSlashRgx?' r':([A-Za-z0-9_]+)' r'([^(/\n])?')) - .value((r) => r.scanner.lastMatch); + static final Parser parameterName = + match(RegExp('$notSlashRgx?' r':([A-Za-z0-9_]+)' r'([^(/\n])?')) + .value((r) => r.scanner.lastMatch!); static final Parser parameterSegment = chain([ parameterName, diff --git a/packages/route/lib/src/middleware_pipeline.dart b/packages/route/lib/src/middleware_pipeline.dart index e4b68ee3..c5a4ad60 100644 --- a/packages/route/lib/src/middleware_pipeline.dart +++ b/packages/route/lib/src/middleware_pipeline.dart @@ -4,10 +4,10 @@ import 'router.dart'; class MiddlewarePipeline { /// All the possible routes that matched the given path. final Iterable> routingResults; - final List _handlers = []; + final List _handlers = []; /// An ordered list of every handler delegated to handle this request. - List get handlers { + List get handlers { /* if (_handlers != null) return _handlers; final handlers = []; @@ -19,7 +19,7 @@ class MiddlewarePipeline { return _handlers = handlers; */ - if (_handlers.isEmpty) { + if (_handlers.isNotEmpty) { return _handlers; } diff --git a/packages/route/lib/src/router.dart b/packages/route/lib/src/router.dart index 24d1da8c..e4f1cdb4 100644 --- a/packages/route/lib/src/router.dart +++ b/packages/route/lib/src/router.dart @@ -284,7 +284,7 @@ class Router { /// Finds the first [Route] that matches the given path, /// with the given method. - bool resolve(String absolute, String relative, List> out, + bool resolve(String absolute, String relative, List> out, {String method = 'GET', bool strip = true}) { final cleanRelative = strip == false ? relative : stripStraySlashes(relative); @@ -334,13 +334,13 @@ class Router { /// Returns the result of [resolve] with [path] passed as /// both `absolute` and `relative`. - Iterable> resolveAbsolute(String path, + Iterable> resolveAbsolute(String path, {String method = 'GET', bool strip = true}) => resolveAll(path, path, method: method, strip: strip); /// Finds every possible [Route] that matches the given path, /// with the given method. - Iterable> resolveAll(String absolute, String relative, + Iterable> resolveAll(String absolute, String relative, {String method = 'GET', bool strip = true}) { if (_useCache == true) { return _cache.putIfAbsent('$method$absolute', diff --git a/packages/route/lib/src/routing_result.dart b/packages/route/lib/src/routing_result.dart index 351d235b..e757d7f4 100644 --- a/packages/route/lib/src/routing_result.dart +++ b/packages/route/lib/src/routing_result.dart @@ -3,7 +3,7 @@ part of angel_route.src.router; /// Represents a complex result of navigating to a path. class RoutingResult { /// The parse result that matched the given sub-path. - final ParseResult parseResult; + final ParseResult parseResult; /// A nested instance, if a sub-path was matched. final Iterable> nested; @@ -47,10 +47,10 @@ class RoutingResult { } /// All handlers on this sub-path and its children. - List get allHandlers { - final handlers = []; + List get allHandlers { + final handlers = []; - void crawl(RoutingResult result) { + void crawl(RoutingResult result) { handlers.addAll(result.handlers); if (result.nested.isNotEmpty == true) { diff --git a/packages/route/pubspec.yaml b/packages/route/pubspec.yaml index b066b604..527a12bc 100644 --- a/packages/route/pubspec.yaml +++ b/packages/route/pubspec.yaml @@ -7,6 +7,7 @@ environment: sdk: '>=2.12.0 <3.0.0' dependencies: combinator: +# path: ../combinator git: url: https://github.com/dukefirehawk/angel.git ref: sdk-2.12.x_nnbd