laxy-verify 1.3.0 → 1.3.2
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 +486 -474
- package/dist/ai-analysis.d.ts +28 -0
- package/dist/ai-analysis.js +32 -0
- package/dist/audit/broken-links.d.ts +25 -25
- package/dist/audit/broken-links.js +97 -97
- package/dist/badge.d.ts +2 -2
- package/dist/badge.js +18 -18
- package/dist/cli.js +1242 -1250
- package/dist/compare-env.d.ts +23 -0
- package/dist/compare-env.js +55 -0
- package/dist/config.d.ts +102 -102
- package/dist/config.js +360 -360
- package/dist/entitlement.d.ts +15 -15
- package/dist/entitlement.js +98 -98
- package/dist/init-analysis.d.ts +6 -0
- package/dist/init-analysis.js +302 -0
- package/dist/init.js +132 -132
- package/dist/lighthouse.d.ts +37 -37
- package/dist/lighthouse.js +231 -231
- package/dist/report-markdown.d.ts +53 -53
- package/dist/report-markdown.js +407 -407
- package/dist/route-discovery.d.ts +7 -0
- package/dist/route-discovery.js +108 -0
- package/dist/security-audit.d.ts +17 -17
- package/dist/security-audit.js +127 -127
- package/dist/serve.d.ts +1 -0
- package/dist/serve.js +36 -0
- package/dist/verification-core/report.js +526 -526
- package/dist/verification-core/types.d.ts +164 -164
- package/dist/visual-diff.d.ts +33 -33
- package/dist/visual-diff.js +213 -213
- package/package.json +1 -1
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-environment Lighthouse comparison (Pro feature).
|
|
3
|
+
*
|
|
4
|
+
* Compares Lighthouse scores between the local build and a reference
|
|
5
|
+
* environment URL (e.g. staging, production) to detect regressions
|
|
6
|
+
* introduced by the current PR.
|
|
7
|
+
*/
|
|
8
|
+
import type { LighthouseScores } from "./grade.js";
|
|
9
|
+
export interface EnvComparisonResult {
|
|
10
|
+
localUrl: string;
|
|
11
|
+
compareUrl: string;
|
|
12
|
+
local: LighthouseScores | null;
|
|
13
|
+
compare: LighthouseScores | null;
|
|
14
|
+
/** Positive = local is better, negative = compare env is better */
|
|
15
|
+
delta: {
|
|
16
|
+
performance: number | null;
|
|
17
|
+
accessibility: number | null;
|
|
18
|
+
seo: number | null;
|
|
19
|
+
bestPractices: number | null;
|
|
20
|
+
} | null;
|
|
21
|
+
}
|
|
22
|
+
export declare function runEnvComparison(localPort: number, compareUrl: string, runs?: number): Promise<EnvComparisonResult>;
|
|
23
|
+
export declare function printEnvComparison(result: EnvComparisonResult): void;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runEnvComparison = runEnvComparison;
|
|
4
|
+
exports.printEnvComparison = printEnvComparison;
|
|
5
|
+
const lighthouse_js_1 = require("./lighthouse.js");
|
|
6
|
+
function scoreDelta(local, compare) {
|
|
7
|
+
if (!local || !compare)
|
|
8
|
+
return null;
|
|
9
|
+
return {
|
|
10
|
+
performance: local.performance - compare.performance,
|
|
11
|
+
accessibility: local.accessibility - compare.accessibility,
|
|
12
|
+
seo: local.seo - compare.seo,
|
|
13
|
+
bestPractices: local.bestPractices - compare.bestPractices,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
async function runEnvComparison(localPort, compareUrl, runs = 1) {
|
|
17
|
+
const localUrl = `http://127.0.0.1:${localPort}/`;
|
|
18
|
+
console.log(`\n [compare] Running env comparison: local vs ${compareUrl}`);
|
|
19
|
+
const [localResult, compareResult] = await Promise.all([
|
|
20
|
+
(0, lighthouse_js_1.runLighthouseOnUrl)(localUrl, runs),
|
|
21
|
+
(0, lighthouse_js_1.runLighthouseOnUrl)(compareUrl, runs),
|
|
22
|
+
]);
|
|
23
|
+
return {
|
|
24
|
+
localUrl,
|
|
25
|
+
compareUrl,
|
|
26
|
+
local: localResult.scores,
|
|
27
|
+
compare: compareResult.scores,
|
|
28
|
+
delta: scoreDelta(localResult.scores, compareResult.scores),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function printEnvComparison(result) {
|
|
32
|
+
console.log("\n Environment comparison:");
|
|
33
|
+
console.log(` Local: ${result.localUrl}`);
|
|
34
|
+
console.log(` Compare: ${result.compareUrl}`);
|
|
35
|
+
if (!result.local && !result.compare) {
|
|
36
|
+
console.log(" Both environments returned no Lighthouse data.");
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const fmt = (v) => (v === null ? "—" : String(v));
|
|
40
|
+
const fmtDelta = (d) => {
|
|
41
|
+
if (d === null)
|
|
42
|
+
return "";
|
|
43
|
+
if (d > 0)
|
|
44
|
+
return ` (+${d})`;
|
|
45
|
+
if (d < 0)
|
|
46
|
+
return ` (${d})`;
|
|
47
|
+
return " (=)";
|
|
48
|
+
};
|
|
49
|
+
const d = result.delta;
|
|
50
|
+
console.log(" Metric Local Compare Delta");
|
|
51
|
+
console.log(` Performance ${fmt(result.local?.performance ?? null).padEnd(6)} ${fmt(result.compare?.performance ?? null).padEnd(8)}${fmtDelta(d?.performance ?? null)}`);
|
|
52
|
+
console.log(` Accessibility ${fmt(result.local?.accessibility ?? null).padEnd(6)} ${fmt(result.compare?.accessibility ?? null).padEnd(8)}${fmtDelta(d?.accessibility ?? null)}`);
|
|
53
|
+
console.log(` SEO ${fmt(result.local?.seo ?? null).padEnd(6)} ${fmt(result.compare?.seo ?? null).padEnd(8)}${fmtDelta(d?.seo ?? null)}`);
|
|
54
|
+
console.log(` Best Practices ${fmt(result.local?.bestPractices ?? null).padEnd(6)} ${fmt(result.compare?.bestPractices ?? null).padEnd(8)}${fmtDelta(d?.bestPractices ?? null)}`);
|
|
55
|
+
}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,102 +1,102 @@
|
|
|
1
|
-
export type FailOn = "unverified" | "bronze" | "silver" | "gold";
|
|
2
|
-
export interface Thresholds {
|
|
3
|
-
performance: number;
|
|
4
|
-
accessibility: number;
|
|
5
|
-
seo: number;
|
|
6
|
-
bestPractices: number;
|
|
7
|
-
}
|
|
8
|
-
export interface UserScenarioStep {
|
|
9
|
-
goto?: string;
|
|
10
|
-
fill?: string;
|
|
11
|
-
with?: string;
|
|
12
|
-
click?: string;
|
|
13
|
-
expect_visible?: string;
|
|
14
|
-
expect_text?: string;
|
|
15
|
-
wait?: number;
|
|
16
|
-
}
|
|
17
|
-
export interface UserScenario {
|
|
18
|
-
name: string;
|
|
19
|
-
steps: UserScenarioStep[];
|
|
20
|
-
}
|
|
21
|
-
export interface VisualDiffConfig {
|
|
22
|
-
pixelmatchThreshold: number;
|
|
23
|
-
warnThreshold: number;
|
|
24
|
-
rollbackThreshold: number;
|
|
25
|
-
ignoreSelectors: string[];
|
|
26
|
-
disableAnimations: boolean;
|
|
27
|
-
}
|
|
28
|
-
export interface LaxyConfig {
|
|
29
|
-
framework: string;
|
|
30
|
-
build_command: string;
|
|
31
|
-
dev_command: string;
|
|
32
|
-
package_manager: string;
|
|
33
|
-
port: number;
|
|
34
|
-
build_timeout: number;
|
|
35
|
-
dev_timeout: number;
|
|
36
|
-
lighthouse_runs: number;
|
|
37
|
-
thresholds: Thresholds;
|
|
38
|
-
fail_on: FailOn;
|
|
39
|
-
scenarios?: UserScenario[];
|
|
40
|
-
crawl: boolean;
|
|
41
|
-
max_crawl_depth: number;
|
|
42
|
-
max_crawl_pages: number;
|
|
43
|
-
browsers: string[];
|
|
44
|
-
/** Explicit list of routes to audit with Lighthouse (e.g. ["/", "/about", "/pricing"]). */
|
|
45
|
-
lighthouse_routes?: string[];
|
|
46
|
-
/** Extra routes to audit even if the crawler cannot discover them (e.g. SPA router.push routes). */
|
|
47
|
-
extra_routes?: string[];
|
|
48
|
-
/** Maximum number of crawl-discovered routes to run Lighthouse on. Default: 5. */
|
|
49
|
-
max_lighthouse_routes: number;
|
|
50
|
-
visual_diff: VisualDiffConfig;
|
|
51
|
-
/** Run TypeScript type check (tsc --noEmit). Default: false. */
|
|
52
|
-
typecheck: boolean;
|
|
53
|
-
/** Run secret/credential leak scan. Default: false. */
|
|
54
|
-
secret_scan: boolean;
|
|
55
|
-
/** Paths to ignore during secret scan. */
|
|
56
|
-
secret_scan_ignore_paths: string[];
|
|
57
|
-
/** Run bundle size analysis. Default: false. */
|
|
58
|
-
bundle_size: boolean;
|
|
59
|
-
/** Run outdated dependency check. Default: false. */
|
|
60
|
-
outdated_check: boolean;
|
|
61
|
-
/** Run deep accessibility audit (axe-core). Default: false. */
|
|
62
|
-
a11y_deep: boolean;
|
|
63
|
-
/** Run deep SEO audit. Default: false. */
|
|
64
|
-
seo_deep: boolean;
|
|
65
|
-
/** Run Core Web Vitals budget check. Default: false. */
|
|
66
|
-
vitals_budget: boolean;
|
|
67
|
-
}
|
|
68
|
-
export declare class ConfigParseError extends Error {
|
|
69
|
-
constructor(msg: string);
|
|
70
|
-
}
|
|
71
|
-
export interface TeamThresholdsConfig {
|
|
72
|
-
performance: number;
|
|
73
|
-
accessibility: number;
|
|
74
|
-
seo: number;
|
|
75
|
-
best_practices: number;
|
|
76
|
-
fail_on: FailOn;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* 로그인된 CLI 토큰으로 팀 공통 임계값을 서버에서 가져온다.
|
|
80
|
-
* 토큰 없음 / 팀 없음 / 네트워크 오류 시 null 반환 (graceful degradation).
|
|
81
|
-
*/
|
|
82
|
-
export declare function fetchTeamThresholds(): Promise<TeamThresholdsConfig | null>;
|
|
83
|
-
export interface LoadConfigOptions {
|
|
84
|
-
dir: string;
|
|
85
|
-
configPath?: string;
|
|
86
|
-
cliFlags?: {
|
|
87
|
-
failOn?: FailOn;
|
|
88
|
-
skipLighthouse?: boolean;
|
|
89
|
-
typecheck?: boolean;
|
|
90
|
-
secretScan?: boolean;
|
|
91
|
-
bundleSize?: boolean;
|
|
92
|
-
outdatedCheck?: boolean;
|
|
93
|
-
a11yDeep?: boolean;
|
|
94
|
-
seoDeep?: boolean;
|
|
95
|
-
vitalsBudget?: boolean;
|
|
96
|
-
};
|
|
97
|
-
ciMode: boolean;
|
|
98
|
-
teamThresholds?: TeamThresholdsConfig | null;
|
|
99
|
-
}
|
|
100
|
-
export declare function loadConfig(options: LoadConfigOptions): LaxyConfig & {
|
|
101
|
-
ciMode: boolean;
|
|
102
|
-
};
|
|
1
|
+
export type FailOn = "unverified" | "bronze" | "silver" | "gold";
|
|
2
|
+
export interface Thresholds {
|
|
3
|
+
performance: number;
|
|
4
|
+
accessibility: number;
|
|
5
|
+
seo: number;
|
|
6
|
+
bestPractices: number;
|
|
7
|
+
}
|
|
8
|
+
export interface UserScenarioStep {
|
|
9
|
+
goto?: string;
|
|
10
|
+
fill?: string;
|
|
11
|
+
with?: string;
|
|
12
|
+
click?: string;
|
|
13
|
+
expect_visible?: string;
|
|
14
|
+
expect_text?: string;
|
|
15
|
+
wait?: number;
|
|
16
|
+
}
|
|
17
|
+
export interface UserScenario {
|
|
18
|
+
name: string;
|
|
19
|
+
steps: UserScenarioStep[];
|
|
20
|
+
}
|
|
21
|
+
export interface VisualDiffConfig {
|
|
22
|
+
pixelmatchThreshold: number;
|
|
23
|
+
warnThreshold: number;
|
|
24
|
+
rollbackThreshold: number;
|
|
25
|
+
ignoreSelectors: string[];
|
|
26
|
+
disableAnimations: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface LaxyConfig {
|
|
29
|
+
framework: string;
|
|
30
|
+
build_command: string;
|
|
31
|
+
dev_command: string;
|
|
32
|
+
package_manager: string;
|
|
33
|
+
port: number;
|
|
34
|
+
build_timeout: number;
|
|
35
|
+
dev_timeout: number;
|
|
36
|
+
lighthouse_runs: number;
|
|
37
|
+
thresholds: Thresholds;
|
|
38
|
+
fail_on: FailOn;
|
|
39
|
+
scenarios?: UserScenario[];
|
|
40
|
+
crawl: boolean;
|
|
41
|
+
max_crawl_depth: number;
|
|
42
|
+
max_crawl_pages: number;
|
|
43
|
+
browsers: string[];
|
|
44
|
+
/** Explicit list of routes to audit with Lighthouse (e.g. ["/", "/about", "/pricing"]). */
|
|
45
|
+
lighthouse_routes?: string[];
|
|
46
|
+
/** Extra routes to audit even if the crawler cannot discover them (e.g. SPA router.push routes). */
|
|
47
|
+
extra_routes?: string[];
|
|
48
|
+
/** Maximum number of crawl-discovered routes to run Lighthouse on. Default: 5. */
|
|
49
|
+
max_lighthouse_routes: number;
|
|
50
|
+
visual_diff: VisualDiffConfig;
|
|
51
|
+
/** Run TypeScript type check (tsc --noEmit). Default: false. */
|
|
52
|
+
typecheck: boolean;
|
|
53
|
+
/** Run secret/credential leak scan. Default: false. */
|
|
54
|
+
secret_scan: boolean;
|
|
55
|
+
/** Paths to ignore during secret scan. */
|
|
56
|
+
secret_scan_ignore_paths: string[];
|
|
57
|
+
/** Run bundle size analysis. Default: false. */
|
|
58
|
+
bundle_size: boolean;
|
|
59
|
+
/** Run outdated dependency check. Default: false. */
|
|
60
|
+
outdated_check: boolean;
|
|
61
|
+
/** Run deep accessibility audit (axe-core). Default: false. */
|
|
62
|
+
a11y_deep: boolean;
|
|
63
|
+
/** Run deep SEO audit. Default: false. */
|
|
64
|
+
seo_deep: boolean;
|
|
65
|
+
/** Run Core Web Vitals budget check. Default: false. */
|
|
66
|
+
vitals_budget: boolean;
|
|
67
|
+
}
|
|
68
|
+
export declare class ConfigParseError extends Error {
|
|
69
|
+
constructor(msg: string);
|
|
70
|
+
}
|
|
71
|
+
export interface TeamThresholdsConfig {
|
|
72
|
+
performance: number;
|
|
73
|
+
accessibility: number;
|
|
74
|
+
seo: number;
|
|
75
|
+
best_practices: number;
|
|
76
|
+
fail_on: FailOn;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* 로그인된 CLI 토큰으로 팀 공통 임계값을 서버에서 가져온다.
|
|
80
|
+
* 토큰 없음 / 팀 없음 / 네트워크 오류 시 null 반환 (graceful degradation).
|
|
81
|
+
*/
|
|
82
|
+
export declare function fetchTeamThresholds(): Promise<TeamThresholdsConfig | null>;
|
|
83
|
+
export interface LoadConfigOptions {
|
|
84
|
+
dir: string;
|
|
85
|
+
configPath?: string;
|
|
86
|
+
cliFlags?: {
|
|
87
|
+
failOn?: FailOn;
|
|
88
|
+
skipLighthouse?: boolean;
|
|
89
|
+
typecheck?: boolean;
|
|
90
|
+
secretScan?: boolean;
|
|
91
|
+
bundleSize?: boolean;
|
|
92
|
+
outdatedCheck?: boolean;
|
|
93
|
+
a11yDeep?: boolean;
|
|
94
|
+
seoDeep?: boolean;
|
|
95
|
+
vitalsBudget?: boolean;
|
|
96
|
+
};
|
|
97
|
+
ciMode: boolean;
|
|
98
|
+
teamThresholds?: TeamThresholdsConfig | null;
|
|
99
|
+
}
|
|
100
|
+
export declare function loadConfig(options: LoadConfigOptions): LaxyConfig & {
|
|
101
|
+
ciMode: boolean;
|
|
102
|
+
};
|