diff --git a/packages/dox-core/lib/app.dart b/packages/dox-core/lib/app.dart index c090efa..15655ea 100644 --- a/packages/dox-core/lib/app.dart +++ b/packages/dox-core/lib/app.dart @@ -84,7 +84,7 @@ class Dox implements IDox { DoxServer().setResponseHandler(config.responseHandler); await DoxServer().listen(config.serverPort, isolateId: 1); - DoxLogger.info(sprintf( + Logger.info(sprintf( 'Server started at http://127.0.0.1:%s with $isolatesToSpawn isolate', [Dox().config.serverPort], )); diff --git a/packages/dox-core/lib/dox_core.dart b/packages/dox-core/lib/dox_core.dart index f942d38..8f0488e 100644 --- a/packages/dox-core/lib/dox_core.dart +++ b/packages/dox-core/lib/dox_core.dart @@ -11,7 +11,6 @@ export 'constants/constants.dart'; export 'env/env.dart'; /// Exceptions - export 'exception/internal_error_exception.dart'; export 'exception/not_found_exception.dart'; export 'exception/query_exception.dart'; @@ -29,15 +28,13 @@ export 'http/response/serializer.dart'; /// interfaces export 'interfaces/app_config.dart'; - -/// auth -export 'interfaces/dox_middleware.dart'; export 'interfaces/dox_service.dart'; export 'interfaces/response_handler_interface.dart'; export 'interfaces/router.dart'; /// Tools export 'ioc/ioc_container.dart'; +export 'middleware/log_middleware.dart'; /// Router export 'router/route.dart'; diff --git a/packages/dox-core/lib/env/env.dart b/packages/dox-core/lib/env/env.dart index f1198cb..9742ef6 100644 --- a/packages/dox-core/lib/env/env.dart +++ b/packages/dox-core/lib/env/env.dart @@ -23,13 +23,14 @@ class Env { /// Evn.get('APP_KEY', 'with_default_value_if_null'); /// Evn.get('PORT', 3000); (This will return int type) /// Evn.get('PORT', 3000); (This will return num type) - /// Evn.get('APP_KEY'); (This will return type String) - /// Current this function support String, int and num types. + /// Evn.get('APP_KEY'); (This will return String type) + /// Currently this function support String, int and num types. /// ``` static T get(String key, [dynamic defaultValue]) { String value = Env().env[key].toString(); - String val = - value.isEmpty || value.toLowerCase() == 'null' ? defaultValue : value; + String val = value.isEmpty || value.toLowerCase() == 'null' + ? defaultValue.toString() + : value; if (T.toString() == 'int') { return int.parse(val) as T; } diff --git a/packages/dox-core/lib/http/http_controller_handler.dart b/packages/dox-core/lib/http/http_controller_handler.dart index 8dc0082..a463963 100644 --- a/packages/dox-core/lib/http/http_controller_handler.dart +++ b/packages/dox-core/lib/http/http_controller_handler.dart @@ -22,7 +22,7 @@ Future middlewareAndControllerHandler(DoxRequest doxReq) async { /// DoxMiddleware class /// with handle function - if (fn is DoxMiddleware) { + if (fn is IDoxMiddleware) { result = await fn.handle(doxReq); } @@ -68,7 +68,7 @@ Future _handleController( FormRequest? formReq = Dox().ioc.getByName(requestName); if (formReq != null && _isFormRequestTypeMatched(fn, formReq)) { /// mapping request inputs field - doxRequest.mapInputs(formReq.mapInputs()); + doxRequest.processInputMapper(formReq.mapInputs()); /// setting dox request to custom form request formReq.setRequest(doxRequest); diff --git a/packages/dox-core/lib/http/http_cors_handler.dart b/packages/dox-core/lib/http/http_cors_handler.dart index 0935afc..6cf0686 100644 --- a/packages/dox-core/lib/http/http_cors_handler.dart +++ b/packages/dox-core/lib/http/http_cors_handler.dart @@ -2,20 +2,22 @@ import 'dart:io'; import 'package:dox_core/dox_core.dart'; -void httpCorsHandler(HttpRequest req) { +void httpCorsHandler(bool? enabled, HttpRequest req) { CORSConfig cors = Dox().config.cors; - - Map headers = { - HttpHeaders.accessControlAllowOriginHeader: cors.allowOrigin, - HttpHeaders.accessControlAllowMethodsHeader: cors.allowMethods, - HttpHeaders.accessControlAllowHeadersHeader: cors.allowHeaders, - HttpHeaders.accessControlExposeHeadersHeader: cors.exposeHeaders, - HttpHeaders.accessControlAllowCredentialsHeader: cors.allowCredentials, - }; - - headers.forEach((String key, dynamic value) { - _setCorsValue(req.response, key, value); - }); + if (enabled ?? cors.enabled) { + Map headers = { + HttpHeaders.accessControlAllowOriginHeader: cors.origin, + HttpHeaders.accessControlAllowMethodsHeader: cors.methods, + HttpHeaders.accessControlAllowHeadersHeader: cors.headers, + HttpHeaders.accessControlExposeHeadersHeader: cors.exposeHeaders, + HttpHeaders.accessControlAllowCredentialsHeader: cors.credentials, + HttpHeaders.accessControlMaxAgeHeader: cors.maxAge, + }; + + headers.forEach((String key, dynamic value) { + _setCorsValue(req.response, key, value); + }); + } } // set cors in header diff --git a/packages/dox-core/lib/http/http_request_handler.dart b/packages/dox-core/lib/http/http_request_handler.dart index f8cc8b7..630c6e4 100644 --- a/packages/dox-core/lib/http/http_request_handler.dart +++ b/packages/dox-core/lib/http/http_request_handler.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:dox_core/dox_core.dart'; import 'package:dox_core/http/http_controller_handler.dart'; +import 'package:dox_core/http/http_cors_handler.dart'; import 'package:dox_core/http/http_error_handler.dart'; import 'package:dox_core/http/http_response_handler.dart'; import 'package:dox_core/http/http_route_handler.dart'; @@ -17,6 +18,8 @@ void httpRequestHandler(HttpRequest req) { RouteData? route = httpRouteHandler(req); if (route == null) return; + httpCorsHandler(route.corsEnabled, req); + if (WebSocketTransformer.isUpgradeRequest(req)) { httpWebSocketHandler(req, route); return; diff --git a/packages/dox-core/lib/http/http_response_handler.dart b/packages/dox-core/lib/http/http_response_handler.dart index 812abb8..909777d 100644 --- a/packages/dox-core/lib/http/http_response_handler.dart +++ b/packages/dox-core/lib/http/http_response_handler.dart @@ -8,22 +8,35 @@ dynamic httpResponseHandler( dynamic payload, HttpRequest request, ) { - /// websocket handler will return websocket payload + /// Websocket handler will return websocket payload /// and in this case we need to remain the connection open for - /// websocket communication. so there is no `res.close()`; + /// websocket communication. So there is no `res.close()` required. if (payload is WebSocket) { return; } - /// if payload is DoxResponse, DoxResponse have process function + /// If there is responseHandler set, handle responseHandler + /// before DoxResponse process. The responseHandler will return + /// DoxResponse to process + ResponseHandlerInterface? customResponseHandler = DoxServer().responseHandler; + if (customResponseHandler != null) { + DoxResponse doxResponse = customResponseHandler + .handle(payload is DoxResponse ? payload : DoxResponse(payload)); + payload = doxResponse; + } + + /// If payload is DoxResponse, DoxResponse have process function /// which will set header and status code in the response - /// and will pass payload/content back to this function `httpResponseHandler` - /// where the payload is not DoxResponse anymore - /// so it will continue belows process + /// and will pass payload/content to `responseDataHandler` function. if (payload is DoxResponse) { - return payload.process(request); + payload.process(request); + return; } +} +/// Handle response for different types of data +/// such as string, stream, Model, List, encodable. +void responseDataHandler(dynamic payload, HttpRequest request) { HttpResponse res = request.response; if (payload == null) { @@ -38,6 +51,8 @@ dynamic httpResponseHandler( return; } + /// if payload is downloadable file, + /// we response contentDisposition header with stream data. if (payload is DownloadableFile) { res.headers.contentType = payload.contentType; res.headers.add(FILE_DOWNLOAD_HEADER, payload.contentDisposition); @@ -51,15 +66,6 @@ dynamic httpResponseHandler( return; } - /// if there is responseHandler we handle responseHandler and - /// get new payload and override existing payload - if (DoxServer().responseHandler != null) { - dynamic result = DoxServer().responseHandler?.handle(DoxResponse(payload)); - if (result != null) { - payload = result; - } - } - /// if payload handle base Http Exception /// we set http status from exception and return as map /// which will parse into json and response as json diff --git a/packages/dox-core/lib/http/http_route_handler.dart b/packages/dox-core/lib/http/http_route_handler.dart index bd52f63..cabc1f8 100644 --- a/packages/dox-core/lib/http/http_route_handler.dart +++ b/packages/dox-core/lib/http/http_route_handler.dart @@ -16,10 +16,10 @@ RouteData? httpRouteHandler(HttpRequest req) { if (route == null) { /// return 200 status on preflight OPTIONS Method if (req.method == HttpRequestMethod.OPTIONS.name) { - httpResponseHandler(null, req); + responseDataHandler(null, req); } else { req.response.statusCode = HttpStatus.notFound; - httpResponseHandler('${req.method} ${req.uri.path} not found', req); + responseDataHandler('${req.method} ${req.uri.path} not found', req); } } return route; diff --git a/packages/dox-core/lib/http/request/dox_request.dart b/packages/dox-core/lib/http/request/dox_request.dart index 4fda284..914adbc 100644 --- a/packages/dox-core/lib/http/request/dox_request.dart +++ b/packages/dox-core/lib/http/request/dox_request.dart @@ -1,3 +1,4 @@ +import 'dart:convert'; import 'dart:io'; import 'package:dox_core/dox_core.dart'; @@ -8,13 +9,20 @@ import 'package:dox_core/validation/dox_validator.dart'; class DoxRequest implements IDoxRequest { final RouteData route; - final Uri uri; - final ContentType? contentType; + final HttpHeaders httpHeaders; + + @override + final ContentType? contentType; + @override final HttpRequest httpRequest; + @override + late Uri uri; + final String? clientIp; + @override String method = 'GET'; @@ -41,6 +49,19 @@ class DoxRequest implements IDoxRequest { _getCookies(); } + /// get route identifier + @override + String getRouteIdentifier() { + return base64.encode( + utf8.encode('${route.method}|${route.domain ?? ''}${route.path}')); + } + + /// get route identifier + @override + RouteData getRouteData() { + return route; + } + /// http request data is form data @override bool isFormData() { @@ -232,9 +253,9 @@ class DoxRequest implements IDoxRequest { } } - /// map request input keys + /// map the request input keys @override - void mapInputs(Map mapper) { + void processInputMapper(Map mapper) { mapper.forEach((String from, String to) { if (from != to) { dynamic temp = _allRequest[from]; @@ -244,7 +265,8 @@ class DoxRequest implements IDoxRequest { }); } - /// support JSON.stringify to convert json + /// To support jsonEncode + @override Map toJson() { Map ret = {}; _allRequest.forEach((String key, dynamic value) { diff --git a/packages/dox-core/lib/http/request/http_request_body.dart b/packages/dox-core/lib/http/request/http_request_body.dart index 4604218..daf36b9 100644 --- a/packages/dox-core/lib/http/request/http_request_body.dart +++ b/packages/dox-core/lib/http/request/http_request_body.dart @@ -7,7 +7,11 @@ class HttpBody { static Future> read(HttpRequest request) async { if (HttpBody.isJson(request.headers.contentType)) { String bodyString = await utf8.decoder.bind(request).join(); - return jsonDecode(bodyString); + try { + return jsonDecode(bodyString); + } catch (err) { + return {}; + } } if (HttpBody.isFormData(request.headers.contentType)) { diff --git a/packages/dox-core/lib/http/response/dox_response.dart b/packages/dox-core/lib/http/response/dox_response.dart index 45c99b7..f15b01f 100644 --- a/packages/dox-core/lib/http/response/dox_response.dart +++ b/packages/dox-core/lib/http/response/dox_response.dart @@ -6,7 +6,7 @@ import 'package:dox_core/http/http_response_handler.dart'; class DoxResponse { /// content can be anything /// String, int, Map, json serializable object, Stream> - dynamic content; + dynamic _contentData; Map _headers = {}; int? _statusCode; @@ -16,16 +16,15 @@ class DoxResponse { /// content can be anything /// String, int, Map, json serializable object, Stream> - DoxResponse(this.content) { - if (content is StreamFile) { - _contentType = content.contentType; - content = content.stream; + DoxResponse(this._contentData) { + if (_contentData is StreamFile) { + _contentType = _contentData.contentType; } - if (content is DownloadableFile) { - header(FILE_DOWNLOAD_HEADER, content.contentDisposition); - _contentType = content.contentType; - content = content.stream; + if (_contentData is DownloadableFile) { + header(FILE_DOWNLOAD_HEADER, _contentData.contentDisposition); + _contentType = _contentData.contentType; + _contentData = _contentData.stream; } } @@ -38,8 +37,29 @@ class DoxResponse { return this; } + /// Set response status code default 200 + /// ``` + /// res.setContent({"foo": "bar"}); + /// ``` + DoxResponse content(dynamic content) { + _contentData = content; + return this; + } + + /// Get original content data + /// ``` + /// res.getContent(); + /// ``` + dynamic getContent() { + return _contentData; + } + + /// set stream data to response + /// ``` + /// res.stream(streamData); + /// ``` DoxResponse stream(Stream> stream) { - content = stream; + content(stream); return this; } @@ -103,7 +123,7 @@ class DoxResponse { for (String cookie in _cookies) { request.response.headers.add(HttpHeaders.setCookieHeader, cookie); } - return httpResponseHandler(content, request); + return responseDataHandler(_contentData, request); } } diff --git a/packages/dox-core/lib/interfaces/app_config.dart b/packages/dox-core/lib/interfaces/app_config.dart index c2bf1dc..d02a489 100644 --- a/packages/dox-core/lib/interfaces/app_config.dart +++ b/packages/dox-core/lib/interfaces/app_config.dart @@ -3,8 +3,8 @@ import 'package:dox_core/dox_core.dart'; import 'package:dox_core/utils/logger.dart'; void defaultErrorHandler(Object? error, StackTrace stackTrace) { - DoxLogger.warn(error); - DoxLogger.danger(stackTrace.toString()); + Logger.warn(error); + Logger.danger(stackTrace.toString()); } class AppConfig { @@ -19,6 +19,7 @@ class AppConfig { final CORSConfig cors; final CacheConfig cache; final FileStorageConfig fileStorage; + final LoggerConfig logger; final List services; AppConfig({ @@ -30,6 +31,7 @@ class AppConfig { this.globalMiddleware = const [], this.routers = const [], this.cors = const CORSConfig(), + this.logger = const LoggerConfig(), this.cache = const CacheConfig(), this.fileStorage = const FileStorageConfig(), this.errorHandler = defaultErrorHandler, @@ -38,18 +40,36 @@ class AppConfig { } class CORSConfig { - final dynamic allowOrigin; - final dynamic allowMethods; - final dynamic allowHeaders; + final bool enabled; + final dynamic origin; + final dynamic methods; + final dynamic headers; final dynamic exposeHeaders; - final bool? allowCredentials; + final bool? credentials; + final num? maxAge; const CORSConfig({ - this.allowOrigin, - this.allowMethods, - this.allowHeaders, + this.enabled = true, + this.origin, + this.methods, + this.headers, this.exposeHeaders, - this.allowCredentials, + this.credentials, + this.maxAge, + }); +} + +class LoggerConfig { + final String name; + final bool enabled; + final bool prettyPrint; + final String level; + + const LoggerConfig({ + this.name = '', + this.enabled = false, + this.prettyPrint = false, + this.level = 'info', }); } diff --git a/packages/dox-core/lib/interfaces/dox_middleware.dart b/packages/dox-core/lib/interfaces/dox_middleware.dart deleted file mode 100644 index 47d348d..0000000 --- a/packages/dox-core/lib/interfaces/dox_middleware.dart +++ /dev/null @@ -1,6 +0,0 @@ -/// coverage:ignore-file -import 'package:dox_core/dox_core.dart'; - -abstract class DoxMiddleware { - dynamic handle(DoxRequest req); -} diff --git a/packages/dox-core/lib/interfaces/response_handler_interface.dart b/packages/dox-core/lib/interfaces/response_handler_interface.dart index 4bbc3fb..859c048 100644 --- a/packages/dox-core/lib/interfaces/response_handler_interface.dart +++ b/packages/dox-core/lib/interfaces/response_handler_interface.dart @@ -3,5 +3,5 @@ import 'package:dox_core/dox_core.dart'; abstract class ResponseHandlerInterface { const ResponseHandlerInterface(); - dynamic handle(DoxResponse res); + DoxResponse handle(DoxResponse res); } diff --git a/packages/dox-core/lib/middleware/log_middleware.dart b/packages/dox-core/lib/middleware/log_middleware.dart index 5fc84b7..a4da926 100644 --- a/packages/dox-core/lib/middleware/log_middleware.dart +++ b/packages/dox-core/lib/middleware/log_middleware.dart @@ -1,30 +1,42 @@ import 'package:dox_core/dox_core.dart'; import 'package:dox_core/utils/json.dart'; -import 'package:dox_core/utils/logger.dart'; -class LogMiddleware extends DoxMiddleware { - Function(Map)? filter; +class LogMiddleware implements IDoxMiddleware { + Map Function(Map)? filter; final bool withHeader; + final bool enabled; - LogMiddleware({this.filter, this.withHeader = false}); + LogMiddleware({ + required this.enabled, + this.filter, + this.withHeader = false, + }); @override - DoxRequest handle(DoxRequest req) { + IDoxRequest handle(IDoxRequest req) { + if (!enabled) { + return req; + } + Map payload = { + 'request': req.all(), + }; + + if (withHeader) { + payload['headers'] = req.headers; + } + Map text = { 'level': 'INFO', 'message': '${req.method} ${req.uri.path}', 'source_ip': req.ip(), 'timestamp': DateTime.now().toIso8601String(), - 'payload': { - 'request': req.all(), - 'headers': withHeader ? req.headers : null, - } + 'payload': payload }; if (filter != null) { text = filter!(text); } - DoxLogger.log(JSON.stringify(text)); + print(JSON.stringify(text)); return req; } } diff --git a/packages/dox-core/lib/router/route.dart b/packages/dox-core/lib/router/route.dart index 0e0718c..fad1537 100644 --- a/packages/dox-core/lib/router/route.dart +++ b/packages/dox-core/lib/router/route.dart @@ -5,7 +5,7 @@ import 'package:dox_core/dox_core.dart'; import 'package:dox_core/router/route_data.dart'; import 'package:dox_core/utils/utils.dart'; -/// get list of routes registered +/// list of routes registered List _routes = []; class Route { @@ -16,6 +16,8 @@ class Route { String _prefix = ''; String? _domain; + bool? _corsEnabled; + List _preMiddleware = []; /// get list of routes registered @@ -61,6 +63,43 @@ class Route { Route()._domain = originalDomain; } + /// group of route to enabled cors + /// ``` + /// Route.enabledCors(() { + /// Route.get('/ping', controller); + /// }); + /// ``` + static void enabledCors(Function() callback) { + _cors(true, callback); + } + + // group of route to disabled cors + /// ``` + /// Route.disabledCors() { + /// Route.get('/ping', controller); + /// }); + /// ``` + static void disabledCors(Function() callback) { + _cors(false, callback); + } + + /// group of route to enable/disable cors + /// ``` + /// Route.cors(true, () { + /// Route.get('/ping', controller); + /// }); + /// ``` + static void _cors(bool enabled, Function() callback) { + bool? originalCorsConfig = Route()._corsEnabled; + + /// set new domain + Route()._corsEnabled = enabled; + callback(); + + /// restore original domain + Route()._corsEnabled = originalCorsConfig; + } + /// middleware for group of routes /// ``` /// Route.group('example.com', () { @@ -260,7 +299,7 @@ class Route { /// resource route /// ``` /// Route.resource('blog', BlogController()); - /// + /// ``` static Route resource(String route, dynamic controller) { String prefix = '${Route()._prefix}/$route'; @@ -327,6 +366,7 @@ class Route { path: path, controllers: controllers, domain: _domain, + corsEnabled: _corsEnabled, )); return this; } diff --git a/packages/dox-core/lib/router/route_data.dart b/packages/dox-core/lib/router/route_data.dart index f41054a..43800db 100644 --- a/packages/dox-core/lib/router/route_data.dart +++ b/packages/dox-core/lib/router/route_data.dart @@ -9,11 +9,13 @@ class RouteData { FormRequest Function()? formRequest; final String? domain; + final bool? corsEnabled; RouteData({ required this.method, required this.path, required this.controllers, + this.corsEnabled, this.preMiddleware = const [], this.domain, }); diff --git a/packages/dox-core/lib/server/dox_server.dart b/packages/dox-core/lib/server/dox_server.dart index da0c4d7..9884dea 100644 --- a/packages/dox-core/lib/server/dox_server.dart +++ b/packages/dox-core/lib/server/dox_server.dart @@ -1,7 +1,6 @@ import 'dart:io'; import 'package:dox_core/dox_core.dart'; -import 'package:dox_core/http/http_cors_handler.dart'; import 'package:dox_core/http/http_request_handler.dart'; class DoxServer { @@ -29,7 +28,6 @@ class DoxServer { ); server.listen( (HttpRequest req) { - httpCorsHandler(req); httpRequestHandler(req); }, onError: onError ?? (dynamic error) => print(error), diff --git a/packages/dox-core/lib/utils/aes_encryptor.dart b/packages/dox-core/lib/utils/aes_encryptor.dart index 32e5680..1311ba7 100644 --- a/packages/dox-core/lib/utils/aes_encryptor.dart +++ b/packages/dox-core/lib/utils/aes_encryptor.dart @@ -1,7 +1,6 @@ import 'dart:convert'; import 'dart:typed_data'; -import 'package:dox_core/utils/logger.dart'; import 'package:encrypt/encrypt.dart'; class AESEncryptor { @@ -30,7 +29,7 @@ class AESEncryptor { String decrypted = encrypter.decrypt64(content, iv: iv); return utf8.decode(base64.decode(decrypted)); } catch (error) { - DoxLogger.danger('AESEncryption Error: ${error.toString()}'); + print('AESEncryption Error: ${error.toString()}'); return ''; } } diff --git a/packages/dox-core/lib/utils/logger.dart b/packages/dox-core/lib/utils/logger.dart index c3d9623..0d2c893 100644 --- a/packages/dox-core/lib/utils/logger.dart +++ b/packages/dox-core/lib/utils/logger.dart @@ -1,54 +1,84 @@ /// coverage:ignore-file +import 'package:dox_core/app.dart'; import 'package:dox_core/utils/json.dart'; -class DoxLogger { - /// log the text with white color - static void log(dynamic text) { - print(text); +class Logger { + static void log(String level, dynamic message, [dynamic data]) { + if (Dox().config.logger.enabled == false) return; + Dox().config.logger.prettyPrint + ? _prettyLog(level, message, data) + : _log(level, message, data); } /// log the text using info color (lightblue) /// ``` - /// DoxLogger.info('using dox is fun'); + /// Logger.info('using dox is fun'); /// ``` - static void info(dynamic text) { - print('\x1B[36m$text\x1B[0m'); + static void info(dynamic message, [dynamic data]) { + log('info', message, data); } /// log the text using warn color (yellow) /// ``` - /// DoxLogger.warn('careful!'); + /// Logger.warn('careful!'); /// - static void warn(dynamic text) { - print('\x1B[33m$text\x1B[0m'); + static void warn(dynamic message, [dynamic data]) { + log('warn', message, data); } /// log the text using success color (green) /// ``` - /// DoxLogger.success('success'); + /// Logger.success('success'); /// - static void success(dynamic text) { - print('\x1B[32m$text\x1B[0m'); + static void success(dynamic message, [dynamic data]) { + log('success', message, data); } /// log the text using danger color (red) /// ``` - /// DoxLogger.danger('failed'); + /// Logger.danger('failed'); /// - static void danger(dynamic text) { - print('\x1B[31m$text\x1B[0m'); + static void danger(dynamic message, [dynamic data]) { + log('danger', message, data); } /// log as json string - /// this function is user for logging services + /// this function is use for logging services /// eg. datadog, sentry etc.. - static void prettyLog(String level, String message, [dynamic data]) { + static void _prettyLog(String level, dynamic message, dynamic data) { + String? payload = ''; + if (data == null || data is String) { + payload = data; + } else if (data is DateTime) { + payload = data.toIso8601String(); + } else { + payload = JSON.stringify(data); + } + Map colors = { + 'info': '36', + 'warn': '33', + 'success': '32', + 'danger': '31', + }; + String? color = colors[level]; + if (payload == null || payload.isEmpty) { + print('\x1B[${color}m$message\x1B[0m'); + return; + } + print('\x1B[${color}m$message => $payload\x1B[0m'); + } + + /// log as json string + /// this function is use for logging services + /// eg. datadog, sentry etc.. + static void _log(String level, dynamic message, dynamic data) { Map text = { 'level': level.toUpperCase(), + 'name': Dox().config.logger.name, 'message': message.toString(), 'timestamp': DateTime.now().toIso8601String(), 'payload': data }; - DoxLogger.log(JSON.stringify(text)); + print(JSON.stringify(text)); } } diff --git a/packages/dox-core/lib/validation/dox_validator.dart b/packages/dox-core/lib/validation/dox_validator.dart index e154273..15ba5b0 100644 --- a/packages/dox-core/lib/validation/dox_validator.dart +++ b/packages/dox-core/lib/validation/dox_validator.dart @@ -99,7 +99,7 @@ class DoxValidator { String args = parts.length >= 2 ? parts[1] : ''; Map? match = _matchings[ruleKey]; if (match == null) { - DoxLogger.warn("$ruleKey rule doesn't exist."); + Logger.warn("$ruleKey rule doesn't exist."); return null; } diff --git a/packages/dox-core/pubspec.yaml b/packages/dox-core/pubspec.yaml index 0929d56..23d67c1 100644 --- a/packages/dox-core/pubspec.yaml +++ b/packages/dox-core/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: mime: ^1.0.4 string_scanner: ^1.1.0 uuid: ^3.0.6 - dox_annotation: ^1.0.5-alpha1.9 + dox_annotation: ^1.0.5-alpha2.0 dev_dependencies: lints: ^2.0.0 diff --git a/packages/dox-core/test/integration/requirements/config/api_router.dart b/packages/dox-core/test/integration/requirements/config/api_router.dart index 89ed676..db53b2b 100644 --- a/packages/dox-core/test/integration/requirements/config/api_router.dart +++ b/packages/dox-core/test/integration/requirements/config/api_router.dart @@ -9,7 +9,7 @@ class ApiRouter extends Router { @override void register() { Route.use(customMiddleware); - Route.use([ClassBasedMiddleware()]); + Route.use([ClassBasedMiddleware()]); Route.get('ping', (DoxRequest req) => 'pong'); } diff --git a/packages/dox-core/test/integration/requirements/config/app.dart b/packages/dox-core/test/integration/requirements/config/app.dart index f62ca9f..183bbf9 100644 --- a/packages/dox-core/test/integration/requirements/config/app.dart +++ b/packages/dox-core/test/integration/requirements/config/app.dart @@ -19,9 +19,10 @@ AppConfig config = AppConfig( // cors configuration cors: CORSConfig( - allowOrigin: '*', - allowMethods: ['GET', 'POST', 'DELETE', 'PUT', 'PATCH'], - allowCredentials: true, + enabled: false, + origin: '*', + methods: ['GET', 'POST', 'DELETE', 'PUT', 'PATCH'], + credentials: true, ), /// response handler @@ -42,7 +43,7 @@ AppConfig config = AppConfig( /// error handler errorHandler: (Object? error, StackTrace stackTrace) { - DoxLogger.danger(error); + Logger.danger(error); }, /// cache driver configuration diff --git a/packages/dox-core/test/integration/requirements/handler.dart b/packages/dox-core/test/integration/requirements/handler.dart index 3f044ca..38653b1 100644 --- a/packages/dox-core/test/integration/requirements/handler.dart +++ b/packages/dox-core/test/integration/requirements/handler.dart @@ -2,5 +2,7 @@ import 'package:dox_core/dox_core.dart'; class ResponseHandler extends ResponseHandlerInterface { @override - void handle(DoxResponse res) {} + DoxResponse handle(DoxResponse res) { + return res; + } } diff --git a/packages/dox-core/test/integration/requirements/middleware/custom_middleware.dart b/packages/dox-core/test/integration/requirements/middleware/custom_middleware.dart index 7163fa1..b733935 100644 --- a/packages/dox-core/test/integration/requirements/middleware/custom_middleware.dart +++ b/packages/dox-core/test/integration/requirements/middleware/custom_middleware.dart @@ -4,9 +4,9 @@ DoxRequest customMiddleware(DoxRequest req) { return req; } -class ClassBasedMiddleware implements DoxMiddleware { +class ClassBasedMiddleware implements IDoxMiddleware { @override - DoxRequest handle(DoxRequest req) { + IDoxRequest handle(IDoxRequest req) { return req; } }