@holmdigital/engine 1.4.9 → 1.4.12
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 +10 -3
- package/dist/{chunk-WZSPSYDS.mjs → chunk-FFTRXRZU.mjs} +3 -7
- package/dist/{chunk-BKI2FFUX.mjs → chunk-YWRTSIUX.mjs} +0 -8
- package/dist/cli/index.js +28 -3
- package/dist/cli/index.mjs +27 -2
- package/dist/{i18n-M6ATDHUS.mjs → i18n-WJLEZT5A.mjs} +1 -1
- package/dist/index.js +3 -3
- package/dist/index.mjs +2 -2
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -51,7 +51,14 @@ npx hd-a11y-scan <url> [options]
|
|
|
51
51
|
| `--generate-tests` | Generate Pseudo-Automation tests |
|
|
52
52
|
| `--invalid-https-cert` | Allow scanning sites with invalid/self-signed HTTPS certificates ⚠️ |
|
|
53
53
|
| `--api-key <key>` | API Key for HolmDigital Cloud |
|
|
54
|
-
| `--cloud-url <url>` | Custom
|
|
54
|
+
| `--cloud-url <url>` | Custom Cloud API Endpoint (default: cloud.holmdigital.se) |
|
|
55
|
+
|
|
56
|
+
### 🏆 Accessibility Badge
|
|
57
|
+
If your site achieves a **100% score**, the CLI will generate a [Shields.io](https://shields.io/) badge that you can add to your project's README:
|
|
58
|
+
|
|
59
|
+

|
|
60
|
+
|
|
61
|
+
The badge uses accessible colors (AAA compliant contrast) and is included in both the CLI output and the HTML report.
|
|
55
62
|
|
|
56
63
|
> **⚠️ Security Note:** The `--invalid-https-cert` flag should only be used in trusted environments (local dev, staging). It disables certificate validation and is not recommended for production. *(Contributed by [@FerdiStro](https://github.com/FerdiStro))*
|
|
57
64
|
|
|
@@ -71,9 +78,9 @@ npx hd-a11y-scan https://example.com --json
|
|
|
71
78
|
"url": "https://example.com",
|
|
72
79
|
"timestamp": "2026-01-13T17:05:11.749Z",
|
|
73
80
|
"metadata": {
|
|
74
|
-
"engineVersion": "1.4.
|
|
81
|
+
"engineVersion": "1.4.12",
|
|
75
82
|
"axeCoreVersion": "4.10.2",
|
|
76
|
-
"standardsVersion": "1.2.
|
|
83
|
+
"standardsVersion": "1.2.3",
|
|
77
84
|
"scanDuration": 2891,
|
|
78
85
|
"pageTitle": "Example Domain",
|
|
79
86
|
"pageLanguage": "en"
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
__require
|
|
3
|
-
} from "./chunk-BKI2FFUX.mjs";
|
|
4
|
-
|
|
5
1
|
// src/core/virtual-dom.ts
|
|
6
2
|
var VirtualDOMBuilder = class {
|
|
7
3
|
page;
|
|
@@ -93,6 +89,7 @@ var VirtualDOMBuilder = class {
|
|
|
93
89
|
};
|
|
94
90
|
|
|
95
91
|
// src/core/regulatory-scanner.ts
|
|
92
|
+
import axeCore from "axe-core";
|
|
96
93
|
import puppeteer from "puppeteer";
|
|
97
94
|
|
|
98
95
|
// src/core/html-validator.ts
|
|
@@ -250,13 +247,13 @@ var RegulatoryScanner = class {
|
|
|
250
247
|
return page;
|
|
251
248
|
}
|
|
252
249
|
async injectAxe(page) {
|
|
253
|
-
const axeSource =
|
|
250
|
+
const axeSource = axeCore.source;
|
|
254
251
|
await page.evaluate(axeSource);
|
|
255
252
|
}
|
|
256
253
|
async enrichResults(axeResults) {
|
|
257
254
|
const reports = [];
|
|
258
255
|
const { searchRulesByTags, generateRegulatoryReport } = await import("@holmdigital/standards");
|
|
259
|
-
const { getCurrentLang } = await import("./i18n-
|
|
256
|
+
const { getCurrentLang } = await import("./i18n-WJLEZT5A.mjs");
|
|
260
257
|
const lang = getCurrentLang();
|
|
261
258
|
for (const violation of axeResults.violations) {
|
|
262
259
|
let report = generateRegulatoryReport(violation.id, lang);
|
|
@@ -342,7 +339,6 @@ var RegulatoryScanner = class {
|
|
|
342
339
|
complianceStatus = stats.total > 0 ? "FAIL" : "PASS";
|
|
343
340
|
break;
|
|
344
341
|
}
|
|
345
|
-
const axeCore = __require("axe-core");
|
|
346
342
|
const metadata = {
|
|
347
343
|
engineVersion: "1.4.7",
|
|
348
344
|
axeCoreVersion: axeCore.version || "4.10.2",
|
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
-
}) : x)(function(x) {
|
|
4
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
-
});
|
|
7
|
-
|
|
8
1
|
// src/locales/en.json
|
|
9
2
|
var en_default = {
|
|
10
3
|
cli: {
|
|
@@ -280,7 +273,6 @@ function getCurrentLang() {
|
|
|
280
273
|
}
|
|
281
274
|
|
|
282
275
|
export {
|
|
283
|
-
__require,
|
|
284
276
|
setLanguage,
|
|
285
277
|
t,
|
|
286
278
|
getCurrentLang
|
package/dist/cli/index.js
CHANGED
|
@@ -358,6 +358,7 @@ var import_chalk = __toESM(require("chalk"));
|
|
|
358
358
|
var import_ora = __toESM(require("ora"));
|
|
359
359
|
|
|
360
360
|
// src/core/regulatory-scanner.ts
|
|
361
|
+
var import_axe_core = __toESM(require("axe-core"));
|
|
361
362
|
var import_puppeteer = __toESM(require("puppeteer"));
|
|
362
363
|
|
|
363
364
|
// src/core/virtual-dom.ts
|
|
@@ -605,7 +606,7 @@ var RegulatoryScanner = class {
|
|
|
605
606
|
return page;
|
|
606
607
|
}
|
|
607
608
|
async injectAxe(page) {
|
|
608
|
-
const axeSource =
|
|
609
|
+
const axeSource = import_axe_core.default.source;
|
|
609
610
|
await page.evaluate(axeSource);
|
|
610
611
|
}
|
|
611
612
|
async enrichResults(axeResults) {
|
|
@@ -697,10 +698,9 @@ var RegulatoryScanner = class {
|
|
|
697
698
|
complianceStatus = stats.total > 0 ? "FAIL" : "PASS";
|
|
698
699
|
break;
|
|
699
700
|
}
|
|
700
|
-
const axeCore = require("axe-core");
|
|
701
701
|
const metadata = {
|
|
702
702
|
engineVersion: "1.4.7",
|
|
703
|
-
axeCoreVersion:
|
|
703
|
+
axeCoreVersion: import_axe_core.default.version || "4.10.2",
|
|
704
704
|
standardsVersion: "1.2.2",
|
|
705
705
|
scanDuration,
|
|
706
706
|
pageTitle,
|
|
@@ -795,6 +795,23 @@ test('${testName}', async ({ page }) => {
|
|
|
795
795
|
}
|
|
796
796
|
};
|
|
797
797
|
|
|
798
|
+
// src/reporting/badge-generator.ts
|
|
799
|
+
var BADGE_COLOR = "00703C";
|
|
800
|
+
var BADGE_BASE_URL = "https://img.shields.io/badge/HolmDigital_Engine";
|
|
801
|
+
function generateBadgeUrl(score) {
|
|
802
|
+
if (score !== 100) {
|
|
803
|
+
return null;
|
|
804
|
+
}
|
|
805
|
+
return `${BADGE_BASE_URL}-100%25-${BADGE_COLOR}?style=flat-square`;
|
|
806
|
+
}
|
|
807
|
+
function generateBadgeMarkdown(score) {
|
|
808
|
+
const url = generateBadgeUrl(score);
|
|
809
|
+
if (!url) {
|
|
810
|
+
return null;
|
|
811
|
+
}
|
|
812
|
+
return ``;
|
|
813
|
+
}
|
|
814
|
+
|
|
798
815
|
// src/reporting/html-template.ts
|
|
799
816
|
init_i18n();
|
|
800
817
|
function generateReportHTML(result) {
|
|
@@ -958,6 +975,7 @@ function generateReportHTML(result) {
|
|
|
958
975
|
<div class="meta">
|
|
959
976
|
<div>${t("report.scan_target", { url: result.url })}</div>
|
|
960
977
|
<div>${t("report.generated", { date: formatDate(result.timestamp) })}</div>
|
|
978
|
+
${generateBadgeUrl(result.score) ? `<div style="margin-top: 0.5rem;"><img src="${generateBadgeUrl(result.score)}" alt="Accessibility Status: 100% Compliant" /></div>` : ""}
|
|
961
979
|
</div>
|
|
962
980
|
</div>
|
|
963
981
|
|
|
@@ -1198,6 +1216,13 @@ program.argument("<url>", "URL to scan").option("--lang <code>", "Language code
|
|
|
1198
1216
|
if (result.complianceStatus === "FAIL") {
|
|
1199
1217
|
console.log(import_chalk.default.red(t("cli.not_compliant")));
|
|
1200
1218
|
}
|
|
1219
|
+
if (result.score === 100) {
|
|
1220
|
+
const badge = generateBadgeMarkdown(result.score);
|
|
1221
|
+
if (badge) {
|
|
1222
|
+
console.log(import_chalk.default.green.bold("\n\u{1F3C6} Perfect Score! Here is your accessibility badge:"));
|
|
1223
|
+
console.log(import_chalk.default.white(badge));
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1201
1226
|
console.log(import_chalk.default.gray("----------------------------------------"));
|
|
1202
1227
|
if (options.viewport) {
|
|
1203
1228
|
console.log(import_chalk.default.blue(t("cli.viewport", { width: viewport.width, height: viewport.height })));
|
package/dist/cli/index.mjs
CHANGED
|
@@ -2,18 +2,35 @@
|
|
|
2
2
|
import {
|
|
3
3
|
PseudoAutomationEngine,
|
|
4
4
|
RegulatoryScanner
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-FFTRXRZU.mjs";
|
|
6
6
|
import {
|
|
7
7
|
getCurrentLang,
|
|
8
8
|
setLanguage,
|
|
9
9
|
t
|
|
10
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-YWRTSIUX.mjs";
|
|
11
11
|
|
|
12
12
|
// src/cli/index.ts
|
|
13
13
|
import { Command } from "commander";
|
|
14
14
|
import chalk from "chalk";
|
|
15
15
|
import ora from "ora";
|
|
16
16
|
|
|
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 ``;
|
|
32
|
+
}
|
|
33
|
+
|
|
17
34
|
// src/reporting/html-template.ts
|
|
18
35
|
function generateReportHTML(result) {
|
|
19
36
|
const criticalCount = result.stats.critical;
|
|
@@ -176,6 +193,7 @@ function generateReportHTML(result) {
|
|
|
176
193
|
<div class="meta">
|
|
177
194
|
<div>${t("report.scan_target", { url: result.url })}</div>
|
|
178
195
|
<div>${t("report.generated", { date: formatDate(result.timestamp) })}</div>
|
|
196
|
+
${generateBadgeUrl(result.score) ? `<div style="margin-top: 0.5rem;"><img src="${generateBadgeUrl(result.score)}" alt="Accessibility Status: 100% Compliant" /></div>` : ""}
|
|
179
197
|
</div>
|
|
180
198
|
</div>
|
|
181
199
|
|
|
@@ -413,6 +431,13 @@ program.argument("<url>", "URL to scan").option("--lang <code>", "Language code
|
|
|
413
431
|
if (result.complianceStatus === "FAIL") {
|
|
414
432
|
console.log(chalk.red(t("cli.not_compliant")));
|
|
415
433
|
}
|
|
434
|
+
if (result.score === 100) {
|
|
435
|
+
const badge = generateBadgeMarkdown(result.score);
|
|
436
|
+
if (badge) {
|
|
437
|
+
console.log(chalk.green.bold("\n\u{1F3C6} Perfect Score! Here is your accessibility badge:"));
|
|
438
|
+
console.log(chalk.white(badge));
|
|
439
|
+
}
|
|
440
|
+
}
|
|
416
441
|
console.log(chalk.gray("----------------------------------------"));
|
|
417
442
|
if (options.viewport) {
|
|
418
443
|
console.log(chalk.blue(t("cli.viewport", { width: viewport.width, height: viewport.height })));
|
package/dist/index.js
CHANGED
|
@@ -365,6 +365,7 @@ __export(index_exports, {
|
|
|
365
365
|
module.exports = __toCommonJS(index_exports);
|
|
366
366
|
|
|
367
367
|
// src/core/regulatory-scanner.ts
|
|
368
|
+
var import_axe_core = __toESM(require("axe-core"));
|
|
368
369
|
var import_puppeteer = __toESM(require("puppeteer"));
|
|
369
370
|
|
|
370
371
|
// src/core/virtual-dom.ts
|
|
@@ -612,7 +613,7 @@ var RegulatoryScanner = class {
|
|
|
612
613
|
return page;
|
|
613
614
|
}
|
|
614
615
|
async injectAxe(page) {
|
|
615
|
-
const axeSource =
|
|
616
|
+
const axeSource = import_axe_core.default.source;
|
|
616
617
|
await page.evaluate(axeSource);
|
|
617
618
|
}
|
|
618
619
|
async enrichResults(axeResults) {
|
|
@@ -704,10 +705,9 @@ var RegulatoryScanner = class {
|
|
|
704
705
|
complianceStatus = stats.total > 0 ? "FAIL" : "PASS";
|
|
705
706
|
break;
|
|
706
707
|
}
|
|
707
|
-
const axeCore = require("axe-core");
|
|
708
708
|
const metadata = {
|
|
709
709
|
engineVersion: "1.4.7",
|
|
710
|
-
axeCoreVersion:
|
|
710
|
+
axeCoreVersion: import_axe_core.default.version || "4.10.2",
|
|
711
711
|
standardsVersion: "1.2.2",
|
|
712
712
|
scanDuration,
|
|
713
713
|
pageTitle,
|
package/dist/index.mjs
CHANGED
|
@@ -2,12 +2,12 @@ import {
|
|
|
2
2
|
PseudoAutomationEngine,
|
|
3
3
|
RegulatoryScanner,
|
|
4
4
|
VirtualDOMBuilder
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-FFTRXRZU.mjs";
|
|
6
6
|
import {
|
|
7
7
|
getCurrentLang,
|
|
8
8
|
setLanguage,
|
|
9
9
|
t
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-YWRTSIUX.mjs";
|
|
11
11
|
export {
|
|
12
12
|
PseudoAutomationEngine,
|
|
13
13
|
RegulatoryScanner,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@holmdigital/engine",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.12",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -34,8 +34,9 @@
|
|
|
34
34
|
"build": "tsup src/index.ts src/cli/index.ts --format cjs,esm --dts --clean",
|
|
35
35
|
"dev": "tsup src/index.ts src/cli/index.ts --format cjs,esm --dts --watch",
|
|
36
36
|
"test": "vitest",
|
|
37
|
+
"test:ci": "vitest run",
|
|
37
38
|
"test:integration": "vitest run --config vitest.integration.config.ts",
|
|
38
|
-
"lint": "eslint src
|
|
39
|
+
"lint": "eslint src",
|
|
39
40
|
"prepublishOnly": "npm run build"
|
|
40
41
|
},
|
|
41
42
|
"keywords": [
|