@cleivermejia/backend 1.0.0

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/package.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "@cleivermejia/backend",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "tsx watch src/test.ts",
8
+ "dev": "tsx watch src/index.ts"
9
+ },
10
+ "keywords": [],
11
+ "author": "",
12
+ "license": "ISC",
13
+ "type": "commonjs",
14
+ "devDependencies": {
15
+ "@types/node": "^25.9.2",
16
+ "typescript": "^6.0.3"
17
+ }
18
+ }
@@ -0,0 +1,56 @@
1
+ import { createServer, IncomingMessage, ServerResponse } from "http";
2
+ import type { Route } from "../interface/route";
3
+ import { Response } from "./response";
4
+ import { Router } from "./router";
5
+ import { Request } from "./request";
6
+ import { Metadata } from "./metadata";
7
+ import { Method } from "../enum/method";
8
+
9
+ export class App {
10
+ public router: Router = new Router();
11
+
12
+ public get(path: string, handler: Function) {
13
+ this.router.get(path, handler);
14
+ }
15
+
16
+ public put(path: string, handler: Function) {
17
+ this.router.put(path, handler);
18
+ }
19
+
20
+ public use(controller: Function) {
21
+ const urlBase: string = Metadata.get(controller.prototype["constructor"])?.path ?? "";
22
+
23
+ Object.getOwnPropertyNames(controller.prototype)
24
+ .filter(m => m !== "constructor")
25
+ .forEach((f: string) => {
26
+ const functionController: Function = controller.prototype[f];
27
+ const route: Route | undefined = Metadata.get(functionController);
28
+
29
+ if (route && route.method === Method.GET) {
30
+ this.get(urlBase + route.path, (req: Request, res: Response) => {
31
+ res.send(functionController());
32
+ });
33
+ }
34
+ });
35
+ }
36
+
37
+ public listen(
38
+ port: number,
39
+ hostname?: string,
40
+ handler?: (() => void) | undefined,
41
+ ) {
42
+ const server = createServer(
43
+ (req: IncomingMessage, res: ServerResponse<IncomingMessage>) => {
44
+ const route: Route | undefined = this.router.routes.find(
45
+ (r: Route) => req.method === r.method && req.url === r.path,
46
+ );
47
+
48
+ if (route?.handler) {
49
+ route.handler(new Request(req), new Response(res));
50
+ }
51
+ },
52
+ );
53
+
54
+ server.listen(port, hostname, handler);
55
+ }
56
+ }
@@ -0,0 +1,24 @@
1
+ import { Method } from "../enum/method";
2
+ import { Metadata } from "./metadata";
3
+
4
+ function Controller(path: string) {
5
+ return function (constructor: Function) {
6
+ Metadata.set(constructor, { method: Method.GET, path });
7
+ };
8
+ }
9
+
10
+ function Get(path?: string) {
11
+ return function <This, Args extends any[], Return>(
12
+ value: (this: This, ...args: Args) => Return,
13
+ context: ClassMethodDecoratorContext,
14
+ ) {
15
+ Metadata.set(value, {
16
+ method: Method.GET,
17
+ path: path ?? "",
18
+ });
19
+
20
+ return value;
21
+ };
22
+ }
23
+
24
+ export { Controller, Get };
@@ -0,0 +1,13 @@
1
+ import type { Route } from "../interface/route";
2
+
3
+ export class Metadata {
4
+ private static weakMap: WeakMap<Function, Route> = new WeakMap();
5
+
6
+ public static set(target: Function, value: Route) {
7
+ Metadata.weakMap.set(target, value);
8
+ }
9
+
10
+ public static get(target: Function) {
11
+ return Metadata.weakMap.get(target);
12
+ }
13
+ }
@@ -0,0 +1,5 @@
1
+ import type { IncomingMessage } from "http";
2
+
3
+ export class Request {
4
+ constructor(req: IncomingMessage) {}
5
+ }
@@ -0,0 +1,19 @@
1
+ import type { ServerResponse } from "http";
2
+
3
+ export class Response {
4
+ constructor(private res: ServerResponse) {}
5
+
6
+ public json(data: unknown) {
7
+ this.res.setHeader("Content-Type", "application/json");
8
+ this.res.end(JSON.stringify(data));
9
+ }
10
+
11
+ public html(text: string) {
12
+ this.res.setHeader("Content-Type", "text/html");
13
+ this.res.end(text);
14
+ }
15
+
16
+ public send(text: string) {
17
+ this.res.end(text.toString());
18
+ }
19
+ }
@@ -0,0 +1,38 @@
1
+ import { Method } from "../enum/method";
2
+ import type { Route } from "../interface/route";
3
+
4
+ export class Router {
5
+ public routes: Route[] = [];
6
+
7
+ public get(path: string, handler: Function) {
8
+ this.routes.push({
9
+ method: Method.GET,
10
+ path,
11
+ handler,
12
+ });
13
+ }
14
+
15
+ public put(path: string, handler: Function) {
16
+ this.routes.push({
17
+ method: Method.PUT,
18
+ path,
19
+ handler,
20
+ });
21
+ }
22
+
23
+ public delete(path: string, handler: Function) {
24
+ this.routes.push({
25
+ method: Method.DELETE,
26
+ path,
27
+ handler,
28
+ });
29
+ }
30
+
31
+ public post(path: string, handler: Function) {
32
+ this.routes.push({
33
+ method: Method.POST,
34
+ path,
35
+ handler,
36
+ });
37
+ }
38
+ }
@@ -0,0 +1,6 @@
1
+ export enum Method {
2
+ GET = "GET",
3
+ PUT = "PUT",
4
+ DELETE = "DELETE",
5
+ POST = "POST"
6
+ }
package/src/index.ts ADDED
@@ -0,0 +1,14 @@
1
+ import { App } from "./core/app";
2
+ import type { Request } from "./core/request";
3
+ import type { Response } from "./core/response";
4
+
5
+ const app = new App();
6
+ const PORT = 3000;
7
+
8
+ app.get("/", (req: Request, res: Response) => {
9
+ res.html('<h1>Hola mundo!</h1>');
10
+ });
11
+
12
+ app.listen(PORT, "localhost", () =>
13
+ console.log(`Servidor encendido http://localhost:${PORT}`),
14
+ );
@@ -0,0 +1,7 @@
1
+ import type { Method } from "../enum/method"
2
+
3
+ export interface Route {
4
+ method: Method
5
+ path: string,
6
+ handler?: Function
7
+ }
package/src/test.ts ADDED
@@ -0,0 +1,27 @@
1
+ import { App } from "./core/app";
2
+ import { Controller, Get } from "./core/decorators";
3
+ import type { Request } from "./core/request";
4
+ import type { Response } from "./core/response";
5
+
6
+ const app = new App();
7
+
8
+ @Controller("/user")
9
+ class User {
10
+ @Get()
11
+ getAll() {
12
+ return JSON.stringify({
13
+ "id": 1,
14
+ "name": "jhon"
15
+ });
16
+ }
17
+ }
18
+
19
+ app.use(User);
20
+
21
+ app.get("/user2", (req: Request, res: Response) => {
22
+ res.send("Asi tambien se puede hacer la api!")
23
+ })
24
+
25
+ app.listen(3000, "localhost", () => {
26
+ console.log(":p");
27
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ // Visit https://aka.ms/tsconfig to read more about this file
3
+ "compilerOptions": {
4
+ // File Layout
5
+ // "rootDir": "./src",
6
+ // "outDir": "./dist",
7
+
8
+ // Environment Settings
9
+ // See also https://aka.ms/tsconfig/module
10
+ "module": "esnext",
11
+ "target": "esnext",
12
+ // For nodejs:
13
+ // "lib": ["esnext"],
14
+ "types": ["node"],
15
+ // and npm install -D @types/node
16
+
17
+ // Other Outputs
18
+ "sourceMap": true,
19
+ "declaration": true,
20
+ "declarationMap": true,
21
+
22
+ // Stricter Typechecking Options
23
+ "noUncheckedIndexedAccess": true,
24
+ "exactOptionalPropertyTypes": true,
25
+
26
+ // Style Options
27
+ // "noImplicitReturns": true,
28
+ // "noImplicitOverride": true,
29
+ // "noUnusedLocals": true,
30
+ // "noUnusedParameters": true,
31
+ // "noFallthroughCasesInSwitch": true,
32
+ // "noPropertyAccessFromIndexSignature": true,
33
+
34
+ // Recommended Options
35
+ "strict": true,
36
+ "jsx": "react-jsx",
37
+ "verbatimModuleSyntax": true,
38
+ "isolatedModules": true,
39
+ "noUncheckedSideEffectImports": true,
40
+ "moduleDetection": "force",
41
+ "skipLibCheck": true,
42
+ }
43
+ }