create-backlist 7.4.0 → 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.
package/bin/qa.js CHANGED
@@ -1,103 +1,191 @@
1
+ #!/usr/bin/env node
2
+
1
3
  // ═══════════════════════════════════════════════════════════════════════════
2
- // Backlist QA CLI — qa.js
3
- // Standalone QA entry point: `node bin/qa.js`
4
+ // Backlist QA CLI — qa.js v9.0
5
+ // Standalone QA entry point: `node bin/qa.js [mode] [--flags]`
4
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
5
17
  // ═══════════════════════════════════════════════════════════════════════════
6
18
 
7
- #!/usr/bin/env node
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 ────────────────────────────────────────────────────
8
46
 
9
- import * as p from '@clack/prompts';
10
- import chalk from 'chalk';
11
- import { runManualQA, runAutomatedQA, viewQAHistory, initQASystem } from '../src/qa/qa-engine.js';
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 ────────────────────────────────────────────────────────────────
12
63
 
13
- // ── QA Banner ────────────────────────────────────────────────────────────
14
64
  function printQABanner() {
15
- const c1 = chalk.hex('#00F5FF');
16
- const c2 = chalk.hex('#BF40FF');
17
- const c3 = chalk.hex('#FF6B6B');
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');
18
71
  const dim = chalk.gray;
19
72
 
20
73
  console.log('');
21
74
  console.log(c1(' ╔══════════════════════════════════════════════════════════════╗'));
22
- console.log(c1(' ║') + c2.bold(' ____ ___ ______ ____ ______________ _ ________ ') + c1('║'));
23
- console.log(c1(' ║') + c2.bold(' / __ )/ | / ____// //_// / _/ ___/ / | / / ____/ ') + c1('║'));
24
- console.log(c1(' ║') + c2.bold(' / __ / /| | / / / ,< / // /\\__ \\ / |/ / / __ ') + c1('║'));
25
- console.log(c1(' ║') + c2.bold('/ /_/ / ___ |/ /___ / /| |/ /___/__ /_ / /| / /_/ / ') + c1('║'));
26
- console.log(c1(' ║') + c2.bold('/_____/_/ |_|\\____//_/ |_/_//____/___//_/ |_/\\____/ ') + 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('║'));
27
80
  console.log(c1(' ║') + ' ' + c1('║'));
28
- console.log(c1(' ║') + c3.bold(' 🧪 QA Testing System — Manual & Automated 🤖 ') + c1('║'));
29
- console.log(c1(' ║') + dim(' Bug Reports · Test Suites · HTML/JSON Export ') + 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('║'));
30
83
  console.log(c1(' ╚══════════════════════════════════════════════════════════════╝'));
31
84
  console.log('');
32
- console.log(dim(' Part of create-backlist v7.0 — Polyglot Backend Engine'));
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'));
33
99
  console.log(dim(' ─────────────────────────────────────────────────────────────'));
34
100
  console.log('');
35
101
  }
36
102
 
37
- // ── Main QA CLI ──────────────────────────────────────────────────────────
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
+
38
127
  async function main() {
39
128
  printQABanner();
129
+ registerShutdownHandlers();
130
+
40
131
  await initQASystem();
132
+ await systemHealthCheck();
41
133
 
42
- p.intro(chalk.hex('#00F5FF').bold(' Backlist QA Testing & Quality Assurance '));
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 '));
43
162
 
44
163
  const mode = await p.select({
45
164
  message: 'Select QA mode:',
46
165
  options: [
47
- {
48
- value: 'manual',
49
- label: '🧪 Manual QA Testing',
50
- hint: 'Interactive — create, execute & track test cases with bug reports',
51
- },
52
- {
53
- value: 'auto',
54
- label: '🤖 Automated QA Testing',
55
- hint: 'One-time run — test suites against your project',
56
- },
57
- {
58
- value: 'auto-continuous',
59
- label: '⚡ Live Continuous Automated QA',
60
- hint: 'Runs every 30s — real-time monitoring',
61
- },
62
- {
63
- value: 'history',
64
- label: '📜 View QA History',
65
- hint: 'See past QA run summaries',
66
- },
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' },
67
171
  ],
68
172
  });
69
-
70
- if (p.isCancel(mode)) {
71
- p.cancel('QA session cancelled.');
72
- process.exit(0);
73
- }
173
+ if (p.isCancel(mode)) { p.cancel('QA session cancelled.'); process.exit(0); }
74
174
 
75
175
  switch (mode) {
76
- case 'manual':
77
- await runManualQA();
78
- break;
79
-
80
- case 'auto':
81
- await runAutomatedQA({ continuous: false });
82
- break;
83
-
84
- case 'auto-continuous':
85
- await runAutomatedQA({ continuous: true });
86
- break;
87
-
88
- case 'history':
89
- await viewQAHistory();
90
- p.outro(chalk.hex('#00F5FF').bold('History viewed.'));
91
- break;
92
-
93
- default:
94
- p.cancel('Unknown mode.');
95
- process.exit(1);
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);
96
182
  }
97
183
  }
98
184
 
99
- main().catch((err) => {
100
- console.error(chalk.red.bold(`\n QA Error: ${err.message || err}`));
101
- if (err.stack) console.error(chalk.gray(err.stack));
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));
102
190
  process.exit(1);
103
- });
191
+ });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "create-backlist",
3
- "version": "7.4.0",
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
7
  "create-backlist": "bin/index.js",
@@ -13,26 +13,31 @@
13
13
  "AiModuls"
14
14
  ],
15
15
  "scripts": {
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 --live"
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"
20
25
  },
21
26
  "author": "W.A.H.ISHAN",
22
27
  "license": "MIT",
23
28
  "dependencies": {
24
- "@babel/parser": "^7.22.7",
25
- "@babel/traverse": "^7.22.8",
26
- "@clack/prompts": "^0.7.0",
27
- "axios": "^1.13.1",
28
- "chalk": "^5.3.0",
29
- "ejs": "^3.1.9",
30
- "execa": "^8.0.1",
31
- "fs-extra": "^11.1.1",
32
- "glob": "^10.3.3",
33
- "inquirer": "^9.2.12",
34
- "ora": "^7.0.1",
35
- "together-ai": "^0.39.0",
36
- "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"
37
42
  }
38
- }
43
+ }