create-backlist 7.3.1 → 9.0.0

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.
Files changed (46) hide show
  1. package/bin/index.js +901 -471
  2. package/bin/qa.js +191 -0
  3. package/package.json +27 -18
  4. package/src/ai-agent.js +581 -124
  5. package/src/analyzer.js +628 -528
  6. package/src/env-resolver.js +70 -70
  7. package/src/generators/dotnet.js +134 -134
  8. package/src/generators/java.js +248 -248
  9. package/src/generators/js.js +345 -345
  10. package/src/generators/nestjs.js +277 -277
  11. package/src/generators/python.js +86 -86
  12. package/src/project-detector.js +131 -131
  13. package/src/qa/qa-engine.js +1187 -0
  14. package/src/templates/dotnet/partials/Dockerfile.ejs +27 -27
  15. package/src/templates/dotnet/partials/docker-compose.yml.ejs +33 -33
  16. package/src/templates/js-express/base/server.js +59 -59
  17. package/src/templates/js-express/partials/Dockerfile.ejs +12 -12
  18. package/src/templates/js-express/partials/auth.controller.js.ejs +66 -66
  19. package/src/templates/js-express/partials/auth.middleware.js.ejs +19 -19
  20. package/src/templates/js-express/partials/auth.routes.js.ejs +9 -9
  21. package/src/templates/js-express/partials/controller.js.ejs +53 -53
  22. package/src/templates/js-express/partials/db.js.ejs +19 -19
  23. package/src/templates/js-express/partials/docker-compose.yml.ejs +46 -46
  24. package/src/templates/js-express/partials/model.js.ejs +18 -18
  25. package/src/templates/js-express/partials/package.json.ejs +17 -17
  26. package/src/templates/js-express/partials/prisma.schema.ejs +21 -21
  27. package/src/templates/js-express/partials/routes.js.ejs +19 -19
  28. package/src/templates/js-express/partials/seeder.js.ejs +103 -103
  29. package/src/templates/js-express/partials/service.js.ejs +51 -51
  30. package/src/templates/js-express/partials/swagger.js.ejs +30 -30
  31. package/src/templates/js-express/partials/test.js.ejs +46 -46
  32. package/src/templates/nestjs/base/app.module.ts +9 -9
  33. package/src/templates/nestjs/base/main.ts +23 -23
  34. package/src/templates/nestjs/base/tsconfig.json +21 -21
  35. package/src/templates/nestjs/partials/auth.controller.ts.ejs +17 -17
  36. package/src/templates/nestjs/partials/auth.module.ts.ejs +17 -17
  37. package/src/templates/nestjs/partials/auth.service.ts.ejs +70 -70
  38. package/src/templates/nestjs/partials/controller.ts.ejs +34 -34
  39. package/src/templates/nestjs/partials/create-dto.ts.ejs +22 -22
  40. package/src/templates/nestjs/partials/jwt-guard.ts.ejs +24 -24
  41. package/src/templates/nestjs/partials/module.ts.ejs +10 -10
  42. package/src/templates/nestjs/partials/package.json.ejs +27 -27
  43. package/src/templates/nestjs/partials/prisma.service.ts.ejs +13 -13
  44. package/src/templates/nestjs/partials/schema.ts.ejs +19 -19
  45. package/src/templates/nestjs/partials/service.ts.ejs +67 -67
  46. package/src/templates/nestjs/partials/update-dto.ts.ejs +4 -4
