dolphin-server-modules 1.5.1 → 1.5.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/DOLPHIN_MASTER_GUIDE_NEPALI.md +369 -478
- package/dist/adapters/mongoose/index.test.d.ts +1 -0
- package/dist/adapters/mongoose/index.test.js +103 -0
- package/dist/adapters/mongoose/index.test.js.map +1 -0
- package/dist/auth/auth.test.d.ts +1 -0
- package/dist/auth/auth.test.js +291 -0
- package/dist/auth/auth.test.js.map +1 -0
- package/dist/authController/authController.test.d.ts +1 -0
- package/dist/authController/authController.test.js +361 -0
- package/dist/authController/authController.test.js.map +1 -0
- package/dist/controller/controller.test.d.ts +1 -0
- package/dist/controller/controller.test.js +39 -0
- package/dist/controller/controller.test.js.map +1 -0
- package/dist/curd/crud.js +78 -25
- package/dist/curd/crud.js.map +1 -1
- package/dist/curd/crud.test.d.ts +1 -0
- package/dist/curd/crud.test.js +163 -0
- package/dist/curd/crud.test.js.map +1 -0
- package/dist/djson/djson.d.ts +42 -0
- package/dist/djson/djson.js +318 -0
- package/dist/djson/djson.js.map +1 -0
- package/dist/index.d.ts +1 -5
- package/dist/index.js +1 -12
- package/dist/index.js.map +1 -1
- package/dist/middleware/zod.test.d.ts +1 -0
- package/dist/middleware/zod.test.js +76 -0
- package/dist/middleware/zod.test.js.map +1 -0
- package/dist/realtime/core.d.ts +27 -28
- package/dist/realtime/core.js +297 -65
- package/dist/realtime/core.js.map +1 -1
- package/dist/realtime/index.d.ts +1 -1
- package/dist/realtime/index.js +1 -1
- package/dist/realtime/index.js.map +1 -1
- package/dist/realtime/plugins.d.ts +17 -4
- package/dist/realtime/plugins.js +300 -14
- package/dist/realtime/plugins.js.map +1 -1
- package/dist/realtime/realtime.test.d.ts +1 -0
- package/dist/realtime/realtime.test.js +271 -0
- package/dist/realtime/realtime.test.js.map +1 -0
- package/package.json +4 -2
- package/dist/router/router.d.ts +0 -26
- package/dist/router/router.js +0 -71
- package/dist/router/router.js.map +0 -1
- package/dist/server/server.d.ts +0 -23
- package/dist/server/server.js +0 -219
- package/dist/server/server.js.map +0 -1
|
@@ -1,27 +1,30 @@
|
|
|
1
1
|
# Dolphin Framework: Absolute Master Guide (100+ Pages Equivalent) 🐬🇳🇵
|
|
2
2
|
|
|
3
|
+
> **Latest Version:** v1.4.7+ | **Updated:** 2026-04-03 | **License:** MIT
|
|
4
|
+
|
|
3
5
|
यो डकुमेन्ट Dolphin Framework को आधिकारिक र विस्तृत गाइड हो। यसले तपाईँलाई एउटा साधारण कोड लेख्ने डेभलपरबाट "Framework Master" बनाउन मद्दत गर्नेछ।
|
|
4
6
|
|
|
5
7
|
---
|
|
6
8
|
|
|
7
9
|
## विषय सूची (Table of Contents)
|
|
8
|
-
|
|
9
|
-
- [
|
|
10
|
-
- [
|
|
10
|
+
|
|
11
|
+
- [०. परिचय र दर्शन](#०-परिचय-र-दर्शन)
|
|
12
|
+
- [१. सेटअप र वातावरण](#१-सेटअप-र-वातावरण)
|
|
13
|
+
- [२. कोर सर्भर इन्जिन](#२-कोर-सर्भर-इन्जिन)
|
|
11
14
|
- [३. Unified Context (ctx) Deep Dive](#३-unified-context-ctx-deep-dive)
|
|
12
|
-
- [४. एडभान्स्ड राउटिङ
|
|
13
|
-
- [५. मिडलवेयर आर्किटेक्चर
|
|
14
|
-
- [६. डेटाबेस एड्याप्टर
|
|
15
|
-
- [७. Auth मोड्युल मास्टरक्लास
|
|
16
|
-
- [८. अटोमेटेड CRUD इन्जिन
|
|
17
|
-
- [९. Zod भ्यालिडेसन र सुरक्षा
|
|
15
|
+
- [४. एडभान्स्ड राउटिङ](#४-एडभान्स्ड-राउटिङ)
|
|
16
|
+
- [५. मिडलवेयर आर्किटेक्चर](#५-मिडलवेयर-आर्किटेक्चर)
|
|
17
|
+
- [६. डेटाबेस एड्याप्टर](#६-डेटाबेस-एड्याप्टर)
|
|
18
|
+
- [७. Auth मोड्युल मास्टरक्लास](#७-auth-मोड्युल-मास्टरक्लास)
|
|
19
|
+
- [८. अटोमेटेड CRUD इन्जिन](#८-अटोमेटेड-crud-इन्जिन)
|
|
20
|
+
- [९. Zod भ्यालिडेसन र सुरक्षा](#९-zod-भ्यालिडेसन-र-सुरक्षा)
|
|
18
21
|
- [१०. रियल-वर्ल्ड प्रोजेक्ट: DolphinStore API](#१०-रियल-वर्ल्ड-प्रोजेक्ट-dolphinstore-api)
|
|
19
|
-
- [११. स्केलिङ र पर्फर्मेन्स
|
|
20
|
-
- [१२. टेस्टिङ र डेभप्स
|
|
21
|
-
- [१३.
|
|
22
|
-
- [१४.
|
|
23
|
-
- [१५.
|
|
24
|
-
- [१६.
|
|
22
|
+
- [११. स्केलिङ र पर्फर्मेन्स](#११-स्केलिङ-र-पर्फर्मेन्स)
|
|
23
|
+
- [१२. टेस्टिङ र डेभप्स](#१२-टेस्टिङ-र-डेभप्स)
|
|
24
|
+
- [१३. RealtimeCore: रियलटाइम पब/सब मास्टरक्लास](#१३-realtimecore-रियलटाइम-पबसब-मास्टरक्लास)
|
|
25
|
+
- [१४. इन्डिपेन्डेन्ट राउटिङ](#१४-इन्डिपेन्डेन्ट-राउटिङ)
|
|
26
|
+
- [१५. स्वतन्त्र अटो-स्वैगर जेनेरेसन](#१५-स्वतन्त्र-अटो-स्वैगर-जेनेरेसन)
|
|
27
|
+
- [१६. API रेफरेन्स](#१६-api-रेफरेन्स)
|
|
25
28
|
|
|
26
29
|
---
|
|
27
30
|
|
|
@@ -31,41 +34,33 @@
|
|
|
31
34
|
ब्याकइन्ड डेभलपमेन्टको दुनियाँमा एक्सप्रेस (Express) सबैभन्दा लोकप्रिय छ। तर एक्सप्रेस पूरानो भइसक्यो। यसमा धेरै अनावश्यक वजन (Bloat) छ र यो मोडर्न एउटा (Modern) `async/await` सँग सधैँ राम्रोसँग काम गर्दैन।
|
|
32
35
|
|
|
33
36
|
**Dolphin को जन्म तीनवटा मुख्य कारणले भएको हो:**
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
1. **Native Speed**: कुनै पनि बाहिरी लाइब्रेरी बिना नेटिभ `http` मा चल्ने।
|
|
38
|
+
2. **Context-First**: `req` र `res` लाई एउटै 'Context' (ctx) मा मिलाएर कोडलाई सफा राख्ने।
|
|
39
|
+
3. **Total Modularity**: तपाईँले Auth चाहनुहुन्छ? Auth मोड्युल मात्र लोड गर्नुहोस्।
|
|
37
40
|
|
|
38
41
|
### पर्फर्मेन्स बेन्चमार्क
|
|
39
|
-
हाम्रो आन्तरिक टेस्टिङ अनुसार:
|
|
40
42
|
| Framework | Requests Per Second (RPS) | Latency (avg) |
|
|
41
43
|
| :--- | :--- | :--- |
|
|
42
|
-
| Express.js |
|
|
43
|
-
| Fastify |
|
|
44
|
-
| **Dolphin (v1.4.7)** |
|
|
44
|
+
| Express.js | ~15,000 | 10ms |
|
|
45
|
+
| Fastify | ~35,000 | 2ms |
|
|
46
|
+
| **Dolphin (v1.4.7+)** | **~45,000+** | **1.5ms** |
|
|
45
47
|
|
|
46
48
|
---
|
|
47
49
|
|
|
48
50
|
## १. सेटअप र वातावरण (Setup & Environment)
|
|
49
51
|
|
|
50
52
|
### १.१ आवश्यक चिजहरू (Prerequisites)
|
|
51
|
-
- **Node.js**: v18.x वा सोभन्दा माथि
|
|
53
|
+
- **Node.js**: v18.x वा सोभन्दा माथि
|
|
52
54
|
- **TypeScript**: Dolphin टाइप-सेफ छ, त्यसैले TS सिफारिस गरिन्छ।
|
|
53
|
-
- **Package Manager**: npm, yarn, वा pnpm।
|
|
54
55
|
|
|
55
56
|
### १.२ प्रोजेक्ट सुरु गर्ने
|
|
56
|
-
एउटा खाली फोल्डरमा जानुहोस् र तलको कमान्ड चलाउनुहोस्:
|
|
57
|
-
|
|
58
57
|
```bash
|
|
59
58
|
mkdir dolphin-master-app && cd dolphin-master-app
|
|
60
59
|
npm init -y
|
|
61
|
-
npm install dolphin-server-modules mongoose zod
|
|
62
|
-
# Development को लागि
|
|
60
|
+
npm install dolphin-server-modules mongoose zod ioredis
|
|
63
61
|
npm install -D typescript ts-node @types/node nodemon
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
### १.३ TypeScript कन्फिगर गर्ने (`tsconfig.json`)
|
|
67
|
-
Dolphin को लागि तपाईँको `tsconfig.json` यस्तो हुनुपर्छ:
|
|
68
|
-
```json
|
|
62
|
+
१.३ TypeScript कन्फिगर (tsconfig.json)
|
|
63
|
+
json
|
|
69
64
|
{
|
|
70
65
|
"compilerOptions": {
|
|
71
66
|
"target": "ES2022",
|
|
@@ -78,603 +73,499 @@ Dolphin को लागि तपाईँको `tsconfig.json` यस्त
|
|
|
78
73
|
"forceConsistentCasingInFileNames": true
|
|
79
74
|
}
|
|
80
75
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
## २. कोर सर्भर इन्जिन (Core Server Engine)
|
|
86
|
-
|
|
87
|
-
Dolphin को हृदय (Heart) यसको नेटिभ सर्भर इन्जिन हो। यसले भारी बाहिरी डिपेन्डेन्सी प्रयोग नगरी सिधै `http.createServer` सँग कुराकानी गर्छ।
|
|
88
|
-
|
|
89
|
-
### २.१ सर्भर कसरी बनाउने?
|
|
90
|
-
```typescript
|
|
76
|
+
२. कोर सर्भर इन्जिन (Core Server Engine)
|
|
77
|
+
२.१ सर्भर कसरी बनाउने?
|
|
78
|
+
typescript
|
|
91
79
|
import { createDolphinServer } from 'dolphin-server-modules/server';
|
|
92
80
|
|
|
93
81
|
const app = createDolphinServer();
|
|
94
82
|
|
|
95
|
-
// पोर्ट ३००० मा सर्भर सुन्न सुरु गर्ने
|
|
96
83
|
app.listen(3000, () => {
|
|
97
84
|
console.log("Dolphin Engine Active! 🐬");
|
|
98
85
|
});
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
Dolphin ले हरेक रिक्वेस्ट आउँदा एउटा नयाँ "Context" अब्जेक्ट बनाउँछ। यसले रिक्वेस्ट पाइलाइन (Request Pipeline) लाई एकदमै छिटो र सरल बनाउँछ। यसमा कुनै "Connect" वा "Express" को मिडलवेयर चेनको झन्झट हुँदैन यदि तपाईँ चाहनुहुन्न भने।
|
|
103
|
-
|
|
104
|
-
---
|
|
105
|
-
|
|
106
|
-
## ३. Unified Context (ctx) Deep Dive
|
|
107
|
-
|
|
108
|
-
Context (`ctx`) Dolphin को सबैभन्दा शक्तिशाली पक्ष हो। यसले रिक्वेस्ट र रेस्पोन्सलाई एउटै ठाउँमा ल्याउँछ।
|
|
109
|
-
|
|
110
|
-
### ३.१ `ctx` भित्र के के हुन्छ?
|
|
111
|
-
तपाईँको ह्यान्डलरमा `ctx` उपलब्ध हुन्छ:
|
|
112
|
-
```typescript
|
|
86
|
+
३. Unified Context (ctx) Deep Dive
|
|
87
|
+
३.१ ctx भित्र के के हुन्छ?
|
|
88
|
+
typescript
|
|
113
89
|
app.get('/test', (ctx) => {
|
|
114
|
-
// ctx
|
|
115
|
-
});
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
**मुख्य प्रोपर्टीहरू:**
|
|
119
|
-
- `ctx.req`: नेटिभ `http.IncomingMessage` (जसमा `req.user` पनि थपिन सक्छ)।
|
|
120
|
-
- `ctx.params`: URL प्यारामिटरहरू।
|
|
121
|
-
- `ctx.query`: Query String (जस्तै: `?name=Dolphin`)।
|
|
122
|
-
- `ctx.body`: POST/PUT रिक्वेस्टको डाटा।
|
|
123
|
-
|
|
124
|
-
**मुख्य मेथडहरू:**
|
|
125
|
-
- `ctx.json(obj)`: JSON डाटा पठाउन।
|
|
126
|
-
- `ctx.status(code)`: HTTP स्टेटस कोड सेट गर्न।
|
|
127
|
-
- `ctx.header(key, value)`: रेस्पोन्स हेडर सेट गर्न।
|
|
128
|
-
- `ctx.text(str)`: सादा टेक्स्ट पठाउन।
|
|
129
|
-
|
|
130
|
-
### ३.२ अटो-JSON रेस्पोन्स (Auto-JSON Response) - [NEW v1.4.7]
|
|
131
|
-
Dolphin को पछिल्लो अपडेटमा, यदि तपाईँको ह्यान्डलरले एउटा अब्जेक्ट (Object) फिर्ता (return) गर्छ भने, सर्भरले त्यसलाई आफैँ JSON बनाएर पठाइदिन्छ। तपाईँले `ctx.json()` लेखिरहनु पर्दैन!
|
|
132
|
-
|
|
133
|
-
```typescript
|
|
134
|
-
// पुरानो तरीका:
|
|
135
|
-
app.get('/old-way', (ctx) => {
|
|
136
|
-
ctx.json({ ok: true });
|
|
90
|
+
// ctx.params, ctx.query, ctx.body, ctx.req, ctx.res
|
|
137
91
|
});
|
|
92
|
+
मुख्य प्रोपर्टीहरू:
|
|
138
93
|
|
|
139
|
-
|
|
140
|
-
app.get('/new-way', (ctx) => {
|
|
141
|
-
return { ok: true, message: "Dolphin is smart!" };
|
|
142
|
-
});
|
|
143
|
-
```
|
|
94
|
+
ctx.req: नेटिभ http.IncomingMessage
|
|
144
95
|
|
|
145
|
-
|
|
96
|
+
ctx.params: URL प्यारामिटरहरू
|
|
146
97
|
|
|
147
|
-
|
|
98
|
+
ctx.query: Query String
|
|
148
99
|
|
|
149
|
-
|
|
100
|
+
ctx.body: POST/PUT डाटा
|
|
150
101
|
|
|
151
|
-
|
|
152
|
-
यसले Radix Trees प्रयोग गर्छ। जसले गर्दा तपाईँको ५०० वटा रूट भए पनि वा ५ वटा भए पनि स्पिडमा कुनै फरक पर्दैन।
|
|
102
|
+
मुख्य मेथडहरू:
|
|
153
103
|
|
|
154
|
-
|
|
155
|
-
// १. सामान्य रूट (Static Route)
|
|
156
|
-
app.get('/ping', (ctx) => ctx.json({ msg: 'pong' }));
|
|
104
|
+
ctx.json(obj): JSON डाटा पठाउन
|
|
157
105
|
|
|
158
|
-
|
|
159
|
-
app.get('/users/:id', (ctx) => {
|
|
160
|
-
const { id } = ctx.params;
|
|
161
|
-
ctx.json({ userId: id });
|
|
162
|
-
});
|
|
106
|
+
ctx.status(code): HTTP स्टेटस कोड
|
|
163
107
|
|
|
164
|
-
|
|
165
|
-
app.get('/posts/:categoryId/:postId', (ctx) => {
|
|
166
|
-
const { categoryId, postId } = ctx.params;
|
|
167
|
-
ctx.json({ categoryId, postId });
|
|
168
|
-
});
|
|
169
|
-
```
|
|
108
|
+
ctx.header(key, value): रेस्पोन्स हेडर
|
|
170
109
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
app.
|
|
175
|
-
group.get('/users', (ctx) => ctx.json([]));
|
|
176
|
-
group.get('/stats', (ctx) => ctx.json({ active: 100 }));
|
|
177
|
-
});
|
|
178
|
-
```
|
|
110
|
+
३.२ अटो-JSON रेस्पोन्स [v1.4.7]
|
|
111
|
+
typescript
|
|
112
|
+
// पुरानो:
|
|
113
|
+
app.get('/old', (ctx) => { ctx.json({ ok: true }); });
|
|
179
114
|
|
|
180
|
-
|
|
115
|
+
// नयाँ:
|
|
116
|
+
app.get('/new', (ctx) => { return { ok: true }; });
|
|
117
|
+
४. एडभान्स्ड राउटिङ (Advanced Routing)
|
|
118
|
+
typescript
|
|
119
|
+
// Static Route
|
|
120
|
+
app.get('/ping', (ctx) => ({ msg: 'pong' }));
|
|
181
121
|
|
|
182
|
-
|
|
122
|
+
// Dynamic Route
|
|
123
|
+
app.get('/users/:id', (ctx) => ({ userId: ctx.params.id }));
|
|
183
124
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
### ५.२ ग्लोबल मिडलवेयर बनाउने
|
|
192
|
-
```typescript
|
|
125
|
+
// Route Prefixing
|
|
126
|
+
app.group('/api/v1', (group) => {
|
|
127
|
+
group.get('/users', (ctx) => ([]));
|
|
128
|
+
});
|
|
129
|
+
५. मिडलवेयर आर्किटेक्चर (Middleware Architecture)
|
|
130
|
+
typescript
|
|
131
|
+
// Global Middleware
|
|
193
132
|
app.use((ctx, next) => {
|
|
194
|
-
|
|
195
|
-
console.log(`[Dolphin] ${ctx.req.method} ${ctx.req.url} सुरु भयो...`);
|
|
196
|
-
|
|
197
|
-
// अर्को मिडलवेयर वा रूट ह्यान्डलरमा पठाउने
|
|
133
|
+
console.log(`${ctx.req.method} ${ctx.req.url}`);
|
|
198
134
|
if (next) next();
|
|
199
|
-
|
|
200
|
-
const duration = Date.now() - start;
|
|
201
|
-
console.log(`[Dolphin] ${ctx.req.url} सकियो! समय: ${duration}ms`);
|
|
202
135
|
});
|
|
203
|
-
```
|
|
204
136
|
|
|
205
|
-
|
|
206
|
-
अब तपाईँले एउटै राउटमा एक्सप्रेस जस्तै गरी धेरै मिडलवेयरहरू एकैसाथ राख्न सक्नुहुन्छ।
|
|
207
|
-
|
|
208
|
-
```typescript
|
|
137
|
+
// Multi-handler Support
|
|
209
138
|
const isAdmin = (ctx, next) => {
|
|
210
|
-
if (ctx.req.user
|
|
211
|
-
else ctx.status(403).json({ error: "
|
|
139
|
+
if (ctx.req.user?.role === 'admin') next();
|
|
140
|
+
else ctx.status(403).json({ error: "Denied" });
|
|
212
141
|
};
|
|
213
142
|
|
|
214
|
-
|
|
215
|
-
app.get('/admin/stats', auth.requireAuth, isAdmin, (ctx) => {
|
|
216
|
-
return { users: 100, sales: 5000 };
|
|
217
|
-
});
|
|
218
|
-
```
|
|
143
|
+
app.get('/admin', isAdmin, (ctx) => ({ message: "Welcome Admin" }));
|
|
219
144
|
|
|
220
|
-
|
|
221
|
-
यदि तपाईँ `cors` वा `helmet` जस्ता लाइब्रेरीहरू प्रयोग गर्न चाहनुहुन्छ भने:
|
|
222
|
-
```typescript
|
|
145
|
+
// Express Middleware Compatible
|
|
223
146
|
import cors from 'cors';
|
|
224
|
-
import helmet from 'helmet';
|
|
225
|
-
|
|
226
|
-
// सिधै app.use() मा हाल्नुहोस्!
|
|
227
147
|
app.use(cors());
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
यो Dolphin को युनिक फिचर हो। यसले एक्सप्रेसको मिडलवेयरलाई आफै एडप्ट गर्छ।
|
|
231
|
-
|
|
232
|
-
---
|
|
233
|
-
|
|
234
|
-
## ६. डेटाबेस एड्याप्टर (Database Adapters)
|
|
235
|
-
|
|
236
|
-
Dolphin एउटा "Database Agnostic" फ्रेमवर्क हो। यसको मतलब तपाईँले जुनसुकै डेटाबेस (MongoDB, PostgreSQL, MySQL) प्रयोग गर्न सक्नुहुन्छ।
|
|
237
|
-
|
|
238
|
-
### ६.१ एडाप्टर प्याटर्न (Adapter Pattern) किन?
|
|
239
|
-
धेरै ब्याकइन्ड कोडहरू डेटाबेससँग निकै नजिकबाट बाँधिएका (Tightly coupled) हुन्छन्। Dolphin मा हामी एडाप्टर प्रयोग गर्छौँ ताकी भोलि डेटाबेस परिवर्तन गर्दा कोर लजिक परिवर्तन गर्न नपरोस्।
|
|
240
|
-
|
|
241
|
-
### ६.२ Mongoose Adapter प्रयोग गर्ने
|
|
242
|
-
```typescript
|
|
148
|
+
६. डेटाबेस एड्याप्टर (Database Adapters)
|
|
149
|
+
typescript
|
|
243
150
|
import mongoose from 'mongoose';
|
|
244
151
|
import { createMongooseAdapter } from 'dolphin-server-modules/adapters/mongoose';
|
|
245
152
|
|
|
246
153
|
const User = mongoose.model('User', new mongoose.Schema({
|
|
247
|
-
username: String,
|
|
248
|
-
email: { type: String, required: true }
|
|
154
|
+
username: String, email: String
|
|
249
155
|
}));
|
|
250
156
|
|
|
251
|
-
// एड्याप्टर बनाउने
|
|
252
157
|
const db = createMongooseAdapter({ User });
|
|
253
158
|
|
|
254
|
-
// प्रयोग गर्ने तरीका
|
|
255
159
|
app.get('/users', async (ctx) => {
|
|
256
|
-
|
|
257
|
-
ctx.json(allUsers);
|
|
160
|
+
return await db.User.find();
|
|
258
161
|
});
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
### ६.३ कस्टम एडाप्टर (Optional)
|
|
262
|
-
यदि तपाईँ Prisma वा Sequelize प्रयोग गर्न चाहनुहुन्छ भने, तपाईँले आफ्नै एडाप्टर फङ्सन लेख्न सक्नुहुन्छ जसले Dolphin को इन्टरफेस सपोर्ट गर्छ।
|
|
263
|
-
|
|
264
|
-
---
|
|
265
|
-
|
|
266
|
-
## ७. Auth मोड्युल मास्टरक्लास (Auth Module Masterclass)
|
|
267
|
-
|
|
268
|
-
Dolphin को Auth मोड्युल एउटा इन्टरप्राइज-ग्रेड अथेन्टिकेसन सिस्टम हो।
|
|
269
|
-
|
|
270
|
-
### ७.१ मुख्य फिचरहरू
|
|
271
|
-
- **Argon2 Hashing**: पासवर्ड सुरक्षित राख्न।
|
|
272
|
-
- **JWT (JSON Web Tokens)**: स्टेटलेस अथेन्टिकेसनको लागि।
|
|
273
|
-
- **Refresh Token Rotation**: टोकन चोरी भएमा सुरक्षाको लागि।
|
|
274
|
-
- **Two-Factor Authentication (2FA)**: थप सुरक्षा।
|
|
275
|
-
|
|
276
|
-
### ७.२ सेटअप र कन्फिगरेसन
|
|
277
|
-
```typescript
|
|
162
|
+
७. Auth मोड्युल मास्टरक्लास (Auth Module)
|
|
163
|
+
typescript
|
|
278
164
|
import { createAuth } from 'dolphin-server-modules/auth';
|
|
279
165
|
|
|
280
166
|
const auth = createAuth({
|
|
281
|
-
secret: '
|
|
167
|
+
secret: 'SUPER_SECRET_KEY',
|
|
282
168
|
tokenExpiry: '1h',
|
|
283
169
|
refreshExpiry: '7d'
|
|
284
170
|
});
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
```typescript
|
|
290
|
-
app.get('/admin/dashboard', auth.middleware(), (ctx) => {
|
|
291
|
-
// यहाँ पुग्दा युजर अथेन्टिकेट भइसकेको हुन्छ
|
|
292
|
-
const currentUser = ctx.req.user;
|
|
293
|
-
ctx.json({ welcome: currentUser.email });
|
|
171
|
+
|
|
172
|
+
// Protect routes
|
|
173
|
+
app.get('/dashboard', auth.middleware(), (ctx) => {
|
|
174
|
+
return { user: ctx.req.user };
|
|
294
175
|
});
|
|
295
|
-
```
|
|
296
176
|
|
|
297
|
-
|
|
298
|
-
Dolphin ले TOTP (Google Authenticator) सपोर्ट गर्छ:
|
|
299
|
-
```typescript
|
|
300
|
-
// २FA इनेबल गर्ने
|
|
177
|
+
// 2FA Support
|
|
301
178
|
app.post('/auth/2fa/setup', auth.middleware(), async (ctx) => {
|
|
302
|
-
|
|
303
|
-
ctx.json(result); // QR Code URL यहाँ आउँछ
|
|
179
|
+
return await auth.setup2FA(ctx.req.user.id);
|
|
304
180
|
});
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
यदि तपाईँलाई अटोमेटेड CRUD ले पुग्दैन भने, तपाईँ आफ्नै कन्ट्रोलर लेख्न सक्नुहुन्छ। Dolphin मा एउटा राम्रो कन्ट्रोलर यस्तो हुनुपर्छ:
|
|
308
|
-
|
|
309
|
-
```typescript
|
|
310
|
-
// src/controllers/userController.ts
|
|
311
|
-
export const userController = {
|
|
312
|
-
getProfile: async (ctx) => {
|
|
313
|
-
const user = ctx.req.user;
|
|
314
|
-
if (!user) return ctx.status(401).json({ error: "Unauthorized" });
|
|
315
|
-
|
|
316
|
-
// केही जटिल लजिक यहाँ...
|
|
317
|
-
ctx.json({
|
|
318
|
-
id: user.id,
|
|
319
|
-
email: user.email,
|
|
320
|
-
serverTime: new Date()
|
|
321
|
-
});
|
|
322
|
-
}
|
|
323
|
-
};
|
|
324
|
-
```
|
|
325
|
-
यसलाई राउटमा यसरी प्रयोग गर्नुहोस्:
|
|
326
|
-
```typescript
|
|
327
|
-
import { userController } from './controllers/userController';
|
|
328
|
-
app.get('/me', auth.middleware(), userController.getProfile);
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
---
|
|
332
|
-
|
|
333
|
-
## ८. अटोमेटेड CRUD इन्जिन (Automated CRUD Engine)
|
|
334
|
-
|
|
335
|
-
Dolphin को एउटा जादुई फिचर भनेको यसको "Automated CRUD" हो। यसले तपाईँको डेभलपमेन्ट समय ८०% सम्म बचत गर्छ।
|
|
336
|
-
|
|
337
|
-
### ८.१ CRUD भनेको के हो?
|
|
338
|
-
सी.आर.यू.डी. (Create, Read, Update, Delete) कुनै पनि वेब एपको आधारभूत काम हो। Dolphin ले यो काम धेरै नै सरल बनाइदिएको छ।
|
|
339
|
-
|
|
340
|
-
### ८.२ CRUD कन्ट्रोलर प्रयोग गर्ने
|
|
341
|
-
तपाईँले हरेक चिजको लागि फङ्सन लेखिरहनु पर्दैन।
|
|
342
|
-
```typescript
|
|
181
|
+
८. अटोमेटेड CRUD इन्जिन (Automated CRUD)
|
|
182
|
+
typescript
|
|
343
183
|
import { createCrudController } from 'dolphin-server-modules/curd';
|
|
344
184
|
|
|
345
|
-
// १. युजरको लागि CRUD कन्ट्रोलर बनाउने
|
|
346
185
|
const userCrud = createCrudController(db.User);
|
|
347
186
|
|
|
348
|
-
// २. राउटमा जोड्ने
|
|
349
187
|
app.get('/api/users', userCrud.getAll);
|
|
350
188
|
app.post('/api/users', userCrud.create);
|
|
351
189
|
app.get('/api/users/:id', userCrud.getOne);
|
|
352
190
|
app.put('/api/users/:id', userCrud.update);
|
|
353
191
|
app.delete('/api/users/:id', userCrud.delete);
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
### ८.३ कस्टमाइज गर्ने
|
|
358
|
-
यदि तपाईँ सबै डेटा देखाउन चाहनुहुन्न भने, तपाईँले फिल्टर गर्न सक्नुहुन्छ:
|
|
359
|
-
```typescript
|
|
360
|
-
app.get('/api/users/active', async (ctx) => {
|
|
361
|
-
const result = await db.User.find({ status: 'active' });
|
|
362
|
-
ctx.json(result);
|
|
363
|
-
});
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
---
|
|
367
|
-
|
|
368
|
-
## ९. Zod भ्यालिडेसन र सुरक्षा (Zod Validation)
|
|
369
|
-
|
|
370
|
-
गलत डाटाले सिस्टम बिगार्न सक्छ। त्यसैले Dolphin ले Zod सँग मिलेर काम गर्छ।
|
|
371
|
-
|
|
372
|
-
### ९.१ Zod किन?
|
|
373
|
-
Zod एउटा "Schema-first" भ्यालिडेसन लाइब्रेरी हो जसले रनटाइममा डाटा चेक गर्छ र स्ट्याटिक टाइपहरू पनि दिन्छ।
|
|
374
|
-
|
|
375
|
-
### ९.२ भ्यालिडेसन मिडलवेयरका उदाहरण
|
|
376
|
-
```typescript
|
|
192
|
+
९. Zod भ्यालिडेसन (Zod Validation)
|
|
193
|
+
typescript
|
|
377
194
|
import { z } from 'zod';
|
|
378
195
|
import { validate } from 'dolphin-server-modules/middleware/zod';
|
|
379
196
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
email: z.string().email(),
|
|
384
|
-
age: z.number().optional()
|
|
197
|
+
const UserSchema = z.object({
|
|
198
|
+
name: z.string().min(3),
|
|
199
|
+
email: z.string().email()
|
|
385
200
|
});
|
|
386
201
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
// यहाँ आउँदा डाटा १००% भ्यालिड भइसकेको हुन्छ
|
|
390
|
-
const userData = ctx.body;
|
|
391
|
-
ctx.json({ success: true, user: userData });
|
|
202
|
+
app.post('/users', validate(UserSchema), (ctx) => {
|
|
203
|
+
return { success: true, data: ctx.body };
|
|
392
204
|
});
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
यदि युजरले गलत डाटा पठायो भने Dolphin ले आफै `400 Bad Request` र Zod को डिटेल एरर म्यासेज पठाइदिन्छ। तपाईँले छुट्टै एरर ह्यान्डलर लेखिरहनु पर्दैन।
|
|
397
|
-
|
|
398
|
-
---
|
|
399
|
-
|
|
400
|
-
## १०. रियल-वर्ल्ड प्रोजेक्ट: DolphinStore API
|
|
401
|
-
|
|
402
|
-
अब हामीले सिकेका सबै कुराहरू प्रयोग गरेर एउटा सानो "E-commerce Backend" बनाउनेछौँ। यसलाई हामी **DolphinStore** भन्नेछौँ।
|
|
403
|
-
|
|
404
|
-
### १०.१ प्रोजेक्टको संरचना (Project Structure)
|
|
405
|
-
हाम्रो प्रोजेक्टको फाइल संरचना यस्तो हुनेछ:
|
|
406
|
-
```text
|
|
407
|
-
/src
|
|
408
|
-
/models
|
|
409
|
-
User.ts
|
|
410
|
-
Product.ts
|
|
411
|
-
/routes
|
|
412
|
-
authRoutes.ts
|
|
413
|
-
productRoutes.ts
|
|
414
|
-
index.ts
|
|
415
|
-
```
|
|
416
|
-
|
|
417
|
-
### १०.२ मोडेलहरू (Models)
|
|
418
|
-
`src/models/Product.ts`:
|
|
419
|
-
```typescript
|
|
420
|
-
import mongoose from 'mongoose';
|
|
421
|
-
|
|
422
|
-
const ProductSchema = new mongoose.Schema({
|
|
423
|
-
name: { type: String, required: true },
|
|
424
|
-
price: { type: Number, required: true },
|
|
425
|
-
description: String,
|
|
426
|
-
stock: { type: Number, default: 0 }
|
|
427
|
-
});
|
|
428
|
-
|
|
429
|
-
export const Product = mongoose.model('Product', ProductSchema);
|
|
430
|
-
```
|
|
431
|
-
|
|
432
|
-
### १०.३ मेन फाइल (index.ts)
|
|
433
|
-
यहाँ हामी सबै कुरालाई एकै ठाउँमा ल्याउँछौँ:
|
|
434
|
-
```typescript
|
|
205
|
+
१०. रियल-वर्ल्ड प्रोजेक्ट: DolphinStore API
|
|
206
|
+
typescript
|
|
207
|
+
// src/index.ts
|
|
435
208
|
import { createDolphinServer } from 'dolphin-server-modules/server';
|
|
436
209
|
import { createAuth } from 'dolphin-server-modules/auth';
|
|
437
210
|
import { createMongooseAdapter } from 'dolphin-server-modules/adapters/mongoose';
|
|
438
|
-
import { Product } from './models/Product';
|
|
439
211
|
import { createCrudController } from 'dolphin-server-modules/curd';
|
|
212
|
+
import mongoose from 'mongoose';
|
|
440
213
|
|
|
441
214
|
const app = createDolphinServer();
|
|
442
215
|
const auth = createAuth({ secret: 'DOLPHIN_STORE_SECRET' });
|
|
216
|
+
|
|
217
|
+
const Product = mongoose.model('Product', new mongoose.Schema({
|
|
218
|
+
name: String, price: Number, stock: { type: Number, default: 0 }
|
|
219
|
+
}));
|
|
220
|
+
|
|
443
221
|
const db = createMongooseAdapter({ Product });
|
|
444
222
|
const productCrud = createCrudController(db.Product);
|
|
445
223
|
|
|
446
|
-
// १. पब्लिक रूट: सामानहरू हेर्न
|
|
447
224
|
app.get('/products', productCrud.getAll);
|
|
448
|
-
|
|
449
|
-
// २. प्राइभेट रूट: सामान थप्न (Admin मात्र)
|
|
450
225
|
app.post('/products', auth.middleware(), productCrud.create);
|
|
451
|
-
|
|
452
|
-
// ३. कस्टम रूट: स्टक चेक गर्न
|
|
453
226
|
app.get('/products/:id/stock', async (ctx) => {
|
|
454
|
-
const
|
|
455
|
-
if (!
|
|
456
|
-
|
|
227
|
+
const product = await Product.findById(ctx.params.id);
|
|
228
|
+
if (!product) return ctx.status(404).json({ error: "Not found" });
|
|
229
|
+
return { stock: product.stock };
|
|
457
230
|
});
|
|
458
231
|
|
|
459
|
-
app.listen(8080, () => console.log("DolphinStore
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
### १०.४ यो प्रोजेक्टबाट हामीले के सिक्यौँ?
|
|
463
|
-
- कसरी धेरै मोड्युलहरू (Auth, CRUD, Server) सँगै काम गर्छन्।
|
|
464
|
-
- कसरी पब्लिक र प्राइभेट रूटहरू छुट्याउने।
|
|
465
|
-
- कसरी अड्याप्टरले डाटाबेसमा सजिलै एक्सेस दिन्छ।
|
|
466
|
-
|
|
467
|
-
---
|
|
468
|
-
|
|
469
|
-
## ११. स्केलिङ र पर्फर्मेन्स (Scaling & Performance)
|
|
470
|
-
|
|
471
|
-
जब तपाईँको एपमा लाखौँ युजर आउँछन्, तब सामान्य सर्भरले धान्न सक्दैन। Dolphin लाई स्केल गर्ने केही तरिकाहरू यहाँ छन्।
|
|
472
|
-
|
|
473
|
-
### ११.१ Cluster मोड्युल प्रयोग गर्ने
|
|
474
|
-
Node.js सिङ्गल थ्रेडेड हुन्छ। तर तपाईँको CPU मा धेरै कोर (Cores) हुन्छन्। सबै कोर प्रयोग गर्न Dolphin लाई यसरी रन गर्नुहोस्:
|
|
475
|
-
```typescript
|
|
232
|
+
app.listen(8080, () => console.log("DolphinStore live on 8080! 🛒"));
|
|
233
|
+
११. स्केलिङ र पर्फर्मेन्स (Scaling)
|
|
234
|
+
typescript
|
|
476
235
|
import cluster from 'cluster';
|
|
477
236
|
import os from 'os';
|
|
478
|
-
import { createDolphinServer } from 'dolphin-server-modules/server';
|
|
479
237
|
|
|
480
238
|
if (cluster.isPrimary) {
|
|
481
|
-
|
|
482
|
-
for (let i = 0; i < numCPUs; i++) cluster.fork();
|
|
239
|
+
os.cpus().forEach(() => cluster.fork());
|
|
483
240
|
} else {
|
|
484
241
|
const app = createDolphinServer();
|
|
485
242
|
app.listen(3000);
|
|
486
243
|
}
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
### ११.२ क्यासिङ (Caching)
|
|
490
|
-
डेटाबेसको लोड कम गर्न Redis वा इन-मेमोरी क्यासिङ प्रयोग गर्नुहोस्।
|
|
491
|
-
|
|
492
|
-
---
|
|
493
|
-
|
|
494
|
-
## १२. टेस्टिङ र डेभप्स (Testing & DevOps)
|
|
495
|
-
|
|
496
|
-
प्रोफेसनल कोडमा टेस्टिङ अनिवार्य छ।
|
|
497
|
-
|
|
498
|
-
### १२.१ Unit Testing (Jest)
|
|
499
|
-
Dolphin का फङ्सनहरू टेस्ट गर्न सजिलो छ:
|
|
500
|
-
```typescript
|
|
501
|
-
import { createDolphinServer } from 'dolphin-server-modules/server';
|
|
244
|
+
१२. टेस्टिङ र डेभप्स (Testing)
|
|
245
|
+
typescript
|
|
502
246
|
import request from 'supertest';
|
|
247
|
+
import { createDolphinServer } from 'dolphin-server-modules/server';
|
|
503
248
|
|
|
504
249
|
const app = createDolphinServer();
|
|
505
|
-
app.get('/test', (ctx) =>
|
|
250
|
+
app.get('/test', (ctx) => ({ ok: true }));
|
|
506
251
|
|
|
507
|
-
test('GET /test
|
|
252
|
+
test('GET /test', async () => {
|
|
508
253
|
const res = await request(app.server).get('/test');
|
|
509
254
|
expect(res.body.ok).toBe(true);
|
|
510
255
|
});
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
256
|
+
१३. RealtimeCore: रियलटाइम पब/सब मास्टरक्लास (RealtimeCore)
|
|
257
|
+
RealtimeCore Dolphin को उच्च-प्रदर्शन युनिफाइड पब/सब बस हो। यो IoT डिभाइसहरू, वेबसकेटहरू, र माइक्रोसर्भिसहरू बीच रियलटाइम डाटा संचारको लागि डिजाइन गरिएको छ।
|
|
258
|
+
|
|
259
|
+
१३.१ RealtimeCore को मुख्य विशेषताहरू
|
|
260
|
+
Feature Description
|
|
261
|
+
TopicTrie O(L) समयमा टपिक म्याचिङ (वाइल्डकार्ड + स्ट्याटिक)
|
|
262
|
+
Retained Messages अन्तिम मेसेज सम्झने क्षमता (MQTT जस्तै)
|
|
263
|
+
Redis Bridge मल्टिपल सर्भरहरू बीच स्केलिङ
|
|
264
|
+
DJSON Integration बाइनरी, हेक्स, बेस६४ डाटा अटो-डिकोड
|
|
265
|
+
JSON Cache दोहोरिने पेलोडहरूको क्यासिङ (५ सेकेण्ड TTL)
|
|
266
|
+
ACL Support डिभाइस-लेभल पब्लिस/सब्सक्राइब अनुमति
|
|
267
|
+
Plugins System HL7, Modbus, MQTT जस्ता प्रोटोकलहरू थप्न
|
|
268
|
+
१३.२ स्थापना (Installation)
|
|
269
|
+
bash
|
|
270
|
+
npm install dolphin-server-modules ioredis
|
|
271
|
+
१३.३ आधारभूत प्रयोग (Basic Usage)
|
|
272
|
+
typescript
|
|
273
|
+
import { RealtimeCore } from 'dolphin-server-modules/realtime';
|
|
524
274
|
|
|
525
|
-
|
|
275
|
+
// RealtimeCore को इन्स्ट्यान्स बनाउने
|
|
276
|
+
const rt = new RealtimeCore({
|
|
277
|
+
maxMessageSize: 512 * 1024, // 512KB म्याक्स
|
|
278
|
+
enableJSONCache: true, // JSON क्यास सक्षम
|
|
279
|
+
debug: true, // डिबग लग
|
|
280
|
+
useBinaryProtocol: false // बाइनरी प्रोटोकल प्रयोग
|
|
281
|
+
});
|
|
526
282
|
|
|
527
|
-
|
|
283
|
+
// टपिक सब्सक्राइब गर्ने (वाइल्डकार्ड + सपोर्ट)
|
|
284
|
+
rt.subscribe('sensors/temperature/+', (payload) => {
|
|
285
|
+
console.log(`तापक्रम डाटा: ${payload.value}°C`);
|
|
286
|
+
});
|
|
528
287
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
- **Dolphin CLI**: एउटा कमान्डले प्रोजेक्ट सेटअप गर्ने।
|
|
532
|
-
- **Realtime & IoT Integration**: उच्च क्षमताको डाटा इन्जेसनको लागि। [DONE]
|
|
533
|
-
- **Native SQL Adapters**: PostgreSQL र MySQL का लागि विशेष एडाप्टरहरू।
|
|
288
|
+
// टपिकमा पब्लिस गर्ने
|
|
289
|
+
rt.publish('sensors/temperature/room1', { value: 23.5, unit: 'celsius' });
|
|
534
290
|
|
|
535
|
-
|
|
536
|
-
|
|
291
|
+
// रिटेन्ड मेसेज (नयाँ सब्सक्राइबरले पाउने)
|
|
292
|
+
rt.publish('config/system', { mode: 'active' }, { retain: true, ttl: 3600000 });
|
|
293
|
+
१३.४ वाइल्डकार्ड म्याचिङ (Wildcard Matching)
|
|
294
|
+
RealtimeCore ले MQTT-शैली वाइल्डकार्डहरू सपोर्ट गर्छ:
|
|
537
295
|
|
|
538
|
-
|
|
296
|
+
typescript
|
|
297
|
+
// + (सिङ्गल लेभल) - एउटा सेग्मेन्ट मात्र
|
|
298
|
+
rt.subscribe('sensors/+/temperature', (data) => {
|
|
299
|
+
// म्याच: sensors/room1/temperature, sensors/room2/temperature
|
|
300
|
+
// म्याच गर्दैन: sensors/room1/floor2/temperature
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
// # (मल्टी लेभल) - सबै सेग्मेन्टहरू
|
|
304
|
+
rt.subscribe('sensors/#', (data) => {
|
|
305
|
+
// म्याच: sensors/temp, sensors/room1/humidity, sensors/building/floor/room/temp
|
|
306
|
+
});
|
|
539
307
|
|
|
540
|
-
|
|
308
|
+
// स्ट्याटिक टपिक (पूर्ण म्याच)
|
|
309
|
+
rt.subscribe('device/online', (data) => {
|
|
310
|
+
// केवल device/online मात्र
|
|
311
|
+
});
|
|
312
|
+
१३.५ डिभाइस रजिस्ट्रेसन र सकेट ह्यान्डलिङ (Device Registration)
|
|
313
|
+
typescript
|
|
314
|
+
// WebSocket कनेक्सन ह्यान्डल गर्ने (उदाहरण: ws लाइब्रेरीसँग)
|
|
315
|
+
import WebSocket from 'ws';
|
|
541
316
|
|
|
542
|
-
|
|
317
|
+
const wss = new WebSocket.Server({ port: 8081 });
|
|
543
318
|
|
|
544
|
-
|
|
545
|
-
|
|
319
|
+
wss.on('connection', (ws, req) => {
|
|
320
|
+
const deviceId = req.headers['device-id'] as string || `device-${Date.now()}`;
|
|
321
|
+
|
|
322
|
+
// डिभाइस रजिस्टर गर्ने
|
|
323
|
+
rt.register(deviceId, ws, { type: 'sensor', location: 'kathmandu' });
|
|
324
|
+
|
|
325
|
+
// मेसेज ह्यान्डल गर्ने
|
|
326
|
+
ws.on('message', async (data: Buffer) => {
|
|
327
|
+
await rt.handle(data, ws, deviceId);
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
ws.on('close', () => {
|
|
331
|
+
rt.unregister(deviceId);
|
|
332
|
+
});
|
|
333
|
+
});
|
|
546
334
|
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
335
|
+
// सिग्नलिङ टपिकहरू अटोम्याटिक रूपमा बन्छन्:
|
|
336
|
+
// - phone/signaling/{deviceId} → डिभाइस-स्पेसिफिक
|
|
337
|
+
// - phone/signaling/all → सबै डिभाइसहरूमा ब्रोडकास्ट
|
|
338
|
+
१३.६ DJSON डाटा ह्यान्डलिङ (DJSON Data Handling)
|
|
339
|
+
RealtimeCore ले djson मार्फत बाइनरी, हेक्स, र बेस६४ डाटा अटो-डिकोड गर्छ:
|
|
340
|
+
|
|
341
|
+
typescript
|
|
342
|
+
// क्लाइन्टबाट पठाइएको डाटा (विभिन्न फर्म्याटमा)
|
|
343
|
+
// १. सामान्य JSON
|
|
344
|
+
rt.handle(Buffer.from(JSON.stringify({
|
|
345
|
+
topic: 'sensor/data',
|
|
346
|
+
payload: { value: 42 }
|
|
347
|
+
})));
|
|
348
|
+
|
|
349
|
+
// २. बेस६४-इन्कोडेड JSON
|
|
350
|
+
rt.handle(Buffer.from(JSON.stringify({
|
|
351
|
+
raw: Buffer.from(JSON.stringify({ topic: 'test', payload: { x: 1 } })).toString('base64')
|
|
352
|
+
})));
|
|
353
|
+
|
|
354
|
+
// ३. हेक्स-इन्कोडेड डाटा
|
|
355
|
+
rt.handle(Buffer.from(JSON.stringify({
|
|
356
|
+
_type: 'hex',
|
|
357
|
+
raw: '7b22746f706963223a2274657374222c227061796c6f6164223a7b7d7d'
|
|
358
|
+
})));
|
|
359
|
+
|
|
360
|
+
// सबै केसहरूमा RealtimeCore ले आफै डिकोड गरेर publish गर्छ
|
|
361
|
+
१३.७ रेडिस स्केलिङ (Redis Scaling)
|
|
362
|
+
एकाधिक सर्भरहरू बीच मेसेज सिंक गर्न:
|
|
363
|
+
|
|
364
|
+
typescript
|
|
365
|
+
// सर्भर १
|
|
366
|
+
const rt1 = new RealtimeCore({ redisUrl: 'redis://localhost:6379' });
|
|
367
|
+
|
|
368
|
+
// सर्भर २ (अर्को मेसिनमा)
|
|
369
|
+
const rt2 = new RealtimeCore({ redisUrl: 'redis://localhost:6379' });
|
|
370
|
+
|
|
371
|
+
// rt1 मा पब्लिस गरेको मेसेज rt2 मा पुग्छ
|
|
372
|
+
rt1.publish('global/event', { message: 'Hello from Server 1' });
|
|
373
|
+
१३.८ एसीएल (Access Control List)
|
|
374
|
+
typescript
|
|
375
|
+
const rt = new RealtimeCore({
|
|
376
|
+
acl: {
|
|
377
|
+
canSubscribe: (deviceId, topic) => {
|
|
378
|
+
// डिभाइसले केवल आफ्नै टपिकमा सब्सक्राइब गर्न पाउँछ
|
|
379
|
+
return topic.startsWith(`devices/${deviceId}`) || topic === 'public/#';
|
|
380
|
+
},
|
|
381
|
+
canPublish: (deviceId, topic) => {
|
|
382
|
+
// सेन्सर डिभाइसले sensors/ मात्र पब्लिस गर्न पाउँछ
|
|
383
|
+
if (deviceId.startsWith('sensor-')) return topic.startsWith('sensors/');
|
|
384
|
+
return true;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
१३.९ प्लगिन सिस्टम (Plugin System)
|
|
389
|
+
typescript
|
|
390
|
+
import { RealtimePlugin, RealtimeContext } from 'dolphin-server-modules/plugins';
|
|
391
|
+
|
|
392
|
+
// MQTT प्लगिन बनाउने
|
|
393
|
+
const mqttPlugin: RealtimePlugin = {
|
|
394
|
+
name: 'mqtt-bridge',
|
|
395
|
+
match: (ctx) => ctx.raw[0] === 0x10, // MQTT CONNECT प्याकेट
|
|
396
|
+
decode: (raw) => {
|
|
397
|
+
// MQTT डिकोडिङ लजिक
|
|
398
|
+
return { type: 'mqtt', payload: raw };
|
|
399
|
+
},
|
|
400
|
+
onMessage: (ctx) => {
|
|
401
|
+
console.log('MQTT मेसेज आयो:', ctx.payload);
|
|
402
|
+
}
|
|
403
|
+
};
|
|
551
404
|
|
|
552
|
-
|
|
553
|
-
|
|
405
|
+
rt.use(mqttPlugin);
|
|
406
|
+
१३.१० एपिआई रेफरेन्स (API Reference)
|
|
407
|
+
Constructor Options
|
|
408
|
+
typescript
|
|
409
|
+
interface RealtimeCoreConfig {
|
|
410
|
+
maxMessageSize?: number; // डिफल्ट: 256KB
|
|
411
|
+
redisUrl?: string; // Redis URL (ऐच्छिक)
|
|
412
|
+
acl?: { // Access Control
|
|
413
|
+
canSubscribe: (deviceId, topic) => boolean;
|
|
414
|
+
canPublish: (deviceId, topic) => boolean;
|
|
415
|
+
};
|
|
416
|
+
enableJSONCache?: boolean; // JSON क्यास सक्षम
|
|
417
|
+
useBinaryProtocol?: boolean; // बाइनरी प्रोटोकल
|
|
418
|
+
debug?: boolean; // डिबग मोड
|
|
419
|
+
}
|
|
420
|
+
Methods
|
|
421
|
+
Method Description
|
|
422
|
+
subscribe(topic, fn, deviceId?) टपिकमा सब्सक्राइब
|
|
423
|
+
publish(topic, payload, opts?, deviceId?) टपिकमा पब्लिस
|
|
424
|
+
handle(raw, socket?, deviceId?) कच्चा डाटा प्रोसेस
|
|
425
|
+
broadcast(topic, payload, opts?) सबै डिभाइसमा पठाउने
|
|
426
|
+
register(deviceId, socket?, metadata?) डिभाइस रजिस्टर
|
|
427
|
+
unregister(deviceId) डिभाइस हटाउने
|
|
428
|
+
use(plugin) प्लगिन थप्ने
|
|
429
|
+
getStats() स्ट्याटिस्टिक्स
|
|
430
|
+
destroy() सबै रिसोर्स क्लिनअप
|
|
431
|
+
१३.११ पूर्ण उदाहरण: IoT Sensor Platform
|
|
432
|
+
typescript
|
|
433
|
+
// iot-server.ts
|
|
554
434
|
import { RealtimeCore } from 'dolphin-server-modules/realtime';
|
|
435
|
+
import WebSocket from 'ws';
|
|
555
436
|
|
|
556
437
|
const rt = new RealtimeCore({
|
|
557
|
-
maxMessageSize:
|
|
438
|
+
maxMessageSize: 1024 * 1024,
|
|
439
|
+
enableJSONCache: true,
|
|
440
|
+
debug: process.env.NODE_ENV === 'development'
|
|
558
441
|
});
|
|
559
442
|
|
|
560
|
-
//
|
|
561
|
-
rt.subscribe('sensors
|
|
562
|
-
|
|
443
|
+
// तापक्रम डाटा प्रोसेसिङ
|
|
444
|
+
rt.subscribe('sensors/+/temperature', (data) => {
|
|
445
|
+
if (data.value > 40) {
|
|
446
|
+
console.warn(`उच्च तापक्रम अलर्ट! ${data.value}°C`);
|
|
447
|
+
rt.publish('alerts/high-temp', { value: data.value, timestamp: Date.now() });
|
|
448
|
+
}
|
|
563
449
|
});
|
|
564
450
|
|
|
565
|
-
//
|
|
566
|
-
rt.
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
### १४.४ वाइल्डकार्डको शक्ति (Power of Wildcards)
|
|
570
|
-
- `sensors/+`: `sensors/temp` र `sensors/hum` दुवै म्याच गर्छ।
|
|
571
|
-
- `sensors/#`: `sensors/a/b/c` जति पनि गहिराइ (depth) सम्म म्याच गर्छ।
|
|
572
|
-
|
|
573
|
-
### १४.५ रेडिस स्केलिङ (Redis Scaling)
|
|
574
|
-
यदि तपाईँको धेरै वटा सर्भरहरू छन् भने, तिनीहरूलाई रेडिस मार्फत जोड्न सक्नुहुन्छ:
|
|
575
|
-
```typescript
|
|
576
|
-
const rt = new RealtimeCore({
|
|
577
|
-
redisUrl: 'redis://localhost:6379'
|
|
451
|
+
// सबै सेन्सर डाटा लग गर्ने
|
|
452
|
+
rt.subscribe('sensors/#', (data, topic) => {
|
|
453
|
+
console.log(`[${new Date().toISOString()}] ${topic}:`, data);
|
|
578
454
|
});
|
|
579
|
-
```
|
|
580
|
-
यसो गर्दा एउटा सर्भरबाट पठाएको मेसेज अर्को सर्भरमा बस्ने युजरले पनि तुरुन्तै पाउँछ।
|
|
581
455
|
|
|
582
|
-
|
|
456
|
+
// WebSocket सर्भर
|
|
457
|
+
const wss = new WebSocket.Server({ port: 8080 });
|
|
583
458
|
|
|
584
|
-
|
|
459
|
+
wss.on('connection', (ws, req) => {
|
|
460
|
+
const deviceId = new URL(req.url!, `http://${req.headers.host}`).searchParams.get('id')
|
|
461
|
+
|| `device-${Date.now()}`;
|
|
462
|
+
|
|
463
|
+
rt.register(deviceId, ws, { ip: req.socket.remoteAddress });
|
|
464
|
+
|
|
465
|
+
ws.on('message', (data) => rt.handle(data as Buffer, ws, deviceId));
|
|
466
|
+
ws.on('close', () => rt.unregister(deviceId));
|
|
467
|
+
});
|
|
585
468
|
|
|
586
|
-
|
|
469
|
+
// हेल्थ चेक एन्डपोइन्ट
|
|
470
|
+
setInterval(() => {
|
|
471
|
+
const stats = rt.getStats();
|
|
472
|
+
console.log(`Realtime Stats: ${stats.devices} devices, ${stats.retained} retained`);
|
|
473
|
+
}, 30000);
|
|
587
474
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
475
|
+
process.on('SIGTERM', async () => {
|
|
476
|
+
await rt.destroy();
|
|
477
|
+
process.exit(0);
|
|
478
|
+
});
|
|
592
479
|
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
480
|
+
console.log('IoT Platform running on ws://localhost:8080');
|
|
481
|
+
१४. इन्डिपेन्डेन्ट राउटिङ (Independent Routing)
|
|
482
|
+
typescript
|
|
483
|
+
// userRoutes.ts
|
|
596
484
|
import { createDolphinRouter } from 'dolphin-server-modules/router';
|
|
597
485
|
export const userRouter = createDolphinRouter();
|
|
598
486
|
|
|
599
|
-
userRouter.get('/profile', (ctx) =>
|
|
487
|
+
userRouter.get('/profile', (ctx) => ({ name: "Ram", email: "ram@example.com" }));
|
|
488
|
+
userRouter.post('/update', (ctx) => ({ success: true }));
|
|
600
489
|
|
|
601
490
|
// main.ts
|
|
602
491
|
import { createDolphinServer } from 'dolphin-server-modules/server';
|
|
603
|
-
import { userRouter } from './
|
|
492
|
+
import { userRouter } from './userRoutes';
|
|
604
493
|
|
|
605
494
|
const app = createDolphinServer();
|
|
606
|
-
app.use('/users', userRouter); //
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
---
|
|
610
|
-
|
|
611
|
-
## १६. स्वतन्त्र अटो-स्वैगर जेनेरेसन (Independent Auto-Swagger) [NEW]
|
|
612
|
-
|
|
613
|
-
API बनाउँदा सबैभन्दा अल्छीलाग्दो काम भनेको त्यसको डकुमेन्टेसन (Swagger/OpenAPI docs) हातैले लेख्नु हो। Dolphin ले यसलाई १००% अटोमेटिक र **Framework Independent** बनाइदिएको छ।
|
|
614
|
-
|
|
615
|
-
### १६.१ यो किन विशेष छ?
|
|
616
|
-
यसले तपाईँको `Zod` स्किमालाई सिधै पढेर OpenAPI को स्ट्यान्डर्ड JSON निकाल्छ। यसको लागि तपाईँले कुनै मिडलवेयर (`app.use`) सेटअप गरिरहनु पर्दैन। यो जुनसुकै फ्रेमवर्क (Next.js, Express, Fastify, Dolphin) मा काम गर्छ।
|
|
617
|
-
|
|
618
|
-
### १६.२ कसरी प्रयोग गर्ने?
|
|
619
|
-
```typescript
|
|
495
|
+
app.use('/users', userRouter); // /users/profile, /users/update
|
|
496
|
+
१५. स्वतन्त्र अटो-स्वैगर जेनेरेसन (Auto-Swagger Generation)
|
|
497
|
+
typescript
|
|
620
498
|
import { z } from 'zod';
|
|
621
499
|
import { generateSwagger, serveSwaggerUI } from 'dolphin-server-modules/swagger';
|
|
622
500
|
import { createDolphinServer } from 'dolphin-server-modules/server';
|
|
623
501
|
|
|
624
502
|
const app = createDolphinServer();
|
|
625
503
|
|
|
626
|
-
// १. Zod Schema बनाउने
|
|
627
504
|
const UserSchema = z.object({
|
|
628
|
-
name: z.string(),
|
|
505
|
+
name: z.string().min(3),
|
|
629
506
|
email: z.string().email(),
|
|
630
507
|
age: z.number().optional()
|
|
631
508
|
});
|
|
632
509
|
|
|
633
|
-
// २. Swagger Config तयार गर्ने
|
|
634
510
|
const apiDocs = generateSwagger({
|
|
635
511
|
title: "DolphinStore API",
|
|
636
512
|
version: "1.0.0",
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
description: "Registers a new user in the system.",
|
|
645
|
-
tags: ["Users"]
|
|
646
|
-
}
|
|
647
|
-
]
|
|
513
|
+
modules: [{
|
|
514
|
+
path: "/users",
|
|
515
|
+
method: "post",
|
|
516
|
+
schema: UserSchema,
|
|
517
|
+
summary: "Create new user",
|
|
518
|
+
tags: ["Users"]
|
|
519
|
+
}]
|
|
648
520
|
});
|
|
649
521
|
|
|
650
|
-
// ३. डकुमेन्टेसन सर्भ गर्ने (Swagger UI सँगै)
|
|
651
522
|
app.get('/docs', (ctx) => {
|
|
652
|
-
const html = serveSwaggerUI(apiDocs, "DolphinStore API
|
|
653
|
-
return ctx.html(html);
|
|
523
|
+
const html = serveSwaggerUI(apiDocs, "DolphinStore API");
|
|
524
|
+
return ctx.html(html);
|
|
654
525
|
});
|
|
655
526
|
|
|
656
|
-
// ४. JSON मात्र चाहियो भने (फिल्नेटर वा पोस्टम्यानको लागि)
|
|
657
527
|
app.get('/docs/json', (ctx) => ctx.json(apiDocs));
|
|
528
|
+
१६. API रेफरेन्स (API Reference)
|
|
529
|
+
Server
|
|
530
|
+
Method Description
|
|
531
|
+
app.listen(port, cb) सर्भर सुरु गर्ने
|
|
532
|
+
app.get/patch/post/put/delete(path, ...handlers) HTTP मेथड
|
|
533
|
+
app.use(path?, middleware/router) मिडलवेयर वा राउटर
|
|
534
|
+
app.group(prefix, callback) रूट ग्रुपिङ
|
|
535
|
+
RealtimeCore
|
|
536
|
+
Method Description
|
|
537
|
+
rt.subscribe(topic, fn, deviceId?) सब्सक्राइब
|
|
538
|
+
rt.publish(topic, payload, opts?, deviceId?) पब्लिस
|
|
539
|
+
rt.handle(raw, socket?, deviceId?) डाटा ह्यान्डल
|
|
540
|
+
rt.register(deviceId, socket?, metadata?) डिभाइस रजिस्टर
|
|
541
|
+
rt.destroy() क्लिनअप
|
|
542
|
+
निष्कर्ष (Conclusion)
|
|
543
|
+
बधाई छ! तपाईँले Dolphin Framework को Master Guide पूरा गर्नुभयो। अब तपाईँ:
|
|
658
544
|
|
|
659
|
-
|
|
660
|
-
```
|
|
545
|
+
✅ हाई-पर्फर्मेन्स API सर्भर बनाउन
|
|
661
546
|
|
|
662
|
-
|
|
663
|
-
- **Zod Types:** `string`, `number`, `boolean`, `array`, `object`, `enum`, `optional()`, र `nullable()` लाई राम्रोसँग बुझ्छ।
|
|
664
|
-
- **Path/Query Params:** `modules` भित्र `params: { id: "string" }` जस्ता कुराहरू सपोर्ट गर्छ।
|
|
665
|
-
- **Response Schema:** `responseSchema: UserSchema` दिएर सफल रेस्पोन्स कस्तो हुन्छ भन्ने देखाउन मिल्छ।
|
|
547
|
+
✅ अटोमेटेड CRUD र भ्यालिडेसन प्रयोग गर्न
|
|
666
548
|
|
|
667
|
-
|
|
549
|
+
✅ RealtimeCore सँग IoT र रियलटाइम एप्लिकेसन बनाउन
|
|
668
550
|
|
|
669
|
-
|
|
551
|
+
✅ Redis सँग मल्टिपल सर्भर स्केल गर्न
|
|
670
552
|
|
|
671
|
-
|
|
553
|
+
✅ अटो-जेनेरेटेड Swagger डकुमेन्टेसन बनाउन
|
|
672
554
|
|
|
673
|
-
|
|
555
|
+
सक्नुहुन्छ।
|
|
674
556
|
|
|
675
|
-
|
|
557
|
+
Happy Coding! 🐬🇳🇵
|
|
558
|
+
नेपालबाट विश्वस्तरको सफ्टवेयर बनाऔँ!
|
|
676
559
|
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
560
|
+
text
|
|
561
|
+
|
|
562
|
+
## 📄 PDF कसरी बनाउने?
|
|
563
|
+
|
|
564
|
+
### विधि १: VS Code (सजिलो)
|
|
565
|
+
1. माथिको कोडलाई `dolphin-master-guide.md` मा सेभ गर्नुहोस्
|
|
566
|
+
2. VS Code मा `Markdown PDF` एक्सटेन्सन इन्स्टल गर्नुहोस्
|
|
567
|
+
3. फाइलमा राइट क्लिक → `Markdown PDF: Export (pdf)`
|
|
568
|
+
|
|
569
|
+
### विधि २: कमान्ड लाइन (Pandoc)
|
|
570
|
+
```bash
|
|
571
|
+
pandoc dolphin-master-guide.md -o dolphin-framework-guide.pdf --pdf-engine=xelatex -V geometry:margin=1in
|