dolphin-server-modules 1.0.4 → 1.0.6
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 +51 -0
- package/TUTORIAL.md +121 -0
- package/dist/server/server.js +13 -2
- package/dist/server/server.js.map +1 -1
- package/package.json +1 -1
- package/scripts/test-dolphin.js +10 -1
- package/server/server.ts +12 -2
package/README.md
CHANGED
|
@@ -21,6 +21,57 @@ npm install dolphin-server-modules
|
|
|
21
21
|
|
|
22
22
|
---
|
|
23
23
|
|
|
24
|
+
## 🚀 Quick Start (Complete Tutorial)
|
|
25
|
+
|
|
26
|
+
Building a high-performance API with Dolphin is simple. Here is a full example:
|
|
27
|
+
|
|
28
|
+
### 1. Define your Database (Mongoose)
|
|
29
|
+
```typescript
|
|
30
|
+
import mongoose from 'mongoose';
|
|
31
|
+
import { createMongooseAdapter } from 'dolphin-server-modules/adapters/mongoose';
|
|
32
|
+
|
|
33
|
+
const User = mongoose.model('User', new mongoose.Schema({
|
|
34
|
+
email: { type: String, required: true },
|
|
35
|
+
password: { type: String, required: true }
|
|
36
|
+
}));
|
|
37
|
+
|
|
38
|
+
const db = createMongooseAdapter({ User });
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### 2. Initialize and Secure your Server
|
|
42
|
+
```typescript
|
|
43
|
+
import { createDolphinServer } from 'dolphin-server-modules/server';
|
|
44
|
+
import { createAuth } from 'dolphin-server-modules/auth';
|
|
45
|
+
|
|
46
|
+
const app = createDolphinServer();
|
|
47
|
+
const auth = createAuth({ secret: 'SUPER_SECRET' });
|
|
48
|
+
|
|
49
|
+
// Global Middleware (Dolphin Style)
|
|
50
|
+
app.use((ctx, next) => {
|
|
51
|
+
console.log(`🐬 ${ctx.req.method} ${ctx.req.url}`);
|
|
52
|
+
next();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Global Middleware (Express Style - Unified Compatibility!)
|
|
56
|
+
import cors from 'cors';
|
|
57
|
+
app.use(cors()); // Just works!
|
|
58
|
+
|
|
59
|
+
// Hello World
|
|
60
|
+
app.get('/', (ctx) => ctx.json({ message: "Welcome to Dolphin!" }));
|
|
61
|
+
|
|
62
|
+
// Secure Route
|
|
63
|
+
app.get('/profile', auth.middleware(), (ctx) => {
|
|
64
|
+
ctx.json({ user: ctx.req.user });
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Dynamic Params
|
|
68
|
+
app.get('/users/:id', (ctx) => ctx.json({ id: ctx.params.id }));
|
|
69
|
+
|
|
70
|
+
app.listen(3000, () => console.log("Dolphin swimming on port 3000!"));
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
24
75
|
## 🛠️ Key Features
|
|
25
76
|
|
|
26
77
|
### ⚡ 1. Native High-Performance Server (`/server`)
|
package/TUTORIAL.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
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 (Universal Support)
|
|
91
|
+
Dolphin is unique because it supports both native Context-based and standard Express-based middlewares.
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
// 1. Dolphin Context Style
|
|
95
|
+
app.use((ctx, next) => {
|
|
96
|
+
console.log(`${ctx.req.method} ${ctx.req.url}`);
|
|
97
|
+
next();
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// 2. Standard Express Style (CORS, Helmet, etc.)
|
|
101
|
+
import cors from 'cors';
|
|
102
|
+
app.use(cors()); // No wrapper needed!
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## 7. Starting the Server
|
|
108
|
+
```typescript
|
|
109
|
+
app.listen(3000, () => {
|
|
110
|
+
console.log("Dolphin is swimming on http://localhost:3000 🐬");
|
|
111
|
+
});
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## 🚀 Performance Tips
|
|
117
|
+
- Use **Context (ctx)** directly for JSON responses.
|
|
118
|
+
- Keep your routes organized using prefixing (coming in v1.1.0).
|
|
119
|
+
- Use the **Zod Middleware** for automatic type-safe validation.
|
|
120
|
+
|
|
121
|
+
Happy Coding!
|
package/dist/server/server.js
CHANGED
|
@@ -34,7 +34,14 @@ function createDolphinServer(options = {}) {
|
|
|
34
34
|
for (const mw of middlewares) {
|
|
35
35
|
if (res.writableEnded)
|
|
36
36
|
return;
|
|
37
|
-
await new Promise(resolve =>
|
|
37
|
+
await new Promise(resolve => {
|
|
38
|
+
if (mw.length === 3) {
|
|
39
|
+
mw(req, res, resolve); // Native Express signature
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
mw(ctx, resolve); // Dolphin Context signature
|
|
43
|
+
}
|
|
44
|
+
});
|
|
38
45
|
}
|
|
39
46
|
// Body parsing for POST/PUT/PATCH
|
|
40
47
|
if (['POST', 'PUT', 'PATCH'].includes(req.method) && req.headers['content-type']?.includes('application/json')) {
|
|
@@ -42,16 +49,20 @@ function createDolphinServer(options = {}) {
|
|
|
42
49
|
for await (const chunk of req)
|
|
43
50
|
chunks.push(chunk);
|
|
44
51
|
try {
|
|
45
|
-
|
|
52
|
+
const parsed = JSON.parse(Buffer.concat(chunks).toString());
|
|
53
|
+
ctx.body = parsed;
|
|
54
|
+
req.body = parsed; // Standard Express compatibility
|
|
46
55
|
}
|
|
47
56
|
catch {
|
|
48
57
|
ctx.body = {};
|
|
58
|
+
req.body = {};
|
|
49
59
|
}
|
|
50
60
|
}
|
|
51
61
|
// Matching route
|
|
52
62
|
const match = router.match(req.method, parsedUrl.pathname);
|
|
53
63
|
if (match) {
|
|
54
64
|
ctx.params = match.params;
|
|
65
|
+
req.params = match.params; // Standard Express compatibility
|
|
55
66
|
try {
|
|
56
67
|
await match.handler(ctx);
|
|
57
68
|
}
|
|
@@ -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/scripts/test-dolphin.js
CHANGED
|
@@ -3,8 +3,17 @@ const http = require('node:http');
|
|
|
3
3
|
|
|
4
4
|
const app = createDolphinServer();
|
|
5
5
|
|
|
6
|
+
// Mock Express Middleware
|
|
7
|
+
app.use((req, res, next) => {
|
|
8
|
+
req.isExpress = true;
|
|
9
|
+
next();
|
|
10
|
+
});
|
|
11
|
+
|
|
6
12
|
app.get('/test', (ctx) => {
|
|
7
|
-
ctx.json({
|
|
13
|
+
ctx.json({
|
|
14
|
+
success: true,
|
|
15
|
+
isExpress: ctx.req.isExpress
|
|
16
|
+
});
|
|
8
17
|
});
|
|
9
18
|
|
|
10
19
|
const PORT = 5005;
|
package/server/server.ts
CHANGED
|
@@ -32,7 +32,13 @@ export function createDolphinServer(options: { port?: number; host?: string } =
|
|
|
32
32
|
// Global middleware execution
|
|
33
33
|
for (const mw of middlewares) {
|
|
34
34
|
if (res.writableEnded) return;
|
|
35
|
-
await new Promise(resolve =>
|
|
35
|
+
await new Promise(resolve => {
|
|
36
|
+
if (mw.length === 3) {
|
|
37
|
+
mw(req, res, resolve); // Native Express signature
|
|
38
|
+
} else {
|
|
39
|
+
mw(ctx, resolve); // Dolphin Context signature
|
|
40
|
+
}
|
|
41
|
+
});
|
|
36
42
|
}
|
|
37
43
|
|
|
38
44
|
// Body parsing for POST/PUT/PATCH
|
|
@@ -40,9 +46,12 @@ export function createDolphinServer(options: { port?: number; host?: string } =
|
|
|
40
46
|
const chunks: any[] = [];
|
|
41
47
|
for await (const chunk of req) chunks.push(chunk);
|
|
42
48
|
try {
|
|
43
|
-
|
|
49
|
+
const parsed = JSON.parse(Buffer.concat(chunks).toString());
|
|
50
|
+
ctx.body = parsed;
|
|
51
|
+
req.body = parsed; // Standard Express compatibility
|
|
44
52
|
} catch {
|
|
45
53
|
ctx.body = {};
|
|
54
|
+
req.body = {};
|
|
46
55
|
}
|
|
47
56
|
}
|
|
48
57
|
|
|
@@ -50,6 +59,7 @@ export function createDolphinServer(options: { port?: number; host?: string } =
|
|
|
50
59
|
const match = router.match(req.method!, parsedUrl.pathname);
|
|
51
60
|
if (match) {
|
|
52
61
|
ctx.params = match.params;
|
|
62
|
+
req.params = match.params; // Standard Express compatibility
|
|
53
63
|
try {
|
|
54
64
|
await match.handler(ctx);
|
|
55
65
|
} catch (err: any) {
|