package/bin/qa.js ADDED
@@ -0,0 +1,191 @@
1
+ #!/usr/bin/env node
2
+
3
+ // ═══════════════════════════════════════════════════════════════════════════
4
+ // Backlist QA CLI — qa.js v9.0
5
+ // Standalone QA entry point: `node bin/qa.js [mode] [--flags]`
6
+ // Copyright (c) W.A.H.ISHAN — MIT License
7
+ //
8
+ // NEW in v9.0:
9
+ // ✦ Live terminal dashboard with real-time metrics
10
+ // ✦ Full end-to-end test suite (API, auth, security, UI, performance)
11
+ // ✦ --scope flag: all | backend | frontend | security | performance
12
+ // ✦ --watch flag: file-change triggered re-run
13
+ // ✦ Post-generation auto-run mode
14
+ // ✦ SIGINT / SIGTERM graceful shutdown with report flush
15
+ // ✦ JSON output for CI pipeline integration
16
+ // ✦ Compact status bar summary on exit
17
+ // ═══════════════════════════════════════════════════════════════════════════
18
+
19
+ import * as p from '@clack/prompts';
20
+ import chalk from 'chalk';
21
+ import fs from 'fs-extra';
22
+ import path from 'node:path';
23
+ import {
24
+ runManualQA,
25
+ runAutomatedQA,
26
+ viewQAHistory,
27
+ initQASystem,
28
+ autoRunPostGeneration,
29
+ } from '../src/qa/qa-engine.js';
30
+
31
+ // ── CLI flags ─────────────────────────────────────────────────────────────
32
+
33
+ const argv = process.argv.slice(2);
34
+ const flags = new Set(argv.filter(a => a.startsWith('--')));
35
+ const posArgs = argv.filter(a => !a.startsWith('--'));
36
+
37
+ const isContinuous = flags.has('--continuous') || flags.has('--watch') || flags.has('-w');
38
+ const isCI = process.env.QA_CI === '1' || flags.has('--ci');
39
+ const noColor = flags.has('--no-color') || process.env.NO_COLOR;
40
+ const isPostGen = flags.has('--post-gen');
41
+ const scope = argv.find(a => a.startsWith('--scope='))?.split('=')[1] ?? 'all';
42
+
43
+ if (noColor) chalk.level = 0;
44
+
45
+ // ── Graceful shutdown ────────────────────────────────────────────────────
46
+
47
+ let shuttingDown = false;
48
+
49
+ function registerShutdownHandlers() {
50
+ const shutdown = (signal) => {
51
+ if (shuttingDown) return;
52
+ shuttingDown = true;
53
+ process.stdout.write('\x1b[?25h'); // ensure cursor restored
54
+ console.log('\n' + chalk.gray(` ${signal} received — shutting down gracefully…`));
55
+ p.cancel('QA session ended.');
56
+ process.exit(0);
57
+ };
58
+ process.on('SIGINT', () => shutdown('SIGINT'));
59
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
60
+ }
61
+
62
+ // ── Banner ────────────────────────────────────────────────────────────────
63
+
64
+ function printQABanner() {
65
+ if (isCI) return;
66
+
67
+ const c1 = chalk.hex('#00F5FF');
68
+ const c2 = chalk.hex('#BF40FF');
69
+ const c3 = chalk.hex('#FF6B6B');
70
+ const c4 = chalk.hex('#00FF9F');
71
+ const dim = chalk.gray;
72
+
73
+ console.log('');
74
+ console.log(c1(' ╔══════════════════════════════════════════════════════════════╗'));
75
+ console.log(c1(' ║') + c2.bold(' ____ ___ ________ __ ____ ___________ ') + c1('║'));
76
+ console.log(c1(' ║') + c2.bold(' / __ )/ | / ____/ //_/ / / / _/ ___/_ ') + c1('║'));
77
+ console.log(c1(' ║') + c2.bold(' / __ / /| | / / / ,< / / / / \\__ \\ ') + c1('║'));
78
+ console.log(c1(' ║') + c2.bold('/ /_/ / ___ |/ /___/ /| | / /____/ / ___/ / ') + c1('║'));
79
+ console.log(c1(' ║') + c2.bold('/_____/_/ |_|\\____/_/ |_| /_____/___//____/ ') + c1('║'));
80
+ console.log(c1(' ║') + ' ' + c1('║'));
81
+ console.log(c1(' ║') + c3.bold(' 🧪 Live QA System v9.0 — Real-time Monitoring 🤖 ') + c1('║'));
82
+ console.log(c1(' ║') + dim(' E2E · Security · Performance · UI · Auto Bug Reports ') + c1('║'));
83
+ console.log(c1(' ╚══════════════════════════════════════════════════════════════╝'));
84
+ console.log('');
85
+
86
+ const mem = process.memoryUsage();
87
+ const heapMB = (mem.heapUsed / 1024 / 1024).toFixed(0);
88
+
89
+ console.log(
90
+ dim(' ') +
91
+ c4('◉ LIVE') + dim(' │ ') +
92
+ dim('Node ') + chalk.white(process.version) + dim(' │ ') +
93
+ dim('Heap ') + chalk.white(heapMB + 'MB') + dim(' │ ') +
94
+ dim('Scope ') + chalk.white(scope) + dim(' │ ') +
95
+ dim('Mode ') + chalk.white(isContinuous ? 'watch' : 'single-run')
96
+ );
97
+ console.log(dim(' Flags: --continuous (-w) --watch --ci --scope=<all|backend|frontend|security> --post-gen --no-color'));
98
+ console.log(dim(' CI: QA_CI=1 node bin/qa.js auto'));
99
+ console.log(dim(' ─────────────────────────────────────────────────────────────'));
100
+ console.log('');
101
+ }
102
+
103
+ // ── System health check ───────────────────────────────────────────────────
104
+
105
+ async function systemHealthCheck() {
106
+ const checks = [
107
+ { name: 'Node.js ≥ 18', fn: () => {
108
+ const maj = parseInt(process.version.replace('v','').split('.')[0]);
109
+ if (maj < 18) throw new Error(`Node.js ${process.version} — requires v18+`);
110
+ }},
111
+ { name: 'QA directories', fn: async () => {
112
+ await fs.ensureDir(path.join(process.cwd(), '.backlist', 'qa', 'reports'));
113
+ }},
114
+ ];
115
+
116
+ const spin = p.spinner();
117
+ spin.start('System health check…');
118
+ for (const check of checks) {
119
+ try { await check.fn(); }
120
+ catch (err) { spin.stop(chalk.red(`✗ ${check.name}: ${err.message}`)); process.exit(1); }
121
+ }
122
+ spin.stop(chalk.green('✓ System healthy — QA ready'));
123
+ }
124
+
125
+ // ── Main ──────────────────────────────────────────────────────────────────
126
+
127
+ async function main() {
128
+ printQABanner();
129
+ registerShutdownHandlers();
130
+
131
+ await initQASystem();
132
+ await systemHealthCheck();
133
+
134
+ // ── Post-generation auto-run ─────────────────────────────────────────
135
+ if (isPostGen) {
136
+ const projectDir = posArgs[0] ? path.resolve(posArgs[0]) : process.cwd();
137
+ const projectName = path.basename(projectDir);
138
+ await autoRunPostGeneration({ projectDir, projectName });
139
+ process.exit(0);
140
+ }
141
+
142
+ // ── CI / positional arg mode ─────────────────────────────────────────
143
+ const modeArg = posArgs[0]?.toLowerCase();
144
+ if (isCI || modeArg) {
145
+ const mode = modeArg ?? 'auto';
146
+ if (!isCI) console.log(chalk.gray(` Mode: ${mode}${isContinuous ? ' (continuous)' : ''}\n`));
147
+
148
+ switch (mode) {
149
+ case 'manual': await runManualQA(); break;
150
+ case 'auto': await runAutomatedQA({ continuous: isContinuous }); break;
151
+ case 'history': await viewQAHistory(); break;
152
+ case 'post-gen': await autoRunPostGeneration(); break;
153
+ default:
154
+ console.error(chalk.red(`Unknown mode: ${mode}. Use: manual | auto | history | post-gen`));
155
+ process.exit(1);
156
+ }
157
+ return;
158
+ }
159
+
160
+ // ── Interactive mode ─────────────────────────────────────────────────
161
+ p.intro(chalk.hex('#00F5FF').bold(' Backlist Live QA v9.0 — Real-time Testing & Monitoring '));
162
+
163
+ const mode = await p.select({
164
+ message: 'Select QA mode:',
165
+ options: [
166
+ { value: 'manual', label: '🧪 Manual QA Testing', hint: 'Interactive test creation, custom cases, bug logging' },
167
+ { value: 'auto', label: '🤖 Full Automated Scan', hint: 'E2E, security, auth, DB, performance — all modules' },
168
+ { value: 'live', label: '⚡ Live Continuous Monitoring', hint: 'Reruns every 30s — real-time dashboard (Ctrl+C to stop)' },
169
+ { value: 'post-gen', label: '🚀 Post-Generation Validation', hint: 'Validate a freshly generated project' },
170
+ { value: 'history', label: '📜 View QA History', hint: 'Browse past runs, compare pass rates, view reports' },
171
+ ],
172
+ });
173
+ if (p.isCancel(mode)) { p.cancel('QA session cancelled.'); process.exit(0); }
174
+
175
+ switch (mode) {
176
+ case 'manual': await runManualQA(); break;
177
+ case 'auto': await runAutomatedQA({ continuous: false }); break;
178
+ case 'live': await runAutomatedQA({ continuous: true }); break;
179
+ case 'post-gen': await autoRunPostGeneration(); break;
180
+ case 'history': await viewQAHistory(); p.outro(chalk.hex('#00F5FF').bold('History viewed.')); break;
181
+ default: p.cancel('Unknown mode.'); process.exit(1);
182
+ }
183
+ }
184
+
185
+ main().catch(err => {
186
+ if (shuttingDown) return;
187
+ process.stdout.write('\x1b[?25h');
188
+ console.error(chalk.red.bold(`\n QA Fatal: ${err.message || err}`));
189
+ if (err.stack && !isCI) console.error(chalk.gray(err.stack));
190
+ process.exit(1);
191
+ });
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "create-backlist",
3
- "version": "7.3.1",
4
- "description": "An advanced, multi-language backend generator based on frontend analysis. Smart Freemium SaaS CLI.",
3
+ "version": "9.0.0",
4
+ "description": "An advanced, multi-language backend generator based on frontend analysis. Smart Freemium SaaS CLI with Live QA.",
5
5
  "type": "module",
