dolphin-server-modules 1.0.3 → 1.0.5
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/README.md +85 -95
- package/TUTORIAL.md +116 -0
- package/dist/router/router.d.ts +1 -1
- package/dist/server/server.d.ts +6 -6
- package/dist/server/server.js +24 -9
- package/dist/server/server.js.map +1 -1
- package/package.json +1 -1
- package/router/router.ts +1 -1
- package/scripts/benchmark.js +12 -0
- package/scripts/benchmark.ts +12 -0
- package/scripts/test-dolphin.js +27 -0
- package/server/server.ts +26 -9
package/README.md
CHANGED
|
@@ -1,140 +1,130 @@
|
|
|
1
|
-
# Dolphin
|
|
1
|
+
# Dolphin Framework 🐬
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Dolphin** is a world-class, ultra-lightweight, and 100% modular backend framework built on native Node.js. It is designed for extreme performance, minimal boilerplate, and a developer-first experience.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
> "Close to native Node.js speed, with the developer experience of a premium framework."
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
npm install dolphin-server-modules
|
|
11
|
-
```
|
|
7
|
+
---
|
|
12
8
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
## 🚀 Core Philosophy
|
|
10
|
+
- **Zero-Dependency Core**: Built on the native Node.js `http` module. No Express, no Fastify overhead.
|
|
11
|
+
- **Extreme Modularity**: Use only what you need. Auth, CRUD, and Routing are all independent.
|
|
12
|
+
- **Performance First**: Optimized matching engines and minimal object allocation.
|
|
13
|
+
- **Type-Safe by Design**: First-class TypeScript support across all modules.
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
You can import exactly what you need without bloating your project.
|
|
15
|
+
---
|
|
20
16
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
import { createDolphinController } from 'dolphin-server-modules/controller';
|
|
25
|
-
import { validateStructure } from 'dolphin-server-modules/middleware/zod';
|
|
17
|
+
## 📦 Installation
|
|
18
|
+
```bash
|
|
19
|
+
npm install dolphin-server-modules
|
|
26
20
|
```
|
|
27
21
|
|
|
28
22
|
---
|
|
29
23
|
|
|
30
|
-
##
|
|
31
|
-
Production-ready authentication supporting **argon2 password hashing**, **JWT**, and **TOTP (2FA)**. It also ships with internal memory LRU caches for protecting against token-reuse and rate-limiting.
|
|
24
|
+
## 🚀 Quick Start (Complete Tutorial)
|
|
32
25
|
|
|
33
|
-
|
|
34
|
-
import { createAuth } from 'dolphin-server-modules/auth';
|
|
26
|
+
Building a high-performance API with Dolphin is simple. Here is a full example:
|
|
35
27
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
28
|
+
### 1. Define your Database (Mongoose)
|
|
29
|
+
```typescript
|
|
30
|
+
import mongoose from 'mongoose';
|
|
31
|
+
import { createMongooseAdapter } from 'dolphin-server-modules/adapters/mongoose';
|
|
40
32
|
|
|
41
|
-
|
|
42
|
-
|
|
33
|
+
const User = mongoose.model('User', new mongoose.Schema({
|
|
34
|
+
email: { type: String, required: true },
|
|
35
|
+
password: { type: String, required: true }
|
|
36
|
+
}));
|
|
43
37
|
|
|
44
|
-
|
|
45
|
-
const session = await auth.login(db, { email: 'user@example.com', password: 'password123' });
|
|
46
|
-
console.log(session.accessToken);
|
|
38
|
+
const db = createMongooseAdapter({ User });
|
|
47
39
|
```
|
|
48
40
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
## 💾 2. CRUD Module (`/crud`)
|
|
52
|
-
A powerful Factory interface for databases providing instant pagination, soft-deletes, and ownership-checks out of the box.
|
|
53
|
-
|
|
41
|
+
### 2. Initialize and Secure your Server
|
|
54
42
|
```typescript
|
|
55
|
-
import {
|
|
43
|
+
import { createDolphinServer } from 'dolphin-server-modules/server';
|
|
44
|
+
import { createAuth } from 'dolphin-server-modules/auth';
|
|
56
45
|
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
46
|
+
const app = createDolphinServer();
|
|
47
|
+
const auth = createAuth({ secret: 'SUPER_SECRET' });
|
|
48
|
+
|
|
49
|
+
// Global Middleware
|
|
50
|
+
app.use((ctx, next) => {
|
|
51
|
+
console.log(`🐬 ${ctx.req.method} ${ctx.req.url}`);
|
|
52
|
+
next();
|
|
60
53
|
});
|
|
61
54
|
|
|
62
|
-
//
|
|
63
|
-
|
|
55
|
+
// Hello World
|
|
56
|
+
app.get('/', (ctx) => ctx.json({ message: "Welcome to Dolphin!" }));
|
|
64
57
|
|
|
65
|
-
//
|
|
66
|
-
|
|
67
|
-
|
|
58
|
+
// Secure Route
|
|
59
|
+
app.get('/profile', auth.middleware(), (ctx) => {
|
|
60
|
+
ctx.json({ user: ctx.req.user });
|
|
68
61
|
});
|
|
69
62
|
|
|
70
|
-
//
|
|
71
|
-
|
|
63
|
+
// Dynamic Params
|
|
64
|
+
app.get('/users/:id', (ctx) => ctx.json({ id: ctx.params.id }));
|
|
72
65
|
|
|
73
|
-
|
|
74
|
-
await crud.restore('posts', newPost.id, 'user_id_1');
|
|
66
|
+
app.listen(3000, () => console.log("Dolphin swimming on port 3000!"));
|
|
75
67
|
```
|
|
76
68
|
|
|
77
69
|
---
|
|
78
70
|
|
|
79
|
-
##
|
|
80
|
-
Easily convert your `crud` instance into instant API Controllers. Supports Next.js App Router, Pages API, and Express out of the box.
|
|
71
|
+
## 🛠️ Key Features
|
|
81
72
|
|
|
73
|
+
### ⚡ 1. Native High-Performance Server (`/server`)
|
|
74
|
+
A thin wrapper around native `http` with a modern `Context` (ctx) based API.
|
|
82
75
|
```typescript
|
|
83
|
-
import {
|
|
84
|
-
|
|
85
|
-
const postController = createDolphinController(crud, 'posts');
|
|
76
|
+
import { createDolphinServer } from 'dolphin-server-modules/server';
|
|
86
77
|
|
|
87
|
-
|
|
88
|
-
export const { GET, POST, PUT, DELETE } = createNextAppRoute(postController);
|
|
89
|
-
```
|
|
78
|
+
const app = createDolphinServer();
|
|
90
79
|
|
|
91
|
-
|
|
80
|
+
app.get('/ping', (ctx) => ctx.json({ message: 'pong' }));
|
|
92
81
|
|
|
93
|
-
|
|
94
|
-
|
|
82
|
+
app.listen(3000);
|
|
83
|
+
```
|
|
95
84
|
|
|
85
|
+
### 🛣️ 2. Intelligent Routing (`/router`)
|
|
86
|
+
Uses a hybrid Radix Tree + Static Map approach for $O(1)$ and $O(L)$ matching. Supports dynamic path parameters out of the box.
|
|
96
87
|
```typescript
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
const dbAdapter = createMongooseAdapter({
|
|
101
|
-
User,
|
|
102
|
-
RefreshToken,
|
|
103
|
-
models: {
|
|
104
|
-
posts: Post // Maps the 'posts' collection to the generic Post model
|
|
105
|
-
}
|
|
88
|
+
app.get('/users/:id', (ctx) => {
|
|
89
|
+
return ctx.json({ userId: ctx.params.id });
|
|
106
90
|
});
|
|
107
|
-
|
|
108
|
-
// Now pass dbAdapter to createAuth or createCRUD initializers!
|
|
109
91
|
```
|
|
110
92
|
|
|
111
|
-
|
|
93
|
+
### 🔒 3. Advanced Auth Module (`/auth`)
|
|
94
|
+
Production-ready security with zero external bloat:
|
|
95
|
+
- Argon2 Hashing & JWT (Timing-safe)
|
|
96
|
+
- Refresh Token Rotation & Reuse Detection
|
|
97
|
+
- 2FA (TOTP) + Recovery Code Management
|
|
112
98
|
|
|
113
|
-
|
|
114
|
-
|
|
99
|
+
### 💾 4. Adapter-Based CRUD & Database (`/crud`)
|
|
100
|
+
Seamlessly switch between databases with the Adapter pattern.
|
|
101
|
+
- **Mongoose Adapter**: Included by default.
|
|
102
|
+
- **Automated CRUD**: Just define a schema and get a full API.
|
|
115
103
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
import { validateAppRoute } from 'dolphin-server-modules/middleware/zod';
|
|
104
|
+
### ✅ 5. Zod-Powered Validation (`/middleware/zod`)
|
|
105
|
+
Validate payloads and params with 100% type inference.
|
|
119
106
|
|
|
120
|
-
|
|
121
|
-
name: z.string().min(2),
|
|
122
|
-
age: z.number().gte(18)
|
|
123
|
-
});
|
|
107
|
+
---
|
|
124
108
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
```
|
|
109
|
+
## 🗺️ Roadmap & Future Vision
|
|
110
|
+
1. **`defineModel` Engine**: Define a schema once, auto-generate CRUD, validation, and types.
|
|
111
|
+
2. **Plugin System**: A robust "hook" based system for extending the framework core.
|
|
112
|
+
3. **IoT & WebSocket Support**: Dedicated ingestion layer for high-throughput data.
|
|
113
|
+
4. **CLI Presets**: `npx dolphin init` for instant project scaffolding.
|
|
131
114
|
|
|
132
115
|
---
|
|
133
116
|
|
|
134
|
-
##
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
117
|
+
## 📊 Performance Comparison
|
|
118
|
+
| Metric | Express | Fastify | **Dolphin** |
|
|
119
|
+
| :--- | :--- | :--- | :--- |
|
|
120
|
+
| **Overhead** | High | Low | **Ultra-Low (Native)** |
|
|
121
|
+
| **Modularity** | Low | Medium | **Extreme** |
|
|
122
|
+
| **DX** | Good | Excellent | **Premium** |
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## 🌐 Documentation
|
|
127
|
+
Detailed documentation is automatically hosted via GitHub Pages from this README.
|
|
128
|
+
|
|
129
|
+
## 📄 License
|
|
130
|
+
ISC © 2026 Dolphin Team
|
package/TUTORIAL.md
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Dolphin Framework Tutorial 🐬
|
|
2
|
+
|
|
3
|
+
Welcome to the official tutorial for the **Dolphin Framework**. This guide will take you from zero to a production-ready API using our native, high-performance modules.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Project Setup
|
|
8
|
+
Create a new directory and initialize your project:
|
|
9
|
+
```bash
|
|
10
|
+
mkdir my-dolphin-app && cd my-dolphin-app
|
|
11
|
+
npm init -y
|
|
12
|
+
npm install dolphin-server-modules mongoose zod
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 2. Database Setup (Mongoose)
|
|
18
|
+
Define your models using Mongoose:
|
|
19
|
+
```typescript
|
|
20
|
+
// models.ts
|
|
21
|
+
import mongoose from 'mongoose';
|
|
22
|
+
|
|
23
|
+
const UserSchema = new mongoose.Schema({
|
|
24
|
+
email: { type: String, required: true, unique: true },
|
|
25
|
+
password: { type: String, required: true }
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
export const User = mongoose.model('User', UserSchema);
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 3. Initialize Dolphin
|
|
34
|
+
Create your main entry point and connect the components:
|
|
35
|
+
```typescript
|
|
36
|
+
// index.ts
|
|
37
|
+
import { createDolphinServer } from 'dolphin-server-modules/server';
|
|
38
|
+
import { createMongooseAdapter } from 'dolphin-server-modules/adapters/mongoose';
|
|
39
|
+
import { createAuth } from 'dolphin-server-modules/auth';
|
|
40
|
+
import { User } from './models';
|
|
41
|
+
|
|
42
|
+
// 1. Setup Adapter
|
|
43
|
+
const db = createMongooseAdapter({ User });
|
|
44
|
+
|
|
45
|
+
// 2. Setup Auth
|
|
46
|
+
const auth = createAuth({ secret: 'SUPER_SECRET' });
|
|
47
|
+
|
|
48
|
+
// 3. Setup Server
|
|
49
|
+
const app = createDolphinServer();
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 4. Routing with Context (ctx)
|
|
55
|
+
Dolphin uses a unified `ctx` object for ultra-clean handlers.
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
// Simple Route
|
|
59
|
+
app.get('/', (ctx) => {
|
|
60
|
+
ctx.json({ message: "Welcome to Dolphin!" });
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Dynamic Route with Params
|
|
64
|
+
app.get('/users/:id', (ctx) => {
|
|
65
|
+
const { id } = ctx.params;
|
|
66
|
+
ctx.json({ userId: id });
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Post Request with Body
|
|
70
|
+
app.post('/echo', (ctx) => {
|
|
71
|
+
ctx.json({ youSent: ctx.body });
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## 5. Adding Authentication Middleware
|
|
78
|
+
Secure your routes with the `auth` module:
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
// Protecting a route
|
|
82
|
+
app.get('/profile', auth.middleware(), (ctx) => {
|
|
83
|
+
// ctx.req.user is automatically populated
|
|
84
|
+
ctx.json({ user: ctx.req.user });
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## 6. Global Middleware
|
|
91
|
+
Add logging or custom logic to every request:
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
app.use((ctx, next) => {
|
|
95
|
+
console.log(`${ctx.req.method} ${ctx.req.url}`);
|
|
96
|
+
next();
|
|
97
|
+
});
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## 7. Starting the Server
|
|
103
|
+
```typescript
|
|
104
|
+
app.listen(3000, () => {
|
|
105
|
+
console.log("Dolphin is swimming on http://localhost:3000 🐬");
|
|
106
|
+
});
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## 🚀 Performance Tips
|
|
112
|
+
- Use **Context (ctx)** directly for JSON responses.
|
|
113
|
+
- Keep your routes organized using prefixing (coming in v1.1.0).
|
|
114
|
+
- Use the **Zod Middleware** for automatic type-safe validation.
|
|
115
|
+
|
|
116
|
+
Happy Coding!
|
package/dist/router/router.d.ts
CHANGED
package/dist/server/server.d.ts
CHANGED
|
@@ -6,13 +6,13 @@ export declare function createDolphinServer(options?: {
|
|
|
6
6
|
use: (mw: any) => number;
|
|
7
7
|
listen: (port?: number, callback?: () => void) => void;
|
|
8
8
|
close: () => http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>;
|
|
9
|
-
get: (path: string, handler: (
|
|
10
|
-
post: (path: string, handler: (
|
|
11
|
-
put: (path: string, handler: (
|
|
12
|
-
delete: (path: string, handler: (
|
|
13
|
-
patch: (path: string, handler: (
|
|
9
|
+
get: (path: string, handler: (ctx: any) => Promise<void> | void) => void;
|
|
10
|
+
post: (path: string, handler: (ctx: any) => Promise<void> | void) => void;
|
|
11
|
+
put: (path: string, handler: (ctx: any) => Promise<void> | void) => void;
|
|
12
|
+
delete: (path: string, handler: (ctx: any) => Promise<void> | void) => void;
|
|
13
|
+
patch: (path: string, handler: (ctx: any) => Promise<void> | void) => void;
|
|
14
14
|
match(method: string, url: string): {
|
|
15
|
-
handler: (
|
|
15
|
+
handler: (ctx: any) => Promise<void> | void;
|
|
16
16
|
params: Record<string, string>;
|
|
17
17
|
} | null;
|
|
18
18
|
};
|
package/dist/server/server.js
CHANGED
|
@@ -15,12 +15,26 @@ function createDolphinServer(options = {}) {
|
|
|
15
15
|
res.writeHead(status, { 'Content-Type': 'application/json' });
|
|
16
16
|
res.end(JSON.stringify(data));
|
|
17
17
|
};
|
|
18
|
+
const host = req.headers.host || 'localhost';
|
|
19
|
+
const parsedUrl = new URL(req.url, `http://${host}`);
|
|
20
|
+
const ctx = {
|
|
21
|
+
req,
|
|
22
|
+
res,
|
|
23
|
+
params: {},
|
|
24
|
+
query: Object.fromEntries(parsedUrl.searchParams),
|
|
25
|
+
body: {},
|
|
26
|
+
state: {},
|
|
27
|
+
json: res.json,
|
|
28
|
+
status: (code) => {
|
|
29
|
+
res.statusCode = code;
|
|
30
|
+
return ctx;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
18
33
|
// Global middleware execution
|
|
19
34
|
for (const mw of middlewares) {
|
|
20
|
-
const next = new Promise(resolve => mw(req, res, resolve));
|
|
21
|
-
await next;
|
|
22
35
|
if (res.writableEnded)
|
|
23
36
|
return;
|
|
37
|
+
await new Promise(resolve => mw(ctx, resolve));
|
|
24
38
|
}
|
|
25
39
|
// Body parsing for POST/PUT/PATCH
|
|
26
40
|
if (['POST', 'PUT', 'PATCH'].includes(req.method) && req.headers['content-type']?.includes('application/json')) {
|
|
@@ -28,25 +42,26 @@ function createDolphinServer(options = {}) {
|
|
|
28
42
|
for await (const chunk of req)
|
|
29
43
|
chunks.push(chunk);
|
|
30
44
|
try {
|
|
31
|
-
|
|
45
|
+
ctx.body = JSON.parse(Buffer.concat(chunks).toString());
|
|
32
46
|
}
|
|
33
47
|
catch {
|
|
34
|
-
|
|
48
|
+
ctx.body = {};
|
|
35
49
|
}
|
|
36
50
|
}
|
|
37
51
|
// Matching route
|
|
38
|
-
const match = router.match(req.method,
|
|
52
|
+
const match = router.match(req.method, parsedUrl.pathname);
|
|
39
53
|
if (match) {
|
|
40
|
-
|
|
54
|
+
ctx.params = match.params;
|
|
41
55
|
try {
|
|
42
|
-
await match.handler(
|
|
56
|
+
await match.handler(ctx);
|
|
43
57
|
}
|
|
44
58
|
catch (err) {
|
|
45
|
-
|
|
59
|
+
console.error('Server Handler Error:', err);
|
|
60
|
+
ctx.json({ error: err.message || 'Internal Server Error' }, err.status || 500);
|
|
46
61
|
}
|
|
47
62
|
}
|
|
48
63
|
else {
|
|
49
|
-
|
|
64
|
+
ctx.json({ error: 'Not Found' }, 404);
|
|
50
65
|
}
|
|
51
66
|
});
|
|
52
67
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../server/server.ts"],"names":[],"mappings":";;;;;AAGA,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../server/server.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/router/router.ts
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const { createDolphinServer } = require('../dist/server/server');
|
|
2
|
+
|
|
3
|
+
const app = createDolphinServer();
|
|
4
|
+
|
|
5
|
+
app.get('/health', (ctx) => {
|
|
6
|
+
ctx.json({ status: 'ok' });
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
const PORT = 5008;
|
|
10
|
+
app.listen(PORT, () => {
|
|
11
|
+
console.log(`Benchmark server running on port ${PORT}`);
|
|
12
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { createDolphinServer } from '../server/server';
|
|
2
|
+
|
|
3
|
+
const app = createDolphinServer();
|
|
4
|
+
|
|
5
|
+
app.get('/health', (ctx: any) => {
|
|
6
|
+
ctx.json({ status: 'ok' });
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
const PORT = 5002;
|
|
10
|
+
app.listen(PORT, () => {
|
|
11
|
+
console.log(`Benchmark server running on port ${PORT}`);
|
|
12
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const { createDolphinServer } = require('../dist/server/server');
|
|
2
|
+
const http = require('node:http');
|
|
3
|
+
|
|
4
|
+
const app = createDolphinServer();
|
|
5
|
+
|
|
6
|
+
app.get('/test', (ctx) => {
|
|
7
|
+
ctx.json({ success: true });
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const PORT = 5005;
|
|
11
|
+
app.listen(PORT, () => {
|
|
12
|
+
console.log(`Test server running on port ${PORT}`);
|
|
13
|
+
|
|
14
|
+
// Make a request immediately
|
|
15
|
+
http.get(`http://127.0.0.1:${PORT}/test`, (res) => {
|
|
16
|
+
let data = '';
|
|
17
|
+
res.on('data', chunk => data += chunk);
|
|
18
|
+
res.on('end', () => {
|
|
19
|
+
console.log('STATUS:', res.statusCode);
|
|
20
|
+
console.log('BODY:', data);
|
|
21
|
+
process.exit(0);
|
|
22
|
+
});
|
|
23
|
+
}).on('error', (err) => {
|
|
24
|
+
console.error('Request Error:', err.message);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
});
|
|
27
|
+
});
|
package/server/server.ts
CHANGED
|
@@ -12,11 +12,27 @@ export function createDolphinServer(options: { port?: number; host?: string } =
|
|
|
12
12
|
res.end(JSON.stringify(data));
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
+
const host = req.headers.host || 'localhost';
|
|
16
|
+
const parsedUrl = new URL(req.url!, `http://${host}`);
|
|
17
|
+
|
|
18
|
+
const ctx: any = {
|
|
19
|
+
req,
|
|
20
|
+
res,
|
|
21
|
+
params: {},
|
|
22
|
+
query: Object.fromEntries(parsedUrl.searchParams),
|
|
23
|
+
body: {},
|
|
24
|
+
state: {},
|
|
25
|
+
json: res.json,
|
|
26
|
+
status: (code: number) => {
|
|
27
|
+
res.statusCode = code;
|
|
28
|
+
return ctx;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
15
32
|
// Global middleware execution
|
|
16
33
|
for (const mw of middlewares) {
|
|
17
|
-
const next = new Promise(resolve => mw(req, res, resolve));
|
|
18
|
-
await next;
|
|
19
34
|
if (res.writableEnded) return;
|
|
35
|
+
await new Promise(resolve => mw(ctx, resolve));
|
|
20
36
|
}
|
|
21
37
|
|
|
22
38
|
// Body parsing for POST/PUT/PATCH
|
|
@@ -24,23 +40,24 @@ export function createDolphinServer(options: { port?: number; host?: string } =
|
|
|
24
40
|
const chunks: any[] = [];
|
|
25
41
|
for await (const chunk of req) chunks.push(chunk);
|
|
26
42
|
try {
|
|
27
|
-
|
|
43
|
+
ctx.body = JSON.parse(Buffer.concat(chunks).toString());
|
|
28
44
|
} catch {
|
|
29
|
-
|
|
45
|
+
ctx.body = {};
|
|
30
46
|
}
|
|
31
47
|
}
|
|
32
48
|
|
|
33
49
|
// Matching route
|
|
34
|
-
const match = router.match(req.method!,
|
|
50
|
+
const match = router.match(req.method!, parsedUrl.pathname);
|
|
35
51
|
if (match) {
|
|
36
|
-
|
|
52
|
+
ctx.params = match.params;
|
|
37
53
|
try {
|
|
38
|
-
await match.handler(
|
|
54
|
+
await match.handler(ctx);
|
|
39
55
|
} catch (err: any) {
|
|
40
|
-
|
|
56
|
+
console.error('Server Handler Error:', err);
|
|
57
|
+
ctx.json({ error: err.message || 'Internal Server Error' }, err.status || 500);
|
|
41
58
|
}
|
|
42
59
|
} else {
|
|
43
|
-
|
|
60
|
+
ctx.json({ error: 'Not Found' }, 404);
|
|
44
61
|
}
|
|
45
62
|
});
|
|
46
63
|
|