eaa-kit 0.1.0 → 0.2.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/README.md +13 -4
- package/dist/astro/index.d.ts +0 -9
- package/dist/astro/index.js +1 -1
- package/dist/audit-CqrR9pIO.js +2 -0
- package/dist/{audit-6gbV0Zjd.js → audit-D4gju2BT.js} +507 -140
- package/dist/{baseline-Itspu3-Y.js → baseline-CV_3lbER.js} +1 -1
- package/dist/{baseline-DQTnNlc4.js → baseline-CgBmzFTr.js} +16 -16
- package/dist/cli/index.js +54 -34
- package/dist/crawl-CtJbMNNb.js +254 -0
- package/dist/index.d.ts +155 -65
- package/dist/index.js +2 -1
- package/dist/init-DRKIdpK1.js +110 -0
- package/dist/{json-1ESNIiHY.js → json-C9xS1PNC.js} +3 -1
- package/dist/load-sCkKsvGQ.js +192 -0
- package/dist/{playwright-BfWuTG_u.js → playwright-DWux49V3.js} +4 -4
- package/dist/project-CiyzKQud.js +258 -0
- package/dist/{render-K9KxDDSA.js → render-BO0nVrrZ.js} +21 -208
- package/dist/routes-BxbSZKXC.js +123 -0
- package/dist/schema-CMZ8ItGk.js +192 -0
- package/package.json +4 -5
- package/dist/audit-VtuUOuyX.js +0 -2
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
//#region src/schema.ts
|
|
2
|
+
function safeParse(schema, value) {
|
|
3
|
+
const issues = [];
|
|
4
|
+
const data = schema.read(value, [], issues);
|
|
5
|
+
if (issues.length > 0) return {
|
|
6
|
+
success: false,
|
|
7
|
+
error: { issues }
|
|
8
|
+
};
|
|
9
|
+
return {
|
|
10
|
+
success: true,
|
|
11
|
+
data
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function fail(issues, path, message) {
|
|
15
|
+
issues.push({
|
|
16
|
+
path,
|
|
17
|
+
message
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
/** Marks a schema as allowed to be absent. */
|
|
21
|
+
function optional(inner) {
|
|
22
|
+
return {
|
|
23
|
+
isOptional: true,
|
|
24
|
+
read: (value, path, issues) => value === void 0 ? void 0 : inner.read(value, path, issues)
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/** Supplies a value when the field is absent. Never when it is present and wrong. */
|
|
28
|
+
function withDefault(inner, fallback) {
|
|
29
|
+
return {
|
|
30
|
+
isOptional: true,
|
|
31
|
+
fallback,
|
|
32
|
+
read: (value, path, issues) => value === void 0 ? fallback() : inner.read(value, path, issues)
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/** Reads with `inner`, then reshapes what came back. */
|
|
36
|
+
function transform(inner, map) {
|
|
37
|
+
return { read: (value, path, issues) => {
|
|
38
|
+
const before = issues.length;
|
|
39
|
+
const parsed = inner.read(value, path, issues);
|
|
40
|
+
return issues.length === before ? map(parsed) : void 0;
|
|
41
|
+
} };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Reads with `first`, then reads that result with `second`.
|
|
45
|
+
*
|
|
46
|
+
* Lets a shorthand form be widened into the full one and validated by the same
|
|
47
|
+
* schema, so both branches of a union produce one type rather than a union the
|
|
48
|
+
* callers have to narrow.
|
|
49
|
+
*/
|
|
50
|
+
function pipe(first, second) {
|
|
51
|
+
return { read: (value, path, issues) => {
|
|
52
|
+
const before = issues.length;
|
|
53
|
+
const parsed = first.read(value, path, issues);
|
|
54
|
+
return issues.length === before ? second.read(parsed, path, issues) : void 0;
|
|
55
|
+
} };
|
|
56
|
+
}
|
|
57
|
+
function nullable(inner) {
|
|
58
|
+
return { read: (value, path, issues) => value === null ? null : inner.read(value, path, issues) };
|
|
59
|
+
}
|
|
60
|
+
function string(options = {}) {
|
|
61
|
+
return { read: (value, path, issues) => {
|
|
62
|
+
if (typeof value !== "string") return fail(issues, path, "expected a string");
|
|
63
|
+
if (options.min !== void 0 && value.length < options.min) return fail(issues, path, options.min === 1 ? "must not be empty" : `must be at least ${options.min} characters`);
|
|
64
|
+
return value;
|
|
65
|
+
} };
|
|
66
|
+
}
|
|
67
|
+
function number() {
|
|
68
|
+
return { read: (value, path, issues) => typeof value === "number" && Number.isFinite(value) ? value : fail(issues, path, "expected a number") };
|
|
69
|
+
}
|
|
70
|
+
/** One of a fixed set. The message lists them, since that is the useful part. */
|
|
71
|
+
function enumeration(values) {
|
|
72
|
+
return { read: (value, path, issues) => typeof value === "string" && values.includes(value) ? value : fail(issues, path, `expected one of ${values.join(", ")}`) };
|
|
73
|
+
}
|
|
74
|
+
function array(item) {
|
|
75
|
+
return { read: (value, path, issues) => {
|
|
76
|
+
if (!Array.isArray(value)) return fail(issues, path, "expected an array");
|
|
77
|
+
const out = [];
|
|
78
|
+
for (const [index, element] of value.entries()) {
|
|
79
|
+
const before = issues.length;
|
|
80
|
+
const parsed = item.read(element, [...path, index], issues);
|
|
81
|
+
if (issues.length === before) out.push(parsed);
|
|
82
|
+
}
|
|
83
|
+
return out;
|
|
84
|
+
} };
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* An object with a known shape. Unknown keys are dropped rather than carried
|
|
88
|
+
* along, which is what keeps a config file from smuggling fields the templates
|
|
89
|
+
* never asked for into a legal document.
|
|
90
|
+
*/
|
|
91
|
+
function object(shape) {
|
|
92
|
+
return { read: (value, path, issues) => {
|
|
93
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return fail(issues, path, "expected an object");
|
|
94
|
+
const source = value;
|
|
95
|
+
const out = {};
|
|
96
|
+
for (const [key, schema] of Object.entries(shape)) {
|
|
97
|
+
const present = Object.hasOwn(source, key);
|
|
98
|
+
const raw = present ? source[key] : void 0;
|
|
99
|
+
if (!present && schema.isOptional !== true) {
|
|
100
|
+
fail(issues, [...path, key], "is required");
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
const before = issues.length;
|
|
104
|
+
const parsed = schema.read(raw, [...path, key], issues);
|
|
105
|
+
if (issues.length === before && parsed !== void 0) out[key] = parsed;
|
|
106
|
+
}
|
|
107
|
+
return out;
|
|
108
|
+
} };
|
|
109
|
+
}
|
|
110
|
+
/** An object of unknown keys, all values sharing one shape. */
|
|
111
|
+
function record(value) {
|
|
112
|
+
return { read: (input, path, issues) => {
|
|
113
|
+
if (typeof input !== "object" || input === null || Array.isArray(input)) return fail(issues, path, "expected an object");
|
|
114
|
+
const out = {};
|
|
115
|
+
for (const [key, raw] of Object.entries(input)) {
|
|
116
|
+
const before = issues.length;
|
|
117
|
+
const parsed = value.read(raw, [...path, key], issues);
|
|
118
|
+
if (issues.length === before) out[key] = parsed;
|
|
119
|
+
}
|
|
120
|
+
return out;
|
|
121
|
+
} };
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* The first alternative that accepts the value.
|
|
125
|
+
*
|
|
126
|
+
* Reports only the last failure rather than every branch's: a union of a string
|
|
127
|
+
* and an object that was given a number produces two complaints about one
|
|
128
|
+
* field, and the reader has to work out which one they were supposed to satisfy.
|
|
129
|
+
*/
|
|
130
|
+
function union(alternatives, message) {
|
|
131
|
+
return { read: (value, path, issues) => {
|
|
132
|
+
for (const alternative of alternatives) {
|
|
133
|
+
const attempt = [];
|
|
134
|
+
const parsed = alternative.read(value, path, attempt);
|
|
135
|
+
if (attempt.length === 0) return parsed;
|
|
136
|
+
}
|
|
137
|
+
return fail(issues, path, message);
|
|
138
|
+
} };
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* A calendar date, `YYYY-MM-DD`.
|
|
142
|
+
*
|
|
143
|
+
* The shape and the date are both checked: `2026-13-45` matches the pattern and
|
|
144
|
+
* is not a day, and a statement carrying it would print something nonsensical
|
|
145
|
+
* or throw out of the formatter.
|
|
146
|
+
*/
|
|
147
|
+
function isoDate() {
|
|
148
|
+
return { read: (value, path, issues) => {
|
|
149
|
+
if (typeof value !== "string" || !/^\d{4}-\d{2}-\d{2}$/.test(value)) return fail(issues, path, "expected a date as YYYY-MM-DD");
|
|
150
|
+
const parsed = /* @__PURE__ */ new Date(`${value}T00:00:00Z`);
|
|
151
|
+
if (Number.isNaN(parsed.getTime()) || !parsed.toISOString().startsWith(value)) return fail(issues, path, `${value} is not a real date`);
|
|
152
|
+
return value;
|
|
153
|
+
} };
|
|
154
|
+
}
|
|
155
|
+
/** An ISO 8601 timestamp, as `new Date().toISOString()` writes one. */
|
|
156
|
+
function isoDateTime() {
|
|
157
|
+
return { read: (value, path, issues) => {
|
|
158
|
+
if (typeof value !== "string" || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/.test(value)) return fail(issues, path, "expected an ISO 8601 timestamp");
|
|
159
|
+
if (Number.isNaN(new Date(value).getTime())) return fail(issues, path, `${value} is not a real timestamp`);
|
|
160
|
+
return value;
|
|
161
|
+
} };
|
|
162
|
+
}
|
|
163
|
+
/** An absolute http or https URL. A statement links to it, so it has to work. */
|
|
164
|
+
function url() {
|
|
165
|
+
return { read: (value, path, issues) => {
|
|
166
|
+
if (typeof value !== "string") return fail(issues, path, "expected a URL");
|
|
167
|
+
let parsed;
|
|
168
|
+
try {
|
|
169
|
+
parsed = new URL(value);
|
|
170
|
+
} catch {
|
|
171
|
+
return fail(issues, path, "expected a URL, including https://");
|
|
172
|
+
}
|
|
173
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return fail(issues, path, "expected an http or https URL");
|
|
174
|
+
return value;
|
|
175
|
+
} };
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* An email address.
|
|
179
|
+
*
|
|
180
|
+
* Deliberately loose. The only address that is definitely deliverable is one
|
|
181
|
+
* that has been delivered to, and a stricter pattern would reject valid
|
|
182
|
+
* addresses — which, for the one field the EAA requires a provider to publish,
|
|
183
|
+
* is the worse failure.
|
|
184
|
+
*/
|
|
185
|
+
function email() {
|
|
186
|
+
return { read: (value, path, issues) => {
|
|
187
|
+
if (typeof value !== "string" || !/^[^\s@]+@[^\s@.]+(?:\.[^\s@.]+)+$/.test(value)) return fail(issues, path, "expected an email address");
|
|
188
|
+
return value;
|
|
189
|
+
} };
|
|
190
|
+
}
|
|
191
|
+
//#endregion
|
|
192
|
+
export { withDefault as _, isoDateTime as a, object as c, record as d, safeParse as f, url as g, union as h, isoDate as i, optional as l, transform as m, email as n, nullable as o, string as p, enumeration as r, number as s, array as t, pipe as u };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eaa-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Build-time WCAG 2.2 AA auditor and EU accessibility statement generator for static sites (EAA / BFSG / BaFG, DACH-localised).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"cli"
|
|
24
24
|
],
|
|
25
25
|
"engines": {
|
|
26
|
-
"node": "
|
|
26
|
+
"node": "^22.22.2 || ^24.15.0 || >=26.0.0"
|
|
27
27
|
},
|
|
28
28
|
"packageManager": "pnpm@10.28.0",
|
|
29
29
|
"bin": {
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"typecheck": "tsc --noEmit",
|
|
54
54
|
"lint": "biome check .",
|
|
55
55
|
"format": "biome check --write .",
|
|
56
|
-
"smoke": "pnpm build && node dist/cli/index.js audit tests/fixtures/site --include about/** --format json && node dist/cli/index.js audit tests/fixtures/site --include
|
|
56
|
+
"smoke": "pnpm build && node dist/cli/index.js audit tests/fixtures/site --include about/** --format json && node dist/cli/index.js audit tests/fixtures/site --include \"about/**\" \"blog/**\" \"drafts/**\" \"legacy.htm\" --concurrency 2 && node dist/cli/index.js audit tests/fixtures/site --include about/** --format html && node dist/cli/index.js audit tests/fixtures/site --baseline examples/baseline.json && node -e \"import('./dist/astro/index.js').then(m => { const i = m.default(); if (i.name !== 'eaa-kit' || typeof i.hooks['astro:build:done'] !== 'function') { throw new Error('astro entry point is not an integration') } console.log('astro entry ok') })\" && node dist/cli/index.js statement --config examples/eaa.config.json && node dist/cli/index.js statement --config examples/eaa.config.json --audit examples/report.json --format html",
|
|
57
57
|
"examples": "pnpm build && node scripts/generate-examples.mjs"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
@@ -73,8 +73,7 @@
|
|
|
73
73
|
"commander": "^15.0.0",
|
|
74
74
|
"jsdom": "^30.0.1",
|
|
75
75
|
"picocolors": "^1.1.1",
|
|
76
|
-
"tinyglobby": "^0.2.17"
|
|
77
|
-
"zod": "^4.4.3"
|
|
76
|
+
"tinyglobby": "^0.2.17"
|
|
78
77
|
},
|
|
79
78
|
"devDependencies": {
|
|
80
79
|
"@biomejs/biome": "^2.5.9",
|
package/dist/audit-VtuUOuyX.js
DELETED