6
6
  "bin": {
7
- "create-backlist": "bin/index.js"
7
+ "create-backlist": "bin/index.js",
8
+ "backlist-qa": "bin/qa.js"
8
9
  },
9
10
  "files": [
10
11
  "bin",
@@ -12,23 +13,31 @@
12
13
  "AiModuls"
13
14
  ],
14
15
  "scripts": {
15
- "start": "node bin/index.js"
16
+ "start" : "node bin/index.js",
17
+ "qa" : "node bin/qa.js",
18
+ "qa:auto" : "node bin/qa.js auto",
19
+ "qa:live" : "node bin/qa.js auto --continuous",
20
+ "qa:manual" : "node bin/qa.js manual",
21
+ "qa:history" : "node bin/qa.js history",
22
+ "qa:security" : "node bin/qa.js auto --scope=security",
23
+ "qa:post-gen" : "node bin/qa.js --post-gen",
24
+ "qa:ci" : "QA_CI=1 node bin/qa.js auto"
16
25
  },
17
26
  "author": "W.A.H.ISHAN",
18
27
  "license": "MIT",
19
28
  "dependencies": {
20
- "@babel/parser": "^7.22.7",
21
- "@babel/traverse": "^7.22.8",
22
- "@clack/prompts": "^0.7.0",
23
- "axios": "^1.13.1",
24
- "chalk": "^5.3.0",
25
- "ejs": "^3.1.9",
26
- "execa": "^8.0.1",
27
- "fs-extra": "^11.1.1",
28
- "glob": "^10.3.3",
29
- "inquirer": "^9.2.12",
30
- "ora": "^7.0.1",
31
- "together-ai": "^0.39.0",
32
- "unzipper": "^0.12.3"
29
+ "@babel/parser" : "^7.22.7",
30
+ "@babel/traverse" : "^7.22.8",
31
+ "@clack/prompts" : "^0.7.0",
32
+ "axios" : "^1.13.1",
33
+ "chalk" : "^5.3.0",
34
+ "ejs" : "^3.1.9",
35
+ "execa" : "^8.0.1",
36
+ "fs-extra" : "^11.1.1",
37
+ "glob" : "^10.3.3",
38
+ "inquirer" : "^9.2.12",
39
+ "ora" : "^7.0.1",
40
+ "together-ai" : "^0.39.0",
41
+ "unzipper" : "^0.12.3"
33
42
  }
34
- }
43
+ }