dolphin-server-modules 1.0.2 → 1.0.3
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/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/router/router.d.ts +13 -0
- package/dist/router/router.js +48 -0
- package/dist/router/router.js.map +1 -0
- package/dist/server/server.d.ts +18 -0
- package/dist/server/server.js +61 -0
- package/dist/server/server.js.map +1 -0
- package/index.ts +3 -0
- package/package.json +4 -2
- package/router/router.ts +59 -0
- package/server/server.ts +55 -0
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -22,4 +22,7 @@ __exportStar(require("./controller/controller"), exports);
|
|
|
22
22
|
// Re-export CRUD but alias DatabaseAdapter to avoid conflicts
|
|
23
23
|
var crud_1 = require("./curd/crud");
|
|
24
24
|
Object.defineProperty(exports, "createCRUD", { enumerable: true, get: function () { return crud_1.createCRUD; } });
|
|
25
|
+
// Re-export Server & Router
|
|
26
|
+
__exportStar(require("./server/server"), exports);
|
|
27
|
+
__exportStar(require("./router/router"), exports);
|
|
25
28
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,iBAAiB;AACjB,8CAA4B;AAC5B,uBAAuB;AACvB,0DAAwC;AACxC,8DAA8D;AAC9D,oCAMqB;AALnB,kGAAA,UAAU,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,iBAAiB;AACjB,8CAA4B;AAC5B,uBAAuB;AACvB,0DAAwC;AACxC,8DAA8D;AAC9D,oCAMqB;AALnB,kGAAA,UAAU,OAAA;AAMZ,4BAA4B;AAC5B,kDAAgC;AAChC,kDAAgC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type Handler = (req: any, res: any) => Promise<void> | void;
|
|
2
|
+
export declare function createDolphinRouter(): {
|
|
3
|
+
get: (path: string, handler: Handler) => void;
|
|
4
|
+
post: (path: string, handler: Handler) => void;
|
|
5
|
+
put: (path: string, handler: Handler) => void;
|
|
6
|
+
delete: (path: string, handler: Handler) => void;
|
|
7
|
+
patch: (path: string, handler: Handler) => void;
|
|
8
|
+
match(method: string, url: string): {
|
|
9
|
+
handler: Handler;
|
|
10
|
+
params: Record<string, string>;
|
|
11
|
+
} | null;
|
|
12
|
+
};
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createDolphinRouter = createDolphinRouter;
|
|
4
|
+
function createDolphinRouter() {
|
|
5
|
+
const routes = [];
|
|
6
|
+
const addRoute = (method, path, handler) => {
|
|
7
|
+
// Convert /users/:id to regex
|
|
8
|
+
const keys = [];
|
|
9
|
+
const pattern = path
|
|
10
|
+
.replace(/:([^\/]+)/g, (_, key) => {
|
|
11
|
+
keys.push(key);
|
|
12
|
+
return '([^\\/]+)';
|
|
13
|
+
})
|
|
14
|
+
.replace(/\//g, '\\/');
|
|
15
|
+
routes.push({
|
|
16
|
+
method: method.toUpperCase(),
|
|
17
|
+
path,
|
|
18
|
+
handler,
|
|
19
|
+
regex: new RegExp(`^${pattern}$`),
|
|
20
|
+
keys
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
return {
|
|
24
|
+
get: (path, handler) => addRoute('GET', path, handler),
|
|
25
|
+
post: (path, handler) => addRoute('POST', path, handler),
|
|
26
|
+
put: (path, handler) => addRoute('PUT', path, handler),
|
|
27
|
+
delete: (path, handler) => addRoute('DELETE', path, handler),
|
|
28
|
+
patch: (path, handler) => addRoute('PATCH', path, handler),
|
|
29
|
+
match(method, url) {
|
|
30
|
+
const path = url.split('?')[0];
|
|
31
|
+
const m = method.toUpperCase();
|
|
32
|
+
for (const route of routes) {
|
|
33
|
+
if (route.method !== m && route.method !== 'ALL')
|
|
34
|
+
continue;
|
|
35
|
+
const match = path.match(route.regex);
|
|
36
|
+
if (match) {
|
|
37
|
+
const params = {};
|
|
38
|
+
route.keys.forEach((key, i) => {
|
|
39
|
+
params[key] = match[i + 1];
|
|
40
|
+
});
|
|
41
|
+
return { handler: route.handler, params };
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../router/router.ts"],"names":[],"mappings":";;AAUA,kDAgDC;AAhDD,SAAgB,mBAAmB;IACjC,MAAM,MAAM,GAAY,EAAE,CAAC;IAE3B,MAAM,QAAQ,GAAG,CAAC,MAAc,EAAE,IAAY,EAAE,OAAgB,EAAE,EAAE;QAClE,8BAA8B;QAC9B,MAAM,IAAI,GAAa,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,IAAI;aACjB,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;YAChC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACf,OAAO,WAAW,CAAC;QACrB,CAAC,CAAC;aACD,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAEzB,MAAM,CAAC,IAAI,CAAC;YACV,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE;YAC5B,IAAI;YACJ,OAAO;YACP,KAAK,EAAE,IAAI,MAAM,CAAC,IAAI,OAAO,GAAG,CAAC;YACjC,IAAI;SACL,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,OAAO;QACL,GAAG,EAAE,CAAC,IAAY,EAAE,OAAgB,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC;QACvE,IAAI,EAAE,CAAC,IAAY,EAAE,OAAgB,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC;QACzE,GAAG,EAAE,CAAC,IAAY,EAAE,OAAgB,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC;QACvE,MAAM,EAAE,CAAC,IAAY,EAAE,OAAgB,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC;QAC7E,KAAK,EAAE,CAAC,IAAY,EAAE,OAAgB,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC;QAE3E,KAAK,CAAC,MAAc,EAAE,GAAW;YAC/B,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;YAE/B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK;oBAAE,SAAS;gBAE3D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBACtC,IAAI,KAAK,EAAE,CAAC;oBACV,MAAM,MAAM,GAA2B,EAAE,CAAC;oBAC1C,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;wBAC5B,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;oBAC7B,CAAC,CAAC,CAAC;oBACH,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;gBAC5C,CAAC;YACH,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import http from 'node:http';
|
|
2
|
+
export declare function createDolphinServer(options?: {
|
|
3
|
+
port?: number;
|
|
4
|
+
host?: string;
|
|
5
|
+
}): {
|
|
6
|
+
use: (mw: any) => number;
|
|
7
|
+
listen: (port?: number, callback?: () => void) => void;
|
|
8
|
+
close: () => http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>;
|
|
9
|
+
get: (path: string, handler: (req: any, res: any) => Promise<void> | void) => void;
|
|
10
|
+
post: (path: string, handler: (req: any, res: any) => Promise<void> | void) => void;
|
|
11
|
+
put: (path: string, handler: (req: any, res: any) => Promise<void> | void) => void;
|
|
12
|
+
delete: (path: string, handler: (req: any, res: any) => Promise<void> | void) => void;
|
|
13
|
+
patch: (path: string, handler: (req: any, res: any) => Promise<void> | void) => void;
|
|
14
|
+
match(method: string, url: string): {
|
|
15
|
+
handler: (req: any, res: any) => Promise<void> | void;
|
|
16
|
+
params: Record<string, string>;
|
|
17
|
+
} | null;
|
|
18
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createDolphinServer = createDolphinServer;
|
|
7
|
+
const node_http_1 = __importDefault(require("node:http"));
|
|
8
|
+
const router_1 = require("../router/router");
|
|
9
|
+
function createDolphinServer(options = {}) {
|
|
10
|
+
const router = (0, router_1.createDolphinRouter)();
|
|
11
|
+
const middlewares = [];
|
|
12
|
+
const server = node_http_1.default.createServer(async (req, res) => {
|
|
13
|
+
// Utility for JSON responses
|
|
14
|
+
res.json = (data, status = 200) => {
|
|
15
|
+
res.writeHead(status, { 'Content-Type': 'application/json' });
|
|
16
|
+
res.end(JSON.stringify(data));
|
|
17
|
+
};
|
|
18
|
+
// Global middleware execution
|
|
19
|
+
for (const mw of middlewares) {
|
|
20
|
+
const next = new Promise(resolve => mw(req, res, resolve));
|
|
21
|
+
await next;
|
|
22
|
+
if (res.writableEnded)
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
// Body parsing for POST/PUT/PATCH
|
|
26
|
+
if (['POST', 'PUT', 'PATCH'].includes(req.method) && req.headers['content-type']?.includes('application/json')) {
|
|
27
|
+
const chunks = [];
|
|
28
|
+
for await (const chunk of req)
|
|
29
|
+
chunks.push(chunk);
|
|
30
|
+
try {
|
|
31
|
+
req.body = JSON.parse(Buffer.concat(chunks).toString());
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
req.body = {};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Matching route
|
|
38
|
+
const match = router.match(req.method, req.url);
|
|
39
|
+
if (match) {
|
|
40
|
+
req.params = match.params;
|
|
41
|
+
try {
|
|
42
|
+
await match.handler(req, res);
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
res.json({ error: err.message || 'Internal Server Error' }, err.status || 500);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
res.json({ error: 'Not Found' }, 404);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
return {
|
|
53
|
+
...router, // Mixin router methods (get, post, etc.)
|
|
54
|
+
use: (mw) => middlewares.push(mw),
|
|
55
|
+
listen: (port = options.port || 3000, callback) => {
|
|
56
|
+
server.listen(port, options.host || '0.0.0.0', callback);
|
|
57
|
+
},
|
|
58
|
+
close: () => server.close()
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../server/server.ts"],"names":[],"mappings":"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"}
|
package/index.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dolphin-server-modules",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Core utility modules for Auth, CRUD, and Controllers",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
"./controller": "./dist/controller/controller.js",
|
|
11
11
|
"./crud": "./dist/curd/crud.js",
|
|
12
12
|
"./middleware/zod": "./dist/middleware/zod.js",
|
|
13
|
-
"./adapters/mongoose": "./dist/adapters/mongoose/index.js"
|
|
13
|
+
"./adapters/mongoose": "./dist/adapters/mongoose/index.js",
|
|
14
|
+
"./server": "./dist/server/server.js",
|
|
15
|
+
"./router": "./dist/router/router.js"
|
|
14
16
|
},
|
|
15
17
|
"scripts": {
|
|
16
18
|
"build": "tsc",
|
package/router/router.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
type Handler = (req: any, res: any) => Promise<void> | void;
|
|
2
|
+
|
|
3
|
+
interface Route {
|
|
4
|
+
method: string;
|
|
5
|
+
path: string;
|
|
6
|
+
handler: Handler;
|
|
7
|
+
regex: RegExp;
|
|
8
|
+
keys: string[];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function createDolphinRouter() {
|
|
12
|
+
const routes: Route[] = [];
|
|
13
|
+
|
|
14
|
+
const addRoute = (method: string, path: string, handler: Handler) => {
|
|
15
|
+
// Convert /users/:id to regex
|
|
16
|
+
const keys: string[] = [];
|
|
17
|
+
const pattern = path
|
|
18
|
+
.replace(/:([^\/]+)/g, (_, key) => {
|
|
19
|
+
keys.push(key);
|
|
20
|
+
return '([^\\/]+)';
|
|
21
|
+
})
|
|
22
|
+
.replace(/\//g, '\\/');
|
|
23
|
+
|
|
24
|
+
routes.push({
|
|
25
|
+
method: method.toUpperCase(),
|
|
26
|
+
path,
|
|
27
|
+
handler,
|
|
28
|
+
regex: new RegExp(`^${pattern}$`),
|
|
29
|
+
keys
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
get: (path: string, handler: Handler) => addRoute('GET', path, handler),
|
|
35
|
+
post: (path: string, handler: Handler) => addRoute('POST', path, handler),
|
|
36
|
+
put: (path: string, handler: Handler) => addRoute('PUT', path, handler),
|
|
37
|
+
delete: (path: string, handler: Handler) => addRoute('DELETE', path, handler),
|
|
38
|
+
patch: (path: string, handler: Handler) => addRoute('PATCH', path, handler),
|
|
39
|
+
|
|
40
|
+
match(method: string, url: string) {
|
|
41
|
+
const path = url.split('?')[0];
|
|
42
|
+
const m = method.toUpperCase();
|
|
43
|
+
|
|
44
|
+
for (const route of routes) {
|
|
45
|
+
if (route.method !== m && route.method !== 'ALL') continue;
|
|
46
|
+
|
|
47
|
+
const match = path.match(route.regex);
|
|
48
|
+
if (match) {
|
|
49
|
+
const params: Record<string, string> = {};
|
|
50
|
+
route.keys.forEach((key, i) => {
|
|
51
|
+
params[key] = match[i + 1];
|
|
52
|
+
});
|
|
53
|
+
return { handler: route.handler, params };
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
package/server/server.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import http from 'node:http';
|
|
2
|
+
import { createDolphinRouter } from '../router/router';
|
|
3
|
+
|
|
4
|
+
export function createDolphinServer(options: { port?: number; host?: string } = {}) {
|
|
5
|
+
const router = createDolphinRouter();
|
|
6
|
+
const middlewares: any[] = [];
|
|
7
|
+
|
|
8
|
+
const server = http.createServer(async (req: any, res: any) => {
|
|
9
|
+
// Utility for JSON responses
|
|
10
|
+
res.json = (data: any, status = 200) => {
|
|
11
|
+
res.writeHead(status, { 'Content-Type': 'application/json' });
|
|
12
|
+
res.end(JSON.stringify(data));
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
// Global middleware execution
|
|
16
|
+
for (const mw of middlewares) {
|
|
17
|
+
const next = new Promise(resolve => mw(req, res, resolve));
|
|
18
|
+
await next;
|
|
19
|
+
if (res.writableEnded) return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Body parsing for POST/PUT/PATCH
|
|
23
|
+
if (['POST', 'PUT', 'PATCH'].includes(req.method!) && req.headers['content-type']?.includes('application/json')) {
|
|
24
|
+
const chunks: any[] = [];
|
|
25
|
+
for await (const chunk of req) chunks.push(chunk);
|
|
26
|
+
try {
|
|
27
|
+
req.body = JSON.parse(Buffer.concat(chunks).toString());
|
|
28
|
+
} catch {
|
|
29
|
+
req.body = {};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Matching route
|
|
34
|
+
const match = router.match(req.method!, req.url!);
|
|
35
|
+
if (match) {
|
|
36
|
+
req.params = match.params;
|
|
37
|
+
try {
|
|
38
|
+
await match.handler(req, res);
|
|
39
|
+
} catch (err: any) {
|
|
40
|
+
res.json({ error: err.message || 'Internal Server Error' }, err.status || 500);
|
|
41
|
+
}
|
|
42
|
+
} else {
|
|
43
|
+
res.json({ error: 'Not Found' }, 404);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
...router, // Mixin router methods (get, post, etc.)
|
|
49
|
+
use: (mw: any) => middlewares.push(mw),
|
|
50
|
+
listen: (port: number = options.port || 3000, callback?: () => void) => {
|
|
51
|
+
server.listen(port, options.host || '0.0.0.0', callback);
|
|
52
|
+
},
|
|
53
|
+
close: () => server.close()
|
|
54
|
+
};
|
|
55
|
+
}
|