dolphin-server-modules 2.11.0 → 2.11.2
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/TUTORIAL_NEPALI.md +181 -0
- package/dist/adapters/mongoose/index.d.ts +4 -4
- package/dist/adapters/mongoose/index.js.map +1 -1
- package/dist/adapters/mongoose/index.test.d.ts +1 -0
- package/dist/adapters/mongoose/index.test.js +145 -0
- package/dist/adapters/mongoose/index.test.js.map +1 -0
- package/dist/adapters/mongoose/integration.test.d.ts +5 -0
- package/dist/adapters/mongoose/integration.test.js +217 -0
- package/dist/adapters/mongoose/integration.test.js.map +1 -0
- package/dist/ai/dolphin-agent/agent.d.ts +5 -0
- package/dist/ai/dolphin-agent/agent.js +93 -35
- package/dist/ai/dolphin-agent/agent.js.map +1 -1
- package/dist/ai/dolphin-agent/config.js +30 -37
- package/dist/ai/dolphin-agent/config.js.map +1 -1
- package/dist/auth/auth.test.d.ts +1 -0
- package/dist/auth/auth.test.js +286 -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 +359 -0
- package/dist/authController/authController.test.js.map +1 -0
- package/dist/bin/cli.js +494 -165
- package/dist/bin/cli.js.map +1 -1
- package/dist/client.test.d.ts +22 -0
- package/dist/client.test.js +573 -0
- package/dist/client.test.js.map +1 -0
- package/dist/controller/controller.test.d.ts +1 -0
- package/dist/controller/controller.test.js +37 -0
- package/dist/controller/controller.test.js.map +1 -0
- package/dist/curd/crud.test.d.ts +1 -0
- package/dist/curd/crud.test.js +104 -0
- package/dist/curd/crud.test.js.map +1 -0
- package/dist/demo-server.d.ts +1 -0
- package/dist/demo-server.js +191 -0
- package/dist/demo-server.js.map +1 -0
- package/dist/djson/djson.test.d.ts +1 -0
- package/dist/djson/djson.test.js +200 -0
- package/dist/djson/djson.test.js.map +1 -0
- package/dist/dolphin-bench.d.ts +1 -0
- package/dist/dolphin-bench.js +63 -0
- package/dist/dolphin-bench.js.map +1 -0
- package/dist/hard-performance-test.d.ts +1 -0
- package/dist/hard-performance-test.js +97 -0
- package/dist/hard-performance-test.js.map +1 -0
- package/dist/middleware/zod.test.d.ts +1 -0
- package/dist/middleware/zod.test.js +74 -0
- package/dist/middleware/zod.test.js.map +1 -0
- package/dist/performance-test.d.ts +1 -0
- package/dist/performance-test.js +92 -0
- package/dist/performance-test.js.map +1 -0
- package/dist/real-test-mongoose.d.ts +1 -0
- package/dist/real-test-mongoose.js +104 -0
- package/dist/real-test-mongoose.js.map +1 -0
- package/dist/realtime/camera.d.ts +119 -0
- package/dist/realtime/camera.js +299 -0
- package/dist/realtime/camera.js.map +1 -0
- package/dist/realtime/camera.test.d.ts +1 -0
- package/dist/realtime/camera.test.js +345 -0
- package/dist/realtime/camera.test.js.map +1 -0
- package/dist/realtime/index.d.ts +2 -0
- package/dist/realtime/index.js +2 -0
- package/dist/realtime/index.js.map +1 -1
- package/dist/realtime/realtime.test.d.ts +1 -0
- package/dist/realtime/realtime.test.js +623 -0
- package/dist/realtime/realtime.test.js.map +1 -0
- package/dist/realtime/rtsp.d.ts +65 -0
- package/dist/realtime/rtsp.js +410 -0
- package/dist/realtime/rtsp.js.map +1 -0
- package/dist/realtime/rtsp.test.d.ts +1 -0
- package/dist/realtime/rtsp.test.js +361 -0
- package/dist/realtime/rtsp.test.js.map +1 -0
- package/dist/router/router.test.d.ts +1 -0
- package/dist/router/router.test.js +45 -0
- package/dist/router/router.test.js.map +1 -0
- package/dist/server/server.test.d.ts +1 -0
- package/dist/server/server.test.js +299 -0
- package/dist/server/server.test.js.map +1 -0
- package/dist/services/ai-service.js +22 -11
- package/dist/services/ai-service.js.map +1 -1
- package/dist/signaling/signaling.test.d.ts +1 -0
- package/dist/signaling/signaling.test.js +112 -0
- package/dist/signaling/signaling.test.js.map +1 -0
- package/dist/swagger/swagger.js +31 -31
- package/dist/swagger/swagger.test.d.ts +1 -0
- package/dist/swagger/swagger.test.js +38 -0
- package/dist/swagger/swagger.test.js.map +1 -0
- package/dist/templates/index.d.ts +6 -0
- package/dist/templates/index.js +282 -105
- package/dist/templates/index.js.map +1 -1
- package/dist/test-2fa-real.d.ts +1 -0
- package/dist/test-2fa-real.js +105 -0
- package/dist/test-2fa-real.js.map +1 -0
- package/dist/test-dolphin.d.ts +1 -0
- package/dist/test-dolphin.js +98 -0
- package/dist/test-dolphin.js.map +1 -0
- package/dist/utils/ctx.d.ts +50 -0
- package/dist/utils/ctx.js +82 -0
- package/dist/utils/ctx.js.map +1 -0
- package/package.json +155 -45
- package/scripts/client.js +838 -0
- package/scripts/dolphin-persist.js +211 -0
package/dist/bin/cli.js
CHANGED
|
@@ -2,54 +2,266 @@
|
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import { createServer } from 'http';
|
|
5
|
+
import net from 'net';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
5
7
|
import { AIService } from '../services/ai-service.js';
|
|
6
8
|
import { CLIUI } from '../utils/ui.js';
|
|
7
9
|
import { TEMPLATES } from '../templates/index.js';
|
|
8
10
|
const args = process.argv.slice(2);
|
|
9
11
|
const command = args[0] || 'help';
|
|
10
|
-
//
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
// Version — package.json बाट dynamic पढ्ने
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname = path.dirname(__filename);
|
|
15
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, '../../package.json'), 'utf8'));
|
|
16
|
+
const VERSION = pkg.version;
|
|
17
|
+
// .env loader
|
|
18
|
+
const envFilePath = path.join(process.cwd(), '.env');
|
|
19
|
+
if (fs.existsSync(envFilePath)) {
|
|
20
|
+
fs.readFileSync(envFilePath, 'utf8').split('\n').forEach(line => {
|
|
21
|
+
const trimmed = line.trim();
|
|
22
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
23
|
+
return;
|
|
24
|
+
const eqIdx = trimmed.indexOf('=');
|
|
25
|
+
if (eqIdx === -1)
|
|
26
|
+
return;
|
|
27
|
+
const key = trimmed.slice(0, eqIdx).trim();
|
|
28
|
+
const value = trimmed.slice(eqIdx + 1).trim().replace(/^["']|["']$/g, '');
|
|
29
|
+
if (key && !process.env[key])
|
|
30
|
+
process.env[key] = value;
|
|
19
31
|
});
|
|
20
32
|
}
|
|
21
33
|
const aiConfig = {
|
|
22
34
|
apiKey: (process.env.DOLPHIN_AI_KEY || process.env.GEMINI_API_KEY || '').trim(),
|
|
23
35
|
baseUrl: process.env.DOLPHIN_AI_BASE_URL,
|
|
24
|
-
model: process.env.DOLPHIN_AI_MODEL
|
|
36
|
+
model: process.env.DOLPHIN_AI_MODEL,
|
|
25
37
|
};
|
|
26
38
|
const useOllama = process.env.USE_OLLAMA === 'true';
|
|
27
39
|
const hasAnyKey = aiConfig.apiKey || process.env.GROQ_API_KEY || process.env.OPENAI_API_KEY;
|
|
28
40
|
if (!hasAnyKey && !useOllama && ['generate', 'generate-full', 'chat'].includes(command)) {
|
|
29
|
-
CLIUI.error('API Key
|
|
41
|
+
CLIUI.error('API Key फेला परेन! .env मा DOLPHIN_AI_KEY, GEMINI_API_KEY, वा GROQ_API_KEY राख्नुहोस्।');
|
|
30
42
|
process.exit(1);
|
|
31
43
|
}
|
|
32
44
|
const ai = new AIService(aiConfig);
|
|
45
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
46
|
+
function ensureDir(dir) {
|
|
47
|
+
if (!fs.existsSync(dir))
|
|
48
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
49
|
+
}
|
|
50
|
+
function writeFile(filePath, content, label) {
|
|
51
|
+
ensureDir(path.dirname(filePath));
|
|
52
|
+
fs.writeFileSync(filePath, content);
|
|
53
|
+
console.log(` 📄 Created: ${label || path.relative(process.cwd(), filePath)}`);
|
|
54
|
+
}
|
|
55
|
+
function capitalize(s) {
|
|
56
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
57
|
+
}
|
|
58
|
+
/** TCP port check — live connection test गर्ने */
|
|
59
|
+
function checkTcpPort(host, port, timeoutMs = 4000) {
|
|
60
|
+
return new Promise((resolve) => {
|
|
61
|
+
const socket = new net.Socket();
|
|
62
|
+
socket.setTimeout(timeoutMs);
|
|
63
|
+
socket.once('connect', () => { socket.destroy(); resolve(true); });
|
|
64
|
+
socket.once('error', () => { socket.destroy(); resolve(false); });
|
|
65
|
+
socket.once('timeout', () => { socket.destroy(); resolve(false); });
|
|
66
|
+
socket.connect(port, host);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/** URI बाट host र port निकाल्ने */
|
|
70
|
+
function parseUri(uri) {
|
|
71
|
+
try {
|
|
72
|
+
const u = new URL(uri);
|
|
73
|
+
const defaults = {
|
|
74
|
+
'mongodb:': 27017, 'mongodb+srv:': 27017,
|
|
75
|
+
'redis:': 6379, 'rediss:': 6380,
|
|
76
|
+
};
|
|
77
|
+
return {
|
|
78
|
+
host: u.hostname || 'localhost',
|
|
79
|
+
port: parseInt(u.port || '') || defaults[u.protocol] || 3000,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return { host: 'localhost', port: 27017 };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Automatically registers the newly created Mongoose model in the entry file (e.g. app.js)
|
|
88
|
+
* where createMongooseAdapter is called, by adding the model import and inserting it into
|
|
89
|
+
* the adapter initialization parameters.
|
|
90
|
+
*/
|
|
91
|
+
function registerModelInAdapter(modelName) {
|
|
92
|
+
const entryFiles = ['app.js', 'app.ts', 'server.js', 'server.ts', 'index.js', 'index.ts'];
|
|
93
|
+
let foundFile = '';
|
|
94
|
+
let content = '';
|
|
95
|
+
for (const file of entryFiles) {
|
|
96
|
+
const fullPath = path.join(process.cwd(), file);
|
|
97
|
+
if (fs.existsSync(fullPath)) {
|
|
98
|
+
const txt = fs.readFileSync(fullPath, 'utf8');
|
|
99
|
+
if (txt.includes('createMongooseAdapter')) {
|
|
100
|
+
foundFile = fullPath;
|
|
101
|
+
content = txt;
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (!foundFile) {
|
|
107
|
+
console.log(` ⚠️ Could not find any file calling createMongooseAdapter to register ${modelName}.`);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
// 1. Add Import
|
|
111
|
+
if (content.includes(`models/${modelName}.js`) || content.includes(`models/${modelName}`)) {
|
|
112
|
+
console.log(` ⚠️ ${modelName} is already imported in ${path.basename(foundFile)}`);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
const importLine = `import { ${modelName} } from './models/${modelName}.js';\n`;
|
|
116
|
+
const modelImportRegex = /import\s+{[^}]+}\s+from\s+['"].\/models\/[^'"]+['"];/g;
|
|
117
|
+
const matches = [...content.matchAll(modelImportRegex)];
|
|
118
|
+
if (matches.length > 0) {
|
|
119
|
+
const lastMatch = matches[matches.length - 1];
|
|
120
|
+
const insertPos = lastMatch.index + lastMatch[0].length;
|
|
121
|
+
content = content.slice(0, insertPos) + '\n' + importLine + content.slice(insertPos);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
const firstImportIdx = content.indexOf('import ');
|
|
125
|
+
if (firstImportIdx !== -1) {
|
|
126
|
+
content = content.slice(0, firstImportIdx) + importLine + content.slice(firstImportIdx);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
content = importLine + content;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// 2. Add to createMongooseAdapter arguments
|
|
134
|
+
const adapterCallRegex = /createMongooseAdapter\s*\(\s*\{([\s\S]*?)\}\s*\)/;
|
|
135
|
+
const match = content.match(adapterCallRegex);
|
|
136
|
+
if (match) {
|
|
137
|
+
const innerContent = match[1];
|
|
138
|
+
if (innerContent.includes(modelName)) {
|
|
139
|
+
console.log(` ⚠️ ${modelName} already registered in createMongooseAdapter`);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
let updatedInner = '';
|
|
143
|
+
if (innerContent.includes('models:')) {
|
|
144
|
+
const modelsRegex = /models\s*:\s*\{\s*([\s\S]*?)\s*\}/;
|
|
145
|
+
const modelsMatch = innerContent.match(modelsRegex);
|
|
146
|
+
if (modelsMatch) {
|
|
147
|
+
const existingModels = modelsMatch[1].trim();
|
|
148
|
+
const updatedModels = existingModels ? `${modelName}, ${existingModels}` : modelName;
|
|
149
|
+
updatedInner = innerContent.replace(modelsRegex, `models: { ${updatedModels} }`);
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
updatedInner = innerContent.trim() + `, models: { ${modelName} }`;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
const trimmedInner = innerContent.trim();
|
|
157
|
+
updatedInner = trimmedInner ? `${trimmedInner}, models: { ${modelName} }` : `models: { ${modelName} }`;
|
|
158
|
+
}
|
|
159
|
+
content = content.replace(adapterCallRegex, `createMongooseAdapter({ ${updatedInner} })`);
|
|
160
|
+
fs.writeFileSync(foundFile, content);
|
|
161
|
+
console.log(` ✅ Registered: ${modelName} registered in ${path.relative(process.cwd(), foundFile)}`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
console.log(` ⚠️ Could not parse createMongooseAdapter call in ${path.basename(foundFile)}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// ─── Commands ─────────────────────────────────────────────────────────────────
|
|
33
169
|
async function run() {
|
|
34
170
|
switch (command) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
171
|
+
// ── serve ────────────────────────────────────────────────────────────
|
|
172
|
+
case 'serve': {
|
|
173
|
+
const port = parseInt(args.find(a => a.startsWith('--port='))?.split('=')[1] || '3000');
|
|
174
|
+
CLIUI.heading(`Dolphin Dev Server — port ${port}`);
|
|
38
175
|
const server = createServer((req, res) => {
|
|
39
176
|
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
|
40
|
-
res.end('Dolphin Server is swimming!\n');
|
|
177
|
+
res.end('🐬 Dolphin Server is swimming!\n');
|
|
41
178
|
});
|
|
42
179
|
server.listen(port, () => {
|
|
43
180
|
CLIUI.success(`Server is live at http://localhost:${port}`);
|
|
181
|
+
console.log(' Ctrl+C थिचेर रोक्नुहोस्।');
|
|
44
182
|
});
|
|
45
183
|
break;
|
|
46
|
-
|
|
184
|
+
}
|
|
185
|
+
// ── connect mongoose|redis ───────────────────────────────────────────
|
|
186
|
+
case 'connect': {
|
|
187
|
+
const dbType = args[1];
|
|
188
|
+
const uriArg = args[2];
|
|
189
|
+
if (dbType === 'mongoose' || dbType === 'mongo' || dbType === 'mongodb') {
|
|
190
|
+
const uri = uriArg || process.env.MONGO_URI || 'mongodb://localhost:27017';
|
|
191
|
+
CLIUI.heading('MongoDB Connection Test');
|
|
192
|
+
console.log(` URI: ${uri.replace(/:\/\/[^@]+@/, '://***@')}`);
|
|
193
|
+
// Step 1: TCP check
|
|
194
|
+
CLIUI.startSpinner('TCP ping...');
|
|
195
|
+
const { host, port } = parseUri(uri);
|
|
196
|
+
const tcpOk = await checkTcpPort(host, port);
|
|
197
|
+
CLIUI.stopSpinner(tcpOk, tcpOk ? `Host reachable: ${host}:${port}` : `Cannot reach ${host}:${port}`);
|
|
198
|
+
if (!tcpOk) {
|
|
199
|
+
console.log('\n \x1b[33mFix — MongoDB start गर्नुहोस्:\x1b[0m');
|
|
200
|
+
console.log(' brew services start mongodb-community (macOS)');
|
|
201
|
+
console.log(' sudo systemctl start mongod (Linux)');
|
|
202
|
+
console.log(' mongod (manual)');
|
|
203
|
+
process.exit(1);
|
|
204
|
+
}
|
|
205
|
+
// Step 2: Mongoose check
|
|
206
|
+
CLIUI.startSpinner('Mongoose handshake...');
|
|
207
|
+
try {
|
|
208
|
+
const mongoose = await import('mongoose');
|
|
209
|
+
await mongoose.default.connect(uri, { serverSelectionTimeoutMS: 5000 });
|
|
210
|
+
const dbHost = mongoose.default.connection.host;
|
|
211
|
+
await mongoose.default.disconnect();
|
|
212
|
+
CLIUI.stopSpinner(true, `Connected! Host: ${dbHost}`);
|
|
213
|
+
CLIUI.success('MongoDB तयार छ। MONGO_URI .env मा राख्नुहोस्।');
|
|
214
|
+
}
|
|
215
|
+
catch (e) {
|
|
216
|
+
CLIUI.stopSpinner(false, e.message);
|
|
217
|
+
CLIUI.error('Mongoose connection failed. URI सही छ?');
|
|
218
|
+
process.exit(1);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
else if (dbType === 'redis') {
|
|
222
|
+
const uri = uriArg || process.env.REDIS_URL || 'redis://localhost:6379';
|
|
223
|
+
CLIUI.heading('Redis Connection Test');
|
|
224
|
+
console.log(` URI: ${uri}`);
|
|
225
|
+
CLIUI.startSpinner('TCP ping...');
|
|
226
|
+
const { host, port } = parseUri(uri);
|
|
227
|
+
const tcpOk = await checkTcpPort(host, port);
|
|
228
|
+
CLIUI.stopSpinner(tcpOk, tcpOk ? `Host reachable: ${host}:${port}` : `Cannot reach ${host}:${port}`);
|
|
229
|
+
if (!tcpOk) {
|
|
230
|
+
console.log('\n \x1b[33mFix — Redis start गर्नुहोस्:\x1b[0m');
|
|
231
|
+
console.log(' brew services start redis (macOS)');
|
|
232
|
+
console.log(' sudo systemctl start redis (Linux)');
|
|
233
|
+
console.log(' redis-server (manual)');
|
|
234
|
+
process.exit(1);
|
|
235
|
+
}
|
|
236
|
+
CLIUI.startSpinner('Redis PING...');
|
|
237
|
+
try {
|
|
238
|
+
const { createClient } = await import('redis');
|
|
239
|
+
const client = createClient({ url: uri });
|
|
240
|
+
await client.connect();
|
|
241
|
+
const pong = await client.ping();
|
|
242
|
+
await client.quit();
|
|
243
|
+
CLIUI.stopSpinner(pong === 'PONG', `Redis replied: ${pong}`);
|
|
244
|
+
CLIUI.success('Redis तयार छ!');
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
CLIUI.stopSpinner(true, 'TCP OK (redis package: npm install redis)');
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
CLIUI.error('Usage:');
|
|
252
|
+
console.log(' dolphin connect mongoose [uri]');
|
|
253
|
+
console.log(' dolphin connect redis [uri]');
|
|
254
|
+
}
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
// ── generate ─────────────────────────────────────────────────────────
|
|
258
|
+
case 'generate': {
|
|
47
259
|
const prompt = args.slice(1).join(' ');
|
|
48
260
|
if (!prompt)
|
|
49
261
|
return CLIUI.error('Usage: dolphin generate "your prompt"');
|
|
50
262
|
CLIUI.startSpinner('AI is generating code');
|
|
51
263
|
try {
|
|
52
|
-
const response = await ai.request(prompt,
|
|
264
|
+
const response = await ai.request(prompt, 'Return ONLY raw JavaScript code. No markdown.');
|
|
53
265
|
const cleanCode = response.replace(/```javascript|```js|```/g, '').trim();
|
|
54
266
|
fs.writeFileSync(path.join(process.cwd(), 'ai-generated.js'), cleanCode);
|
|
55
267
|
CLIUI.stopSpinner(true, 'File generated: ai-generated.js');
|
|
@@ -58,202 +270,319 @@ async function run() {
|
|
|
58
270
|
CLIUI.stopSpinner(false, e.message);
|
|
59
271
|
}
|
|
60
272
|
break;
|
|
61
|
-
|
|
273
|
+
}
|
|
274
|
+
// ── generate-full ────────────────────────────────────────────────────
|
|
275
|
+
case 'generate-full': {
|
|
62
276
|
const fullPrompt = args.slice(1).join(' ');
|
|
63
277
|
if (!fullPrompt)
|
|
64
278
|
return CLIUI.error('Usage: dolphin generate-full "project description"');
|
|
65
279
|
CLIUI.startSpinner('Architecting full project structure');
|
|
66
280
|
try {
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
- Use 'dolphin-server-modules/crud' for createCrudController(dbAdapter, modelName)
|
|
74
|
-
Example usage:
|
|
75
|
-
const app = createDolphinServer();
|
|
76
|
-
const db = createMongooseAdapter(uri);
|
|
77
|
-
const crud = createCrudController(db, "Task");
|
|
78
|
-
app.get("/tasks", crud.getAll);
|
|
79
|
-
app.post("/tasks", crud.create);
|
|
80
|
-
Project Structure:
|
|
81
|
-
- package.json (MUST include "type": "module")
|
|
82
|
-
- index.js (main server)
|
|
83
|
-
- models/ (Mongoose models)
|
|
84
|
-
- .env (env vars)
|
|
85
|
-
|
|
86
|
-
CRITICAL: Return ONLY a valid JSON object.
|
|
87
|
-
IMPORTANT: All code content inside JSON strings MUST have escaped newlines (use \\n).
|
|
88
|
-
Example: { "file.js": "import x from 'y';\\nconsole.log(x);" }
|
|
89
|
-
No markdown. No conversational text.`;
|
|
90
|
-
const response = await ai.request(fullPrompt, systemPrompt);
|
|
91
|
-
fs.writeFileSync('debug-ai-response.txt', response);
|
|
92
|
-
// Robust JSON extraction using stack-based matching
|
|
93
|
-
let cleaned = "";
|
|
94
|
-
let i = response.indexOf('{');
|
|
95
|
-
if (i !== -1) {
|
|
96
|
-
let stack = 0;
|
|
97
|
-
let inString = false;
|
|
98
|
-
let escaped = false;
|
|
99
|
-
let start = i;
|
|
100
|
-
for (let j = i; j < response.length; j++) {
|
|
101
|
-
const char = response[j];
|
|
102
|
-
if (char === '"' && !escaped)
|
|
103
|
-
inString = !inString;
|
|
104
|
-
if (!inString) {
|
|
105
|
-
if (char === '{')
|
|
106
|
-
stack++;
|
|
107
|
-
if (char === '}')
|
|
108
|
-
stack--;
|
|
109
|
-
if (stack === 0) {
|
|
110
|
-
cleaned = response.substring(start, j + 1);
|
|
111
|
-
break;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
if (char === '\\' && !escaped)
|
|
115
|
-
escaped = true;
|
|
116
|
-
else
|
|
117
|
-
escaped = false;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
if (!cleaned)
|
|
121
|
-
cleaned = response.replace(/```json|```/g, '').trim();
|
|
281
|
+
const sysPrompt = `You are a Dolphin Framework expert. Generate a production-ready backend project.
|
|
282
|
+
Use: createDolphinServer(), createMongooseAdapter({User,RefreshToken}), createDolphinAuthController(), createCrudController().
|
|
283
|
+
Return ONLY a JSON object: {filePath: fileContent}. No markdown.`;
|
|
284
|
+
const response = await ai.request(fullPrompt, sysPrompt);
|
|
285
|
+
const jsonMatch = response.match(/\{[\s\S]*\}/);
|
|
286
|
+
const cleaned = jsonMatch ? jsonMatch[0] : response.replace(/```json|```/g, '').trim();
|
|
122
287
|
let files;
|
|
123
288
|
try {
|
|
124
289
|
files = JSON.parse(cleaned);
|
|
125
290
|
}
|
|
126
|
-
catch
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
const fixed = cleaned.replace(/"([^"]*)"/g, (match, content) => {
|
|
130
|
-
return '"' + content.replace(/\n/g, '\\n').replace(/\r/g, '\\r') + '"';
|
|
131
|
-
});
|
|
132
|
-
files = JSON.parse(fixed);
|
|
291
|
+
catch {
|
|
292
|
+
const sanitized = cleaned.replace(/[\x00-\x1F\x7F-\x9F]/g, (c) => c === '\n' ? '\\n' : c === '\r' ? '\\r' : c === '\t' ? '\\t' : '');
|
|
293
|
+
files = JSON.parse(sanitized);
|
|
133
294
|
}
|
|
134
295
|
Object.entries(files).forEach(([fPath, content]) => {
|
|
135
296
|
const fullPath = path.join(process.cwd(), fPath);
|
|
136
|
-
// Don't overwrite existing .env files to protect API keys
|
|
137
297
|
if (fPath === '.env' && fs.existsSync(fullPath)) {
|
|
138
|
-
console.log(
|
|
298
|
+
console.log(' ⚠️ Skipped: .env');
|
|
139
299
|
return;
|
|
140
300
|
}
|
|
141
|
-
|
|
301
|
+
ensureDir(path.dirname(fullPath));
|
|
142
302
|
fs.writeFileSync(fullPath, content);
|
|
143
303
|
console.log(` 📄 Created: ${fPath}`);
|
|
144
304
|
});
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
JWT_SECRET=your_ultra_secret_jwt_key_here
|
|
150
|
-
GEMINI_API_KEY=your_gemini_api_key_here
|
|
151
|
-
GROQ_API_KEY=your_groq_api_key_here
|
|
152
|
-
OPENAI_API_KEY=your_openai_api_key_here
|
|
153
|
-
`;
|
|
154
|
-
fs.writeFileSync(envPath, defaultEnv);
|
|
155
|
-
console.log(` 📄 Created: .env (with defaults)`);
|
|
305
|
+
const dotEnv = path.join(process.cwd(), '.env');
|
|
306
|
+
if (!fs.existsSync(dotEnv)) {
|
|
307
|
+
fs.writeFileSync(dotEnv, TEMPLATES.env);
|
|
308
|
+
console.log(' 📄 Created: .env');
|
|
156
309
|
}
|
|
157
|
-
CLIUI.stopSpinner(true, 'Project architected
|
|
310
|
+
CLIUI.stopSpinner(true, 'Project architected!');
|
|
158
311
|
}
|
|
159
312
|
catch (e) {
|
|
160
313
|
CLIUI.stopSpinner(false, e.message);
|
|
161
314
|
}
|
|
162
315
|
break;
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
CLIUI.error(`[Dolphin-Agent]
|
|
169
|
-
});
|
|
316
|
+
}
|
|
317
|
+
// ── chat ─────────────────────────────────────────────────────────────
|
|
318
|
+
case 'chat': {
|
|
319
|
+
import('../ai/dolphin-agent/index.js')
|
|
320
|
+
.then(m => { const a = m.initAgentHook({ framework: 'dolphin', autoGenerateEnv: false }); a.interactiveChat(); })
|
|
321
|
+
.catch(err => CLIUI.error(`[Dolphin-Agent] ${err.message}`));
|
|
170
322
|
break;
|
|
323
|
+
}
|
|
324
|
+
// ── init / init-prod ─────────────────────────────────────────────────
|
|
171
325
|
case 'init':
|
|
172
|
-
case 'init-prod':
|
|
173
|
-
CLIUI.heading('
|
|
326
|
+
case 'init-prod': {
|
|
327
|
+
CLIUI.heading('Production Project Scaffold');
|
|
174
328
|
const dirs = ['models', 'controllers', 'routes', 'middleware', 'services', 'config'];
|
|
175
|
-
dirs.forEach(
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
329
|
+
dirs.forEach(d => { ensureDir(path.join(process.cwd(), d)); console.log(` 📁 ${d}/`); });
|
|
330
|
+
const files = [
|
|
331
|
+
['app.js', TEMPLATES.app],
|
|
332
|
+
['config/db.js', TEMPLATES.mongoose],
|
|
333
|
+
['.env', TEMPLATES.env],
|
|
334
|
+
['.gitignore', 'node_modules/\ndist/\n.env\n*.log\n'],
|
|
335
|
+
];
|
|
336
|
+
files.forEach(([rel, content]) => {
|
|
337
|
+
const full = path.join(process.cwd(), rel);
|
|
338
|
+
if (!fs.existsSync(full)) {
|
|
339
|
+
fs.writeFileSync(full, content);
|
|
340
|
+
console.log(` 📄 Created: ${rel}`);
|
|
341
|
+
}
|
|
186
342
|
});
|
|
343
|
+
CLIUI.success('Structure ready!');
|
|
344
|
+
console.log('\n Next steps:');
|
|
345
|
+
console.log(' 1. npm install dolphin-server-modules mongoose');
|
|
346
|
+
console.log(' 2. dolphin connect mongoose — DB test');
|
|
347
|
+
console.log(' 3. node app.js — Server start');
|
|
348
|
+
import('../ai/dolphin-agent/index.js')
|
|
349
|
+
.then(m => m.initAgentHook({ framework: 'dolphin', autoGenerateEnv: true }))
|
|
350
|
+
.catch(() => { });
|
|
187
351
|
break;
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
352
|
+
}
|
|
353
|
+
// ── add ──────────────────────────────────────────────────────────────
|
|
354
|
+
case 'add': {
|
|
355
|
+
const sub = args[1];
|
|
356
|
+
const name = args[2];
|
|
357
|
+
// add adapter
|
|
358
|
+
if (sub === 'adapter') {
|
|
359
|
+
const type = name || '';
|
|
360
|
+
const configDir = path.join(process.cwd(), 'config');
|
|
361
|
+
if (['mongoose', 'mongo', 'mongodb'].includes(type)) {
|
|
362
|
+
writeFile(path.join(configDir, 'db.js'), TEMPLATES.mongoose, 'config/db.js');
|
|
363
|
+
CLIUI.success('Mongoose adapter added!');
|
|
364
|
+
console.log('\n Usage: import { connectDB } from \'./config/db.js\';');
|
|
365
|
+
console.log(' connectDB(process.env.MONGO_URI);');
|
|
366
|
+
}
|
|
367
|
+
else if (['sequelize', 'mysql', 'postgres', 'sql'].includes(type)) {
|
|
368
|
+
writeFile(path.join(configDir, 'db.js'), TEMPLATES.sequelize, 'config/db.js');
|
|
369
|
+
CLIUI.success('Sequelize adapter added!');
|
|
370
|
+
console.log('\n MySQL: npm install sequelize mysql2');
|
|
371
|
+
console.log(' PostgreSQL: npm install sequelize pg pg-hstore');
|
|
372
|
+
}
|
|
373
|
+
else if (type === 'redis') {
|
|
374
|
+
writeFile(path.join(configDir, 'redis.js'), TEMPLATES.redis, 'config/redis.js');
|
|
375
|
+
CLIUI.success('Redis adapter added!');
|
|
376
|
+
console.log('\n Install: npm install redis');
|
|
377
|
+
console.log(' Usage: import { connectRedis, cache } from \'./config/redis.js\';');
|
|
198
378
|
}
|
|
199
379
|
else {
|
|
200
|
-
CLIUI.error('
|
|
380
|
+
CLIUI.error('Unknown adapter. Available: mongoose | sequelize | redis');
|
|
381
|
+
console.log(' Examples:');
|
|
382
|
+
console.log(' dolphin add adapter mongoose');
|
|
383
|
+
console.log(' dolphin add adapter sequelize');
|
|
384
|
+
console.log(' dolphin add adapter redis');
|
|
201
385
|
}
|
|
386
|
+
// add auth
|
|
202
387
|
}
|
|
203
|
-
else if (
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
CLIUI.success('Auth controller and User model added.');
|
|
388
|
+
else if (sub === 'auth') {
|
|
389
|
+
writeFile(path.join(process.cwd(), 'controllers', 'auth.js'), TEMPLATES.auth, 'controllers/auth.js');
|
|
390
|
+
writeFile(path.join(process.cwd(), 'models', 'User.js'), TEMPLATES.authModel, 'models/User.js');
|
|
391
|
+
CLIUI.success('Auth controller + User model added!');
|
|
392
|
+
console.log('\n app.js मा थप्नुहोस्:');
|
|
393
|
+
console.log(' import { auth } from \'./controllers/auth.js\';');
|
|
394
|
+
console.log(' app.post(\'/api/auth/register\', auth.register);');
|
|
395
|
+
console.log(' app.post(\'/api/auth/login\', auth.login);');
|
|
396
|
+
// add crud
|
|
213
397
|
}
|
|
214
|
-
else if (
|
|
215
|
-
const name = args[2];
|
|
398
|
+
else if (sub === 'crud') {
|
|
216
399
|
if (!name)
|
|
217
400
|
return CLIUI.error('Usage: dolphin add crud <ModelName>');
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
401
|
+
const N = capitalize(name);
|
|
402
|
+
writeFile(path.join(process.cwd(), 'controllers', `${N.toLowerCase()}.js`), TEMPLATES.crud(N), `controllers/${N.toLowerCase()}.js`);
|
|
403
|
+
writeFile(path.join(process.cwd(), 'models', `${N}.js`), TEMPLATES.crudModel(N), `models/${N}.js`);
|
|
404
|
+
CLIUI.success(`CRUD for ${N} generated!`);
|
|
405
|
+
// add model
|
|
406
|
+
}
|
|
407
|
+
else if (sub === 'model') {
|
|
408
|
+
if (!name)
|
|
409
|
+
return CLIUI.error('Usage: dolphin add model <ModelName> [--adapter]');
|
|
410
|
+
const N = capitalize(name);
|
|
411
|
+
writeFile(path.join(process.cwd(), 'models', `${N}.js`), TEMPLATES.model(N), `models/${N}.js`);
|
|
412
|
+
CLIUI.success(`${N} model added!`);
|
|
413
|
+
if (args.includes('--adapter') || args.includes('-a')) {
|
|
414
|
+
registerModelInAdapter(N);
|
|
415
|
+
}
|
|
416
|
+
// add model-adapter
|
|
417
|
+
}
|
|
418
|
+
else if (sub === 'model-adapter') {
|
|
419
|
+
if (!name)
|
|
420
|
+
return CLIUI.error('Usage: dolphin add model-adapter <ModelName>');
|
|
421
|
+
const N = capitalize(name);
|
|
422
|
+
writeFile(path.join(process.cwd(), 'models', `${N}.js`), TEMPLATES.model(N), `models/${N}.js`);
|
|
423
|
+
CLIUI.success(`${N} model added!`);
|
|
424
|
+
registerModelInAdapter(N);
|
|
425
|
+
// add middleware
|
|
426
|
+
}
|
|
427
|
+
else if (sub === 'middleware' || sub === 'mw') {
|
|
428
|
+
if (!name)
|
|
429
|
+
return CLIUI.error('Usage: dolphin add middleware <Name>');
|
|
430
|
+
const N = capitalize(name);
|
|
431
|
+
writeFile(path.join(process.cwd(), 'middleware', `${name.toLowerCase()}.js`), TEMPLATES.middleware(N), `middleware/${name.toLowerCase()}.js`);
|
|
432
|
+
CLIUI.success(`${N} middleware added!`);
|
|
433
|
+
console.log(`\n app.use() मा थप्नुहोस्: import { ${name.toLowerCase()}Middleware } from './middleware/${name.toLowerCase()}.js';`);
|
|
434
|
+
// add route
|
|
435
|
+
}
|
|
436
|
+
else if (sub === 'route' || sub === 'router') {
|
|
437
|
+
if (!name)
|
|
438
|
+
return CLIUI.error('Usage: dolphin add route <Name>');
|
|
439
|
+
const N = capitalize(name);
|
|
440
|
+
writeFile(path.join(process.cwd(), 'routes', `${name.toLowerCase()}.js`), TEMPLATES.route(N), `routes/${name.toLowerCase()}.js`);
|
|
441
|
+
CLIUI.success(`${N} route added!`);
|
|
442
|
+
console.log(`\n import { ${name.toLowerCase()}Router } from './routes/${name.toLowerCase()}.js';`);
|
|
443
|
+
console.log(` app.use('', ${name.toLowerCase()}Router);`);
|
|
444
|
+
// add service
|
|
445
|
+
}
|
|
446
|
+
else if (sub === 'service' || sub === 'svc') {
|
|
447
|
+
if (!name)
|
|
448
|
+
return CLIUI.error('Usage: dolphin add service <Name>');
|
|
449
|
+
const N = capitalize(name);
|
|
450
|
+
writeFile(path.join(process.cwd(), 'services', `${N}.service.js`), TEMPLATES.service(N), `services/${N}.service.js`);
|
|
451
|
+
CLIUI.success(`${N}Service added!`);
|
|
229
452
|
}
|
|
230
453
|
else {
|
|
231
|
-
CLIUI.error('Usage: dolphin add <
|
|
454
|
+
CLIUI.error('Usage: dolphin add <subcommand>');
|
|
455
|
+
console.log('\n adapter <mongoose|sequelize|redis> DB adapter');
|
|
456
|
+
console.log(' auth Auth system');
|
|
457
|
+
console.log(' crud <ModelName> CRUD controller + model');
|
|
458
|
+
console.log(' model <ModelName> [--adapter] Mongoose model (optionally registers it)');
|
|
459
|
+
console.log(' model-adapter <ModelName> Mongoose model & registers in adapter');
|
|
460
|
+
console.log(' middleware <Name> Middleware');
|
|
461
|
+
console.log(' route <Name> Route file');
|
|
462
|
+
console.log(' service <Name> Service class');
|
|
232
463
|
}
|
|
233
464
|
break;
|
|
465
|
+
}
|
|
466
|
+
// ── status ───────────────────────────────────────────────────────────
|
|
467
|
+
case 'status': {
|
|
468
|
+
CLIUI.heading('Dolphin Project Status');
|
|
469
|
+
const cwd = process.cwd();
|
|
470
|
+
const checks = [
|
|
471
|
+
{ label: 'package.json', file: 'package.json' },
|
|
472
|
+
{ label: '.env', file: '.env' },
|
|
473
|
+
{ label: 'app.js / app.ts', file: 'app.js', alt: 'app.ts' },
|
|
474
|
+
{ label: 'config/db.js', file: 'config/db.js', alt: 'config/db.ts' },
|
|
475
|
+
{ label: 'models/', dir: 'models' },
|
|
476
|
+
{ label: 'controllers/', dir: 'controllers' },
|
|
477
|
+
{ label: 'routes/', dir: 'routes' },
|
|
478
|
+
{ label: 'middleware/', dir: 'middleware' },
|
|
479
|
+
{ label: 'services/', dir: 'services' },
|
|
480
|
+
];
|
|
481
|
+
checks.forEach(({ label, file, alt, dir }) => {
|
|
482
|
+
let exists = false;
|
|
483
|
+
if (dir)
|
|
484
|
+
exists = fs.existsSync(path.join(cwd, dir));
|
|
485
|
+
else
|
|
486
|
+
exists = fs.existsSync(path.join(cwd, file)) || (alt ? fs.existsSync(path.join(cwd, alt)) : false);
|
|
487
|
+
const icon = exists ? '\x1b[32m✔\x1b[0m' : '\x1b[33m–\x1b[0m';
|
|
488
|
+
console.log(` ${icon} ${label}`);
|
|
489
|
+
});
|
|
490
|
+
const projPkg = path.join(cwd, 'package.json');
|
|
491
|
+
if (fs.existsSync(projPkg)) {
|
|
492
|
+
const p = JSON.parse(fs.readFileSync(projPkg, 'utf8'));
|
|
493
|
+
const dsm = p.dependencies?.['dolphin-server-modules'] || p.devDependencies?.['dolphin-server-modules'];
|
|
494
|
+
console.log(`\n dolphin-server-modules: ${dsm || '(package.json मा छैन)'}`);
|
|
495
|
+
}
|
|
496
|
+
const dotEnv = path.join(cwd, '.env');
|
|
497
|
+
if (fs.existsSync(dotEnv)) {
|
|
498
|
+
const envText = fs.readFileSync(dotEnv, 'utf8');
|
|
499
|
+
console.log('\n .env keys:');
|
|
500
|
+
['MONGO_URI', 'JWT_SECRET', 'REDIS_URL', 'PORT'].forEach(k => {
|
|
501
|
+
const set = envText.includes(k + '=') && !envText.match(new RegExp(k + '=your_'));
|
|
502
|
+
console.log(` ${set ? '\x1b[32m✔\x1b[0m' : '\x1b[33m–\x1b[0m'} ${k}`);
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
console.log(`\n 🐬 Dolphin CLI v${VERSION}`);
|
|
506
|
+
break;
|
|
507
|
+
}
|
|
508
|
+
// ── deploy ───────────────────────────────────────────────────────────
|
|
509
|
+
case 'deploy': {
|
|
510
|
+
CLIUI.heading('Production Deployment (PM2)');
|
|
511
|
+
const entry = fs.existsSync(path.join(process.cwd(), 'dist/index.js')) ? 'dist/index.js'
|
|
512
|
+
: fs.existsSync(path.join(process.cwd(), 'app.js')) ? 'app.js' : 'index.js';
|
|
513
|
+
console.log(`
|
|
514
|
+
\x1b[1mStep 1\x1b[0m — PM2 install:
|
|
515
|
+
\x1b[36mnpm install -g pm2\x1b[0m
|
|
516
|
+
|
|
517
|
+
\x1b[1mStep 2\x1b[0m — Build (TypeScript भए):
|
|
518
|
+
\x1b[36mnpm run build\x1b[0m
|
|
519
|
+
|
|
520
|
+
\x1b[1mStep 3\x1b[0m — Start:
|
|
521
|
+
\x1b[36mpm2 start ${entry} --name "dolphin-app" --env production\x1b[0m
|
|
522
|
+
|
|
523
|
+
\x1b[1mStep 4\x1b[0m — Auto-start on reboot:
|
|
524
|
+
\x1b[36mpm2 startup && pm2 save\x1b[0m
|
|
525
|
+
|
|
526
|
+
\x1b[1mStep 5\x1b[0m — Logs:
|
|
527
|
+
\x1b[36mpm2 logs dolphin-app\x1b[0m
|
|
528
|
+
|
|
529
|
+
─── ecosystem.config.js (cluster mode) ────────────────
|
|
530
|
+
module.exports = {
|
|
531
|
+
apps: [{ name: 'dolphin-app', script: '${entry}',
|
|
532
|
+
instances: 'max', exec_mode: 'cluster',
|
|
533
|
+
env_production: { NODE_ENV: 'production', PORT: 3000 }
|
|
534
|
+
}]
|
|
535
|
+
};
|
|
536
|
+
\x1b[36mpm2 start ecosystem.config.js --env production\x1b[0m
|
|
537
|
+
`);
|
|
538
|
+
break;
|
|
539
|
+
}
|
|
540
|
+
// ── version ──────────────────────────────────────────────────────────
|
|
234
541
|
case '-v':
|
|
235
542
|
case '--version':
|
|
236
|
-
|
|
543
|
+
case 'version':
|
|
544
|
+
console.log(`🐬 Dolphin CLI v${VERSION}`);
|
|
237
545
|
break;
|
|
546
|
+
// ── help ─────────────────────────────────────────────────────────────
|
|
238
547
|
case 'help':
|
|
239
548
|
default:
|
|
240
|
-
CLIUI.heading(
|
|
241
|
-
console.log(`
|
|
242
|
-
|
|
243
|
-
serve
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
add
|
|
249
|
-
add
|
|
250
|
-
add
|
|
251
|
-
-
|
|
252
|
-
|
|
253
|
-
|
|
549
|
+
CLIUI.heading(`Dolphin Framework CLI v${VERSION}`);
|
|
550
|
+
console.log(`
|
|
551
|
+
\x1b[1mServer\x1b[0m
|
|
552
|
+
serve [--port=N] Dev server start गर्ने
|
|
553
|
+
|
|
554
|
+
\x1b[1mScaffolding\x1b[0m
|
|
555
|
+
init / init-prod Production project scaffold
|
|
556
|
+
add adapter <type> DB adapter (mongoose|sequelize|redis)
|
|
557
|
+
add auth Auth controller + User model
|
|
558
|
+
add crud <ModelName> CRUD controller + Model
|
|
559
|
+
add model <ModelName> Mongoose model मात्र (use --adapter or model-adapter to register)
|
|
560
|
+
add model-adapter <ModelName> Mongoose model + registers in adapter
|
|
561
|
+
add middleware <Name> Middleware file
|
|
562
|
+
add route <Name> Route file
|
|
563
|
+
add service <Name> Service class
|
|
564
|
+
|
|
565
|
+
\x1b[1mDatabase\x1b[0m
|
|
566
|
+
connect mongoose [uri] MongoDB connection test
|
|
567
|
+
connect redis [uri] Redis connection test
|
|
568
|
+
|
|
569
|
+
\x1b[1mAI (API key चाहिन्छ)\x1b[0m
|
|
570
|
+
generate <prompt> Quick AI code generation
|
|
571
|
+
generate-full <prompt> Full project AI architecture
|
|
572
|
+
chat Autonomous AI Agent (Cursor mode)
|
|
573
|
+
|
|
574
|
+
\x1b[1mProject\x1b[0m
|
|
575
|
+
status Project health check
|
|
576
|
+
deploy PM2 deployment guide
|
|
577
|
+
|
|
578
|
+
\x1b[1mInfo\x1b[0m
|
|
579
|
+
-v / --version Version
|
|
580
|
+
help यो help
|
|
581
|
+
`);
|
|
254
582
|
}
|
|
255
583
|
}
|
|
256
584
|
run().catch(err => {
|
|
257
585
|
CLIUI.error(err.message);
|
|
586
|
+
process.exit(1);
|
|
258
587
|
});
|
|
259
588
|
//# sourceMappingURL=cli.js.map
|