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.0.1 to 1.1.0

.changeset/config.json

32

dist/application/application.js

@@ -118,15 +118,19 @@ "use strict";

}
this._express[route.getMethod()]("/".concat(routePath), this.createApplicationRequestHandler(route.getRequestHandler()));
this._express[route.getMethod()]("/".concat(routePath), this.createApplicationRequestHandler(route, controller));
};
AppConfigurator.prototype.createApplicationRequestHandler = function (routeRequestHandler) {
AppConfigurator.prototype.createApplicationRequestHandler = function (route, controller) {
var _this = this;
return function (req, res) { return __awaiter(_this, void 0, void 0, function () {
var response, error_1;
return __generator(this, function (_a) {
switch (_a.label) {
var context, response, error_1;
var _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_a.trys.push([0, 2, 3, 4]);
return [4 /*yield*/, routeRequestHandler(req, res)];
_b.trys.push([0, 3, 4, 5]);
return [4 /*yield*/, ((_a = controller.getHandler()) === null || _a === void 0 ? void 0 : _a(req, res))];
case 1:
response = _a.sent();
context = _b.sent();
return [4 /*yield*/, route.getRequestHandler()(req, res, context)];
case 2:
response = _b.sent();
if (AppConfigurator.canSendResponse(res)) {

@@ -138,5 +142,5 @@ if (!res.statusCode) {

}
return [3 /*break*/, 4];
case 2:
error_1 = _a.sent();
return [3 /*break*/, 5];
case 3:
error_1 = _b.sent();
if (AppConfigurator.canSendResponse(res)) {

@@ -150,7 +154,7 @@ if (error_1 instanceof request_error_1.RequestError) {

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

@@ -157,0 +161,0 @@ });

@@ -1,6 +0,8 @@

import { RouteConfigurator } from '../route/route';
export declare class ControllerConfiguration {
import { RouteConfigurator } from "../route/route";
export type ControllerHandler<C> = (request: any, response: any) => Promise<C>;
export declare class ControllerConfiguration<C = unknown> {
private _prefix;
private _controllers;
private _routes;
private _handler;
/**

@@ -10,3 +12,3 @@ * Register child controller in controller

*/
registerController(controller: ControllerConfiguration): ControllerConfiguration;
registerController(controller: ControllerConfiguration): this;
/**

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

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

@@ -22,3 +24,3 @@ * Register route in controller

*/
registerRoute(route: RouteConfigurator): ControllerConfiguration;
registerRoute(route: RouteConfigurator<C>): this;
/**

@@ -28,3 +30,3 @@ * Register array of routes in controller

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

@@ -34,7 +36,13 @@ * Register controller prefix which will be used by all routes

*/
prefix(prefix: string): ControllerConfiguration;
prefix(prefix: string): this;
/**
* Register controller handler which will be used by all routes
* @param handler - ControllerHandler function
*/
handler<NewContext>(handler: ControllerHandler<NewContext>): ControllerConfiguration<NewContext>;
getPrefix(): string;
getRoutes(): RouteConfigurator[];
getRoutes(): RouteConfigurator<C>[];
getControllers(): ControllerConfiguration[];
getHandler(): ControllerHandler<C> | undefined;
}
export declare function Controller(): ControllerConfiguration;
export declare function Controller<C = unknown>(): ControllerConfiguration<C>;

@@ -6,3 +6,3 @@ "use strict";

function ControllerConfiguration() {
this._prefix = '';
this._prefix = "";
this._controllers = [];

@@ -59,2 +59,10 @@ this._routes = [];

};
/**
* Register controller handler which will be used by all routes
* @param handler - ControllerHandler function
*/
ControllerConfiguration.prototype.handler = function (handler) {
this._handler = handler;
return this;
};
ControllerConfiguration.prototype.getPrefix = function () {

@@ -69,2 +77,5 @@ return this._prefix;

};
ControllerConfiguration.prototype.getHandler = function () {
return this._handler;
};
return ControllerConfiguration;

@@ -71,0 +82,0 @@ }());

export { Application, AppConfigurator } from "./application/application";
export { Controller, ControllerConfiguration } from "./controller/controller";
export { Route, RouteConfigurator } from "./route/route";
export { Controller, ControllerConfiguration, ControllerHandler } from "./controller/controller";
export { Route, RouteConfigurator, RouteHandler } from "./route/route";
export { RequestError } from "./error/request.error";
import Express from "express";
export type RouteHandler = (request: Express.Request, response: Express.Response) => unknown;
export type RequestHandler = (request: Express.Request, response: Express.Response) => unknown;
export type RouteHandler<C = unknown> = (request: Express.Request, response: Express.Response, context?: C) => unknown;
export type HttpMethod = "get" | "post" | "head" | "put" | "delete" | "options" | "patch";
export declare class RouteConfigurator {
export declare class RouteConfigurator<C = unknown> {
private _method;

@@ -13,3 +12,3 @@ private _path;

*/
method(method: HttpMethod): RouteConfigurator;
method(method: HttpMethod): this;
/**

@@ -19,3 +18,3 @@ * Register path of route alongside with prefix it is used to create full path

*/
path(path: string): RouteConfigurator;
path(path: string): this;
/**

@@ -25,3 +24,3 @@ * Set request handler, here you can handle request

*/
handler(handler: RouteHandler): RouteConfigurator;
handler(handler: RouteHandler<C>): this;
getMethod(): string;

@@ -33,4 +32,4 @@ getPath(): string;

*/
getRequestHandler(): RequestHandler;
getRequestHandler(): RouteHandler<C>;
}
export declare function Route(): RouteConfigurator;
export declare function Route<C>(): RouteConfigurator<C>;
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });

@@ -78,8 +42,3 @@ exports.Route = exports.RouteConfigurator = void 0;

RouteConfigurator.prototype.getRequestHandler = function () {
var _this = this;
return function (request, response) { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2 /*return*/, this._handler(request, response)];
});
}); };
return this._handler;
};

@@ -86,0 +45,0 @@ return RouteConfigurator;

@@ -5,12 +5,11 @@ import { Route, RouteConfigurator } from "arrow-express";

import { UserService } from "../../../data/services/user.service";
import { AuthorizeGuard } from "../../guards/authorize.guard";
import { UserContext } from "../../guards/authorize.guard";
export function GetMyselfRoute(userService: UserService): RouteConfigurator {
return Route()
export function GetMyselfRoute(userService: UserService): RouteConfigurator<UserContext> {
return Route<UserContext>()
.method("get")
.path("myself")
.handler(async (req): Promise<User> => {
const context = await AuthorizeGuard(req);
.handler(async (req, res, context): Promise<User> => {
return await userService.getUserById(context.userId);
});
}

@@ -5,12 +5,11 @@ import { Route, RouteConfigurator } from "arrow-express";

import { UserService } from "../../../data/services/user.service";
import { AuthorizeGuard } from "../../guards/authorize.guard";
import { UserContext } from "../../guards/authorize.guard";
export function GetUserByIdRoute(userService: UserService): RouteConfigurator {
return Route()
export function GetUserByIdRoute(userService: UserService): RouteConfigurator<UserContext> {
return Route<UserContext>()
.method("get")
.path(":id")
.handler(async (req): Promise<User> => {
await AuthorizeGuard(req);
return await userService.getUserById(Number(req.params.id));
});
}

@@ -1,2 +0,2 @@

import { Controller, ControllerConfiguration, RouteConfigurator } from "arrow-express";
import { Controller, ControllerConfiguration } from "arrow-express";

@@ -6,5 +6,9 @@ import { UserService } from "../../data/services/user.service";

import { GetMyselfRoute } from "./routes/getMyself.route";
import { AuthorizeGuard } from "../guards/authorize.guard";
export function UserController(userService: UserService): ControllerConfiguration {
return Controller().prefix("users").registerRoutes(GetUserByIdRoute(userService), GetMyselfRoute(userService));
return Controller()
.handler(AuthorizeGuard)
.prefix("users")
.registerRoutes(GetUserByIdRoute(userService), GetMyselfRoute(userService));
}
// Express packages
import Express from 'express';
import Compression from 'compression';
import cors from 'cors';
import Express from "express";
import Compression from "compression";
import cors from "cors";
// Api packages
import {Application} from "arrow-express";
import {UserController} from "./api/user/user.controller";
import { Application } from "arrow-express";
import { UserController } from "./api/user/user.controller";
// Data packages
import { UserService } from './data/services/user.service';
import { UserService } from "./data/services/user.service";

@@ -22,3 +22,3 @@ async function startServer() {

Application({
app: expressApplication
app: expressApplication,
})

@@ -25,0 +25,0 @@ .registerController(UserController(userService))

@@ -1,9 +0,9 @@

import Express from 'express';
import Express from "express";
import { Application } from './application';
import { Controller } from '../controller/controller';
import { Route } from '../route/route';
import { RequestError } from '../error/request.error';
import {mocked} from "ts-jest/utils";
import {ConfigurationError} from "../error/configuration.error";
import { Application } from "./application";
import { Controller } from "../controller/controller";
import { Route } from "../route/route";
import { RequestError } from "../error/request.error";
import { mocked } from "ts-jest/utils";
import { ConfigurationError } from "../error/configuration.error";

@@ -15,8 +15,7 @@ const ExpressAppStub: Express.Application = {

_router: {
stack: []
}
stack: [],
},
} as unknown as Express.Application;
describe('Application', () => {
describe("Application", () => {
afterEach(() => {

@@ -27,103 +26,66 @@ mocked(ExpressAppStub.use).mockReset();

});
describe('configure', () => {
it('should throw error if app is configured multiple times', () => {
const testApplication = Application({app: ExpressAppStub, logRequests: false});
describe("configure", () => {
it("should throw error if app is configured multiple times", () => {
const testApplication = Application({ app: ExpressAppStub, logRequests: false });
testApplication.configure(false);
expect(testApplication.configure). toThrow();
expect(testApplication.configure).toThrow();
});
describe('route registration', () => {
it('should register post route', () => {
describe("route registration", () => {
it("should register post route", () => {
const handlerSpy = jest.fn();
Application({app: ExpressAppStub, logRequests: false})
Application({ app: ExpressAppStub, logRequests: false })
.registerController(
Controller()
.prefix('prefix')
.registerRoute(
Route()
.method('post')
.path('path')
.handler(handlerSpy)
)
).configure(false);
expect(ExpressAppStub.post).toHaveBeenCalledWith('/prefix/path', expect.any(Function));
Controller().prefix("prefix").registerRoute(Route().method("post").path("path").handler(handlerSpy))
)
.configure(false);
expect(ExpressAppStub.post).toHaveBeenCalledWith("/prefix/path", expect.any(Function));
});
it('should register get route', () => {
it("should register get route", () => {
const handlerSpy = jest.fn();
Application({app: ExpressAppStub, logRequests: false})
Application({ app: ExpressAppStub, logRequests: false })
.registerController(
Controller().prefix('prefix')
.registerRoute(
Route()
.method('get')
.path('')
.handler(handlerSpy)
)
).configure(false);
expect(ExpressAppStub.get).toHaveBeenCalledWith('/prefix', expect.any(Function));
Controller().prefix("prefix").registerRoute(Route().method("get").path("").handler(handlerSpy))
)
.configure(false);
expect(ExpressAppStub.get).toHaveBeenCalledWith("/prefix", expect.any(Function));
});
it('should register route without path', () => {
it("should register route without path", () => {
const handlerSpy = jest.fn();
Application({app: ExpressAppStub})
.registerController(
Controller().prefix('prefix')
.registerRoute(
Route()
.method('get')
.handler(handlerSpy)
)
).configure(false);
expect(ExpressAppStub.get).toHaveBeenCalledWith('/prefix', expect.any(Function));
Application({ app: ExpressAppStub })
.registerController(Controller().prefix("prefix").registerRoute(Route().method("get").handler(handlerSpy)))
.configure(false);
expect(ExpressAppStub.get).toHaveBeenCalledWith("/prefix", expect.any(Function));
});
it('should register route without path and prefix', () => {
it("should register route without path and prefix", () => {
const handlerSpy = jest.fn();
Application({app: ExpressAppStub})
.registerController(
Controller()
.registerRoute(
Route()
.method('get')
.handler(handlerSpy)
)
).configure(false);
expect(ExpressAppStub.get).toHaveBeenCalledWith('/', expect.any(Function));
Application({ app: ExpressAppStub })
.registerController(Controller().registerRoute(Route().method("get").handler(handlerSpy)))
.configure(false);
expect(ExpressAppStub.get).toHaveBeenCalledWith("/", expect.any(Function));
});
it('should throw configuration error when route without method is registered', () => {
it("should throw configuration error when route without method is registered", () => {
const handlerSpy = jest.fn();
const app = Application({app: ExpressAppStub})
.registerController(
Controller().prefix('prefix')
.registerRoute(
Route()
.path('')
.handler(handlerSpy)
)
);
const app = Application({ app: ExpressAppStub }).registerController(
Controller().prefix("prefix").registerRoute(Route().path("").handler(handlerSpy))
);
expect(() => app.configure(false)).toThrow(ConfigurationError);
});
describe('sub controllers', () => {
it('should register sub controller route', () => {
describe("sub controllers", () => {
it("should register sub controller route", () => {
const handlerSpy = jest.fn();
Application({app: ExpressAppStub})
Application({ app: ExpressAppStub })
.registerController(
Controller()
.prefix('root')
.registerController(
Controller()
.prefix('sub')
.registerRoute(
Route()
.method('get')
.handler(handlerSpy)
)
)
).configure(false);
expect(ExpressAppStub.get).toHaveBeenCalledWith('/root/sub', expect.any(Function));
.prefix("root")
.registerController(Controller().prefix("sub").registerRoute(Route().method("get").handler(handlerSpy)))
)
.configure(false);
expect(ExpressAppStub.get).toHaveBeenCalledWith("/root/sub", expect.any(Function));
});

@@ -133,6 +95,6 @@ });

});
describe('request handling', () => {
describe("request handling", () => {
let resSpy: Express.Response;
beforeEach(() => {
resSpy= {
resSpy = {
status: jest.fn().mockImplementation(() => resSpy),

@@ -143,44 +105,26 @@ send: jest.fn().mockImplementation(() => resSpy),

});
it('should response 200', async () => {
it("should response 200", async () => {
const spy = jest.fn();
Application({app: ExpressAppStub, logRequests: false})
.registerController(
Controller()
.registerRoute(
Route()
.method('get')
.handler(spy)
)
).configure(false);
Application({ app: ExpressAppStub, logRequests: false })
.registerController(Controller().registerRoute(Route().method("get").handler(spy)))
.configure(false);
await mocked(ExpressAppStub.get).mock.calls[0][1]({} as never, resSpy);
expect(resSpy.status).toHaveBeenCalledWith(200);
});
it('should not override statusCode', async () => {
it("should not override statusCode", async () => {
const spy = jest.fn();
resSpy.statusCode = 301;
Application({app: ExpressAppStub, logRequests: false})
.registerController(
Controller()
.registerRoute(
Route()
.method('get')
.handler(spy)
)
).configure(false);
Application({ app: ExpressAppStub, logRequests: false })
.registerController(Controller().registerRoute(Route().method("get").handler(spy)))
.configure(false);
await mocked(ExpressAppStub.get).mock.calls[0][1]({} as never, resSpy);
expect(resSpy.status).not.toHaveBeenCalledWith(200);
});
it('should not response 200 when res is not writable', async () => {
it("should not response 200 when res is not writable", async () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(resSpy.writableEnded as boolean) = true;
const spy = jest.fn();
Application({app: ExpressAppStub, logRequests: false})
.registerController(
Controller()
.registerRoute(
Route()
.method('get')
.handler(spy)
)
).configure(false);
Application({ app: ExpressAppStub, logRequests: false })
.registerController(Controller().registerRoute(Route().method("get").handler(spy)))
.configure(false);
await mocked(ExpressAppStub.get).mock.calls[0][1]({} as never, resSpy);

@@ -190,60 +134,36 @@ expect(resSpy.status).not.toHaveBeenCalled();

describe('error handling', () => {
it('should response code 500 by default', async () => {
describe("error handling", () => {
it("should response code 500 by default", async () => {
const spy = jest.fn().mockRejectedValue(new RequestError());
Application({app: ExpressAppStub, logRequests: false})
.registerController(
Controller()
.registerRoute(
Route()
.method('get')
.handler(spy)
)
).configure(false);
Application({ app: ExpressAppStub, logRequests: false })
.registerController(Controller().registerRoute(Route().method("get").handler(spy)))
.configure(false);
await mocked(ExpressAppStub.get).mock.calls[0][1]({} as never, resSpy);
expect(resSpy.status).toHaveBeenCalledWith(500);
});
it('should response code 500 on non RequestError', async () => {
it("should response code 500 on non RequestError", async () => {
const spy = jest.fn().mockRejectedValue(new Error());
Application({app: ExpressAppStub, logRequests: false})
.registerController(
Controller()
.registerRoute(
Route()
.method('get')
.handler(spy)
)
).configure(false);
Application({ app: ExpressAppStub, logRequests: false })
.registerController(Controller().registerRoute(Route().method("get").handler(spy)))
.configure(false);
await mocked(ExpressAppStub.get).mock.calls[0][1]({} as never, resSpy);
expect(resSpy.status).toHaveBeenCalledWith(500);
});
it('should response 404', async () => {
it("should response 404", async () => {
const spy = jest.fn().mockRejectedValue(new RequestError(404));
Application({app: ExpressAppStub, logRequests: false})
.registerController(
Controller()
.registerRoute(
Route()
.method('get')
.handler(spy)
)
).configure(false);
Application({ app: ExpressAppStub, logRequests: false })
.registerController(Controller().registerRoute(Route().method("get").handler(spy)))
.configure(false);
await mocked(ExpressAppStub.get).mock.calls[0][1]({} as never, resSpy);
expect(resSpy.status).toHaveBeenCalledWith(404);
});
it('should send error response', async () => {
it("should send error response", async () => {
const response = {
code: 1,
message: 'msg'
message: "msg",
};
const spy = jest.fn().mockRejectedValue(new RequestError(401, response));
Application({app: ExpressAppStub, logRequests: false})
.registerController(
Controller()
.registerRoute(
Route()
.method('get')
.handler(spy)
)
).configure(false);
Application({ app: ExpressAppStub, logRequests: false })
.registerController(Controller().registerRoute(Route().method("get").handler(spy)))
.configure(false);
await mocked(ExpressAppStub.get).mock.calls[0][1]({} as never, resSpy);

@@ -253,20 +173,44 @@ expect(resSpy.send).toHaveBeenCalledWith(response);

});
it('should not response', async () => {
it("should not response", async () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(resSpy.writableEnded as boolean) = true;
const spy = jest.fn().mockRejectedValue(new Error());
Application({app: ExpressAppStub, logRequests: false})
.registerController(
Controller()
.registerRoute(
Route()
.method('get')
.handler(spy)
)
).configure(false);
Application({ app: ExpressAppStub, logRequests: false })
.registerController(Controller().registerRoute(Route().method("get").handler(spy)))
.configure(false);
await mocked(ExpressAppStub.get).mock.calls[0][1]({} as never, resSpy);
expect(resSpy.status).not.toHaveBeenCalled();
});
it("should pass context from controller handler to route handler", async () => {
const spy = jest.fn().mockResolvedValue("context");
const routeSpy = jest.fn();
Application({ app: ExpressAppStub, logRequests: false })
.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(), "context");
});
it("should call controller handler", async () => {
const spy = jest.fn().mockRejectedValue(new Error());
Application({ app: ExpressAppStub, logRequests: false })
.registerController(Controller().handler(spy).registerRoute(Route().method("get")))
.configure(false);
await mocked(ExpressAppStub.get).mock.calls[0][1]({} as never, resSpy);
expect(spy).toHaveBeenCalled();
});
it("should send error response from controller handler", async () => {
const response = {
code: 1,
message: "msg",
};
const spy = jest.fn().mockRejectedValue(new RequestError(401, response));
Application({ app: ExpressAppStub, logRequests: false })
.registerController(Controller().handler(spy).registerRoute(Route().method("get")))
.configure(false);
await mocked(ExpressAppStub.get).mock.calls[0][1]({} as never, resSpy);
expect(resSpy.send).toHaveBeenCalledWith(response);
expect(resSpy.status).toHaveBeenCalledWith(401);
});
});
});
});
import Express from "express";
import { ControllerConfiguration } from "../controller/controller";
import { RequestHandler, RouteConfigurator } from "../route/route";
import { RouteHandler, RouteConfigurator } from "../route/route";
import { RequestError } from "../error/request.error";

@@ -87,9 +87,13 @@ import { ConfigurationError } from "../error/configuration.error";

this._express[route.getMethod()](`/${routePath}`, this.createApplicationRequestHandler(route.getRequestHandler()));
this._express[route.getMethod()](`/${routePath}`, this.createApplicationRequestHandler(route, controller));
}
private createApplicationRequestHandler(routeRequestHandler: RequestHandler): Express.RequestHandler {
private createApplicationRequestHandler(
route: RouteConfigurator,
controller: ControllerConfiguration
): Express.RequestHandler {
return async (req: Express.Request, res: Express.Response) => {
try {
const response = await routeRequestHandler(req, res);
const context = await controller.getHandler()?.(req, res);
const response = await route.getRequestHandler()(req, res, context);
if (AppConfigurator.canSendResponse(res)) {

@@ -96,0 +100,0 @@ if (!res.statusCode) {

@@ -1,7 +0,9 @@

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

@@ -12,3 +14,3 @@ /**

*/
registerController(controller: ControllerConfiguration): ControllerConfiguration {
registerController(controller: ControllerConfiguration): this {
this._controllers.push(controller);

@@ -18,3 +20,2 @@ return this;

/**

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

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

@@ -34,3 +35,3 @@ return this;

*/
registerRoute(route: RouteConfigurator): ControllerConfiguration {
registerRoute(route: RouteConfigurator<C>): this {
this._routes.push(route);

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

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

@@ -53,3 +54,3 @@ return this;

*/
prefix(prefix: string): ControllerConfiguration {
prefix(prefix: string): this {
this._prefix = prefix;

@@ -59,2 +60,11 @@ return this;

/**
* Register controller handler which will be used by all routes
* @param handler - ControllerHandler function
*/
handler<NewContext>(handler: ControllerHandler<NewContext>): ControllerConfiguration<NewContext> {
this._handler = handler as unknown as ControllerHandler<C>;
return this as unknown as ControllerConfiguration<NewContext>;
}
getPrefix(): string {

@@ -64,3 +74,3 @@ return this._prefix;

getRoutes(): RouteConfigurator[] {
getRoutes(): RouteConfigurator<C>[] {
return this._routes;

@@ -72,6 +82,10 @@ }

}
getHandler(): ControllerHandler<C> | undefined {
return this._handler;
}
}
export function Controller(): ControllerConfiguration {
return new ControllerConfiguration();
export function Controller<C = unknown>(): ControllerConfiguration<C> {
return new ControllerConfiguration<C>();
}
/* istanbul ignore file */
export { Application, AppConfigurator } from "./application/application";
export { Controller, ControllerConfiguration } from "./controller/controller";
export { Route, RouteConfigurator } from "./route/route";
export { RequestError } from "./error/request.error";
export { Controller, ControllerConfiguration, ControllerHandler } from "./controller/controller";
export { Route, RouteConfigurator, RouteHandler } from "./route/route";
export { RequestError } from "./error/request.error";
import Express from "express";
export type RouteHandler = (request: Express.Request, response: Express.Response) => unknown;
export type RequestHandler = (request: Express.Request, response: Express.Response) => unknown;
export type RouteHandler<C = unknown> = (request: Express.Request, response: Express.Response, context?: C) => unknown;
export type HttpMethod = "get" | "post" | "head" | "put" | "delete" | "options" | "patch";
export class RouteConfigurator {
export class RouteConfigurator<C = unknown> {
private _method: HttpMethod;
private _path: string;
private _handler: RouteHandler;
private _handler: RouteHandler<C>;

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

*/
method(method: HttpMethod): RouteConfigurator {
method(method: HttpMethod): this {
this._method = method || "get";

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

path(path: string): RouteConfigurator {
path(path: string): this {
this._path = path;

@@ -36,3 +35,3 @@ return this;

*/
handler(handler: RouteHandler): RouteConfigurator {
handler(handler: RouteHandler<C>): this {
this._handler = handler;

@@ -54,11 +53,9 @@ return this;

*/
getRequestHandler(): RequestHandler {
return async (request: Express.Request, response: Express.Response) => {
return this._handler(request, response);
};
getRequestHandler(): RouteHandler<C> {
return this._handler;
}
}
export function Route(): RouteConfigurator {
return new RouteConfigurator();
export function Route<C>(): RouteConfigurator<C> {
return new RouteConfigurator<C>();
}
{
"name": "arrow-express",
"version": "1.0.1",
"version": "1.1.0",
"description": "Library to bootstrap express applications with zero configuration",

@@ -25,2 +25,3 @@ "main": "dist/index.js",

"devDependencies": {
"@changesets/cli": "^2.26.1",
"@types/express": "^4.17.11",

@@ -27,0 +28,0 @@ "@types/jest": "^26.0.20",

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