Socket
Socket
Sign inDemoInstall

arrow-express

Package Overview
Dependencies
71
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.2.3 to 2.0.0

4

dist/application/application.d.ts

@@ -24,3 +24,3 @@ import Express from "express";

*/
registerController(controller: ControllerConfiguration<any>): AppConfigurator;
registerController(controller: ControllerConfiguration<any, any>): AppConfigurator;
/**

@@ -30,3 +30,3 @@ * Register list of controllers in application.

*/
registerControllers(...controllers: ControllerConfiguration<any>[]): AppConfigurator;
registerControllers(...controllers: ControllerConfiguration<any, any>[]): AppConfigurator;
private printExpressConfig;

@@ -33,0 +33,0 @@ private startControllers;

@@ -103,23 +103,29 @@ "use strict";

};
AppConfigurator.prototype.startController = function (controller, prefix) {
AppConfigurator.prototype.startController = function (controller, controllersChain) {
var _this = this;
if (prefix === void 0) { prefix = ""; }
if (!controllersChain) {
controllersChain = [controller];
}
else {
controllersChain.push(controller);
}
controller.getControllers().forEach(function (subController) {
_this.startController(subController, AppConfigurator.getRoutePath(controller.getPrefix(), prefix));
_this.startController(subController, controllersChain);
});
controller.getRoutes().forEach(function (route) {
_this.registerRouteInExpress(controller, route, prefix);
_this.registerRouteInExpress(controllersChain, route);
});
};
AppConfigurator.prototype.registerRouteInExpress = function (controller, route, prefix) {
var routePath = AppConfigurator.getRoutePath(prefix, controller.getPrefix(), route.getPath());
AppConfigurator.prototype.registerRouteInExpress = function (controllersChain, route) {
var controllersPrefix = controllersChain.reduce(function (prefixAcc, controller) { return AppConfigurator.getRoutePath(prefixAcc, controller.getPrefix()); }, "");
var routePath = AppConfigurator.getRoutePath(controllersPrefix, route.getPath());
if (!route.getMethod()) {
throw new configuration_error_1.ConfigurationError("Route ".concat(routePath, " has no method specified"));
}
this._express[route.getMethod()]("/".concat(routePath), this.createApplicationRequestHandler(route, controller));
this._express[route.getMethod()]("/".concat(routePath), this.createApplicationRequestHandler(route, controllersChain));
};
AppConfigurator.prototype.createApplicationRequestHandler = function (route, controller) {
AppConfigurator.prototype.createApplicationRequestHandler = function (route, controllersChain) {
var _this = this;
return function (req, res) { return __awaiter(_this, void 0, void 0, function () {
var context, response, error_1;
var context, _i, controllersChain_1, controller, newContextValue, response, error_1;
var _a;

@@ -129,8 +135,19 @@ return __generator(this, function (_b) {

case 0:
_b.trys.push([0, 3, 4, 5]);
return [4 /*yield*/, ((_a = controller.getHandler()) === null || _a === void 0 ? void 0 : _a(req, res))];
_b.trys.push([0, 6, 7, 8]);
context = void 0;
_i = 0, controllersChain_1 = controllersChain;
_b.label = 1;
case 1:
context = _b.sent();
return [4 /*yield*/, route.getRequestHandler()(req, res, context)];
if (!(_i < controllersChain_1.length)) return [3 /*break*/, 4];
controller = controllersChain_1[_i];
return [4 /*yield*/, ((_a = controller.getHandler()) === null || _a === void 0 ? void 0 : _a(req, res, context))];
case 2:
newContextValue = _b.sent();
context = newContextValue ? newContextValue : context;
_b.label = 3;
case 3:
_i++;
return [3 /*break*/, 1];
case 4: return [4 /*yield*/, route.getRequestHandler()(req, res, context)];
case 5:
response = _b.sent();

@@ -143,4 +160,4 @@ if (AppConfigurator.canSendResponse(res)) {

}
return [3 /*break*/, 5];
case 3:
return [3 /*break*/, 8];
case 6:
error_1 = _b.sent();

@@ -155,7 +172,7 @@ if (AppConfigurator.canSendResponse(res)) {

}
return [3 /*break*/, 5];
case 4:
return [3 /*break*/, 8];
case 7:
this.logRequest(req, res);
return [7 /*endfinally*/];
case 5: return [2 /*return*/];
case 8: return [2 /*return*/];
}

@@ -162,0 +179,0 @@ });

import { RouteConfigurator } from "../route/route";
import Express from "express";
export type ControllerHandler<C = undefined> = (request: Express.Request, response: Express.Response) => Promise<C>;
export declare class ControllerConfiguration<C = undefined> {
export type ControllerHandler<C = undefined, R = undefined> = (request: Express.Request, response: Express.Response, rootContext?: R) => Promise<C>;
export declare class ControllerConfiguration<C = undefined, R = undefined> {
private _prefix;

@@ -13,3 +13,3 @@ private _controllers;

*/
registerController(controller: ControllerConfiguration): this;
registerController(controller: ControllerConfiguration<any, C>): this;
/**

@@ -19,3 +19,3 @@ * Register array of controllers in controller

*/
registerControllers(...controllers: ControllerConfiguration[]): this;
registerControllers(...controllers: ControllerConfiguration<any>[]): this;
/**

@@ -30,3 +30,3 @@ * Register route in controller

*/
registerRoutes(...routes: RouteConfigurator<C>[]): this;
registerRoutes(...routes: RouteConfigurator<C, R>[]): this;
/**

@@ -41,8 +41,8 @@ * Register controller prefix which will be used by all routes

*/
handler<NewContext>(handler: ControllerHandler<NewContext>): ControllerConfiguration<NewContext>;
handler<NewContext>(handler: ControllerHandler<NewContext, R>): ControllerConfiguration<NewContext, R>;
getPrefix(): string;
getRoutes(): RouteConfigurator<C>[];
getControllers(): ControllerConfiguration[];
getHandler(): ControllerHandler<C> | undefined;
getControllers(): ControllerConfiguration<any, C>[];
getHandler(): ControllerHandler<C, R> | undefined;
}
export declare function Controller<C = undefined>(): ControllerConfiguration<C>;
export declare function Controller<C = undefined, R = undefined>(): ControllerConfiguration<C, R>;
import Express from "express";
export type RouteHandler<C = undefined, R = unknown> = (request: Express.Request, response: Express.Response, context: C) => R | Promise<R>;
export type RouteHandler<C = undefined, R = undefined> = (request: Express.Request, response: Express.Response, context: C) => R | Promise<R>;
export type HttpMethod = "get" | "post" | "head" | "put" | "delete" | "options" | "patch";
export declare class RouteConfigurator<C = undefined, R = unknown> {
export declare class RouteConfigurator<C = undefined, R = undefined> {
private _method;

@@ -31,2 +31,2 @@ private _path;

}
export declare function Route<C = undefined, R = unknown>(): RouteConfigurator<C, R>;
export declare function Route<C = undefined, R = undefined>(): RouteConfigurator<C, R>;

@@ -6,5 +6,5 @@ import { Controller, ControllerConfiguration } from "arrow-express";

import { GetMyselfRoute } from "./routes/getMyself.route";
import { AuthorizeGuard } from "../guards/authorize.guard";
import { AuthorizeGuard, UserContext } from "../guards/authorize.guard";
export function UserController(userService: UserService): ControllerConfiguration {
export function UserController(userService: UserService): ControllerConfiguration<UserContext> {
return Controller()

@@ -11,0 +11,0 @@ .handler(AuthorizeGuard)

import Express from "express";
import { Application } from "./application";
import { Controller } from "../controller/controller";
import { Controller, ControllerHandler } from "../controller/controller";
import { Route } from "../route/route";

@@ -179,3 +179,3 @@ import { RequestError } from "../error/request.error";

it("should pass context from controller handler to route handler", async () => {
const spy = jest.fn().mockResolvedValue("context");
const spy = jest.fn().mockResolvedValue("context") as ControllerHandler<any>;
const routeSpy = jest.fn();

@@ -188,4 +188,34 @@ Application({ app: ExpressAppStub, logRequests: false })

});
it("should pass context from root controller to route handler", async () => {
const spy = jest.fn().mockResolvedValue("context") as ControllerHandler<any>;
const routeSpy = jest.fn();
Application({ app: ExpressAppStub, logRequests: false })
.registerController(
Controller()
.handler(spy)
.registerController(Controller().registerRoute(Route().method("get").handler(routeSpy)))
)
.configure(false);
await mocked(ExpressAppStub.get).mock.calls[0][1]({} as never, resSpy);
expect(routeSpy).toHaveBeenCalledWith(expect.anything(), expect.anything(), "context");
});
it("should pass context through controllers chain", async () => {
const rootSpy = jest.fn().mockResolvedValue("root") as ControllerHandler<any>;
const spy = jest.fn().mockImplementation((_, __, context) => context + "-child") as ControllerHandler<any>;
const routeSpy = jest.fn();
Application({ app: ExpressAppStub, logRequests: false })
.registerController(
Controller()
.handler(rootSpy)
.registerController(Controller().handler(spy).registerRoute(Route().method("get").handler(routeSpy)))
)
.configure(false);
await mocked(ExpressAppStub.get).mock.calls[0][1]({} as never, resSpy);
expect(routeSpy).toHaveBeenCalledWith(expect.anything(), expect.anything(), "root-child");
});
it("should call controller handler", async () => {
const spy = jest.fn().mockRejectedValue(new Error());
const spy = jest.fn().mockRejectedValue(new Error()) as ControllerHandler<any>;
Application({ app: ExpressAppStub, logRequests: false })

@@ -202,3 +232,3 @@ .registerController(Controller().handler(spy).registerRoute(Route().method("get")))

};
const spy = jest.fn().mockRejectedValue(new RequestError(401, response));
const spy = jest.fn().mockRejectedValue(new RequestError(401, response)) as ControllerHandler<any>;
Application({ app: ExpressAppStub, logRequests: false })

@@ -205,0 +235,0 @@ .registerController(Controller().handler(spy).registerRoute(Route().method("get")))

@@ -46,3 +46,3 @@ import Express from "express";

*/
registerController(controller: ControllerConfiguration<any>): AppConfigurator {
registerController(controller: ControllerConfiguration<any, any>): AppConfigurator {
this._controllers.push(controller);

@@ -56,3 +56,3 @@ return this;

*/
registerControllers(...controllers: ControllerConfiguration<any>[]): AppConfigurator {
registerControllers(...controllers: ControllerConfiguration<any, any>[]): AppConfigurator {
controllers.forEach(controller => this.registerController(controller));

@@ -73,13 +73,22 @@ return this;

private startController(controller: ControllerConfiguration, prefix = "") {
private startController(controller: ControllerConfiguration, controllersChain?: ControllerConfiguration[]) {
if (!controllersChain) {
controllersChain = [controller];
} else {
controllersChain.push(controller);
}
controller.getControllers().forEach(subController => {
this.startController(subController, AppConfigurator.getRoutePath(controller.getPrefix(), prefix));
this.startController(subController, controllersChain);
});
controller.getRoutes().forEach(route => {
this.registerRouteInExpress(controller, route, prefix);
this.registerRouteInExpress(controllersChain, route);
});
}
private registerRouteInExpress(controller: ControllerConfiguration, route: RouteConfigurator, prefix?: string) {
const routePath = AppConfigurator.getRoutePath(prefix, controller.getPrefix(), route.getPath());
private registerRouteInExpress(controllersChain: ControllerConfiguration[], route: RouteConfigurator) {
const controllersPrefix = controllersChain.reduce(
(prefixAcc, controller) => AppConfigurator.getRoutePath(prefixAcc, controller.getPrefix()),
""
);
const routePath = AppConfigurator.getRoutePath(controllersPrefix, route.getPath());

@@ -90,3 +99,3 @@ if (!route.getMethod()) {

this._express[route.getMethod()](`/${routePath}`, this.createApplicationRequestHandler(route, controller));
this._express[route.getMethod()](`/${routePath}`, this.createApplicationRequestHandler(route, controllersChain));
}

@@ -96,7 +105,13 @@

route: RouteConfigurator,
controller: ControllerConfiguration
controllersChain: ControllerConfiguration[]
): Express.RequestHandler {
return async (req: Express.Request, res: Express.Response) => {
try {
const context = await controller.getHandler()?.(req, res);
let context: undefined;
for (const controller of controllersChain) {
const newContextValue = await controller.getHandler()?.(req, res, context);
context = newContextValue ? newContextValue : context;
}
const response = await route.getRequestHandler()(req, res, context);

@@ -103,0 +118,0 @@ if (AppConfigurator.canSendResponse(res)) {

import { RouteConfigurator } from "../route/route";
import Express from "express";
export type ControllerHandler<C = undefined> = (request: Express.Request, response: Express.Response) => Promise<C>;
export class ControllerConfiguration<C = undefined> {
export type ControllerHandler<C = undefined, R = undefined> = (
request: Express.Request,
response: Express.Response,
rootContext?: R
) => Promise<C>;
export class ControllerConfiguration<C = undefined, R = undefined> {
private _prefix = "";
private _controllers: ControllerConfiguration[] = [];
private _controllers: ControllerConfiguration<unknown, C>[] = [];
private _routes: RouteConfigurator<C>[] = [];
private _handler: ControllerHandler<C> | undefined;
private _handler: ControllerHandler<C, R> | undefined;

@@ -15,3 +20,3 @@ /**

*/
registerController(controller: ControllerConfiguration): this {
registerController(controller: ControllerConfiguration<any, C>): this {
this._controllers.push(controller);

@@ -25,3 +30,3 @@ return this;

*/
registerControllers(...controllers: ControllerConfiguration[]): this {
registerControllers(...controllers: ControllerConfiguration<any>[]): this {
controllers.forEach(this.registerController.bind(this));

@@ -44,3 +49,3 @@ return this;

*/
registerRoutes(...routes: RouteConfigurator<C>[]): this {
registerRoutes(...routes: RouteConfigurator<C, R>[]): this {
routes.forEach(this.registerRoute.bind(this));

@@ -62,5 +67,5 @@ return this;

*/
handler<NewContext>(handler: ControllerHandler<NewContext>): ControllerConfiguration<NewContext> {
this._handler = handler as unknown as ControllerHandler<C>;
return this as unknown as ControllerConfiguration<NewContext>;
handler<NewContext>(handler: ControllerHandler<NewContext, R>): ControllerConfiguration<NewContext, R> {
this._handler = handler as unknown as ControllerHandler<C, R>;
return this as unknown as ControllerConfiguration<NewContext, R>;
}

@@ -76,7 +81,7 @@

getControllers(): ControllerConfiguration[] {
getControllers(): ControllerConfiguration<any, C>[] {
return this._controllers;
}
getHandler(): ControllerHandler<C> | undefined {
getHandler(): ControllerHandler<C, R> | undefined {
return this._handler;

@@ -86,4 +91,4 @@ }

export function Controller<C = undefined>(): ControllerConfiguration<C> {
return new ControllerConfiguration<C>();
export function Controller<C = undefined, R = undefined>(): ControllerConfiguration<C, R> {
return new ControllerConfiguration<C, R>();
}
import Express from "express";
export type RouteHandler<C = undefined, R = unknown> = (
export type RouteHandler<C = undefined, R = undefined> = (
request: Express.Request,

@@ -10,3 +10,3 @@ response: Express.Response,

export class RouteConfigurator<C = undefined, R = unknown> {
export class RouteConfigurator<C = undefined, R = undefined> {
private _method: HttpMethod;

@@ -60,4 +60,4 @@ private _path: string;

export function Route<C = undefined, R = unknown>(): RouteConfigurator<C, R> {
export function Route<C = undefined, R = undefined>(): RouteConfigurator<C, R> {
return new RouteConfigurator<C, R>();
}
{
"name": "arrow-express",
"version": "1.2.3",
"version": "2.0.0",
"description": "Library to bootstrap express applications with zero configuration",

@@ -10,9 +10,2 @@ "main": "dist/index.js",

},
"scripts": {
"build": "tsc --declaration --project tsconfig.json",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"lint": "./node_modules/.bin/eslint ."
},
"repository": {

@@ -52,3 +45,10 @@ "type": "git",

},
"homepage": "https://github.com/Mighty683/arrow-express#readme"
}
"homepage": "https://github.com/Mighty683/arrow-express#readme",
"scripts": {
"build": "tsc --declaration --project tsconfig.json",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"lint": "./node_modules/.bin/eslint ."
}
}

@@ -97,2 +97,6 @@ # Arrow Express

#### Controller handler
Controller handler can be used to eg: authorize user and get it's context which will be passed to routes. Handlers like controllers can be chained.
### Route

@@ -141,2 +145,3 @@

- `response` - which is Express.Response
- `context` - which is resolution of controller's handler

@@ -143,0 +148,0 @@ Features of route handler:

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc