express-genix 4.1.1 → 4.2.1
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 +23 -2
- package/index.js +37 -4
- package/package.json +1 -1
- package/templates/core/env.ejs +11 -8
- package/templates/core/env.example.ejs +11 -8
package/README.md
CHANGED
|
@@ -93,6 +93,7 @@ You'll be prompted for:
|
|
|
93
93
|
3. **Database** — MongoDB, PostgreSQL (Sequelize), PostgreSQL (Prisma), or None
|
|
94
94
|
4. **Features** — Auth, Rate Limiting, Swagger, Redis, Docker, CI/CD, WebSocket, Request ID, Email, File Uploads, Soft Deletes, Audit Logging, Prometheus Metrics, API Versioning, Background Jobs, GraphQL, MCP Server, AI/LLM Service
|
|
95
95
|
5. **Logger** — Winston or Pino
|
|
96
|
+
6. **AI Provider** _(if AI selected)_ — OpenAI, Anthropic, Google Gemini, or Ollama (local)
|
|
96
97
|
|
|
97
98
|
The CLI generates your project, installs dependencies, formats code, and creates an initial git commit.
|
|
98
99
|
|
|
@@ -210,6 +211,26 @@ my-express-app/
|
|
|
210
211
|
| GET | `/graphql` | GraphQL Playground (Apollo Server) |
|
|
211
212
|
|
|
212
213
|
### AI / LLM (LangChain)
|
|
214
|
+
|
|
215
|
+
When you select the **AI / LLM Service** feature, you'll be asked to pick a provider:
|
|
216
|
+
|
|
217
|
+
| Provider | Models | API Key Required |
|
|
218
|
+
|----------|--------|------------------|
|
|
219
|
+
| **OpenAI** | GPT-4o, GPT-4o-mini | `OPENAI_API_KEY` |
|
|
220
|
+
| **Anthropic** | Claude Sonnet, Claude Opus | `ANTHROPIC_API_KEY` |
|
|
221
|
+
| **Google Gemini** | Gemini 2.0 Flash | `GOOGLE_API_KEY` |
|
|
222
|
+
| **Ollama** | Llama 3, Mistral, etc. | None (runs locally) |
|
|
223
|
+
|
|
224
|
+
The CLI generates your `.env` with the correct provider, model, and API key variable — just fill in your key and run `npm run dev`.
|
|
225
|
+
|
|
226
|
+
For Ollama, install it from [ollama.com](https://ollama.com) and pull a model:
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
ollama pull llama3
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**Endpoints:**
|
|
233
|
+
|
|
213
234
|
| Method | Endpoint | Description |
|
|
214
235
|
|--------|----------|-------------|
|
|
215
236
|
| POST | `/api/ai/chat` | Chat with AI (complete response) |
|
|
@@ -267,8 +288,8 @@ Generated `.env` includes auto-generated JWT secrets:
|
|
|
267
288
|
| `UPLOAD_MAX_SIZE` | Max file upload size in bytes | `5242880` (5 MB) |
|
|
268
289
|
| `UPLOAD_DIR` | Upload destination directory | `uploads` |
|
|
269
290
|
| `MCP_SERVER_NAME` | MCP server display name | project name |
|
|
270
|
-
| `AI_PROVIDER` | LLM provider (
|
|
271
|
-
| `AI_MODEL` | Model name |
|
|
291
|
+
| `AI_PROVIDER` | LLM provider (set by CLI) | `openai` |
|
|
292
|
+
| `AI_MODEL` | Model name (set by CLI based on provider) | varies |
|
|
272
293
|
| `AI_TEMPERATURE` | Sampling temperature | `0.7` |
|
|
273
294
|
| `AI_MAX_TOKENS` | Max response tokens | `2048` |
|
|
274
295
|
| `OPENAI_API_KEY` | OpenAI API key (if using OpenAI) | — |
|
package/index.js
CHANGED
|
@@ -15,7 +15,7 @@ const prompt = inquirer.createPromptModule();
|
|
|
15
15
|
const generateSecret = (length = 64) => crypto.randomBytes(length).toString('hex');
|
|
16
16
|
|
|
17
17
|
const CODA_EXTENSION_ID = 'express-genix.coda-ai';
|
|
18
|
-
const CODA_VSIX_URL = 'https://github.com/LambdaAI001/coda/releases/download/v0.
|
|
18
|
+
const CODA_VSIX_URL = 'https://github.com/LambdaAI001/coda/releases/download/v0.2.0/coda-ai-0.2.0.vsix';
|
|
19
19
|
|
|
20
20
|
async function promptCodaExtension() {
|
|
21
21
|
const inquirerPrompt = inquirer.createPromptModule();
|
|
@@ -162,6 +162,18 @@ async function main() {
|
|
|
162
162
|
{ name: 'Pino (fast, low overhead)', value: 'pino' },
|
|
163
163
|
],
|
|
164
164
|
},
|
|
165
|
+
{
|
|
166
|
+
type: 'list',
|
|
167
|
+
name: 'aiProvider',
|
|
168
|
+
message: 'AI / LLM Provider:',
|
|
169
|
+
choices: [
|
|
170
|
+
{ name: 'OpenAI (GPT-4o, GPT-4o-mini)', value: 'openai' },
|
|
171
|
+
{ name: 'Anthropic (Claude)', value: 'anthropic' },
|
|
172
|
+
{ name: 'Google Gemini', value: 'gemini' },
|
|
173
|
+
{ name: 'Ollama (local, no API key needed)', value: 'ollama' },
|
|
174
|
+
],
|
|
175
|
+
when: (ans) => (ans.features || []).includes('ai'),
|
|
176
|
+
},
|
|
165
177
|
]);
|
|
166
178
|
|
|
167
179
|
const features = answers.features || [];
|
|
@@ -192,6 +204,7 @@ async function main() {
|
|
|
192
204
|
hasGraphQL: features.includes('graphql'),
|
|
193
205
|
hasMCP: features.includes('mcp'),
|
|
194
206
|
hasAI: features.includes('ai'),
|
|
207
|
+
aiProvider: answers.aiProvider || 'openai',
|
|
195
208
|
jwtSecret: generateSecret(),
|
|
196
209
|
jwtRefreshSecret: generateSecret(),
|
|
197
210
|
};
|
|
@@ -250,9 +263,15 @@ Configuration:
|
|
|
250
263
|
Database: ${config.isNoDatabase ? 'None' : config.db}
|
|
251
264
|
Authentication: ${config.hasAuth ? 'JWT with refresh tokens' : 'None'}
|
|
252
265
|
Logger: ${config.logger}
|
|
253
|
-
Features: ${features.join(', ') || 'base'}
|
|
266
|
+
Features: ${features.join(', ') || 'base'}${config.hasAI ? `\n AI Provider: ${config.aiProvider}` : ''}
|
|
254
267
|
`);
|
|
255
268
|
|
|
269
|
+
if (config.hasAI && config.aiProvider !== 'ollama') {
|
|
270
|
+
const keyMap = { openai: 'OPENAI_API_KEY', anthropic: 'ANTHROPIC_API_KEY', gemini: 'GOOGLE_API_KEY' };
|
|
271
|
+
console.log(`\x1b[33m⚠ Don't forget to set your API key in .env:\x1b[0m`);
|
|
272
|
+
console.log(` ${keyMap[config.aiProvider]}=your-key-here\n`);
|
|
273
|
+
}
|
|
274
|
+
|
|
256
275
|
// Prompt to install Coda VS Code extension for AI/MCP projects
|
|
257
276
|
if (config.hasAI || config.hasMCP) {
|
|
258
277
|
await promptCodaExtension();
|
|
@@ -310,20 +329,33 @@ Configuration:
|
|
|
310
329
|
const aiConfig = await runAiCommand(description);
|
|
311
330
|
|
|
312
331
|
const inquirerPrompt = inquirer.createPromptModule();
|
|
313
|
-
const
|
|
332
|
+
const aiFollowUp = await inquirerPrompt([
|
|
314
333
|
{
|
|
315
334
|
type: 'confirm',
|
|
316
335
|
name: 'confirmed',
|
|
317
336
|
message: 'Generate project with this configuration?',
|
|
318
337
|
default: true,
|
|
319
338
|
},
|
|
339
|
+
{
|
|
340
|
+
type: 'list',
|
|
341
|
+
name: 'aiProvider',
|
|
342
|
+
message: 'AI / LLM Provider:',
|
|
343
|
+
choices: [
|
|
344
|
+
{ name: 'OpenAI (GPT-4o, GPT-4o-mini)', value: 'openai' },
|
|
345
|
+
{ name: 'Anthropic (Claude)', value: 'anthropic' },
|
|
346
|
+
{ name: 'Google Gemini', value: 'gemini' },
|
|
347
|
+
{ name: 'Ollama (local, no API key needed)', value: 'ollama' },
|
|
348
|
+
],
|
|
349
|
+
when: (ans) => ans.confirmed && (aiConfig.features || []).includes('ai'),
|
|
350
|
+
},
|
|
320
351
|
]);
|
|
321
352
|
|
|
322
|
-
if (!confirmed) {
|
|
353
|
+
if (!aiFollowUp.confirmed) {
|
|
323
354
|
console.log('Cancelled.');
|
|
324
355
|
process.exit(0);
|
|
325
356
|
}
|
|
326
357
|
|
|
358
|
+
aiConfig.aiProvider = aiFollowUp.aiProvider || 'openai';
|
|
327
359
|
const features = aiConfig.features || [];
|
|
328
360
|
const config = {
|
|
329
361
|
projectName: aiConfig.projectName,
|
|
@@ -352,6 +384,7 @@ Configuration:
|
|
|
352
384
|
hasGraphQL: features.includes('graphql'),
|
|
353
385
|
hasMCP: features.includes('mcp'),
|
|
354
386
|
hasAI: features.includes('ai'),
|
|
387
|
+
aiProvider: aiConfig.aiProvider || 'openai',
|
|
355
388
|
jwtSecret: generateSecret(),
|
|
356
389
|
jwtRefreshSecret: generateSecret(),
|
|
357
390
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "express-genix",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.1",
|
|
4
4
|
"description": "Production-grade CLI to generate Express apps with JWT, RBAC, GraphQL, TypeScript, Prisma, MongoDB, PostgreSQL, file uploads, email, background jobs, and more",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
package/templates/core/env.ejs
CHANGED
|
@@ -33,15 +33,18 @@ UPLOAD_MAX_SIZE=5242880
|
|
|
33
33
|
MCP_SERVER_NAME=<%= projectName %>
|
|
34
34
|
<% } %><% if (hasAI) { %>
|
|
35
35
|
# AI Service (LangChain)
|
|
36
|
-
AI_PROVIDER
|
|
37
|
-
AI_MODEL=gpt-4o-mini
|
|
38
|
-
|
|
36
|
+
AI_PROVIDER=<%= aiProvider %>
|
|
37
|
+
<% if (aiProvider === 'openai') { %>AI_MODEL=gpt-4o-mini
|
|
38
|
+
<% } else if (aiProvider === 'anthropic') { %>AI_MODEL=claude-sonnet-4-20250514
|
|
39
|
+
<% } else if (aiProvider === 'gemini') { %>AI_MODEL=gemini-2.0-flash
|
|
40
|
+
<% } else if (aiProvider === 'ollama') { %>AI_MODEL=llama3
|
|
41
|
+
<% } %>AI_TEMPERATURE=0.7
|
|
39
42
|
AI_MAX_TOKENS=2048
|
|
40
|
-
OPENAI_API_KEY=
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
<% } %><% if (db === 'mongodb') { %>
|
|
43
|
+
<% if (aiProvider === 'openai') { %>OPENAI_API_KEY=
|
|
44
|
+
<% } else if (aiProvider === 'anthropic') { %>ANTHROPIC_API_KEY=
|
|
45
|
+
<% } else if (aiProvider === 'gemini') { %>GOOGLE_API_KEY=
|
|
46
|
+
<% } else if (aiProvider === 'ollama') { %>OLLAMA_BASE_URL=http://localhost:11434
|
|
47
|
+
<% } %><% } %><% if (db === 'mongodb') { %>
|
|
45
48
|
# Database
|
|
46
49
|
MONGO_URI=mongodb://localhost:27017/<%= projectName %>
|
|
47
50
|
<% } %><% if (db === 'postgresql' || isPrisma) { %>
|
|
@@ -33,15 +33,18 @@ UPLOAD_MAX_SIZE=5242880
|
|
|
33
33
|
MCP_SERVER_NAME=<%= projectName %>
|
|
34
34
|
<% } %><% if (hasAI) { %>
|
|
35
35
|
# AI Service (LangChain)
|
|
36
|
-
AI_PROVIDER
|
|
37
|
-
AI_MODEL=gpt-4o-mini
|
|
38
|
-
|
|
36
|
+
AI_PROVIDER=<%= aiProvider %>
|
|
37
|
+
<% if (aiProvider === 'openai') { %>AI_MODEL=gpt-4o-mini
|
|
38
|
+
<% } else if (aiProvider === 'anthropic') { %>AI_MODEL=claude-sonnet-4-20250514
|
|
39
|
+
<% } else if (aiProvider === 'gemini') { %>AI_MODEL=gemini-2.0-flash
|
|
40
|
+
<% } else if (aiProvider === 'ollama') { %>AI_MODEL=llama3
|
|
41
|
+
<% } %>AI_TEMPERATURE=0.7
|
|
39
42
|
AI_MAX_TOKENS=2048
|
|
40
|
-
OPENAI_API_KEY=
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
<% } %><% if (db === 'mongodb') { %>
|
|
43
|
+
<% if (aiProvider === 'openai') { %>OPENAI_API_KEY=
|
|
44
|
+
<% } else if (aiProvider === 'anthropic') { %>ANTHROPIC_API_KEY=
|
|
45
|
+
<% } else if (aiProvider === 'gemini') { %>GOOGLE_API_KEY=
|
|
46
|
+
<% } else if (aiProvider === 'ollama') { %>OLLAMA_BASE_URL=http://localhost:11434
|
|
47
|
+
<% } %><% } %><% if (db === 'mongodb') { %>
|
|
45
48
|
# Database
|
|
46
49
|
MONGO_URI=mongodb://localhost:27017/<%= projectName %>
|
|
47
50
|
<% } %><% if (db === 'postgresql' || isPrisma) { %>
|