framework-do-dede 0.0.13 → 0.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/decorators/controller.d.ts +35 -0
- package/dist/decorators/controller.js +88 -0
- package/dist/decorators/di.d.ts +1 -0
- package/dist/decorators/di.js +7 -0
- package/dist/decorators/index.d.ts +4 -0
- package/dist/decorators/index.js +4 -0
- package/dist/decorators/usecase.d.ts +1 -0
- package/dist/decorators/usecase.js +5 -0
- package/dist/dede.d.ts +15 -44
- package/dist/dede.js +29 -0
- package/dist/di/registry.d.ts +15 -0
- package/dist/di/registry.js +47 -0
- package/dist/handlers/controller.handler.d.ts +6 -0
- package/dist/handlers/controller.handler.js +77 -0
- package/dist/handlers/index.d.ts +2 -0
- package/dist/handlers/index.js +2 -0
- package/dist/http/ElysiaHttpServer.d.ts +5 -0
- package/dist/http/ElysiaHttpServer.js +13 -0
- package/dist/http/ExpressHttpServer.d.ts +5 -0
- package/dist/http/ExpressHttpServer.js +14 -0
- package/dist/http/FrameworkError.d.ts +3 -0
- package/dist/http/FrameworkError.js +5 -0
- package/dist/http/HttpServer.d.ts +31 -0
- package/dist/http/HttpServer.js +91 -0
- package/dist/http/ServerError.d.ts +23 -0
- package/dist/http/ServerError.js +41 -0
- package/dist/http/index.d.ts +3 -0
- package/dist/http/index.js +3 -0
- package/dist/index.d.ts +12 -35
- package/dist/index.js +26 -15466
- package/dist/protocols/Controller.d.ts +14 -0
- package/dist/protocols/Controller.js +1 -0
- package/dist/protocols/HttpMiddleware.d.ts +3 -0
- package/dist/protocols/HttpMiddleware.js +1 -0
- package/dist/protocols/UseCase.d.ts +3 -0
- package/dist/protocols/UseCase.js +1 -0
- package/dist/protocols/Validation.d.ts +3 -0
- package/dist/protocols/Validation.js +1 -0
- package/dist/protocols/index.d.ts +4 -0
- package/dist/protocols/index.js +1 -0
- package/package.json +15 -6
- package/dist/Controller.d.ts +0 -13
- package/dist/ElysiaHttpServer.d.ts +0 -12
- package/dist/ExpressHttpServer.d.ts +0 -13
- package/dist/FrameworkError.d.ts +0 -5
- package/dist/HttpMiddleware.d.ts +0 -3
- package/dist/HttpServer.d.ts +0 -114
- package/dist/ServerError.d.ts +0 -42
- package/dist/UseCase.d.ts +0 -3
- package/dist/Validation.d.ts +0 -3
- package/dist/controller.d.ts +0 -11
- package/dist/controller.handler.d.ts +0 -86
- package/dist/di.d.ts +0 -1
- package/dist/example.d.ts +0 -40
- package/dist/index.cjs +0 -15485
- package/dist/registry.d.ts +0 -4
- package/dist/usecase.d.ts +0 -1
- package/dist/usecase.handler.d.ts +0 -23
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Validation } from "@/protocols/Validation";
|
|
2
|
+
import { HttpMiddleware } from "@/protocols";
|
|
3
|
+
export declare function Controller(basePath: string): (target: any) => void;
|
|
4
|
+
export declare function Middleware(middlewareClass: new () => HttpMiddleware): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
|
|
5
|
+
export declare function Post(config?: {
|
|
6
|
+
path?: string;
|
|
7
|
+
statusCode?: number;
|
|
8
|
+
params?: string[];
|
|
9
|
+
query?: string[];
|
|
10
|
+
}): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
|
|
11
|
+
export declare function Get(config?: {
|
|
12
|
+
path?: string;
|
|
13
|
+
statusCode?: number;
|
|
14
|
+
params?: string[];
|
|
15
|
+
query?: string[];
|
|
16
|
+
}): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
|
|
17
|
+
export declare function Put(config?: {
|
|
18
|
+
path?: string;
|
|
19
|
+
statusCode?: number;
|
|
20
|
+
params?: string[];
|
|
21
|
+
query?: string[];
|
|
22
|
+
}): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
|
|
23
|
+
export declare function Patch(config?: {
|
|
24
|
+
path?: string;
|
|
25
|
+
statusCode?: number;
|
|
26
|
+
params?: string[];
|
|
27
|
+
query?: string[];
|
|
28
|
+
}): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
|
|
29
|
+
export declare function Delete(config?: {
|
|
30
|
+
path?: string;
|
|
31
|
+
statusCode?: number;
|
|
32
|
+
params?: string[];
|
|
33
|
+
query?: string[];
|
|
34
|
+
}): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
|
|
35
|
+
export declare function Validator(validationClass: new () => Validation): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { FrameworkError } from "@/http/FrameworkError";
|
|
2
|
+
import { Registry } from "@/di/registry";
|
|
3
|
+
const middlewares = new Map();
|
|
4
|
+
export function Controller(basePath) {
|
|
5
|
+
return function (target) {
|
|
6
|
+
Reflect.defineMetadata('basePath', basePath, target);
|
|
7
|
+
if (!Registry.has('controllers'))
|
|
8
|
+
Registry.register('controllers', []);
|
|
9
|
+
Registry.addDependency('controllers', target);
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function Middleware(middlewareClass) {
|
|
13
|
+
return function (target, propertyKey, descriptor) {
|
|
14
|
+
if (typeof middlewareClass.prototype.execute !== 'function') {
|
|
15
|
+
throw new FrameworkError('The concrete class does not implement the Middleware interface.');
|
|
16
|
+
}
|
|
17
|
+
// Retrieve existing middlewares for this method or initialize an empty array
|
|
18
|
+
const middlewares = Reflect.getMetadata('middlewares', target, propertyKey) || [];
|
|
19
|
+
// Create a new instance of the middleware and add it to the array
|
|
20
|
+
const middlewareInstance = new middlewareClass();
|
|
21
|
+
middlewares.push(middlewareInstance);
|
|
22
|
+
// Update the metadata with the new array of middleware instances
|
|
23
|
+
Reflect.defineMetadata('middlewares', middlewares, target, propertyKey);
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export function Post(config = {}) {
|
|
27
|
+
return function (target, propertyKey, descriptor) {
|
|
28
|
+
Reflect.defineMetadata('route', {
|
|
29
|
+
method: 'post',
|
|
30
|
+
path: config.path || '',
|
|
31
|
+
params: config.params,
|
|
32
|
+
query: config.query,
|
|
33
|
+
statusCode: config.statusCode || 200
|
|
34
|
+
}, target, propertyKey);
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export function Get(config = {}) {
|
|
38
|
+
return function (target, propertyKey, descriptor) {
|
|
39
|
+
Reflect.defineMetadata('route', {
|
|
40
|
+
method: 'get',
|
|
41
|
+
path: config.path || '',
|
|
42
|
+
params: config.params,
|
|
43
|
+
query: config.query,
|
|
44
|
+
statusCode: config.statusCode || 200
|
|
45
|
+
}, target, propertyKey);
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export function Put(config = {}) {
|
|
49
|
+
return function (target, propertyKey, descriptor) {
|
|
50
|
+
Reflect.defineMetadata('route', {
|
|
51
|
+
method: 'put',
|
|
52
|
+
path: config.path || '',
|
|
53
|
+
params: config.params,
|
|
54
|
+
query: config.query,
|
|
55
|
+
statusCode: config.statusCode || 200
|
|
56
|
+
}, target, propertyKey);
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export function Patch(config = {}) {
|
|
60
|
+
return function (target, propertyKey, descriptor) {
|
|
61
|
+
Reflect.defineMetadata('route', {
|
|
62
|
+
method: 'patch',
|
|
63
|
+
path: config.path || '',
|
|
64
|
+
params: config.params,
|
|
65
|
+
query: config.query,
|
|
66
|
+
statusCode: config.statusCode || 200
|
|
67
|
+
}, target, propertyKey);
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export function Delete(config = {}) {
|
|
71
|
+
return function (target, propertyKey, descriptor) {
|
|
72
|
+
Reflect.defineMetadata('route', {
|
|
73
|
+
method: 'delete',
|
|
74
|
+
path: config.path || '',
|
|
75
|
+
params: config.params,
|
|
76
|
+
query: config.query,
|
|
77
|
+
statusCode: config.statusCode || 200
|
|
78
|
+
}, target, propertyKey);
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
export function Validator(validationClass) {
|
|
82
|
+
return function (target, propertyKey, descriptor) {
|
|
83
|
+
if (typeof validationClass.prototype.validate !== 'function') {
|
|
84
|
+
throw new FrameworkError('the concrete class does not implement Validation class".');
|
|
85
|
+
}
|
|
86
|
+
Reflect.defineMetadata('validation', new validationClass(), target, propertyKey);
|
|
87
|
+
};
|
|
88
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function Inject(token: string): (target: any, propertyKey: string | symbol | undefined, parameterIndex: number) => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function Auth(propertyName?: string): Function;
|
package/dist/dede.d.ts
CHANGED
|
@@ -1,47 +1,18 @@
|
|
|
1
|
-
export
|
|
2
|
-
name: string
|
|
3
|
-
classLoader: any
|
|
4
|
-
autoLoad?: boolean
|
|
5
|
-
}
|
|
6
|
-
|
|
1
|
+
export type Register = {
|
|
2
|
+
name: string;
|
|
3
|
+
classLoader: any;
|
|
4
|
+
autoLoad?: boolean;
|
|
5
|
+
};
|
|
7
6
|
export type Options = {
|
|
8
7
|
framework: {
|
|
9
|
-
use: 'elysia' | 'express'
|
|
10
|
-
port?: number
|
|
11
|
-
middlewares?: CallableFunction[]
|
|
12
|
-
}
|
|
13
|
-
registries: Register[]
|
|
8
|
+
use: 'elysia' | 'express';
|
|
9
|
+
port?: number;
|
|
10
|
+
middlewares?: CallableFunction[];
|
|
11
|
+
};
|
|
12
|
+
registries: Register[];
|
|
13
|
+
};
|
|
14
|
+
export declare class Dede {
|
|
15
|
+
static init({ framework, registries }: Options): Promise<void>;
|
|
16
|
+
private static clearControllers;
|
|
17
|
+
private static loadRegistries;
|
|
14
18
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
export class Dede {
|
|
18
|
-
static async init ({ framework, registries }: Options): Promise<void> {
|
|
19
|
-
this.registerControllers();
|
|
20
|
-
await this.loadRegistries(registries);
|
|
21
|
-
let httpServer!: HttpServer
|
|
22
|
-
if (framework.use === 'elysia') {
|
|
23
|
-
httpServer = new ElysiaHttpServer(framework.middlewares || [])
|
|
24
|
-
}
|
|
25
|
-
if (framework.use === 'express') {
|
|
26
|
-
httpServer = new ExpressHttpServer(framework.middlewares || [])
|
|
27
|
-
}
|
|
28
|
-
new ControllerHandler(httpServer, framework.port || 80)
|
|
29
|
-
this.clearControllers()
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
private static registerControllers() {
|
|
34
|
-
Registry.register('controllers', []);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
private static clearControllers() {
|
|
38
|
-
Registry.clear('controllers');
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
private static async loadRegistries(registries: Register []) {
|
|
42
|
-
registries.forEach(({ classLoader, name, autoLoad = true}) => {
|
|
43
|
-
if (autoLoad) Registry.register(name, Registry.classLoader(classLoader));
|
|
44
|
-
else Registry.register(name, classLoader);
|
|
45
|
-
})
|
|
46
|
-
}
|
|
47
|
-
}
|
package/dist/dede.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Registry } from "./di/registry";
|
|
2
|
+
import { ControllerHandler } from "./handlers";
|
|
3
|
+
import { ElysiaHttpServer } from "./http/ElysiaHttpServer";
|
|
4
|
+
import { ExpressHttpServer } from "./http/ExpressHttpServer";
|
|
5
|
+
export class Dede {
|
|
6
|
+
static async init({ framework, registries }) {
|
|
7
|
+
await this.loadRegistries(registries);
|
|
8
|
+
let httpServer;
|
|
9
|
+
if (framework.use === 'elysia') {
|
|
10
|
+
httpServer = new ElysiaHttpServer(framework.middlewares || []);
|
|
11
|
+
}
|
|
12
|
+
if (framework.use === 'express') {
|
|
13
|
+
httpServer = new ExpressHttpServer(framework.middlewares || []);
|
|
14
|
+
}
|
|
15
|
+
new ControllerHandler(httpServer, framework.port || 80);
|
|
16
|
+
this.clearControllers();
|
|
17
|
+
}
|
|
18
|
+
static clearControllers() {
|
|
19
|
+
Registry.clear('controllers');
|
|
20
|
+
}
|
|
21
|
+
static async loadRegistries(registries) {
|
|
22
|
+
registries.forEach(({ classLoader, name, autoLoad = true }) => {
|
|
23
|
+
if (autoLoad)
|
|
24
|
+
Registry.register(name, Registry.classLoader(classLoader));
|
|
25
|
+
else
|
|
26
|
+
Registry.register(name, classLoader);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
declare class ComponentRegistry {
|
|
3
|
+
private static instance;
|
|
4
|
+
private dependencies;
|
|
5
|
+
static getInstance(): ComponentRegistry;
|
|
6
|
+
register(token: string, dependency: any): void;
|
|
7
|
+
has(token: string): boolean;
|
|
8
|
+
addDependency(token: string, dependency: any): void;
|
|
9
|
+
resolve<T>(token: string): T;
|
|
10
|
+
clear(token: string): void;
|
|
11
|
+
classLoader<T>(target: new (...args: any[]) => T): T;
|
|
12
|
+
inject(token: string): (target: any, propertyKey: string | symbol | undefined, parameterIndex: number) => void;
|
|
13
|
+
}
|
|
14
|
+
export declare const Registry: ComponentRegistry;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Inject } from '@/decorators';
|
|
2
|
+
import 'reflect-metadata';
|
|
3
|
+
class ComponentRegistry {
|
|
4
|
+
static instance;
|
|
5
|
+
dependencies = new Map();
|
|
6
|
+
static getInstance() {
|
|
7
|
+
if (!this.instance) {
|
|
8
|
+
this.instance = new ComponentRegistry();
|
|
9
|
+
}
|
|
10
|
+
return this.instance;
|
|
11
|
+
}
|
|
12
|
+
register(token, dependency) {
|
|
13
|
+
this.dependencies.set(token, dependency);
|
|
14
|
+
}
|
|
15
|
+
has(token) {
|
|
16
|
+
return this.dependencies.has(token);
|
|
17
|
+
}
|
|
18
|
+
addDependency(token, dependency) {
|
|
19
|
+
if (!this.dependencies.has(token))
|
|
20
|
+
throw new Error(`Dependency ${token} not registered`);
|
|
21
|
+
if (!Array.isArray(this.dependencies.get(token)))
|
|
22
|
+
throw new Error("Dependency must be an array");
|
|
23
|
+
this.dependencies.get(token).push(dependency);
|
|
24
|
+
}
|
|
25
|
+
resolve(token) {
|
|
26
|
+
const dependency = this.dependencies.get(token);
|
|
27
|
+
if (!dependency) {
|
|
28
|
+
throw new Error(`Dependency ${token} not registered`);
|
|
29
|
+
}
|
|
30
|
+
return dependency;
|
|
31
|
+
}
|
|
32
|
+
clear(token) {
|
|
33
|
+
const dependency = this.dependencies.get(token);
|
|
34
|
+
if (!dependency)
|
|
35
|
+
return;
|
|
36
|
+
this.dependencies.set(token, null);
|
|
37
|
+
}
|
|
38
|
+
classLoader(target) {
|
|
39
|
+
const paramtypes = Reflect.getMetadata('injections', target) || [];
|
|
40
|
+
const args = paramtypes.map((token) => ComponentRegistry.getInstance().resolve(token));
|
|
41
|
+
return new target(...args);
|
|
42
|
+
}
|
|
43
|
+
inject(token) {
|
|
44
|
+
return Inject(token);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export const Registry = ComponentRegistry.getInstance();
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Registry } from "@/di/registry";
|
|
2
|
+
export default class ControllerHandler {
|
|
3
|
+
constructor(httpServer, port) {
|
|
4
|
+
for (const { instance, instanceMethod, middlewares, method, route, statusCode, params, query, validation } of this.registryControllers()) {
|
|
5
|
+
httpServer.register({
|
|
6
|
+
method,
|
|
7
|
+
route,
|
|
8
|
+
statusCode,
|
|
9
|
+
params,
|
|
10
|
+
query
|
|
11
|
+
}, async (input) => {
|
|
12
|
+
const filterParams = this.filter(input.params, params);
|
|
13
|
+
const queryParams = this.filter(input.query, query);
|
|
14
|
+
let mergedParams = { ...filterParams, ...queryParams, ...(input.body || {}) };
|
|
15
|
+
if (validation)
|
|
16
|
+
mergedParams = validation.validate({ ...filterParams, ...queryParams, ...(input.body || {}) });
|
|
17
|
+
let middlewareData = {};
|
|
18
|
+
if (middlewares) {
|
|
19
|
+
for (const middleware of middlewares) {
|
|
20
|
+
const middlewareResult = await middleware.execute({ headers: input.headers, ...mergedParams });
|
|
21
|
+
middlewareData = { ...middlewareResult, ...middlewareData };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const request = { headers: input.headers, data: mergedParams, middlewareData };
|
|
25
|
+
return await instance[instanceMethod](mergedParams, request);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
httpServer.listen(port);
|
|
29
|
+
}
|
|
30
|
+
registryControllers() {
|
|
31
|
+
const registryControllers = Registry.resolve('controllers');
|
|
32
|
+
const controllers = [];
|
|
33
|
+
for (const controller of registryControllers) {
|
|
34
|
+
const basePath = Reflect.getMetadata('basePath', controller);
|
|
35
|
+
const injections = Reflect.getMetadata('injections', controller) || [];
|
|
36
|
+
const args = injections.map((token) => Registry.resolve(token));
|
|
37
|
+
const instance = new controller(...args);
|
|
38
|
+
const methodNames = Object.getOwnPropertyNames(controller.prototype).filter(method => method !== 'constructor');
|
|
39
|
+
for (const methodName of methodNames) {
|
|
40
|
+
const validation = Reflect.getMetadata('validation', controller.prototype, methodName);
|
|
41
|
+
const routeConfig = Reflect.getMetadata('route', controller.prototype, methodName);
|
|
42
|
+
const middlewares = Reflect.getMetadata('middlewares', controller.prototype, methodName);
|
|
43
|
+
controllers.push({
|
|
44
|
+
method: routeConfig.method,
|
|
45
|
+
route: basePath + routeConfig.path,
|
|
46
|
+
params: routeConfig.params,
|
|
47
|
+
query: routeConfig.query,
|
|
48
|
+
statusCode: routeConfig.statusCode,
|
|
49
|
+
instance,
|
|
50
|
+
instanceMethod: methodName,
|
|
51
|
+
middlewares,
|
|
52
|
+
validation
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return controllers;
|
|
57
|
+
}
|
|
58
|
+
filter(params, filterParams) {
|
|
59
|
+
const filter = {};
|
|
60
|
+
for (const paramName of filterParams || []) {
|
|
61
|
+
const [paramNameFiltered, type] = paramName.split('|');
|
|
62
|
+
let value = params[paramName] || params[paramNameFiltered];
|
|
63
|
+
if (!value)
|
|
64
|
+
return;
|
|
65
|
+
if (type === 'boolean')
|
|
66
|
+
value = value === 'true';
|
|
67
|
+
if (type === 'integer') {
|
|
68
|
+
value = value.replace(/[^0-9]/g, '');
|
|
69
|
+
value = value ? parseInt(value) : 0;
|
|
70
|
+
}
|
|
71
|
+
if (type === 'string')
|
|
72
|
+
value = value.toString();
|
|
73
|
+
filter[paramNameFiltered] = value;
|
|
74
|
+
}
|
|
75
|
+
return filter;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// @ts-ignore
|
|
2
|
+
import Elysia from "elysia";
|
|
3
|
+
import HttpServer from "./HttpServer";
|
|
4
|
+
export class ElysiaHttpServer extends HttpServer {
|
|
5
|
+
constructor(uses) {
|
|
6
|
+
super(new Elysia(), 'elysia');
|
|
7
|
+
uses?.forEach(use => this.framework.use(use));
|
|
8
|
+
}
|
|
9
|
+
listen(port) {
|
|
10
|
+
super.listen(port);
|
|
11
|
+
console.log(`Server listening on port ${port}`);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// @ts-ignore
|
|
2
|
+
import express from "express";
|
|
3
|
+
import HttpServer from "./HttpServer";
|
|
4
|
+
const app = express();
|
|
5
|
+
export class ExpressHttpServer extends HttpServer {
|
|
6
|
+
constructor(uses) {
|
|
7
|
+
super(app, 'express');
|
|
8
|
+
uses?.forEach(use => this.framework.use(use));
|
|
9
|
+
}
|
|
10
|
+
listen(port) {
|
|
11
|
+
super.listen(port);
|
|
12
|
+
console.log(`Server listening on port ${port}`);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export type HttpStatusCode = 200 | 201 | 204 | 401 | 403 | 404 | 409 | 422 | 500;
|
|
2
|
+
export type AllowedMethods = 'get' | 'post' | 'put' | 'delete' | 'patch';
|
|
3
|
+
export type HttpServerParams = {
|
|
4
|
+
method: AllowedMethods;
|
|
5
|
+
route: string;
|
|
6
|
+
statusCode?: number;
|
|
7
|
+
params?: string[];
|
|
8
|
+
query?: string[];
|
|
9
|
+
};
|
|
10
|
+
type FrameworkWeb = {
|
|
11
|
+
listen(port: number): void;
|
|
12
|
+
use(middleware: CallableFunction): void;
|
|
13
|
+
get(route: string, handler: CallableFunction): void;
|
|
14
|
+
post(route: string, handler: CallableFunction): void;
|
|
15
|
+
put(route: string, handler: CallableFunction): void;
|
|
16
|
+
delete(route: string, handler: CallableFunction): void;
|
|
17
|
+
patch(route: string, handler: CallableFunction): void;
|
|
18
|
+
};
|
|
19
|
+
export default abstract class HttpServer {
|
|
20
|
+
protected framework: FrameworkWeb;
|
|
21
|
+
protected frameworkName: string;
|
|
22
|
+
protected defaultMessageError: string;
|
|
23
|
+
constructor(framework: FrameworkWeb, frameworkName: 'elysia' | 'express');
|
|
24
|
+
use(middleware: CallableFunction): HttpServer;
|
|
25
|
+
register(httpServerParams: HttpServerParams, handler: CallableFunction): void;
|
|
26
|
+
listen(port: number): void;
|
|
27
|
+
private mountRoute;
|
|
28
|
+
private elysia;
|
|
29
|
+
private express;
|
|
30
|
+
}
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { FrameworkError } from "./FrameworkError";
|
|
2
|
+
import { ServerError } from "./ServerError";
|
|
3
|
+
export default class HttpServer {
|
|
4
|
+
framework;
|
|
5
|
+
frameworkName;
|
|
6
|
+
defaultMessageError = 'Ops, An unexpected error occurred';
|
|
7
|
+
constructor(framework, frameworkName) {
|
|
8
|
+
if (frameworkName !== 'elysia' && frameworkName !== 'express')
|
|
9
|
+
throw new FrameworkError('Framework not supported');
|
|
10
|
+
this.framework = framework;
|
|
11
|
+
this.frameworkName = frameworkName;
|
|
12
|
+
}
|
|
13
|
+
use(middleware) {
|
|
14
|
+
this.framework.use(middleware);
|
|
15
|
+
return this;
|
|
16
|
+
}
|
|
17
|
+
register(httpServerParams, handler) {
|
|
18
|
+
const route = this.mountRoute(httpServerParams);
|
|
19
|
+
if (this.frameworkName === 'elysia')
|
|
20
|
+
return this.elysia(httpServerParams, route, handler);
|
|
21
|
+
return this.express(httpServerParams, route, handler);
|
|
22
|
+
}
|
|
23
|
+
listen(port) {
|
|
24
|
+
this.framework.listen(port);
|
|
25
|
+
}
|
|
26
|
+
mountRoute(httpServerParams) {
|
|
27
|
+
const params = httpServerParams.params?.map((param) => param.split('|')[0]);
|
|
28
|
+
if (params && params.length > 0) {
|
|
29
|
+
const paramsMounted = params.map((v) => {
|
|
30
|
+
return v.includes('_') ? `${v.replace('_', '/')}` : `/:${v}`;
|
|
31
|
+
}).join('');
|
|
32
|
+
return `${httpServerParams.route}${paramsMounted}`;
|
|
33
|
+
}
|
|
34
|
+
return httpServerParams.route;
|
|
35
|
+
}
|
|
36
|
+
elysia(httpServerParams, route, handler) {
|
|
37
|
+
const method = httpServerParams.method;
|
|
38
|
+
(this.framework[method])(route, async ({ headers, set, query, params, body, request, path }) => {
|
|
39
|
+
try {
|
|
40
|
+
set.status = httpServerParams.statusCode ?? 200;
|
|
41
|
+
const output = await handler({
|
|
42
|
+
headers,
|
|
43
|
+
query,
|
|
44
|
+
params,
|
|
45
|
+
body
|
|
46
|
+
});
|
|
47
|
+
return output;
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
if (error instanceof ServerError) {
|
|
51
|
+
set.status = error.getStatusCode();
|
|
52
|
+
return {
|
|
53
|
+
error: error.message,
|
|
54
|
+
statusCode: error.getStatusCode()
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
set.status = 500;
|
|
58
|
+
return {
|
|
59
|
+
error: this.defaultMessageError,
|
|
60
|
+
statusCode: 500
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
express(httpServerParams, route, handler) {
|
|
66
|
+
const method = httpServerParams.method;
|
|
67
|
+
this.framework[method](route, async (request, res) => {
|
|
68
|
+
try {
|
|
69
|
+
const output = await handler({
|
|
70
|
+
headers: request.headers,
|
|
71
|
+
query: request.query,
|
|
72
|
+
params: request.params,
|
|
73
|
+
body: request.body
|
|
74
|
+
});
|
|
75
|
+
return res.status(httpServerParams.statusCode ?? 200).json(output);
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
if (error instanceof ServerError) {
|
|
79
|
+
return res.status(error.getStatusCode()).json({
|
|
80
|
+
error: error.message,
|
|
81
|
+
statusCode: error.getStatusCode()
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return res.status(500).json({
|
|
85
|
+
error: this.defaultMessageError,
|
|
86
|
+
statusCode: 500
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare abstract class ServerError extends Error {
|
|
2
|
+
private statusCode;
|
|
3
|
+
constructor(message: string, statusCode: number);
|
|
4
|
+
getStatusCode(): number;
|
|
5
|
+
}
|
|
6
|
+
export declare class NotFound extends ServerError {
|
|
7
|
+
constructor(message: string);
|
|
8
|
+
}
|
|
9
|
+
export declare class Forbidden extends ServerError {
|
|
10
|
+
constructor(message: string);
|
|
11
|
+
}
|
|
12
|
+
export declare class UnprocessableEntity extends ServerError {
|
|
13
|
+
constructor(message: string);
|
|
14
|
+
}
|
|
15
|
+
export declare class Conflict extends ServerError {
|
|
16
|
+
constructor(message: string);
|
|
17
|
+
}
|
|
18
|
+
export declare class Unauthorized extends ServerError {
|
|
19
|
+
constructor(message: string);
|
|
20
|
+
}
|
|
21
|
+
export declare class BadRequest extends ServerError {
|
|
22
|
+
constructor(message: string);
|
|
23
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export class ServerError extends Error {
|
|
2
|
+
statusCode;
|
|
3
|
+
constructor(message, statusCode) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = this.constructor.name;
|
|
6
|
+
this.statusCode = statusCode;
|
|
7
|
+
}
|
|
8
|
+
getStatusCode() {
|
|
9
|
+
return this.statusCode;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export class NotFound extends ServerError {
|
|
13
|
+
constructor(message) {
|
|
14
|
+
super(message, 404);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export class Forbidden extends ServerError {
|
|
18
|
+
constructor(message) {
|
|
19
|
+
super(message, 403);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export class UnprocessableEntity extends ServerError {
|
|
23
|
+
constructor(message) {
|
|
24
|
+
super(message, 422);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export class Conflict extends ServerError {
|
|
28
|
+
constructor(message) {
|
|
29
|
+
super(message, 409);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export class Unauthorized extends ServerError {
|
|
33
|
+
constructor(message) {
|
|
34
|
+
super(message, 401);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export class BadRequest extends ServerError {
|
|
38
|
+
constructor(message) {
|
|
39
|
+
super(message, 400);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import HttpServer from "./HttpServer";
|
|
2
|
+
import { ServerError, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, BadRequest } from "./ServerError";
|
|
3
|
+
export { ServerError, BadRequest, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, HttpServer };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import HttpServer from "./HttpServer";
|
|
2
|
+
import { ServerError, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, BadRequest } from "./ServerError";
|
|
3
|
+
export { ServerError, BadRequest, NotFound, Forbidden, Conflict, Unauthorized, UnprocessableEntity, HttpServer };
|