@holmdigital/engine 1.4.11 → 2.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.
@@ -1,36 +1,23 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  PseudoAutomationEngine,
4
- RegulatoryScanner
5
- } from "../chunk-WZSPSYDS.mjs";
4
+ RegulatoryScanner,
5
+ generateBadgeMarkdown,
6
+ generateBadgeUrl,
7
+ generateStatement,
8
+ generateStatementContent
9
+ } from "../chunk-ZO2XNHHT.mjs";
6
10
  import {
7
11
  getCurrentLang,
8
12
  setLanguage,
9
13
  t
10
- } from "../chunk-BKI2FFUX.mjs";
14
+ } from "../chunk-32WU5BD6.mjs";
11
15
 
12
16
  // src/cli/index.ts
13
17
  import { Command } from "commander";
14
18
  import chalk from "chalk";
15
19
  import ora from "ora";
16
20
 
17
- // src/reporting/badge-generator.ts
18
- var BADGE_COLOR = "00703C";
19
- var BADGE_BASE_URL = "https://img.shields.io/badge/HolmDigital_Engine";
20
- function generateBadgeUrl(score) {
21
- if (score !== 100) {
22
- return null;
23
- }
24
- return `${BADGE_BASE_URL}-100%25-${BADGE_COLOR}?style=flat-square`;
25
- }
26
- function generateBadgeMarkdown(score) {
27
- const url = generateBadgeUrl(score);
28
- if (!url) {
29
- return null;
30
- }
31
- return `![Accessibility Status: 100% Compliant](${url})`;
32
- }
33
-
34
21
  // src/reporting/html-template.ts
