qualyx 0.3.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 +523 -0
- package/dist/cli/commands/init.d.ts +6 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +124 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/list.d.ts +3 -0
- package/dist/cli/commands/list.d.ts.map +1 -0
- package/dist/cli/commands/list.js +122 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/run.d.ts +12 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +160 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/schedule.d.ts +19 -0
- package/dist/cli/commands/schedule.d.ts.map +1 -0
- package/dist/cli/commands/schedule.js +240 -0
- package/dist/cli/commands/schedule.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +3 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +47 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +194 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/claude-runner.d.ts +23 -0
- package/dist/core/claude-runner.d.ts.map +1 -0
- package/dist/core/claude-runner.js +196 -0
- package/dist/core/claude-runner.js.map +1 -0
- package/dist/core/config-loader.d.ts +137 -0
- package/dist/core/config-loader.d.ts.map +1 -0
- package/dist/core/config-loader.js +239 -0
- package/dist/core/config-loader.js.map +1 -0
- package/dist/core/executor.d.ts +75 -0
- package/dist/core/executor.d.ts.map +1 -0
- package/dist/core/executor.js +337 -0
- package/dist/core/executor.js.map +1 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +7 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/prompt-builder.d.ts +24 -0
- package/dist/core/prompt-builder.d.ts.map +1 -0
- package/dist/core/prompt-builder.js +145 -0
- package/dist/core/prompt-builder.js.map +1 -0
- package/dist/core/retry-handler.d.ts +42 -0
- package/dist/core/retry-handler.d.ts.map +1 -0
- package/dist/core/retry-handler.js +126 -0
- package/dist/core/retry-handler.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/email.d.ts +38 -0
- package/dist/integrations/email.d.ts.map +1 -0
- package/dist/integrations/email.js +216 -0
- package/dist/integrations/email.js.map +1 -0
- package/dist/integrations/index.d.ts +5 -0
- package/dist/integrations/index.d.ts.map +1 -0
- package/dist/integrations/index.js +5 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/integrations/jira.d.ts +68 -0
- package/dist/integrations/jira.d.ts.map +1 -0
- package/dist/integrations/jira.js +288 -0
- package/dist/integrations/jira.js.map +1 -0
- package/dist/integrations/slack.d.ts +66 -0
- package/dist/integrations/slack.d.ts.map +1 -0
- package/dist/integrations/slack.js +192 -0
- package/dist/integrations/slack.js.map +1 -0
- package/dist/integrations/teams.d.ts +72 -0
- package/dist/integrations/teams.d.ts.map +1 -0
- package/dist/integrations/teams.js +197 -0
- package/dist/integrations/teams.js.map +1 -0
- package/dist/reporters/console.d.ts +83 -0
- package/dist/reporters/console.d.ts.map +1 -0
- package/dist/reporters/console.js +299 -0
- package/dist/reporters/console.js.map +1 -0
- package/dist/reporters/html.d.ts +29 -0
- package/dist/reporters/html.d.ts.map +1 -0
- package/dist/reporters/html.js +105 -0
- package/dist/reporters/html.js.map +1 -0
- package/dist/storage/results.d.ts +61 -0
- package/dist/storage/results.d.ts.map +1 -0
- package/dist/storage/results.js +111 -0
- package/dist/storage/results.js.map +1 -0
- package/dist/storage/sqlite.d.ts +70 -0
- package/dist/storage/sqlite.d.ts.map +1 -0
- package/dist/storage/sqlite.js +240 -0
- package/dist/storage/sqlite.js.map +1 -0
- package/dist/types/index.d.ts +1239 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +105 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +75 -0
- package/templates/crontab.hbs +24 -0
- package/templates/github-schedule.yml.hbs +153 -0
- package/templates/prompt.md.hbs +147 -0
- package/templates/report.html.hbs +423 -0
- package/templates/slack-message.json.hbs +93 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { loadConfig, ConfigLoadError } from '../../core/config-loader.js';
|
|
3
|
+
import { printList } from '../../reporters/console.js';
|
|
4
|
+
export async function runList(resource, configPath, options = {}) {
|
|
5
|
+
try {
|
|
6
|
+
const result = loadConfig(configPath);
|
|
7
|
+
const config = result.config;
|
|
8
|
+
if (options.format === 'json') {
|
|
9
|
+
// Output as JSON
|
|
10
|
+
if (resource === 'apps') {
|
|
11
|
+
const apps = config.apps.map((app) => ({
|
|
12
|
+
name: app.name,
|
|
13
|
+
url: app.url,
|
|
14
|
+
environments: app.environments,
|
|
15
|
+
rulesCount: app.rules.length,
|
|
16
|
+
}));
|
|
17
|
+
console.log(JSON.stringify(apps, null, 2));
|
|
18
|
+
}
|
|
19
|
+
else if (resource === 'rules') {
|
|
20
|
+
const rules = config.apps.flatMap((app) => app.rules.map((rule) => ({
|
|
21
|
+
appName: app.name,
|
|
22
|
+
id: rule.id,
|
|
23
|
+
name: rule.name,
|
|
24
|
+
severity: rule.severity,
|
|
25
|
+
stepsCount: rule.steps.length,
|
|
26
|
+
validationsCount: rule.validations?.length || 0,
|
|
27
|
+
})));
|
|
28
|
+
console.log(JSON.stringify(rules, null, 2));
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
// Output full config summary
|
|
32
|
+
const summary = {
|
|
33
|
+
organization: config.organization.name,
|
|
34
|
+
appsCount: config.apps.length,
|
|
35
|
+
totalRules: config.apps.reduce((sum, app) => sum + app.rules.length, 0),
|
|
36
|
+
apps: config.apps.map((app) => ({
|
|
37
|
+
name: app.name,
|
|
38
|
+
url: app.url,
|
|
39
|
+
rulesCount: app.rules.length,
|
|
40
|
+
rules: app.rules.map((rule) => ({
|
|
41
|
+
id: rule.id,
|
|
42
|
+
name: rule.name,
|
|
43
|
+
severity: rule.severity,
|
|
44
|
+
})),
|
|
45
|
+
})),
|
|
46
|
+
};
|
|
47
|
+
console.log(JSON.stringify(summary, null, 2));
|
|
48
|
+
}
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
// Table/text output
|
|
52
|
+
if (resource === 'apps') {
|
|
53
|
+
printApps(config.apps);
|
|
54
|
+
}
|
|
55
|
+
else if (resource === 'rules') {
|
|
56
|
+
printRules(config.apps);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// Print everything
|
|
60
|
+
printList(config.apps.map((app) => ({
|
|
61
|
+
name: app.name,
|
|
62
|
+
url: app.url,
|
|
63
|
+
rules: app.rules.map((rule) => ({
|
|
64
|
+
id: rule.id,
|
|
65
|
+
name: rule.name,
|
|
66
|
+
severity: rule.severity,
|
|
67
|
+
})),
|
|
68
|
+
})));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
if (error instanceof ConfigLoadError) {
|
|
73
|
+
console.log();
|
|
74
|
+
console.log(chalk.red(` Error: ${error.message}`));
|
|
75
|
+
console.log();
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function printApps(apps) {
|
|
82
|
+
console.log();
|
|
83
|
+
console.log(chalk.bold.cyan(' Apps'));
|
|
84
|
+
console.log();
|
|
85
|
+
for (const app of apps) {
|
|
86
|
+
console.log(chalk.bold(` ${app.name}`));
|
|
87
|
+
console.log(chalk.gray(` URL: ${app.url}`));
|
|
88
|
+
console.log(chalk.gray(` Rules: ${app.rules.length}`));
|
|
89
|
+
console.log();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function printRules(apps) {
|
|
93
|
+
console.log();
|
|
94
|
+
console.log(chalk.bold.cyan(' Rules'));
|
|
95
|
+
console.log();
|
|
96
|
+
for (const app of apps) {
|
|
97
|
+
console.log(chalk.bold(` ${app.name}`));
|
|
98
|
+
for (const rule of app.rules) {
|
|
99
|
+
const severityColor = getSeverityColor(rule.severity);
|
|
100
|
+
console.log(` ${chalk.gray('•')} ${rule.name}`);
|
|
101
|
+
console.log(chalk.gray(` ID: ${rule.id}`));
|
|
102
|
+
console.log(` Severity: ${severityColor(rule.severity.toUpperCase())}`);
|
|
103
|
+
console.log(chalk.gray(` Steps: ${rule.steps.length}`));
|
|
104
|
+
}
|
|
105
|
+
console.log();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function getSeverityColor(severity) {
|
|
109
|
+
switch (severity) {
|
|
110
|
+
case 'critical':
|
|
111
|
+
return chalk.red;
|
|
112
|
+
case 'high':
|
|
113
|
+
return chalk.yellow;
|
|
114
|
+
case 'medium':
|
|
115
|
+
return chalk.blue;
|
|
116
|
+
case 'low':
|
|
117
|
+
return chalk.gray;
|
|
118
|
+
default:
|
|
119
|
+
return chalk.white;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/cli/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAGvD,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,QAAsC,EACtC,UAAmB,EACnB,UAAuB,EAAE;IAEzB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;QACtC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAE7B,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC9B,iBAAiB;YACjB,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;gBACxB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;oBACrC,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,GAAG,EAAE,GAAG,CAAC,GAAG;oBACZ,YAAY,EAAE,GAAG,CAAC,YAAY;oBAC9B,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM;iBAC7B,CAAC,CAAC,CAAC;gBACJ,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7C,CAAC;iBAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;gBAChC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CACxC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;oBACvB,OAAO,EAAE,GAAG,CAAC,IAAI;oBACjB,EAAE,EAAE,IAAI,CAAC,EAAE;oBACX,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;oBAC7B,gBAAgB,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,IAAI,CAAC;iBAChD,CAAC,CAAC,CACJ,CAAC;gBACF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC9C,CAAC;iBAAM,CAAC;gBACN,6BAA6B;gBAC7B,MAAM,OAAO,GAAG;oBACd,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC,IAAI;oBACtC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM;oBAC7B,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;oBACvE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;wBAC9B,IAAI,EAAE,GAAG,CAAC,IAAI;wBACd,GAAG,EAAE,GAAG,CAAC,GAAG;wBACZ,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM;wBAC5B,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;4BAC9B,EAAE,EAAE,IAAI,CAAC,EAAE;4BACX,IAAI,EAAE,IAAI,CAAC,IAAI;4BACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;yBACxB,CAAC,CAAC;qBACJ,CAAC,CAAC;iBACJ,CAAC;gBACF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAChD,CAAC;YACD,OAAO;QACT,CAAC;QAED,oBAAoB;QACpB,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;YACxB,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;aAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YAChC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,mBAAmB;YACnB,SAAS,CACP,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBACxB,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,GAAG,EAAE,GAAG,CAAC,GAAG;gBACZ,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;oBAC9B,EAAE,EAAE,IAAI,CAAC,EAAE;oBACX,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;iBACxB,CAAC,CAAC;aACJ,CAAC,CAAC,CACJ,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,eAAe,EAAE,CAAC;YACrC,OAAO,CAAC,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACpD,OAAO,CAAC,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,IAA4D;IAC7E,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC1D,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CACjB,IAA6G;IAE7G,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAEzC,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YAC7B,MAAM,aAAa,GAAG,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACtD,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YACnD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YAChD,OAAO,CAAC,GAAG,CAAC,mBAAmB,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;YAC7E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC/D,CAAC;QAED,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAgB;IACxC,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,UAAU;YACb,OAAO,KAAK,CAAC,GAAG,CAAC;QACnB,KAAK,MAAM;YACT,OAAO,KAAK,CAAC,MAAM,CAAC;QACtB,KAAK,QAAQ;YACX,OAAO,KAAK,CAAC,IAAI,CAAC;QACpB,KAAK,KAAK;YACR,OAAO,KAAK,CAAC,IAAI,CAAC;QACpB;YACE,OAAO,KAAK,CAAC,KAAK,CAAC;IACvB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { RunOptions } from '../../types/index.js';
|
|
2
|
+
export interface RunCommandOptions extends RunOptions {
|
|
3
|
+
config?: string;
|
|
4
|
+
report?: boolean;
|
|
5
|
+
reportDir?: string;
|
|
6
|
+
save?: boolean;
|
|
7
|
+
parallel?: boolean;
|
|
8
|
+
maxParallel?: number;
|
|
9
|
+
collectMetrics?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function runRun(options?: RunCommandOptions): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/run.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,sBAAsB,CAAC;AAEhF,MAAM,WAAW,iBAAkB,SAAQ,UAAU;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AA6DD,wBAAsB,MAAM,CAAC,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2G3E"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { loadConfig, ConfigLoadError } from '../../core/config-loader.js';
|
|
3
|
+
import { Executor } from '../../core/executor.js';
|
|
4
|
+
import { ConsoleReporter, printDryRunPreview } from '../../reporters/console.js';
|
|
5
|
+
import { generateHtmlReport } from '../../reporters/html.js';
|
|
6
|
+
import { saveRunResult } from '../../storage/results.js';
|
|
7
|
+
import { sendSlackNotification } from '../../integrations/slack.js';
|
|
8
|
+
import { sendEmailNotification } from '../../integrations/email.js';
|
|
9
|
+
import { sendTeamsNotification } from '../../integrations/teams.js';
|
|
10
|
+
import { processJiraIssues } from '../../integrations/jira.js';
|
|
11
|
+
/**
|
|
12
|
+
* Process integrations (notifications, Jira issues) after a test run.
|
|
13
|
+
*/
|
|
14
|
+
async function processIntegrations(runResult, config, reportPath) {
|
|
15
|
+
// Send Slack notification
|
|
16
|
+
if (config.notifications?.slack) {
|
|
17
|
+
try {
|
|
18
|
+
await sendSlackNotification(runResult, config, reportPath);
|
|
19
|
+
console.log(chalk.gray(' Slack notification sent'));
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
23
|
+
console.log(chalk.yellow(` Warning: Slack notification failed: ${errorMessage}`));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// Send email notification
|
|
27
|
+
if (config.notifications?.email) {
|
|
28
|
+
try {
|
|
29
|
+
await sendEmailNotification(runResult, config, reportPath);
|
|
30
|
+
console.log(chalk.gray(' Email notification sent'));
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
34
|
+
console.log(chalk.yellow(` Warning: Email notification failed: ${errorMessage}`));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Send Teams notification
|
|
38
|
+
if (config.notifications?.teams) {
|
|
39
|
+
try {
|
|
40
|
+
await sendTeamsNotification(runResult, config, reportPath);
|
|
41
|
+
console.log(chalk.gray(' Teams notification sent'));
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
45
|
+
console.log(chalk.yellow(` Warning: Teams notification failed: ${errorMessage}`));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Process Jira issues for failures
|
|
49
|
+
if (config.integrations?.jira && runResult.failed > 0) {
|
|
50
|
+
try {
|
|
51
|
+
const jiraResults = await processJiraIssues(runResult, config);
|
|
52
|
+
if (jiraResults.length > 0) {
|
|
53
|
+
console.log(chalk.gray(' Jira issues processed:'));
|
|
54
|
+
for (const result of jiraResults) {
|
|
55
|
+
const action = result.action === 'created' ? 'Created' : 'Updated';
|
|
56
|
+
console.log(chalk.gray(` ${action}: ${result.issueKey} (${result.testId})`));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
62
|
+
console.log(chalk.yellow(` Warning: Jira integration failed: ${errorMessage}`));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export async function runRun(options = {}) {
|
|
67
|
+
try {
|
|
68
|
+
// Load configuration
|
|
69
|
+
const result = loadConfig(options.config);
|
|
70
|
+
const config = result.config;
|
|
71
|
+
// Show warnings
|
|
72
|
+
if (result.warnings.length > 0) {
|
|
73
|
+
console.log();
|
|
74
|
+
console.log(chalk.yellow(' Warnings:'));
|
|
75
|
+
for (const warning of result.warnings) {
|
|
76
|
+
console.log(chalk.yellow(` - ${warning}`));
|
|
77
|
+
}
|
|
78
|
+
console.log();
|
|
79
|
+
}
|
|
80
|
+
// Create executor
|
|
81
|
+
const executor = new Executor(config, {
|
|
82
|
+
app: options.app,
|
|
83
|
+
rule: options.rule,
|
|
84
|
+
environment: options.environment,
|
|
85
|
+
dryRun: options.dryRun,
|
|
86
|
+
headed: options.headed,
|
|
87
|
+
verbose: options.verbose,
|
|
88
|
+
retries: options.retries,
|
|
89
|
+
timeout: options.timeout,
|
|
90
|
+
parallel: options.parallel,
|
|
91
|
+
maxParallel: options.maxParallel,
|
|
92
|
+
collectMetrics: options.collectMetrics,
|
|
93
|
+
});
|
|
94
|
+
// Handle dry-run mode
|
|
95
|
+
if (options.dryRun) {
|
|
96
|
+
const previews = executor.getExecutionPreview();
|
|
97
|
+
if (previews.length === 0) {
|
|
98
|
+
console.log();
|
|
99
|
+
console.log(chalk.yellow(' No tests match the specified filters'));
|
|
100
|
+
console.log();
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
printDryRunPreview(previews, options.verbose);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
// Set up console reporter
|
|
107
|
+
const consoleReporter = new ConsoleReporter({ verbose: options.verbose });
|
|
108
|
+
const callbacks = consoleReporter.getCallbacks();
|
|
109
|
+
// Execute tests with callbacks
|
|
110
|
+
const runResult = await new Executor(config, {
|
|
111
|
+
...options,
|
|
112
|
+
callbacks,
|
|
113
|
+
}).run();
|
|
114
|
+
// Save results to storage if enabled (default: true)
|
|
115
|
+
if (options.save !== false) {
|
|
116
|
+
try {
|
|
117
|
+
saveRunResult(runResult, config);
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
// Non-fatal: log warning but continue
|
|
121
|
+
console.log(chalk.yellow(` Warning: Could not save results to storage`));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Generate HTML report if requested
|
|
125
|
+
let reportPath;
|
|
126
|
+
if (options.report) {
|
|
127
|
+
try {
|
|
128
|
+
reportPath = generateHtmlReport(runResult, { outputDir: options.reportDir || './qualyx-reports' }, config.organization.name);
|
|
129
|
+
console.log(chalk.green(` HTML report generated: ${reportPath}`));
|
|
130
|
+
console.log();
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
console.log(chalk.yellow(` Warning: Could not generate HTML report`));
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// Send notifications and process integrations
|
|
137
|
+
await processIntegrations(runResult, config, reportPath);
|
|
138
|
+
// Exit with appropriate code
|
|
139
|
+
if (runResult.failed > 0) {
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
if (error instanceof ConfigLoadError) {
|
|
145
|
+
console.log();
|
|
146
|
+
console.log(chalk.red(` Configuration Error: ${error.message}`));
|
|
147
|
+
console.log();
|
|
148
|
+
process.exit(1);
|
|
149
|
+
}
|
|
150
|
+
// Handle Claude not available
|
|
151
|
+
if (error instanceof Error && error.message.includes('Claude Code CLI')) {
|
|
152
|
+
console.log();
|
|
153
|
+
console.log(chalk.red(` ${error.message}`));
|
|
154
|
+
console.log();
|
|
155
|
+
process.exit(1);
|
|
156
|
+
}
|
|
157
|
+
throw error;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/cli/commands/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface ScheduleCommandOptions {
|
|
2
|
+
config?: string;
|
|
3
|
+
output?: string;
|
|
4
|
+
format?: 'table' | 'json';
|
|
5
|
+
projectPath?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* List all scheduled rules.
|
|
9
|
+
*/
|
|
10
|
+
export declare function runScheduleList(options?: ScheduleCommandOptions): Promise<void>;
|
|
11
|
+
/**
|
|
12
|
+
* Generate crontab entries for scheduled rules.
|
|
13
|
+
*/
|
|
14
|
+
export declare function runScheduleCron(options?: ScheduleCommandOptions): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Generate GitHub Actions workflow for scheduled rules.
|
|
17
|
+
*/
|
|
18
|
+
export declare function runScheduleGithub(options?: ScheduleCommandOptions): Promise<void>;
|
|
19
|
+
//# sourceMappingURL=schedule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/schedule.ts"],"names":[],"mappings":"AA0DA,MAAM,WAAW,sBAAsB;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CA2CzF;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CA2CzF;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CAyD3F"}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { readFileSync, writeFileSync, existsSync } from 'node:fs';
|
|
3
|
+
import { resolve, dirname } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import Handlebars from 'handlebars';
|
|
6
|
+
import { loadConfig, getScheduledRules, ConfigLoadError } from '../../core/config-loader.js';
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = dirname(__filename);
|
|
9
|
+
// Template paths
|
|
10
|
+
const crontabTemplatePath = resolve(__dirname, '../../../templates/crontab.hbs');
|
|
11
|
+
const githubTemplatePath = resolve(__dirname, '../../../templates/github-schedule.yml.hbs');
|
|
12
|
+
// Register Handlebars helpers
|
|
13
|
+
Handlebars.registerHelper('escapeShell', (str) => {
|
|
14
|
+
return str.replace(/'/g, "'\\''");
|
|
15
|
+
});
|
|
16
|
+
Handlebars.registerHelper('gt', (a, b) => {
|
|
17
|
+
return a > b;
|
|
18
|
+
});
|
|
19
|
+
Handlebars.registerHelper('formatCronDescription', (schedule) => {
|
|
20
|
+
// Basic cron expression descriptions
|
|
21
|
+
const parts = schedule.split(' ');
|
|
22
|
+
if (parts.length !== 5)
|
|
23
|
+
return schedule;
|
|
24
|
+
const [minute, hour, dayOfMonth, month, dayOfWeek] = parts;
|
|
25
|
+
// Common patterns
|
|
26
|
+
if (schedule === '* * * * *')
|
|
27
|
+
return 'every minute';
|
|
28
|
+
if (schedule === '0 * * * *')
|
|
29
|
+
return 'every hour';
|
|
30
|
+
if (schedule === '0 0 * * *')
|
|
31
|
+
return 'daily at midnight';
|
|
32
|
+
if (schedule === '0 0 * * 0')
|
|
33
|
+
return 'weekly on Sunday';
|
|
34
|
+
if (minute.includes('/')) {
|
|
35
|
+
const interval = minute.split('/')[1];
|
|
36
|
+
return `every ${interval} minutes`;
|
|
37
|
+
}
|
|
38
|
+
if (hour.includes('/')) {
|
|
39
|
+
const interval = hour.split('/')[1];
|
|
40
|
+
return `every ${interval} hours`;
|
|
41
|
+
}
|
|
42
|
+
if (dayOfMonth === '*' && month === '*') {
|
|
43
|
+
if (dayOfWeek !== '*') {
|
|
44
|
+
const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
|
45
|
+
const dayNum = parseInt(dayOfWeek, 10);
|
|
46
|
+
if (!isNaN(dayNum) && dayNum >= 0 && dayNum <= 6) {
|
|
47
|
+
return `weekly on ${days[dayNum]} at ${hour}:${minute.padStart(2, '0')}`;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return `daily at ${hour}:${minute.padStart(2, '0')}`;
|
|
51
|
+
}
|
|
52
|
+
return schedule;
|
|
53
|
+
});
|
|
54
|
+
/**
|
|
55
|
+
* List all scheduled rules.
|
|
56
|
+
*/
|
|
57
|
+
export async function runScheduleList(options = {}) {
|
|
58
|
+
try {
|
|
59
|
+
const result = loadConfig(options.config);
|
|
60
|
+
const scheduledRules = getScheduledRules(result.config);
|
|
61
|
+
if (scheduledRules.length === 0) {
|
|
62
|
+
console.log();
|
|
63
|
+
console.log(chalk.yellow(' No scheduled rules found'));
|
|
64
|
+
console.log(chalk.gray(' Add a schedule field to rules in your qualyx.yml:'));
|
|
65
|
+
console.log(chalk.gray(' schedule: "0 7 * * *" # Daily at 7 AM'));
|
|
66
|
+
console.log();
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (options.format === 'json') {
|
|
70
|
+
console.log(JSON.stringify(scheduledRules, null, 2));
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
console.log();
|
|
74
|
+
console.log(chalk.bold.cyan(' Scheduled Rules'));
|
|
75
|
+
console.log();
|
|
76
|
+
for (const rule of scheduledRules) {
|
|
77
|
+
const severityBadge = getSeverityBadge(rule.severity);
|
|
78
|
+
console.log(` ${severityBadge} ${chalk.bold(rule.ruleName)}`);
|
|
79
|
+
console.log(chalk.gray(` App: ${rule.appName}`));
|
|
80
|
+
console.log(chalk.gray(` ID: ${rule.ruleId}`));
|
|
81
|
+
console.log(chalk.cyan(` Schedule: ${rule.schedule}`));
|
|
82
|
+
console.log();
|
|
83
|
+
}
|
|
84
|
+
console.log(chalk.gray(` Total: ${scheduledRules.length} scheduled rule(s)`));
|
|
85
|
+
console.log();
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
if (error instanceof ConfigLoadError) {
|
|
89
|
+
console.log();
|
|
90
|
+
console.log(chalk.red(` Configuration Error: ${error.message}`));
|
|
91
|
+
console.log();
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
throw error;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Generate crontab entries for scheduled rules.
|
|
99
|
+
*/
|
|
100
|
+
export async function runScheduleCron(options = {}) {
|
|
101
|
+
try {
|
|
102
|
+
const result = loadConfig(options.config);
|
|
103
|
+
const scheduledRules = getScheduledRules(result.config);
|
|
104
|
+
if (scheduledRules.length === 0) {
|
|
105
|
+
console.log();
|
|
106
|
+
console.log(chalk.yellow(' No scheduled rules found'));
|
|
107
|
+
console.log();
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const projectPath = options.projectPath || process.cwd();
|
|
111
|
+
const templateSource = loadTemplate(crontabTemplatePath);
|
|
112
|
+
const template = Handlebars.compile(templateSource);
|
|
113
|
+
const output = template({
|
|
114
|
+
rules: scheduledRules,
|
|
115
|
+
projectPath,
|
|
116
|
+
generatedAt: new Date().toISOString(),
|
|
117
|
+
});
|
|
118
|
+
if (options.output) {
|
|
119
|
+
writeFileSync(options.output, output, 'utf-8');
|
|
120
|
+
console.log();
|
|
121
|
+
console.log(chalk.green(` Crontab entries written to: ${options.output}`));
|
|
122
|
+
console.log(chalk.gray(` Install with: crontab ${options.output}`));
|
|
123
|
+
console.log();
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
console.log();
|
|
127
|
+
console.log(chalk.bold.cyan(' Generated Crontab Entries'));
|
|
128
|
+
console.log();
|
|
129
|
+
console.log(output);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
if (error instanceof ConfigLoadError) {
|
|
134
|
+
console.log();
|
|
135
|
+
console.log(chalk.red(` Configuration Error: ${error.message}`));
|
|
136
|
+
console.log();
|
|
137
|
+
process.exit(1);
|
|
138
|
+
}
|
|
139
|
+
throw error;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Generate GitHub Actions workflow for scheduled rules.
|
|
144
|
+
*/
|
|
145
|
+
export async function runScheduleGithub(options = {}) {
|
|
146
|
+
try {
|
|
147
|
+
const result = loadConfig(options.config);
|
|
148
|
+
const scheduledRules = getScheduledRules(result.config);
|
|
149
|
+
if (scheduledRules.length === 0) {
|
|
150
|
+
console.log();
|
|
151
|
+
console.log(chalk.yellow(' No scheduled rules found'));
|
|
152
|
+
console.log();
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const templateSource = loadTemplate(githubTemplatePath);
|
|
156
|
+
const template = Handlebars.compile(templateSource);
|
|
157
|
+
// Group rules by schedule for efficient workflow triggers
|
|
158
|
+
const scheduleGroups = groupBySchedule(scheduledRules);
|
|
159
|
+
const output = template({
|
|
160
|
+
rules: scheduledRules,
|
|
161
|
+
scheduleGroups,
|
|
162
|
+
generatedAt: new Date().toISOString(),
|
|
163
|
+
organizationName: result.config.organization.name,
|
|
164
|
+
});
|
|
165
|
+
const defaultOutputPath = '.github/workflows/qualyx-scheduled.yml';
|
|
166
|
+
if (options.output) {
|
|
167
|
+
// Ensure directory exists
|
|
168
|
+
const outputDir = dirname(options.output);
|
|
169
|
+
if (outputDir && outputDir !== '.' && !existsSync(outputDir)) {
|
|
170
|
+
const fs = await import('node:fs');
|
|
171
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
172
|
+
}
|
|
173
|
+
writeFileSync(options.output, output, 'utf-8');
|
|
174
|
+
console.log();
|
|
175
|
+
console.log(chalk.green(` GitHub Actions workflow written to: ${options.output}`));
|
|
176
|
+
console.log(chalk.gray(' Commit and push to enable scheduled runs.'));
|
|
177
|
+
console.log();
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
console.log();
|
|
181
|
+
console.log(chalk.bold.cyan(' Generated GitHub Actions Workflow'));
|
|
182
|
+
console.log();
|
|
183
|
+
console.log(output);
|
|
184
|
+
console.log();
|
|
185
|
+
console.log(chalk.gray(` To save: qualyx schedule github --output ${defaultOutputPath}`));
|
|
186
|
+
console.log();
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
if (error instanceof ConfigLoadError) {
|
|
191
|
+
console.log();
|
|
192
|
+
console.log(chalk.red(` Configuration Error: ${error.message}`));
|
|
193
|
+
console.log();
|
|
194
|
+
process.exit(1);
|
|
195
|
+
}
|
|
196
|
+
throw error;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Load a Handlebars template file.
|
|
201
|
+
*/
|
|
202
|
+
function loadTemplate(templatePath) {
|
|
203
|
+
if (!existsSync(templatePath)) {
|
|
204
|
+
throw new Error(`Template not found: ${templatePath}`);
|
|
205
|
+
}
|
|
206
|
+
return readFileSync(templatePath, 'utf-8');
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Get colored severity badge.
|
|
210
|
+
*/
|
|
211
|
+
function getSeverityBadge(severity) {
|
|
212
|
+
switch (severity) {
|
|
213
|
+
case 'critical':
|
|
214
|
+
return chalk.bgRed.white(' CRITICAL ');
|
|
215
|
+
case 'high':
|
|
216
|
+
return chalk.bgYellow.black(' HIGH ');
|
|
217
|
+
case 'medium':
|
|
218
|
+
return chalk.bgBlue.white(' MEDIUM ');
|
|
219
|
+
case 'low':
|
|
220
|
+
return chalk.bgGray.white(' LOW ');
|
|
221
|
+
default:
|
|
222
|
+
return chalk.bgGray.white(` ${severity.toUpperCase()} `);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Group scheduled rules by their cron schedule.
|
|
227
|
+
*/
|
|
228
|
+
function groupBySchedule(rules) {
|
|
229
|
+
const groups = new Map();
|
|
230
|
+
for (const rule of rules) {
|
|
231
|
+
const existing = groups.get(rule.schedule) || [];
|
|
232
|
+
existing.push(rule);
|
|
233
|
+
groups.set(rule.schedule, existing);
|
|
234
|
+
}
|
|
235
|
+
return Array.from(groups.entries()).map(([schedule, rules]) => ({
|
|
236
|
+
schedule,
|
|
237
|
+
rules,
|
|
238
|
+
}));
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=schedule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule.js","sourceRoot":"","sources":["../../../src/cli/commands/schedule.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/validate.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,wBAAsB,WAAW,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiDnG"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { loadConfig, ConfigLoadError } from '../../core/config-loader.js';
|
|
3
|
+
import { printValidationResult } from '../../reporters/console.js';
|
|
4
|
+
export async function runValidate(configPath, options = {}) {
|
|
5
|
+
try {
|
|
6
|
+
const result = loadConfig(configPath);
|
|
7
|
+
// Gather statistics
|
|
8
|
+
const stats = {
|
|
9
|
+
apps: result.config.apps.length,
|
|
10
|
+
rules: result.config.apps.reduce((sum, app) => sum + app.rules.length, 0),
|
|
11
|
+
criticalRules: result.config.apps
|
|
12
|
+
.flatMap((app) => app.rules)
|
|
13
|
+
.filter((rule) => rule.severity === 'critical').length,
|
|
14
|
+
};
|
|
15
|
+
printValidationResult(result.filePath, true, [], result.warnings);
|
|
16
|
+
console.log(chalk.gray(' Configuration Summary:'));
|
|
17
|
+
console.log(chalk.gray(` Organization: ${result.config.organization.name}`));
|
|
18
|
+
console.log(chalk.gray(` Apps: ${stats.apps}`));
|
|
19
|
+
console.log(chalk.gray(` Total Rules: ${stats.rules}`));
|
|
20
|
+
console.log(chalk.gray(` Critical Rules: ${stats.criticalRules}`));
|
|
21
|
+
if (result.config.organization.defaults) {
|
|
22
|
+
console.log(chalk.gray(' Defaults:'));
|
|
23
|
+
console.log(chalk.gray(` Timeout: ${result.config.organization.defaults.timeout}ms`));
|
|
24
|
+
console.log(chalk.gray(` Retries: ${result.config.organization.defaults.retries}`));
|
|
25
|
+
}
|
|
26
|
+
console.log();
|
|
27
|
+
// In strict mode, warnings are treated as errors
|
|
28
|
+
if (options.strict && result.warnings.length > 0) {
|
|
29
|
+
console.log(chalk.red(' Strict mode: warnings treated as errors'));
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
if (error instanceof ConfigLoadError) {
|
|
35
|
+
const errors = error.validationErrors
|
|
36
|
+
? error.validationErrors.errors.map((e) => {
|
|
37
|
+
const path = e.path.length > 0 ? ` at "${e.path.join('.')}"` : '';
|
|
38
|
+
return `${e.message}${path}`;
|
|
39
|
+
})
|
|
40
|
+
: [error.message];
|
|
41
|
+
printValidationResult(error.filePath || 'unknown', false, errors, []);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=validate.js.map
|