seo-testing-tool 1.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/LICENSE +21 -0
- package/README.md +228 -0
- package/dist/auth/GoogleOAuthService.d.ts +31 -0
- package/dist/auth/GoogleOAuthService.d.ts.map +1 -0
- package/dist/auth/GoogleOAuthService.js +69 -0
- package/dist/auth/GoogleOAuthService.js.map +1 -0
- package/dist/auth/TokenManager.d.ts +56 -0
- package/dist/auth/TokenManager.d.ts.map +1 -0
- package/dist/auth/TokenManager.js +190 -0
- package/dist/auth/TokenManager.js.map +1 -0
- package/dist/cli/commands.d.ts +36 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +471 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/formatters.d.ts +24 -0
- package/dist/cli/formatters.d.ts.map +1 -0
- package/dist/cli/formatters.js +175 -0
- package/dist/cli/formatters.js.map +1 -0
- package/dist/cli.d.ts +15 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +62 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/AnalysisConfig.d.ts +13 -0
- package/dist/config/AnalysisConfig.d.ts.map +1 -0
- package/dist/config/AnalysisConfig.js +10 -0
- package/dist/config/AnalysisConfig.js.map +1 -0
- package/dist/config/env.d.ts +30 -0
- package/dist/config/env.d.ts.map +1 -0
- package/dist/config/env.js +77 -0
- package/dist/config/env.js.map +1 -0
- package/dist/database/DatabaseService.d.ts +106 -0
- package/dist/database/DatabaseService.d.ts.map +1 -0
- package/dist/database/DatabaseService.js +180 -0
- package/dist/database/DatabaseService.js.map +1 -0
- package/dist/database/TimeSeriesService.d.ts +53 -0
- package/dist/database/TimeSeriesService.d.ts.map +1 -0
- package/dist/database/TimeSeriesService.js +122 -0
- package/dist/database/TimeSeriesService.js.map +1 -0
- package/dist/database/db.d.ts +20 -0
- package/dist/database/db.d.ts.map +1 -0
- package/dist/database/db.js +60 -0
- package/dist/database/db.js.map +1 -0
- package/dist/database/schema.d.ts +687 -0
- package/dist/database/schema.d.ts.map +1 -0
- package/dist/database/schema.js +62 -0
- package/dist/database/schema.js.map +1 -0
- package/dist/demo.d.ts +13 -0
- package/dist/demo.d.ts.map +1 -0
- package/dist/demo.js +149 -0
- package/dist/demo.js.map +1 -0
- package/dist/gsc/GSCDataFetcher.d.ts +100 -0
- package/dist/gsc/GSCDataFetcher.d.ts.map +1 -0
- package/dist/gsc/GSCDataFetcher.js +398 -0
- package/dist/gsc/GSCDataFetcher.js.map +1 -0
- package/dist/gsc/GSCPermissionService.d.ts +20 -0
- package/dist/gsc/GSCPermissionService.d.ts.map +1 -0
- package/dist/gsc/GSCPermissionService.js +84 -0
- package/dist/gsc/GSCPermissionService.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +41 -0
- package/dist/index.js.map +1 -0
- package/dist/notifications/NotificationService.d.ts +64 -0
- package/dist/notifications/NotificationService.d.ts.map +1 -0
- package/dist/notifications/NotificationService.js +115 -0
- package/dist/notifications/NotificationService.js.map +1 -0
- package/dist/orchestrator/SEOExperimentOrchestrator.d.ts +69 -0
- package/dist/orchestrator/SEOExperimentOrchestrator.d.ts.map +1 -0
- package/dist/orchestrator/SEOExperimentOrchestrator.js +199 -0
- package/dist/orchestrator/SEOExperimentOrchestrator.js.map +1 -0
- package/dist/services/ExportService.d.ts +52 -0
- package/dist/services/ExportService.d.ts.map +1 -0
- package/dist/services/ExportService.js +238 -0
- package/dist/services/ExportService.js.map +1 -0
- package/dist/smoke-test.d.ts +10 -0
- package/dist/smoke-test.d.ts.map +1 -0
- package/dist/smoke-test.js +73 -0
- package/dist/smoke-test.js.map +1 -0
- package/dist/stats/StatisticalEngine.d.ts +48 -0
- package/dist/stats/StatisticalEngine.d.ts.map +1 -0
- package/dist/stats/StatisticalEngine.js +205 -0
- package/dist/stats/StatisticalEngine.js.map +1 -0
- package/dist/stats/TDistribution.d.ts +28 -0
- package/dist/stats/TDistribution.d.ts.map +1 -0
- package/dist/stats/TDistribution.js +120 -0
- package/dist/stats/TDistribution.js.map +1 -0
- package/drizzle/0000_hot_whiplash.sql +51 -0
- package/drizzle/0001_open_photon.sql +9 -0
- package/drizzle/0002_faulty_the_watchers.sql +1 -0
- package/drizzle/meta/0000_snapshot.json +360 -0
- package/drizzle/meta/0001_snapshot.json +428 -0
- package/drizzle/meta/0002_snapshot.json +420 -0
- package/drizzle/meta/_journal.json +27 -0
- package/package.json +89 -0
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Commands
|
|
3
|
+
*
|
|
4
|
+
* Implementazione dei 7 comandi: login, add, list, status, run, export, delete
|
|
5
|
+
*/
|
|
6
|
+
import { createInterface } from 'readline/promises';
|
|
7
|
+
import { writeFile } from 'fs/promises';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import chalk from 'chalk';
|
|
10
|
+
import inquirer from 'inquirer';
|
|
11
|
+
import { eq, like, desc, count } from 'drizzle-orm';
|
|
12
|
+
import { db } from '../database/db.js';
|
|
13
|
+
import { users, tests, metrics, auditLogs, oauthTokens } from '../database/schema.js';
|
|
14
|
+
import { StatisticalEngine } from '../stats/StatisticalEngine.js';
|
|
15
|
+
import { SEOExperimentOrchestrator } from '../orchestrator/SEOExperimentOrchestrator.js';
|
|
16
|
+
import { ReportExportService } from '../services/ExportService.js';
|
|
17
|
+
import { GoogleOAuthService } from '../auth/GoogleOAuthService.js';
|
|
18
|
+
import { TokenManager } from '../auth/TokenManager.js';
|
|
19
|
+
import { getGoogleOAuthConfig } from '../config/env.js';
|
|
20
|
+
import { colors, colorStatus, colorImprovement, formatTestTable, formatStatusDetail, renderClicksChart, } from './formatters.js';
|
|
21
|
+
// --- Helpers ---
|
|
22
|
+
async function prompt(question, defaultValue) {
|
|
23
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
24
|
+
const suffix = defaultValue ? ` ${colors.muted(`[${defaultValue}]`)} ` : ' ';
|
|
25
|
+
try {
|
|
26
|
+
const answer = await rl.question(`${colors.info('?')} ${question}${suffix}`);
|
|
27
|
+
return answer.trim() || defaultValue || '';
|
|
28
|
+
}
|
|
29
|
+
finally {
|
|
30
|
+
rl.close();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function today() {
|
|
34
|
+
return new Date().toISOString().split('T')[0];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Cerca test per ID esatto o parziale. Restituisce il test o null.
|
|
38
|
+
* Se ci sono più candidati con ID parziale, li stampa e restituisce null.
|
|
39
|
+
*/
|
|
40
|
+
function findTestById(id) {
|
|
41
|
+
// Cerca per ID esatto
|
|
42
|
+
const exact = db.select().from(tests).where(eq(tests.id, id)).get();
|
|
43
|
+
if (exact)
|
|
44
|
+
return exact;
|
|
45
|
+
// Prova con ID parziale
|
|
46
|
+
const candidates = db.select().from(tests).where(like(tests.id, `${id}%`)).all();
|
|
47
|
+
if (candidates.length === 1)
|
|
48
|
+
return candidates[0];
|
|
49
|
+
if (candidates.length > 1) {
|
|
50
|
+
console.log(colors.uncertain(` Trovati ${candidates.length} test con ID che inizia per "${id}":`));
|
|
51
|
+
for (const c of candidates) {
|
|
52
|
+
console.log(` ${colors.muted(c.id.substring(0, 8))} ${c.name}`);
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
console.log(colors.error(` Test "${id}" non trovato.`));
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
// --- Commands ---
|
|
60
|
+
/**
|
|
61
|
+
* login — Collega l'account Google per accedere a Google Search Console
|
|
62
|
+
*/
|
|
63
|
+
export async function loginCommand() {
|
|
64
|
+
console.log('');
|
|
65
|
+
console.log(colors.header(' Login Google Search Console'));
|
|
66
|
+
console.log(colors.muted(' ' + '\u2500'.repeat(40)));
|
|
67
|
+
console.log('');
|
|
68
|
+
try {
|
|
69
|
+
const oauthConfig = getGoogleOAuthConfig();
|
|
70
|
+
const oauthService = new GoogleOAuthService({
|
|
71
|
+
clientId: oauthConfig.clientId,
|
|
72
|
+
clientSecret: oauthConfig.clientSecret,
|
|
73
|
+
redirectUri: oauthConfig.redirectUri,
|
|
74
|
+
});
|
|
75
|
+
// Genera URL di autenticazione
|
|
76
|
+
const authUrl = oauthService.getAuthorizationUrl(oauthConfig.scopes);
|
|
77
|
+
console.log(colors.info(' \uD83D\uDD10 Per collegare il tuo account Google, apri questo URL nel browser:'));
|
|
78
|
+
console.log('');
|
|
79
|
+
console.log(` ${chalk.underline(authUrl)}`);
|
|
80
|
+
console.log('');
|
|
81
|
+
console.log(colors.muted(' Dopo il login, Google ti mostrerà un Codice di Autorizzazione.'));
|
|
82
|
+
console.log(colors.muted(' Copialo e incollalo qui sotto.'));
|
|
83
|
+
console.log('');
|
|
84
|
+
// Chiedi il codice di autorizzazione
|
|
85
|
+
const { code } = await inquirer.prompt([{
|
|
86
|
+
type: 'input',
|
|
87
|
+
name: 'code',
|
|
88
|
+
message: 'Incolla il Codice di Autorizzazione:',
|
|
89
|
+
validate: (input) => input.trim().length > 0 || 'Il codice è obbligatorio.',
|
|
90
|
+
}]);
|
|
91
|
+
console.log('');
|
|
92
|
+
console.log(colors.muted(' Scambio codice in corso...'));
|
|
93
|
+
// Scambia il codice per i token
|
|
94
|
+
const tokenResponse = await oauthService.exchangeCodeForTokens(code.trim());
|
|
95
|
+
// Determina userId
|
|
96
|
+
const userId = process.env['USER_ID'] || 'default-user';
|
|
97
|
+
// Assicurati che l'utente esista
|
|
98
|
+
const existingUser = db.select().from(users).where(eq(users.id, userId)).get();
|
|
99
|
+
if (!existingUser) {
|
|
100
|
+
db.insert(users).values({ id: userId, email: `${userId}@seo-tool.local` }).run();
|
|
101
|
+
}
|
|
102
|
+
// Salva (o aggiorna) i token nel database
|
|
103
|
+
const expiresAt = Date.now() + tokenResponse.expires_in * 1000;
|
|
104
|
+
const existing = db.select().from(oauthTokens).where(eq(oauthTokens.userId, userId)).get();
|
|
105
|
+
if (existing) {
|
|
106
|
+
db.update(oauthTokens)
|
|
107
|
+
.set({
|
|
108
|
+
accessToken: tokenResponse.access_token,
|
|
109
|
+
refreshToken: tokenResponse.refresh_token,
|
|
110
|
+
expiresAt,
|
|
111
|
+
updatedAt: new Date().toISOString(),
|
|
112
|
+
})
|
|
113
|
+
.where(eq(oauthTokens.userId, userId))
|
|
114
|
+
.run();
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
db.insert(oauthTokens).values({
|
|
118
|
+
userId,
|
|
119
|
+
accessToken: tokenResponse.access_token,
|
|
120
|
+
refreshToken: tokenResponse.refresh_token,
|
|
121
|
+
expiresAt,
|
|
122
|
+
}).run();
|
|
123
|
+
}
|
|
124
|
+
// Registra nell'audit log
|
|
125
|
+
db.insert(auditLogs).values({
|
|
126
|
+
testId: 'system',
|
|
127
|
+
action: 'user_login',
|
|
128
|
+
userId,
|
|
129
|
+
}).run();
|
|
130
|
+
console.log('');
|
|
131
|
+
console.log(colors.success(' \u2705 Login effettuato! Ora puoi lanciare \'seo-tool run\' per scaricare i dati.'));
|
|
132
|
+
console.log('');
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
136
|
+
if (msg.includes('Google OAuth credentials not configured')) {
|
|
137
|
+
console.log(colors.error(' Credenziali Google non configurate.'));
|
|
138
|
+
console.log(colors.muted(' Crea un file .env con GOOGLE_CLIENT_ID e GOOGLE_CLIENT_SECRET.'));
|
|
139
|
+
console.log(colors.muted(' Vedi .env.example per un esempio.'));
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
console.log(colors.error(` Errore: ${msg}`));
|
|
143
|
+
}
|
|
144
|
+
console.log('');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* add — Crea un nuovo test SEO con prompt interattivi
|
|
149
|
+
*/
|
|
150
|
+
export async function addCommand() {
|
|
151
|
+
console.log('');
|
|
152
|
+
console.log(colors.header(' Nuovo Test SEO'));
|
|
153
|
+
console.log(colors.muted(' ' + '\u2500'.repeat(40)));
|
|
154
|
+
console.log('');
|
|
155
|
+
try {
|
|
156
|
+
const name = await prompt('Nome del test:');
|
|
157
|
+
if (!name) {
|
|
158
|
+
console.log(colors.error(' Nome obbligatorio. Operazione annullata.'));
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const siteUrl = await prompt('Proprietà GSC (es. sc-domain:example.com):');
|
|
162
|
+
if (!siteUrl) {
|
|
163
|
+
console.log(colors.error(' Proprietà GSC obbligatoria. Operazione annullata.'));
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const urlsInput = await prompt('URL da monitorare (separati da virgola):');
|
|
167
|
+
const urls = urlsInput.split(',').map(u => u.trim()).filter(Boolean);
|
|
168
|
+
if (urls.length === 0) {
|
|
169
|
+
console.log(colors.error(' Almeno un URL necessario. Operazione annullata.'));
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
const splitDateStr = await prompt('Split Date (YYYY-MM-DD):', today());
|
|
173
|
+
const startDateStr = await prompt('Data inizio raccolta (YYYY-MM-DD):', '2024-01-01');
|
|
174
|
+
const userId = await prompt('User ID:', process.env['USER_ID'] || 'default-user');
|
|
175
|
+
// Validazione date
|
|
176
|
+
const splitDate = new Date(splitDateStr);
|
|
177
|
+
const startDate = new Date(startDateStr);
|
|
178
|
+
if (isNaN(splitDate.getTime()) || isNaN(startDate.getTime())) {
|
|
179
|
+
console.log(colors.error(' Formato data non valido. Usa YYYY-MM-DD.'));
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
// Verifica che l'utente esista, altrimenti crealo
|
|
183
|
+
const existingUser = db.select().from(users).where(eq(users.id, userId)).get();
|
|
184
|
+
if (!existingUser) {
|
|
185
|
+
db.insert(users).values({ id: userId, email: `${userId}@seo-tool.local` }).run();
|
|
186
|
+
}
|
|
187
|
+
// Crea il test
|
|
188
|
+
const test = db.insert(tests).values({
|
|
189
|
+
name,
|
|
190
|
+
siteUrl,
|
|
191
|
+
urls: JSON.stringify(urls),
|
|
192
|
+
startDate: startDate.toISOString(),
|
|
193
|
+
splitDate: splitDate.toISOString(),
|
|
194
|
+
status: 'running',
|
|
195
|
+
userId,
|
|
196
|
+
}).returning().get();
|
|
197
|
+
console.log('');
|
|
198
|
+
console.log(colors.success(` Test creato con successo!`));
|
|
199
|
+
console.log(` ${colors.muted('ID:')} ${test.id}`);
|
|
200
|
+
console.log('');
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
console.error(colors.error(` Errore: ${error instanceof Error ? error.message : error}`));
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* list — Mostra tabella con tutti i test
|
|
208
|
+
*/
|
|
209
|
+
export async function listCommand() {
|
|
210
|
+
try {
|
|
211
|
+
const allTests = db.select().from(tests).orderBy(desc(tests.createdAt)).all();
|
|
212
|
+
console.log('');
|
|
213
|
+
if (allTests.length === 0) {
|
|
214
|
+
console.log(colors.muted(' Nessun test trovato. Usa "seo-tool add" per crearne uno.'));
|
|
215
|
+
console.log('');
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
console.log(colors.header(` ${allTests.length} test trovati`));
|
|
219
|
+
console.log('');
|
|
220
|
+
console.log(formatTestTable(allTests));
|
|
221
|
+
console.log('');
|
|
222
|
+
}
|
|
223
|
+
catch (error) {
|
|
224
|
+
console.error(colors.error(` Errore: ${error instanceof Error ? error.message : error}`));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* status <id> — Dettaglio di un singolo test con analisi e grafico
|
|
229
|
+
*/
|
|
230
|
+
export async function statusCommand(id) {
|
|
231
|
+
try {
|
|
232
|
+
const test = findTestById(id);
|
|
233
|
+
if (!test)
|
|
234
|
+
return;
|
|
235
|
+
// Carica metriche ordinate per data
|
|
236
|
+
const testMetrics = db
|
|
237
|
+
.select()
|
|
238
|
+
.from(metrics)
|
|
239
|
+
.where(eq(metrics.testId, test.id))
|
|
240
|
+
.orderBy(metrics.date)
|
|
241
|
+
.all();
|
|
242
|
+
// Dividi metriche before/after
|
|
243
|
+
const splitDateStr = test.splitDate;
|
|
244
|
+
const beforeClicks = testMetrics
|
|
245
|
+
.filter((m) => m.date < splitDateStr)
|
|
246
|
+
.map((m) => m.clicks);
|
|
247
|
+
const afterClicks = testMetrics
|
|
248
|
+
.filter((m) => m.date >= splitDateStr)
|
|
249
|
+
.map((m) => m.clicks);
|
|
250
|
+
// Analisi statistica
|
|
251
|
+
const engine = new StatisticalEngine();
|
|
252
|
+
const analysis = engine.analyze({
|
|
253
|
+
before: beforeClicks,
|
|
254
|
+
after: afterClicks,
|
|
255
|
+
});
|
|
256
|
+
// Attacca dati per il formatter
|
|
257
|
+
const testView = {
|
|
258
|
+
...test,
|
|
259
|
+
metrics: testMetrics,
|
|
260
|
+
_beforeClicks: beforeClicks,
|
|
261
|
+
_afterClicks: afterClicks,
|
|
262
|
+
};
|
|
263
|
+
// Stampa dettaglio
|
|
264
|
+
console.log(formatStatusDetail(testView, analysis));
|
|
265
|
+
// Grafico ASCII
|
|
266
|
+
if (testMetrics.length > 0) {
|
|
267
|
+
console.log(renderClicksChart(testMetrics, new Date(test.splitDate)));
|
|
268
|
+
// Bonus: proponi export
|
|
269
|
+
const { wantExport } = await inquirer.prompt([{
|
|
270
|
+
type: 'confirm',
|
|
271
|
+
name: 'wantExport',
|
|
272
|
+
message: 'Vuoi esportare questi dati ora?',
|
|
273
|
+
default: false,
|
|
274
|
+
}]);
|
|
275
|
+
if (wantExport) {
|
|
276
|
+
await exportCommand(test.id);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
catch (error) {
|
|
281
|
+
console.error(colors.error(` Errore: ${error instanceof Error ? error.message : error}`));
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* run — Sincronizza tutti i test attivi via orchestratore
|
|
286
|
+
*/
|
|
287
|
+
export async function runCommand() {
|
|
288
|
+
console.log('');
|
|
289
|
+
console.log(colors.header(' Sincronizzazione Test Attivi'));
|
|
290
|
+
console.log(colors.muted(' ' + '\u2500'.repeat(40)));
|
|
291
|
+
console.log('');
|
|
292
|
+
console.log(colors.info(' Avvio sincronizzazione...'));
|
|
293
|
+
console.log('');
|
|
294
|
+
try {
|
|
295
|
+
// Carica config OAuth e token dal database
|
|
296
|
+
const oauthConfig = getGoogleOAuthConfig();
|
|
297
|
+
const tokenManager = new TokenManager({
|
|
298
|
+
clientId: oauthConfig.clientId,
|
|
299
|
+
clientSecret: oauthConfig.clientSecret,
|
|
300
|
+
});
|
|
301
|
+
// Popola il TokenManager con i token salvati nel DB
|
|
302
|
+
const savedTokens = db.select().from(oauthTokens).all();
|
|
303
|
+
if (savedTokens.length === 0) {
|
|
304
|
+
console.log(colors.error(' Nessun account Google collegato.'));
|
|
305
|
+
console.log(colors.muted(' Esegui prima "seo-tool login" per autenticarti.'));
|
|
306
|
+
console.log('');
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
for (const t of savedTokens) {
|
|
310
|
+
const remainingSeconds = Math.max(0, Math.floor((t.expiresAt - Date.now()) / 1000));
|
|
311
|
+
await tokenManager.saveTokens(t.userId, {
|
|
312
|
+
access_token: t.accessToken,
|
|
313
|
+
refresh_token: t.refreshToken,
|
|
314
|
+
expires_in: remainingSeconds,
|
|
315
|
+
token_type: 'Bearer',
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
const orchestrator = new SEOExperimentOrchestrator({ tokenManager });
|
|
319
|
+
const result = await orchestrator.syncAllActiveTests();
|
|
320
|
+
if (result.totalTests === 0) {
|
|
321
|
+
console.log(colors.muted(' Nessun test attivo da sincronizzare.'));
|
|
322
|
+
console.log('');
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
// Risultati per ogni test
|
|
326
|
+
for (const r of result.results) {
|
|
327
|
+
const icon = r.isSignificant ? chalk.green('\u2714') : chalk.yellow('\u25CB');
|
|
328
|
+
const pStr = r.pValue !== null ? `p=${r.pValue.toFixed(4)}` : '';
|
|
329
|
+
const changeStr = colorImprovement(r.percentageChange);
|
|
330
|
+
console.log(` ${icon} ${colors.muted(r.testId.substring(0, 8))} ${changeStr} ${colors.muted(pStr)}`);
|
|
331
|
+
if (r.notificationSent) {
|
|
332
|
+
console.log(` ${colors.info('\u2190 Notifica inviata')}`);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
// Errori
|
|
336
|
+
for (const err of result.errors) {
|
|
337
|
+
console.log(` ${chalk.red('\u2717')} ${colors.muted(err.testId.substring(0, 8))} ${colors.error(err.error)}`);
|
|
338
|
+
}
|
|
339
|
+
// Riepilogo
|
|
340
|
+
console.log('');
|
|
341
|
+
console.log(colors.muted(' ' + '\u2500'.repeat(40)));
|
|
342
|
+
console.log(` ${colors.success(`${result.successCount} completati`)} \u00B7 ${result.errorCount > 0 ? colors.error(`${result.errorCount} errori`) : colors.muted('0 errori')}`);
|
|
343
|
+
console.log('');
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
console.error(colors.error(` Errore fatale: ${error instanceof Error ? error.message : error}`));
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* export <id> — Esporta dati test su file Excel o CSV (con scelta interattiva)
|
|
351
|
+
*/
|
|
352
|
+
export async function exportCommand(id, options) {
|
|
353
|
+
try {
|
|
354
|
+
const test = findTestById(id);
|
|
355
|
+
if (!test)
|
|
356
|
+
return;
|
|
357
|
+
const testMetrics = db
|
|
358
|
+
.select()
|
|
359
|
+
.from(metrics)
|
|
360
|
+
.where(eq(metrics.testId, test.id))
|
|
361
|
+
.orderBy(metrics.date)
|
|
362
|
+
.all();
|
|
363
|
+
if (testMetrics.length === 0) {
|
|
364
|
+
console.log('');
|
|
365
|
+
console.log(colors.uncertain(' ⚠ Nessuna metrica disponibile per questo test.'));
|
|
366
|
+
console.log(colors.muted(' Esegui prima "seo-tool run" per raccogliere dati da GSC.'));
|
|
367
|
+
console.log('');
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
// Scelta formato: flag CLI oppure prompt interattivo
|
|
371
|
+
let format = options?.format;
|
|
372
|
+
if (!format) {
|
|
373
|
+
const answer = await inquirer.prompt([{
|
|
374
|
+
type: 'list',
|
|
375
|
+
name: 'format',
|
|
376
|
+
message: 'In quale formato vuoi esportare?',
|
|
377
|
+
choices: [
|
|
378
|
+
{ name: 'Excel (.xlsx) — Report completo con grafici e formattazione', value: 'xlsx' },
|
|
379
|
+
{ name: 'CSV (.csv) — Dati piatti per import in altri tool', value: 'csv' },
|
|
380
|
+
],
|
|
381
|
+
}]);
|
|
382
|
+
format = answer.format;
|
|
383
|
+
}
|
|
384
|
+
// Prepara input per ExportService
|
|
385
|
+
const metricRows = testMetrics.map((m) => ({
|
|
386
|
+
date: m.date,
|
|
387
|
+
clicks: m.clicks,
|
|
388
|
+
impressions: m.impressions,
|
|
389
|
+
gapFilled: m.gapFilled ?? false,
|
|
390
|
+
}));
|
|
391
|
+
const exportInput = {
|
|
392
|
+
test: {
|
|
393
|
+
id: test.id,
|
|
394
|
+
name: test.name,
|
|
395
|
+
siteUrl: test.siteUrl,
|
|
396
|
+
urls: JSON.parse(test.urls),
|
|
397
|
+
startDate: test.startDate,
|
|
398
|
+
splitDate: test.splitDate,
|
|
399
|
+
status: test.status,
|
|
400
|
+
lastPValue: test.lastPValue,
|
|
401
|
+
lastImprovement: test.lastImprovement,
|
|
402
|
+
},
|
|
403
|
+
metrics: metricRows,
|
|
404
|
+
};
|
|
405
|
+
const exportService = new ReportExportService();
|
|
406
|
+
const result = format === 'xlsx'
|
|
407
|
+
? await exportService.exportToExcel(exportInput)
|
|
408
|
+
: await exportService.exportToCSV(exportInput);
|
|
409
|
+
// Scrivi il file nella cartella corrente
|
|
410
|
+
const filePath = path.resolve(result.fileName);
|
|
411
|
+
await writeFile(filePath, result.buffer);
|
|
412
|
+
console.log('');
|
|
413
|
+
console.log(colors.success(' Export completato!'));
|
|
414
|
+
console.log(` ${colors.muted('File:')} ${filePath}`);
|
|
415
|
+
console.log(` ${colors.muted('Formato:')} ${result.format.toUpperCase()}`);
|
|
416
|
+
console.log(` ${colors.muted('Metriche:')} ${result.rowCount} giorni`);
|
|
417
|
+
console.log('');
|
|
418
|
+
}
|
|
419
|
+
catch (error) {
|
|
420
|
+
console.error(colors.error(` Errore: ${error instanceof Error ? error.message : error}`));
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* delete <id> — Elimina un test (con conferma interattiva) e registra nell'Audit Log
|
|
425
|
+
*/
|
|
426
|
+
export async function deleteCommand(id) {
|
|
427
|
+
try {
|
|
428
|
+
const test = findTestById(id);
|
|
429
|
+
if (!test)
|
|
430
|
+
return;
|
|
431
|
+
// Conta metriche collegate
|
|
432
|
+
const metricsResult = db
|
|
433
|
+
.select({ total: count() })
|
|
434
|
+
.from(metrics)
|
|
435
|
+
.where(eq(metrics.testId, test.id))
|
|
436
|
+
.get();
|
|
437
|
+
const metricsCount = metricsResult?.total ?? 0;
|
|
438
|
+
// Mostra info e chiedi conferma
|
|
439
|
+
console.log('');
|
|
440
|
+
console.log(colors.header(' Eliminazione Test'));
|
|
441
|
+
console.log(colors.muted(' ' + '\u2500'.repeat(40)));
|
|
442
|
+
console.log(` ${colors.muted('Nome:')} ${test.name}`);
|
|
443
|
+
console.log(` ${colors.muted('ID:')} ${test.id}`);
|
|
444
|
+
console.log(` ${colors.muted('Stato:')} ${colorStatus(test.status)}`);
|
|
445
|
+
console.log(` ${colors.muted('Metriche:')} ${metricsCount} record`);
|
|
446
|
+
console.log('');
|
|
447
|
+
const answer = await prompt(chalk.red('Confermi l\'eliminazione? Questa operazione è irreversibile. (s/N):'));
|
|
448
|
+
if (answer.toLowerCase() !== 's' && answer.toLowerCase() !== 'si' && answer.toLowerCase() !== 'sì') {
|
|
449
|
+
console.log(colors.muted(' Operazione annullata.'));
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
// Elimina il test (le metriche vengono eliminate via ON DELETE CASCADE)
|
|
453
|
+
db.delete(tests).where(eq(tests.id, test.id)).run();
|
|
454
|
+
// Registra nell'Audit Log
|
|
455
|
+
db.insert(auditLogs).values({
|
|
456
|
+
testId: test.id,
|
|
457
|
+
action: 'test_deleted',
|
|
458
|
+
userId: test.userId,
|
|
459
|
+
}).run();
|
|
460
|
+
console.log('');
|
|
461
|
+
console.log(colors.success(` Test "${test.name}" eliminato con successo.`));
|
|
462
|
+
if (metricsCount > 0) {
|
|
463
|
+
console.log(colors.muted(` ${metricsCount} metriche rimosse (cascade).`));
|
|
464
|
+
}
|
|
465
|
+
console.log('');
|
|
466
|
+
}
|
|
467
|
+
catch (error) {
|
|
468
|
+
console.error(colors.error(` Errore: ${error instanceof Error ? error.message : error}`));
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Formatters
|
|
3
|
+
*
|
|
4
|
+
* Colori, tabelle e grafici ASCII per il terminale.
|
|
5
|
+
*/
|
|
6
|
+
import type { AnalysisResult } from '../stats/StatisticalEngine.js';
|
|
7
|
+
export declare const colors: {
|
|
8
|
+
significant: import("chalk").ChalkInstance;
|
|
9
|
+
uncertain: import("chalk").ChalkInstance;
|
|
10
|
+
notSignificant: import("chalk").ChalkInstance;
|
|
11
|
+
error: import("chalk").ChalkInstance;
|
|
12
|
+
success: import("chalk").ChalkInstance;
|
|
13
|
+
info: import("chalk").ChalkInstance;
|
|
14
|
+
header: import("chalk").ChalkInstance;
|
|
15
|
+
muted: import("chalk").ChalkInstance;
|
|
16
|
+
value: import("chalk").ChalkInstance;
|
|
17
|
+
};
|
|
18
|
+
export declare function colorPValue(p: number | null): string;
|
|
19
|
+
export declare function colorStatus(status: string): string;
|
|
20
|
+
export declare function colorImprovement(pct: number | null): string;
|
|
21
|
+
export declare function formatTestTable(tests: any[]): string;
|
|
22
|
+
export declare function formatStatusDetail(test: any, analysis: AnalysisResult): string;
|
|
23
|
+
export declare function renderClicksChart(metrics: any[], splitDate: Date): string;
|
|
24
|
+
//# sourceMappingURL=formatters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../src/cli/formatters.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAIpE,eAAO,MAAM,MAAM;;;;;;;;;;CAUlB,CAAC;AAEF,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAKpD;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAQlD;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAO3D;AAID,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,MAAM,CA8BpD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,cAAc,GAAG,MAAM,CA6D9E;AAID,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,GAAG,MAAM,CAgDzE"}
|