Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions packages/pharaoh/lib/pharaoh.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
library;

export 'src/core.dart' hide $PharaohImpl;
export 'src/view/view.dart';
export 'src/http/cookie.dart';
export 'src/http/request.dart';
export 'src/http/response.dart';
export 'src/http/router.dart';

export 'src/shelf_interop/adapter.dart';
export 'src/shelf_interop/shelf.dart' show ShelfBody;

export 'src/utils/utils.dart';
export 'src/utils/exceptions.dart';
export 'src/router/router_handler.dart';

export 'src/middleware/session_mw.dart';
export 'src/middleware/body_parser.dart';
export 'src/middleware/cookie_parser.dart';
export 'src/middleware/request_logger.dart';

// shelf
export 'src/shelf_interop/adapter.dart';
export 'src/shelf_interop/shelf.dart' show ShelfBody;
export 'package:spanner/spanner.dart' show HTTPMethod;
11 changes: 3 additions & 8 deletions packages/pharaoh/lib/pharaoh_next.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
export 'src/_next/validation.dart';
export 'src/_next/router.dart';
export 'pharaoh.dart';
export 'src/_next/core.dart';
export 'src/_next/http.dart';
export 'src/core.dart';

export 'src/http/response.dart';
export 'src/http/request.dart';
export 'src/router/router_handler.dart';
export 'package:spanner/spanner.dart' show HTTPMethod;
export 'src/_next/router.dart';
export 'src/_next/validation.dart';
6 changes: 3 additions & 3 deletions packages/pharaoh/lib/src/_next/_core/core_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ class _PharaohNextImpl implements Application {
int get port => config.port;

Pharaoh _createPharaohInstance({OnErrorCallback? onException}) {
final pharaoh = Pharaoh()
..useSpanner(_spanner)
..viewEngine = _viewEngine;
final pharaoh = Pharaoh()..useSpanner(_spanner);
Pharaoh.viewEngine = _viewEngine;

if (onException != null) pharaoh.onError(onException);
return pharaoh;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/pharaoh/lib/src/_next/http.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import 'dart:io';
import '../http/request.dart';
import '../http/response.dart';
import '../middleware/session_mw.dart';
import '../router/router_handler.dart';
import '../http/router.dart';
import 'core.dart';

@inject
Expand Down
2 changes: 1 addition & 1 deletion packages/pharaoh/lib/src/_next/router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import 'package:grammer/grammer.dart';
import 'package:meta/meta.dart';
import '../http/request.dart';
import '../http/response.dart';
import '../router/router_handler.dart';
import '../http/router.dart';
import 'validation.dart';
import 'core.dart';

Expand Down
55 changes: 0 additions & 55 deletions packages/pharaoh/lib/src/core.dart

This file was deleted.

4 changes: 1 addition & 3 deletions packages/pharaoh/lib/src/http/request.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import 'dart:io';

import 'package:http_parser/http_parser.dart';
import 'package:pharaoh/pharaoh.dart';
import 'package:spanner/spanner.dart';

import 'message.dart';

Expand All @@ -15,8 +14,7 @@ class RequestContext {
/// cookies & session
static const String cookies = '$phar.cookies';
static const String signedCookies = '$phar.signedcookies';
static const String session = '$phar.session.cookie';
static const String sessionId = '$phar.session.id';
static const String session = '$phar.session';
}

HTTPMethod getHttpMethod(HttpRequest req) => switch (req.method) {
Expand Down
2 changes: 1 addition & 1 deletion packages/pharaoh/lib/src/http/request_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class _$RequestImpl extends Request {
Session? get session => _context[RequestContext.session];

@override
String? get sessionId => _context[RequestContext.sessionId];
String? get sessionId => session?.id;

@override
Object? operator [](String name) => _context[name];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,70 @@
part of 'core.dart';
import 'dart:async';
import 'dart:io';

class $PharaohImpl extends RouterContract
import 'package:collection/collection.dart';
import 'package:http_parser/http_parser.dart';
import 'package:meta/meta.dart';
import 'package:spanner/spanner.dart';
import 'package:spanner/src/tree/tree.dart' show BASE_PATH;

import '../middleware/body_parser.dart';
import '../middleware/session_mw.dart';
import '../shelf_interop/shelf.dart' as shelf;
import '../utils/exceptions.dart';
import '../view/view.dart';

import 'request.dart';
import 'response.dart';

part 'router/router_contract.dart';
part 'router/router_handler.dart';

typedef PharaohError = ({Object exception, StackTrace trace});

typedef OnErrorCallback = FutureOr<Response> Function(
PharaohError error,
Request req,
Response res,
);

abstract class Pharaoh implements RouterContract {
static _$GroupRouter get router => _$GroupRouter();

factory Pharaoh() => _$PharaohImpl();

static ViewEngine? viewEngine;

void onError(OnErrorCallback onError);

void useSpanner(Spanner spanner);

void useRequestHook(RequestHook hook);

void group(String path, _$GroupRouter router);

Uri get uri;

Future<Pharaoh> listen({int port = 3000});

@visibleForTesting
void handleRequest(HttpRequest httpReq);

Future<void> shutdown();
}

class _$PharaohImpl extends RouterContract
with RouteDefinitionMixin
implements Pharaoh {
late final HttpServer _server;

OnErrorCallback? _onErrorCb;

static ViewEngine? viewEngine_;

final List<ReqResHook> _preResponseHooks = [
final List<RequestHook> _requestHooks = [
sessionPreResponseHook,
viewRenderHook,
];

$PharaohImpl() {
_$PharaohImpl() {
useSpanner(Spanner());
use(bodyParser);
}
Expand Down Expand Up @@ -42,15 +92,6 @@ class $PharaohImpl extends RouterContract
);
}

@override
Pharaoh group(final String path, final RouterContract router) {
if (router is! GroupRouter) {
throw PharaohException.value('Router is not an instance of GroupRouter');
}
router.commit(path, spanner);
return this;
}

@override
Future<Pharaoh> listen({int port = 3000}) async {
_server = await HttpServer.bind(InternetAddress.anyIPv4, port, shared: true)
Expand Down Expand Up @@ -114,21 +155,22 @@ class $PharaohImpl extends RouterContract
req.params.addAll(routeResult.params);
}

reqRes = await executeHandlers(resolvedHandlers, reqRes);

for (final job in _preResponseHooks) {
reqRes = await Future.microtask(() => job(reqRes));
for (final hook in _requestHooks.whereNot((e) => e.onBefore == null)) {
reqRes = await hook.onBefore!.call(req, reqRes.res);
}

if (!reqRes.res.ended) {
return reqRes.merge(routeNotFound());
reqRes = await executeHandlers(resolvedHandlers, reqRes);
if (!reqRes.res.ended) reqRes = reqRes.merge(routeNotFound());

for (final hook in _requestHooks.whereNot((e) => e.onAfter == null)) {
reqRes = await hook.onAfter!.call(reqRes.req, reqRes.res);
}

return reqRes;
}

Future<void> forward(HttpRequest request, Response res_) async {
var coding = res_.headers['transfer-encoding'];
var coding = res_.headers[HttpHeaders.transferEncodingHeader];

final statusCode = res_.statusCode;
request.response.statusCode = statusCode;
Expand Down Expand Up @@ -187,14 +229,21 @@ class $PharaohImpl extends RouterContract
Future<void> shutdown() async => _server.close();

@override
ViewEngine? get viewEngine => viewEngine_;
void onError(OnErrorCallback errorCb) => _onErrorCb = errorCb;

@override
set viewEngine(ViewEngine? engine) => viewEngine_ = engine;
void useRequestHook(RequestHook hook) => _requestHooks.add(hook);

@override
void onError(OnErrorCallback errorCb) => _onErrorCb = errorCb;
void group(String path, _$GroupRouter router) {
spanner.attachNode(path, router.spanner.root);
}
}

// ignore: constant_identifier_names
const _XPoweredByHeader = 'X-Powered-By';

class _$GroupRouter extends RouterContract with RouteDefinitionMixin {
_$GroupRouter() {
useSpanner(Spanner());
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
import 'package:spanner/spanner.dart';
import 'package:spanner/src/tree/tree.dart' show BASE_PATH;
part of '../router.dart';

import 'router_contract.dart';
import 'router_handler.dart';
sealed class RouterContract {
void get(String path, RequestHandler hdler);

void post(String path, RequestHandler hdler);

void put(String path, RequestHandler hdler);

void delete(String path, RequestHandler hdler);

void head(String path, RequestHandler hdler);

void patch(String path, RequestHandler hdler);

void options(String path, RequestHandler hdler);

void trace(String path, RequestHandler hdler);

void use(Middleware middleware);

void on(String path, Middleware hdler, {HTTPMethod method = HTTPMethod.ALL});
}

mixin RouteDefinitionMixin on RouterContract {
late Spanner spanner;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import 'dart:async';

import '../http/request.dart';
import '../http/response.dart';
import '../utils/exceptions.dart';
part of '../router.dart';

typedef ReqRes = ({Request req, Response res});

typedef ReqResHook = FutureOr<ReqRes> Function(ReqRes reqRes);
final class RequestHook {
final FutureOr<ReqRes> Function(Request req, Response res)? onBefore;
final FutureOr<ReqRes> Function(Request req, Response res)? onAfter;
const RequestHook({this.onAfter, this.onBefore});
}

typedef NextFunction<Next> = dynamic Function([dynamic result, Next? chain]);

Expand All @@ -19,13 +19,13 @@ typedef Middleware = FutureOr<void> Function(
);

extension ReqResExtension on ReqRes {
ReqRes merge(dynamic val) {
if (val == null) return this;
if (val is Request) return (req: val, res: this.res);
if (val is Response) return (req: this.req, res: val);
if (val is ReqRes) return val;
throw PharaohException.value('Invalid Type used on merge', val);
}
ReqRes merge(dynamic val) => switch (val) {
ReqRes() => val,
Response() => (req: this.req, res: val),
Request() => (req: val, res: this.res),
null => this,
_ => throw PharaohException.value('Invalid Type used on merge', val)
};
}

extension MiddlewareChainExtension on Middleware {
Expand Down
2 changes: 1 addition & 1 deletion packages/pharaoh/lib/src/middleware/body_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import 'package:mime/mime.dart';

import '../http/request.dart';
import '../http/response.dart';
import '../router/router_handler.dart';
import '../http/router.dart';

sealed class MimeType {
static const String multiPartForm = 'multipart/form-data';
Expand Down
2 changes: 1 addition & 1 deletion packages/pharaoh/lib/src/middleware/cookie_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import 'package:pharaoh/src/utils/utils.dart';

import '../http/cookie.dart';
import '../http/request.dart';
import '../router/router_handler.dart';
import '../http/router.dart';

Middleware cookieParser({CookieOpts opts = const CookieOpts()}) {
opts.validate();
Expand Down
Loading