35
22
  function generateReportHTML(result) {
36
23
  const criticalCount = result.stats.critical;
@@ -152,6 +139,37 @@ function generateReportHTML(result) {
152
139
  .badge-high { background: #fffbeb; color: #d97706; border: 1px solid #fde68a; }
153
140
  .badge-medium { background: #fefce8; color: #ca8a04; border: 1px solid #fef08a; }
154
141
  .badge-low { background: #f8fafc; color: #475569; border: 1px solid #e2e8f0; }
142
+ .badge-wad { background: #eff6ff; color: #1d4ed8; border: 1px solid #bfdbfe; margin-left: 0.5rem; }
143
+ .badge-eaa { background: #faf5ff; color: #7c3aed; border: 1px solid #ddd6fe; margin-left: 0.5rem; }
144
+ .legal-summary {
145
+ background: linear-gradient(135deg, #eff6ff 0%, #faf5ff 100%);
146
+ border: 1px solid #c7d2fe;
147
+ border-radius: 12px;
148
+ padding: 1.5rem;
149
+ margin-bottom: 2rem;
150
+ }
151
+ .legal-summary-title {
152
+ font-size: 1rem;
153
+ font-weight: 600;
154
+ color: #3730a3;
155
+ margin-bottom: 1rem;
156
+ }
157
+ .legal-grid {
158
+ display: grid;
159
+ grid-template-columns: repeat(3, 1fr);
160
+ gap: 1rem;
161
+ }
162
+ .legal-stat {
163
+ text-align: center;
164
+ }
165
+ .legal-stat-value {
166
+ font-size: 1.5rem;
167
+ font-weight: 700;
168
+ }
169
+ .legal-stat-label {
170
+ font-size: 0.75rem;
171
+ color: #64748b;
172
+ }
155
173
 
156
174
  .violation-meta {
157
175
  font-size: 0.875rem;
@@ -220,6 +238,26 @@ function generateReportHTML(result) {
220
238
  </div>
221
239
  </div>
222
240
 
241
+ ${result.legalSummary ? `
242
+ <div class="legal-summary">
243
+ <div class="legal-summary-title">\u{1F1EA}\u{1F1FA} EU Legal Framework Impact</div>
244
+ <div class="legal-grid">
245
+ <div class="legal-stat">
246
+ <div class="legal-stat-value" style="color: #1d4ed8;">${result.legalSummary.wadApplicable}</div>
247
+ <div class="legal-stat-label">WAD (Public Sector) Violations</div>
248
+ </div>
249
+ <div class="legal-stat">
250
+ <div class="legal-stat-value" style="color: #7c3aed;">${result.legalSummary.eaaApplicable}</div>
251
+ <div class="legal-stat-label">EAA (Private Sector) Violations</div>
252
+ </div>
253
+ <div class="legal-stat">
254
+ <div class="legal-stat-value" style="color: #dc2626;">${result.legalSummary.eaaDeadlineViolations}</div>
255
+ <div class="legal-stat-label">EAA 2025 Deadline Issues</div>
256
+ </div>
257
+ </div>
258
+ </div>
259
+ ` : ""}
260
+
223
261
  <div class="section-title">${t("report.detailed_violations")}</div>
224
262
 
225
263
  ${[...result.reports].sort((a, b) => {
@@ -233,11 +271,16 @@ function generateReportHTML(result) {
233
271
  <div class="violation-card">
234
272
  <div class="violation-header">
235
273
  <div class="violation-title">${report.ruleId}</div>
236
- <span class="badge ${riskClass}">${report.holmdigitalInsight.diggRisk}</span>
274
+ <div>
275
+ <span class="badge ${riskClass}">${report.holmdigitalInsight.diggRisk}</span>
276
+ ${report.legalContext?.appliesTo?.includes("WAD") ? '<span class="badge badge-wad">WAD</span>' : ""}
277
+ ${report.legalContext?.appliesTo?.includes("EAA") ? '<span class="badge badge-eaa">EAA</span>' : ""}
278
+ </div>
237
279
  </div>
238
280
  <div class="violation-meta">
239
281
  WCAG ${report.wcagCriteria} \u2022 EN 301 549 ${report.en301549Criteria}
240
282
  ${report.dosLagenReference ? `\u2022 ${report.dosLagenReference}` : ""}
283
+ ${report.legalContext?.eaaDeadline ? `<br/><strong>\u26A0\uFE0F EAA Deadline:</strong> ${report.legalContext.eaaDeadline}` : ""}
241
284
  </div>
242
285
  <div style="font-size: 0.95rem; color: #334155; line-height: 1.5;">
243
286
  ${report.holmdigitalInsight.swedishInterpretation}
@@ -370,6 +413,7 @@ async function sendToCloud(config, result) {
370
413
  }
371
414
 
372
415
  // src/cli/index.ts
416
+ import { cosmiconfig } from "cosmiconfig";
373
417
  function isValidUrl(urlString) {
374
418
  try {
375
419
  const url = new URL(urlString);
@@ -380,22 +424,46 @@ function isValidUrl(urlString) {
380
424
  }
381
425
  var program = new Command();
382
426
  program.name("hd-a11y-scan").description("HolmDigital Regulatory Scanner").version("0.1.0");
383
- program.argument("<url>", "URL to scan").option("--lang <code>", "Language code (en, sv)", "en").option("--ci", "Run in CI/CD mode (exit code 1 on critical failures)").option("--generate-tests", "Generate Pseudo-Automation tests").option("--json", "Output as JSON").option("--pdf <path>", "Generate PDF report to path").option("--viewport <size>", 'Set viewport (e.g. "mobile", "desktop", "1024x768")').option("--threshold <level>", "Severity threshold for compliance (critical, high, medium, low)", "high").option("--api-key <key>", "API key for HolmDigital Cloud authentication").option("--cloud-url <url>", "Cloud API URL", "https://cloud.holmdigital.se").option("--invalid-https-cert", "Allow scanning on pages with invalid https certificate").action(async (url, options) => {
427
+ program.argument("<url>", "URL to scan").option("--lang <code>", "Language code (en, sv)").option("--ci", "Run in CI/CD mode (exit code 1 on critical failures)").option("--generate-tests", "Generate Pseudo-Automation tests").option("--json", "Output as JSON").option("--junit <path>", "Generate JUnit XML report").option("--pdf <path>", "Generate PDF report to path").option("--statement <path>", "Generate accessibility statement HTML to path").option("--format <type>", "Output format for statement (html, md)", "html").option("--viewport <size>", 'Set viewport (e.g. "mobile", "desktop", "1024x768")').option("--threshold <level>", "Severity threshold (critical, high, medium, low)").option("--api-key <key>", "API key for HolmDigital Cloud").option("--cloud-url <url>", "Cloud API URL").option("--invalid-https-cert", "Allow scanning on pages with invalid https certificate").option("--email <email>", "Contact email for accessibility statement").option("--phone <number>", "Contact phone number for accessibility statement").option("--org <name>", "Organization name for accessibility statement").option("--response-time <time>", "Expected response time for accessibility statement").option("--country <code>", "Country code for accessibility statement enforcement body").option("--publish-date <date>", "Publish date for the website (YYYY-MM-DD)").action(async (url, cliOptions) => {
428
+ const explorer = cosmiconfig("a11y");
429
+ const configResult = await explorer.search();
430
+ const fileConfig = configResult ? configResult.config : {};
431
+ const options = {
432
+ lang: cliOptions.lang || fileConfig.lang || "en",
433
+ ci: cliOptions.ci ?? fileConfig.ci ?? false,
434
+ generateTests: cliOptions.generateTests ?? fileConfig.generateTests ?? false,
435
+ json: cliOptions.json ?? fileConfig.json ?? false,
436
+ junit: cliOptions.junit || fileConfig.junit,
437
+ pdf: cliOptions.pdf || fileConfig.pdf,
438
+ statement: cliOptions.statement || fileConfig.statement,
439
+ format: cliOptions.format || fileConfig.format || "html",
440
+ viewport: cliOptions.viewport || fileConfig.viewport,
441
+ // Handled specifically below
442
+ threshold: cliOptions.threshold || fileConfig.threshold || "high",
443
+ apiKey: cliOptions.apiKey || fileConfig.apiKey,
444
+ cloudUrl: cliOptions.cloudUrl || fileConfig.cloudUrl || "https://cloud.holmdigital.se",
445
+ invalidHttpsCert: cliOptions.invalidHttpsCert ?? fileConfig.invalidHttpsCert ?? false,
446
+ // Metadata for accessibility statement
447
+ email: cliOptions.email || fileConfig.email,
448
+ phone: cliOptions.phone || fileConfig.phone,
449
+ org: cliOptions.org || fileConfig.org,
450
+ responseTime: cliOptions.responseTime || fileConfig.responseTime,
451
+ country: cliOptions.country || fileConfig.country,
452
+ publishDate: cliOptions.publishDate || fileConfig.publishDate
453
+ };
384
454
  setLanguage(options.lang);
385
455
  if (!isValidUrl(url)) {
386
- console.error(chalk.red(`Error: Invalid URL format '${url}'`));
387
- console.error(chalk.gray("URL must start with http:// or https://"));
388
- process.exit(1);
389
456
  }
390
457
  if (!options.json) {
391
458
  console.log(chalk.blue.bold(t("cli.title")));
459
+ if (configResult) console.log(chalk.gray(`Loaded config from ${configResult.filepath}`));
392
460
  console.log(chalk.gray(t("cli.scanning", { url })));
393
461
  }
394
462
  const spinner = !options.json ? ora(t("cli.initializing")).start() : null;
395
463
  let scanner;
396
464
  try {
397
465
  let viewport = { width: 1280, height: 720 };
398
- if (options.viewport) {
466
+ if (options.viewport && typeof options.viewport === "string") {
399
467
  if (options.viewport === "mobile") viewport = { width: 375, height: 667 };
400
468
  else if (options.viewport === "desktop") viewport = { width: 1920, height: 1080 };
401
469
  else if (options.viewport === "tablet") viewport = { width: 768, height: 1024 };
@@ -403,6 +471,8 @@ program.argument("<url>", "URL to scan").option("--lang <code>", "Language code
403
471
  const [w, h] = options.viewport.split("x").map(Number);
404
472
  if (w && h) viewport = { width: w, height: h };
405
473
  }
474
+ } else if (options.viewport && typeof options.viewport === "object") {
475
+ viewport = options.viewport;
406
476
  }
407
477
  scanner = new RegulatoryScanner({
408
478
  url,
@@ -422,15 +492,30 @@ program.argument("<url>", "URL to scan").option("--lang <code>", "Language code
422
492
  await generatePDF(html, options.pdf);
423
493
  if (spinner) spinner.succeed(t("cli.pdf_saved", { path: options.pdf }));
424
494
  }
495
+ if (options.statement) {
496
+ if (spinner) spinner.start(t("cli.generating_statement", { path: options.statement }));
497
+ const metadata = {
498
+ contactEmail: options.email,
499
+ phoneNumber: options.phone,
500
+ organizationName: options.org,
501
+ responseTime: options.responseTime,
502
+ country: options.country,
503
+ publishDate: options.publishDate
504
+ };
505
+ if (options.statement.toLowerCase().endsWith(".pdf")) {
506
+ const htmlContent = await generateStatementContent(result, options.lang, "html", metadata);
507
+ await generatePDF(htmlContent, options.statement);
508
+ } else {
509
+ await generateStatement(result, options.statement, options.lang, options.format, metadata);
510
+ }
511
+ if (spinner) spinner.succeed(t("cli.statement_saved", { path: options.statement }));
512
+ }
425
513
  if (options.json) {
426
514
  console.log(JSON.stringify(result, null, 2));
427
515
  } else {
428
- console.log(chalk.bold(t("cli.score", { score: result.score })));
429
- const statusColor = result.complianceStatus === "PASS" ? chalk.green : chalk.red;
430
- console.log(statusColor.bold(t("cli.status", { status: result.complianceStatus })));
431
- if (result.complianceStatus === "FAIL") {
432
- console.log(chalk.red(t("cli.not_compliant")));
433
- }
516
+ console.log("\n");
517
+ const scoreColor = result.score >= 90 ? chalk.green : result.score >= 70 ? chalk.yellow : chalk.red;
518
+ console.log(chalk.bold(`[ Compliance Score: ${scoreColor(result.score + "/100")} ] ${result.score >= 90 ? "\u{1F7E2}" : result.score >= 70 ? "\u{1F7E1}" : "\u{1F534}"}`));
434
519
  if (result.score === 100) {
435
520
  const badge = generateBadgeMarkdown(result.score);
436
521
  if (badge) {
@@ -439,46 +524,87 @@ program.argument("<url>", "URL to scan").option("--lang <code>", "Language code
439
524
  }
440
525
  }
441
526
  console.log(chalk.gray("----------------------------------------"));
442
- if (options.viewport) {
443
- console.log(chalk.blue(t("cli.viewport", { width: viewport.width, height: viewport.height })));
527
+ const calculateCategoryScore = (filterFn) => {
528
+ const failures = result.reports.filter(filterFn).length;
529
+ return Math.max(10, 100 - failures * 20);
530
+ };
531
+ const cats = [
532
+ {
533
+ name: "HTML Structure",
534
+ score: calculateCategoryScore((r) => ["1.3.1", "4.1.1", "4.1.2"].some((c) => r.wcagCriteria.includes(c))),
535
+ critical: false
536
+ },
537
+ {
538
+ name: "Keyboard Nav ",
539
+ score: calculateCategoryScore((r) => ["2.1.1", "2.1.2", "2.4.3", "2.4.7"].some((c) => r.wcagCriteria.includes(c))),
540
+ critical: result.reports.some((r) => ["2.1.1", "2.1.2"].some((c) => r.wcagCriteria.includes(c)) && r.holmdigitalInsight.diggRisk === "critical")
541
+ },
542
+ {
543
+ name: "Contrast ",
544
+ score: calculateCategoryScore((r) => r.wcagCriteria.includes("1.4.3") || r.ruleId === "color-contrast"),
545
+ critical: false
546
+ }
547
+ ];
548
+ cats.forEach((cat) => {
549
+ const width = 10;
550
+ const filled = Math.round(cat.score / 100 * width);
551
+ const empty = width - filled;
552
+ const bar = "\u2588".repeat(filled) + "\u2591".repeat(empty);
553
+ let statusText = `${cat.score}%`;
554
+ if (cat.critical) statusText += chalk.red(" (CRITICAL FAIL)");
555
+ else if (cat.score < 100) statusText += chalk.gray(" (Minor issues)");
556
+ console.log(`${cat.name} [${cat.score >= 80 ? chalk.green(bar) : cat.score >= 50 ? chalk.yellow(bar) : chalk.red(bar)}] ${statusText}`);
557
+ });
558
+ console.log(chalk.gray("----------------------------------------"));
559
+ let legalRisk = "LOW";
560
+ let riskReason = "No critical violations found.";
561
+ let riskIcon = "\u2705";
562
+ if (result.legalSummary && result.legalSummary.eaaDeadlineViolations > 0) {
563
+ legalRisk = "HIGH";
564
+ const hasKeyboardIssues = result.reports.some((r) => ["2.1.1", "2.1.2"].some((c) => r.wcagCriteria.includes(c)));
565
+ const hasContrastIssues = result.reports.some((r) => r.wcagCriteria.includes("1.4.3") || r.ruleId === "color-contrast");
566
+ const hasStructureIssues = result.reports.some((r) => r.wcagCriteria.includes("1.3.1"));
567
+ if (hasKeyboardIssues) riskReason = "Keyboard accessibility blocks EAA compliance";
568
+ else if (hasContrastIssues) riskReason = "Contrast issues block EAA compliance";
569
+ else if (hasStructureIssues) riskReason = "HTML structure issues block EAA compliance";
570
+ else riskReason = `${result.legalSummary.eaaDeadlineViolations} EAA deadline violation(s) found`;
571
+ riskIcon = "\u2696\uFE0F ";
572
+ } else if (result.stats.critical > 0) {
573
+ legalRisk = "MEDIUM";
574
+ riskReason = "Critical violations found.";
575
+ riskIcon = "\u26A0\uFE0F ";
444
576
  }
577
+ console.log(`${riskIcon} Legal Risk: ${legalRisk === "HIGH" ? chalk.red.bold(legalRisk) : legalRisk === "MEDIUM" ? chalk.yellow.bold(legalRisk) : chalk.green(legalRisk)} (${chalk.white(riskReason)})`);
578
+ console.log("\n");
445
579
  if (result.htmlValidation && !result.htmlValidation.valid) {
446
- console.log(chalk.red.bold("\n\u26A0\uFE0F Structural HTML Issues Detected"));
580
+ console.log(chalk.red.bold("\u26A0\uFE0F Structural HTML Issues Detected"));
447
581
  console.log(chalk.yellow(" These issues may affect accessibility tool accuracy (e.g. contrast calculations)\n"));
448
582
  result.htmlValidation.errors.forEach((error) => {
449
583
  console.log(chalk.red(` [${error.rule}] ${error.message}`));
450
- if (error.selector) console.log(chalk.gray(` ${error.selector}`));
451
- console.log(chalk.gray(` Line: ${error.line}, Col: ${error.column}
452
- `));
453
584
  });
585
+ console.log(chalk.gray(" ... and more (run with --json for full details)"));
454
586
  console.log(chalk.gray("----------------------------------------"));
455
587
  }
456
- result.reports.forEach((report) => {
588
+ if (result.reports.length > 0) {
589
+ console.log(chalk.bold("Top Violations:"));
590
+ }
591
+ result.reports.forEach((report, i) => {
592
+ if (i > 5) return;
457
593
  const color = report.holmdigitalInsight.diggRisk === "critical" ? chalk.red : chalk.yellow;
458
594
  console.log(color.bold(`
459
595
  [${report.holmdigitalInsight.diggRisk.toUpperCase()}] ${report.ruleId}`));
460
596
  console.log(chalk.white(`WCAG: ${report.wcagCriteria} | EN 301 549: ${report.en301549Criteria}`));
461
- console.log(chalk.gray(`Legitimitet: ${report.dosLagenReference}`));
462
597
  if (report.remediation.component) {
463
- console.log(chalk.green(t("cli.prescriptive_fix")));
464
- console.log(t("cli.use_component", { component: chalk.bold(report.remediation.component) }));
465
- }
466
- if (report.failingNodes && report.failingNodes.length > 0) {
467
- console.log(chalk.gray("\nAffected Elements:"));
468
- report.failingNodes.forEach((node, index) => {
469
- if (index < 5) {
470
- console.log(chalk.cyan(`\u279C ${node.target}`));
471
- console.log(chalk.gray(` ${node.html}`));
472
- }
473
- });
474
- if (report.failingNodes.length > 5) {
475
- console.log(chalk.gray(` ...and ${report.failingNodes.length - 5} more`));
476
- }
598
+ console.log(chalk.green(`Fix: Use component <${report.remediation.component} />`));
477
599
  }
478
600
  });
601
+ if (result.reports.length > 5) {
602
+ console.log(chalk.gray(`
603
+ ... and ${result.reports.length - 5} more issues.`));
604
+ }
479
605
  console.log(chalk.gray("\n----------------------------------------"));
480
- console.log(`Critical: ${result.stats.critical} | High: ${result.stats.high} | Medium: ${result.stats.medium} | Total: ${result.stats.total}
481
- `);
606
+ console.log(`Scan Date: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}`);
607
+ console.log("\n");
482
608
  if (options.generateTests) {
483
609
  console.log(chalk.magenta.bold(t("cli.pseudo_tests")));
484
610
  const automation = new PseudoAutomationEngine();
@@ -490,6 +616,18 @@ program.argument("<url>", "URL to scan").option("--lang <code>", "Language code
490
616
  });
491
617
  }
492
618
  }
619
+ if (options.ci && result.reports.length > 0) {
620
+ const { generateGitHubActionsAnnotations } = await import("../github-actions-CGWJSLMB.mjs");
621
+ generateGitHubActionsAnnotations(result.reports);
622
+ }
623
+ if (options.junit) {
624
+ const { generateJUnitXML } = await import("../junit-generator-FK3GE5E4.mjs");
625
+ const fs = await import("fs/promises");
626
+ const xml = generateJUnitXML(result.reports, url, result.metadata.scanDuration);
627
+ await fs.writeFile(options.junit, xml);
628
+ if (spinner) spinner.succeed(t("cli.junit_saved", { path: options.junit }));
629
+ else if (!options.json) console.log(chalk.green(`\u2713 JUnit report saved to ${options.junit}`));
630
+ }
493
631
  if (options.ci && result.stats.critical > 0) {
494
632
  if (!options.json) console.error(chalk.red(t("cli.critical_failure")));
495
633
  process.exit(1);
@@ -0,0 +1,24 @@
1
+ // src/reporting/github-actions.ts
2
+ function generateGitHubActionsAnnotations(reports) {
3
+ reports.forEach((report) => {
4
+ let level = "warning";
5
+ if (report.holmdigitalInsight.diggRisk === "critical") {
6
+ level = "error";
7
+ }
8
+ const title = `[${report.ruleId}] ${report.wcagCriteria}`;
9
+ const message = `${report.holmdigitalInsight.reasoning}
10
+
11
+ Legitimacy: ${report.dosLagenReference}
12
+ Fix: ${report.remediation.component ? `Use <${report.remediation.component} />` : "Manual remediation required"}`;
13
+ if (report.failingNodes && report.failingNodes.length > 0) {
14
+ report.failingNodes.forEach((node) => {
15
+ console.log(`::${level} title=${title}::${message} (Target: ${node.target})`);
16
+ });
17
+ } else {
18
+ console.log(`::${level} title=${title}::${message}`);
19
+ }
20
+ });
21
+ }
22
+ export {
23
+ generateGitHubActionsAnnotations
24
+ };
@@ -2,7 +2,7 @@ import {
2
2
  getCurrentLang,
3
3
  setLanguage,
4
4
  t
5
- } from "./chunk-BKI2FFUX.mjs";
5
+ } from "./chunk-32WU5BD6.mjs";
6
6
  export {
7
7
  getCurrentLang,
8
8
  setLanguage,
package/dist/index.d.mts CHANGED
@@ -49,6 +49,11 @@ interface ScanResult {
49
49
  score: number;
50
50
  complianceStatus: 'PASS' | 'FAIL';
51
51
  htmlValidation?: ValidationResult;
52
+ legalSummary?: {
53
+ wadApplicable: number;
54
+ eaaApplicable: number;
55
+ eaaDeadlineViolations: number;
56
+ };
52
57
  }
53
58
  declare class RegulatoryScanner {
54
59
  private browser;
@@ -107,6 +112,8 @@ var cli = {
107
112
  pdf_saved: "PDF Report saved to {path}",
108
113
  scan_failed: "Scan failed",
109
114
  critical_failure: "\nCI/CD Failure: Critical regulatory violations found.",
115
+ generating_statement: "Generating Accessibility Statement...",
116
+ statement_saved: "Accessibility Statement saved to {path}",
110
117
  score: "\nCompliance Score: {score}/100",
111
118
  status: "Compliance Status: {status}",
112
119
  not_compliant: " (Not compliant with legal requirements)",
@@ -114,7 +121,8 @@ var cli = {
114
121
  prescriptive_fix: "\n💡 Prescriptive Fix:",
115
122
  use_component: "Use component: {component}",
116
123
  pseudo_tests: "\n🧬 Generating Pseudo-Automation Tests...\n",
117
- test_for: "Test for {ruleId}:"
124
+ test_for: "Test for {ruleId}:",
125
+ junit_saved: "JUnit XML report saved to {path}"
118
126
  };
119
127
  var report = {
120
128
  title: "Accessibility Report - {url}",
@@ -144,4 +152,15 @@ declare function setLanguage(lang: string): void;
144
152
  declare function t(key: LocaleKey, params?: Record<string, string | number>): string;
145
153
  declare function getCurrentLang(): string;
146
154
 
147
- export { PseudoAutomationEngine, RegulatoryScanner, type ScanMetadata, type ScanResult, type ScannerOptions, VirtualDOMBuilder, type VirtualDOMConfig, type VirtualNode, getCurrentLang, setLanguage, t };
155
+ interface StatementMetadata {
156
+ organizationName?: string;
157
+ contactEmail?: string;
158
+ phoneNumber?: string;
159
+ responseTime?: string;
160
+ country?: string;
161
+ publishDate?: string | Date;
162
+ }
163
+ declare function generateStatementContent(result: ScanResult, lang?: string, format?: 'html' | 'md' | 'markdown', metadata?: StatementMetadata): Promise<string>;
164
+ declare function generateStatement(result: ScanResult, outputPath: string, lang?: string, format?: 'html' | 'md' | 'markdown', metadata?: StatementMetadata): Promise<void>;
165
+
166
+ export { PseudoAutomationEngine, RegulatoryScanner, type ScanMetadata, type ScanResult, type ScannerOptions, type StatementMetadata, VirtualDOMBuilder, type VirtualDOMConfig, type VirtualNode, generateStatement, generateStatementContent, getCurrentLang, setLanguage, t };
package/dist/index.d.ts CHANGED
@@ -49,6 +49,11 @@ interface ScanResult {
49
49
  score: number;
50
50
  complianceStatus: 'PASS' | 'FAIL';
51
51
  htmlValidation?: ValidationResult;
52
+ legalSummary?: {
53
+ wadApplicable: number;
54
+ eaaApplicable: number;
55
+ eaaDeadlineViolations: number;
56
+ };
52
57
  }
53
58
  declare class RegulatoryScanner {
54
59
  private browser;
@@ -107,6 +112,8 @@ var cli = {
107
112
  pdf_saved: "PDF Report saved to {path}",
108
113
  scan_failed: "Scan failed",
109
114
  critical_failure: "\nCI/CD Failure: Critical regulatory violations found.",
115
+ generating_statement: "Generating Accessibility Statement...",
116
+ statement_saved: "Accessibility Statement saved to {path}",
110
117
  score: "\nCompliance Score: {score}/100",
111
118
  status: "Compliance Status: {status}",
112
119
  not_compliant: " (Not compliant with legal requirements)",
@@ -114,7 +121,8 @@ var cli = {
114
121
  prescriptive_fix: "\n💡 Prescriptive Fix:",
115
122
  use_component: "Use component: {component}",
116
123
  pseudo_tests: "\n🧬 Generating Pseudo-Automation Tests...\n",
117
- test_for: "Test for {ruleId}:"
124
+ test_for: "Test for {ruleId}:",
125
+ junit_saved: "JUnit XML report saved to {path}"
118
126
  };
119
127
  var report = {
120
128
  title: "Accessibility Report - {url}",
@@ -144,4 +152,15 @@ declare function setLanguage(lang: string): void;
144
152
  declare function t(key: LocaleKey, params?: Record<string, string | number>): string;
145
153
  declare function getCurrentLang(): string;
146
154
 
147
- export { PseudoAutomationEngine, RegulatoryScanner, type ScanMetadata, type ScanResult, type ScannerOptions, VirtualDOMBuilder, type VirtualDOMConfig, type VirtualNode, getCurrentLang, setLanguage, t };
155
+ interface StatementMetadata {
156
+ organizationName?: string;
157
+ contactEmail?: string;
158
+ phoneNumber?: string;
159
+ responseTime?: string;
160
+ country?: string;
161
+ publishDate?: string | Date;
162
+ }
163
+ declare function generateStatementContent(result: ScanResult, lang?: string, format?: 'html' | 'md' | 'markdown', metadata?: StatementMetadata): Promise<string>;
164
+ declare function generateStatement(result: ScanResult, outputPath: string, lang?: string, format?: 'html' | 'md' | 'markdown', metadata?: StatementMetadata): Promise<void>;
165
+
166
+ export { PseudoAutomationEngine, RegulatoryScanner, type ScanMetadata, type ScanResult, type ScannerOptions, type StatementMetadata, VirtualDOMBuilder, type VirtualDOMConfig, type VirtualNode, generateStatement, generateStatementContent, getCurrentLang, setLanguage, t };