@code-pushup/axe-plugin 0.105.0 → 0.107.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 +135 -20
- package/package.json +4 -4
- package/src/index.d.ts +1 -1
- package/src/index.js +1 -1
- package/src/index.js.map +1 -1
- package/src/lib/axe-plugin.js +2 -2
- package/src/lib/axe-plugin.js.map +1 -1
- package/src/lib/categories.d.ts +13 -15
- package/src/lib/categories.js +27 -31
- package/src/lib/categories.js.map +1 -1
- package/src/lib/config.d.ts +1 -0
- package/src/lib/config.js +2 -1
- package/src/lib/config.js.map +1 -1
- package/src/lib/constants.d.ts +5 -0
- package/src/lib/constants.js +5 -0
- package/src/lib/constants.js.map +1 -1
- package/src/lib/groups.d.ts +3 -0
- package/src/lib/groups.js +6 -3
- package/src/lib/groups.js.map +1 -1
- package/src/lib/meta/format.d.ts +1 -0
- package/src/lib/meta/format.js +1 -0
- package/src/lib/meta/format.js.map +1 -1
- package/src/lib/meta/processing.d.ts +1 -0
- package/src/lib/meta/processing.js +1 -0
- package/src/lib/meta/processing.js.map +1 -1
- package/src/lib/meta/transform.d.ts +3 -0
- package/src/lib/meta/transform.js +3 -0
- package/src/lib/meta/transform.js.map +1 -1
- package/src/lib/runner/run-axe.d.ts +25 -2
- package/src/lib/runner/run-axe.js +91 -56
- package/src/lib/runner/run-axe.js.map +1 -1
- package/src/lib/runner/runner.d.ts +2 -1
- package/src/lib/runner/runner.js +13 -6
- package/src/lib/runner/runner.js.map +1 -1
- package/src/lib/runner/setup.d.ts +9 -0
- package/src/lib/runner/setup.js +42 -0
- package/src/lib/runner/setup.js.map +1 -0
- package/src/lib/utils.d.ts +26 -2
- package/src/lib/utils.js +55 -0
- package/src/lib/utils.js.map +1 -1
package/README.md
CHANGED
|
@@ -68,9 +68,10 @@ axePlugin(urls: PluginUrls, options?: AxePluginOptions)
|
|
|
68
68
|
| Property | Type | Default | Description |
|
|
69
69
|
| -------------- | ----------- | ------------ | ----------------------------------------- |
|
|
70
70
|
| `preset` | `AxePreset` | `'wcag21aa'` | Accessibility ruleset preset |
|
|
71
|
+
| `setupScript` | `string` | `undefined` | Path to authentication setup script |
|
|
71
72
|
| `scoreTargets` | `object` | `undefined` | Pass/fail thresholds for audits or groups |
|
|
72
73
|
|
|
73
|
-
See [Presets](#presets)
|
|
74
|
+
See [Presets](#presets) and [Authentication](#authentication) sections below.
|
|
74
75
|
|
|
75
76
|
## Multiple URLs
|
|
76
77
|
|
|
@@ -92,6 +93,56 @@ axePlugin({
|
|
|
92
93
|
|
|
93
94
|
URLs with higher weights contribute more to overall scores. For example, a URL with weight 3 has three times the influence of a URL with weight 1.
|
|
94
95
|
|
|
96
|
+
## Authentication
|
|
97
|
+
|
|
98
|
+
To test login-protected pages, provide a `setupScript` that authenticates before analysis:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
axePlugin('https://example.com/dashboard', {
|
|
102
|
+
setupScript: './axe-setup.ts',
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The setup script must export a default async function that receives a Playwright `Page` instance:
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
// axe-setup.ts
|
|
110
|
+
import type { Page } from 'playwright-core';
|
|
111
|
+
|
|
112
|
+
export default async function (page: Page): Promise<void> {
|
|
113
|
+
await page.goto('https://example.com/login');
|
|
114
|
+
await page.fill('#username', process.env.USERNAME);
|
|
115
|
+
await page.fill('#password', process.env.PASSWORD);
|
|
116
|
+
await page.click('button[type="submit"]');
|
|
117
|
+
await page.waitForURL('**/dashboard');
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The script runs once before analyzing URLs. Authentication state (cookies, localStorage) is automatically shared across all URL analyses.
|
|
122
|
+
|
|
123
|
+
<details>
|
|
124
|
+
<summary>Alternative: Cookie-based authentication</summary>
|
|
125
|
+
|
|
126
|
+
If you have a session token, you can inject it directly via cookies:
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
// axe-setup.ts
|
|
130
|
+
import type { Page } from 'playwright-core';
|
|
131
|
+
|
|
132
|
+
export default async function (page: Page): Promise<void> {
|
|
133
|
+
await page.context().addCookies([
|
|
134
|
+
{
|
|
135
|
+
name: 'session_token',
|
|
136
|
+
value: process.env.SESSION_TOKEN,
|
|
137
|
+
domain: 'example.com',
|
|
138
|
+
path: '/',
|
|
139
|
+
},
|
|
140
|
+
]);
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
</details>
|
|
145
|
+
|
|
95
146
|
## Presets
|
|
96
147
|
|
|
97
148
|
Choose which accessibility ruleset to test against using the `preset` option:
|
|
@@ -163,51 +214,105 @@ Use `npx code-pushup print-config --onlyPlugins=axe` to list all audits and grou
|
|
|
163
214
|
|
|
164
215
|
The plugin provides helpers to integrate Axe results into your categories.
|
|
165
216
|
|
|
166
|
-
###
|
|
217
|
+
### Building categories with ref helpers
|
|
167
218
|
|
|
168
|
-
Use `
|
|
219
|
+
Use `axeGroupRefs` and `axeAuditRefs` to build categories. These helpers automatically handle multi-URL expansion:
|
|
169
220
|
|
|
170
221
|
```ts
|
|
171
|
-
import axePlugin, {
|
|
222
|
+
import axePlugin, { axeGroupRefs } from '@code-pushup/axe-plugin';
|
|
172
223
|
|
|
173
224
|
const axe = axePlugin('https://example.com');
|
|
174
225
|
|
|
175
226
|
export default {
|
|
176
227
|
plugins: [axe],
|
|
177
|
-
categories:
|
|
228
|
+
categories: [
|
|
229
|
+
{
|
|
230
|
+
slug: 'a11y',
|
|
231
|
+
title: 'Accessibility',
|
|
232
|
+
refs: axeGroupRefs(axe),
|
|
233
|
+
},
|
|
234
|
+
],
|
|
178
235
|
};
|
|
179
236
|
```
|
|
180
237
|
|
|
181
|
-
|
|
238
|
+
For multi-URL setups, refs are automatically expanded for each URL with appropriate weights:
|
|
239
|
+
|
|
240
|
+
```ts
|
|
241
|
+
import axePlugin, { axeGroupRefs } from '@code-pushup/axe-plugin';
|
|
242
|
+
|
|
243
|
+
const axe = axePlugin({
|
|
244
|
+
'https://example.com': 2,
|
|
245
|
+
'https://example.com/about': 1,
|
|
246
|
+
});
|
|
182
247
|
|
|
183
|
-
|
|
248
|
+
export default {
|
|
249
|
+
plugins: [axe],
|
|
250
|
+
categories: [
|
|
251
|
+
{
|
|
252
|
+
slug: 'a11y',
|
|
253
|
+
title: 'Accessibility',
|
|
254
|
+
refs: axeGroupRefs(axe),
|
|
255
|
+
},
|
|
256
|
+
],
|
|
257
|
+
};
|
|
258
|
+
```
|
|
184
259
|
|
|
185
|
-
|
|
260
|
+
### Custom categories with specific groups
|
|
261
|
+
|
|
262
|
+
For fine-grained control, specify which groups to include:
|
|
186
263
|
|
|
187
264
|
```ts
|
|
188
|
-
import axePlugin, {
|
|
265
|
+
import axePlugin, { axeGroupRefs } from '@code-pushup/axe-plugin';
|
|
189
266
|
|
|
190
|
-
const axe = axePlugin(
|
|
267
|
+
const axe = axePlugin('https://example.com');
|
|
191
268
|
|
|
192
269
|
export default {
|
|
193
270
|
plugins: [axe],
|
|
194
|
-
categories:
|
|
271
|
+
categories: [
|
|
195
272
|
{
|
|
196
|
-
slug: '
|
|
197
|
-
title: '
|
|
198
|
-
refs: [
|
|
273
|
+
slug: 'a11y',
|
|
274
|
+
title: 'Accessibility',
|
|
275
|
+
refs: [...axeGroupRefs(axe, 'aria', 2), ...axeGroupRefs(axe, 'color'), ...axeGroupRefs(axe, 'keyboard')],
|
|
199
276
|
},
|
|
200
|
-
]
|
|
277
|
+
],
|
|
201
278
|
};
|
|
202
279
|
```
|
|
203
280
|
|
|
281
|
+
### Combining with Lighthouse
|
|
282
|
+
|
|
283
|
+
For comprehensive accessibility testing, combine Axe with Lighthouse's accessibility group in a single category:
|
|
284
|
+
|
|
285
|
+
```ts
|
|
286
|
+
import axePlugin, { axeGroupRefs } from '@code-pushup/axe-plugin';
|
|
287
|
+
import lighthousePlugin, { lighthouseGroupRefs } from '@code-pushup/lighthouse-plugin';
|
|
288
|
+
|
|
289
|
+
const urls = ['https://example.com', 'https://example.com/about'];
|
|
290
|
+
const axe = axePlugin(urls);
|
|
291
|
+
const lighthouse = await lighthousePlugin(urls);
|
|
292
|
+
|
|
293
|
+
export default {
|
|
294
|
+
plugins: [axe, lighthouse],
|
|
295
|
+
categories: [
|
|
296
|
+
{
|
|
297
|
+
slug: 'a11y',
|
|
298
|
+
title: 'Accessibility',
|
|
299
|
+
refs: [...lighthouseGroupRefs(lighthouse, 'accessibility'), ...axeGroupRefs(axe)],
|
|
300
|
+
},
|
|
301
|
+
],
|
|
302
|
+
};
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
This gives you both Lighthouse's performance-focused accessibility audits and Axe's comprehensive WCAG coverage in one category score.
|
|
306
|
+
|
|
204
307
|
### Helper functions
|
|
205
308
|
|
|
206
|
-
| Function
|
|
207
|
-
|
|
|
208
|
-
| `
|
|
209
|
-
| `
|
|
210
|
-
|
|
309
|
+
| Function | Description |
|
|
310
|
+
| -------------- | -------------------------------------------------------- |
|
|
311
|
+
| `axeGroupRefs` | Creates category refs to Axe group(s), handles multi-URL |
|
|
312
|
+
| `axeAuditRefs` | Creates category refs to Axe audit(s), handles multi-URL |
|
|
313
|
+
|
|
314
|
+
> [!TIP]
|
|
315
|
+
> Weights determine each ref's influence on the category score. Use weight `0` to include a ref as info only, without affecting the score.
|
|
211
316
|
|
|
212
317
|
### Type safety
|
|
213
318
|
|
|
@@ -219,6 +324,16 @@ import type { AxeGroupSlug } from '@code-pushup/axe-plugin';
|
|
|
219
324
|
const group: AxeGroupSlug = 'aria';
|
|
220
325
|
```
|
|
221
326
|
|
|
327
|
+
### Deprecated helpers
|
|
328
|
+
|
|
329
|
+
The following helpers are deprecated and will be removed in a future version:
|
|
330
|
+
|
|
331
|
+
| Function | Replacement |
|
|
332
|
+
| --------------- | ------------------------------------------------- |
|
|
333
|
+
| `axeCategories` | Build categories manually with `axeGroupRefs` |
|
|
334
|
+
| `axeGroupRef` | Use `axeGroupRefs` (plural) for multi-URL support |
|
|
335
|
+
| `axeAuditRef` | Use `axeAuditRefs` (plural) for multi-URL support |
|
|
336
|
+
|
|
222
337
|
## Resources
|
|
223
338
|
|
|
224
339
|
- **[Axe-core rules](https://github.com/dequelabs/axe-core/blob/develop/doc/rule-descriptions.md)** - Complete list of accessibility rules
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-pushup/axe-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.107.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Code PushUp plugin for detecting accessibility issues using Axe 🌐",
|
|
6
6
|
"homepage": "https://github.com/code-pushup/cli/tree/main/packages/plugin-axe#readme",
|
|
@@ -42,11 +42,11 @@
|
|
|
42
42
|
"type": "module",
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@axe-core/playwright": "^4.11.0",
|
|
45
|
-
"@code-pushup/models": "0.
|
|
46
|
-
"@code-pushup/utils": "0.
|
|
45
|
+
"@code-pushup/models": "0.107.0",
|
|
46
|
+
"@code-pushup/utils": "0.107.0",
|
|
47
47
|
"axe-core": "^4.11.0",
|
|
48
48
|
"playwright-core": "^1.56.1",
|
|
49
|
-
"zod": "^4.1
|
|
49
|
+
"zod": "^4.2.1"
|
|
50
50
|
},
|
|
51
51
|
"files": [
|
|
52
52
|
"src",
|
package/src/index.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ import { axePlugin } from './lib/axe-plugin.js';
|
|
|
2
2
|
export default axePlugin;
|
|
3
3
|
export type { AxePluginOptions, AxePreset } from './lib/config.js';
|
|
4
4
|
export type { AxeGroupSlug } from './lib/groups.js';
|
|
5
|
-
export { axeAuditRef, axeGroupRef } from './lib/utils.js';
|
|
5
|
+
export { axeAuditRef, axeAuditRefs, axeGroupRef, axeGroupRefs, } from './lib/utils.js';
|
|
6
6
|
export { axeCategories } from './lib/categories.js';
|
package/src/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { axePlugin } from './lib/axe-plugin.js';
|
|
2
2
|
export default axePlugin;
|
|
3
|
-
export { axeAuditRef, axeGroupRef } from './lib/utils.js';
|
|
3
|
+
export { axeAuditRef, axeAuditRefs, axeGroupRef, axeGroupRefs, } from './lib/utils.js';
|
|
4
4
|
export { axeCategories } from './lib/categories.js';
|
|
5
5
|
//# sourceMappingURL=index.js.map
|
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,eAAe,SAAS,CAAC;AAKzB,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,eAAe,SAAS,CAAC;AAKzB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,WAAW,EACX,YAAY,GACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
|
package/src/lib/axe-plugin.js
CHANGED
|
@@ -14,7 +14,7 @@ import { createRunnerFunction } from './runner/runner.js';
|
|
|
14
14
|
* @returns Plugin configuration
|
|
15
15
|
*/
|
|
16
16
|
export function axePlugin(urls, options = {}) {
|
|
17
|
-
const { preset, scoreTargets, timeout } = validate(axePluginOptionsSchema, options);
|
|
17
|
+
const { preset, scoreTargets, timeout, setupScript } = validate(axePluginOptionsSchema, options);
|
|
18
18
|
const { urls: normalizedUrls, context } = normalizeUrlInput(urls);
|
|
19
19
|
const { audits, groups, ruleIds } = processAuditsAndGroups(normalizedUrls, preset);
|
|
20
20
|
const packageJson = createRequire(import.meta.url)('../../package.json');
|
|
@@ -28,7 +28,7 @@ export function axePlugin(urls, options = {}) {
|
|
|
28
28
|
version: packageJson.version,
|
|
29
29
|
audits,
|
|
30
30
|
groups,
|
|
31
|
-
runner: createRunnerFunction(normalizedUrls, ruleIds, timeout),
|
|
31
|
+
runner: createRunnerFunction(normalizedUrls, ruleIds, timeout, setupScript),
|
|
32
32
|
context,
|
|
33
33
|
...(scoreTargets && { scoreTargets }),
|
|
34
34
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"axe-plugin.js","sourceRoot":"","sources":["../../../src/lib/axe-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAGL,QAAQ,GACT,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAyB,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CACvB,IAAgB,EAChB,UAA4B,EAAE;IAE9B,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,GAAG,QAAQ,
|
|
1
|
+
{"version":3,"file":"axe-plugin.js","sourceRoot":"","sources":["../../../src/lib/axe-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAGL,QAAQ,GACT,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAyB,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CACvB,IAAgB,EAChB,UAA4B,EAAE;IAE9B,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,QAAQ,CAC7D,sBAAsB,EACtB,OAAO,CACR,CAAC;IAEF,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAElE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,sBAAsB,CACxD,cAAc,EACd,MAAM,CACP,CAAC;IAEF,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAChD,oBAAoB,CACkB,CAAC;IAEzC,OAAO;QACL,IAAI,EAAE,eAAe;QACrB,KAAK,EAAE,gBAAgB;QACvB,IAAI,EAAE,eAAe;QACrB,WAAW,EACT,qEAAqE;QACvE,OAAO,EAAE,uDAAuD;QAChE,WAAW,EAAE,WAAW,CAAC,IAAI;QAC7B,OAAO,EAAE,WAAW,CAAC,OAAO;QAC5B,MAAM;QACN,MAAM;QACN,MAAM,EAAE,oBAAoB,CAAC,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC;QAC3E,OAAO;QACP,GAAG,CAAC,YAAY,IAAI,EAAE,YAAY,EAAE,CAAC;KACtC,CAAC;AACJ,CAAC"}
|
package/src/lib/categories.d.ts
CHANGED
|
@@ -1,22 +1,20 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type CategoryConfig, type PluginConfig } from '@code-pushup/models';
|
|
2
2
|
import { type PluginUrlContext } from '@code-pushup/utils';
|
|
3
|
-
import { type AxeCategoryGroupSlug } from './groups.js';
|
|
4
3
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* @public
|
|
8
|
-
* @param plugin - {@link PluginConfig} object with groups and context
|
|
9
|
-
* @param categories - {@link CategoryConfig} optional user-defined categories
|
|
10
|
-
* @returns {CategoryConfig[]} - expanded and aggregated categories
|
|
4
|
+
* @deprecated Use `axeGroupRefs` to build categories manually instead.
|
|
11
5
|
*
|
|
12
6
|
* @example
|
|
13
|
-
*
|
|
14
|
-
* const
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
7
|
+
* // Instead of:
|
|
8
|
+
* const categories = axeCategories(axePlugin);
|
|
9
|
+
*
|
|
10
|
+
* // Use:
|
|
11
|
+
* const categories = [
|
|
12
|
+
* {
|
|
13
|
+
* slug: 'a11y',
|
|
14
|
+
* title: 'Accessibility',
|
|
15
|
+
* refs: axeGroupRefs(axePlugin),
|
|
16
|
+
* },
|
|
17
|
+
* ];
|
|
18
18
|
*/
|
|
19
19
|
export declare function axeCategories(plugin: Pick<PluginConfig, 'groups' | 'context'>, categories?: CategoryConfig[]): CategoryConfig[];
|
|
20
|
-
export declare function createAggregatedCategory(groups: Group[], context: PluginUrlContext): CategoryConfig;
|
|
21
20
|
export declare function expandAggregatedCategory(category: CategoryConfig, context: PluginUrlContext): CategoryConfig;
|
|
22
|
-
export declare function extractGroupSlugs(groups: Group[]): AxeCategoryGroupSlug[];
|
package/src/lib/categories.js
CHANGED
|
@@ -1,56 +1,52 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { validate, } from '@code-pushup/models';
|
|
2
|
+
import { expandCategoryRefs, pluginUrlContextSchema, shouldExpandForUrls, } from '@code-pushup/utils';
|
|
2
3
|
import { AXE_PLUGIN_SLUG } from './constants.js';
|
|
3
|
-
import {
|
|
4
|
+
import { axeGroupRefs } from './utils.js';
|
|
4
5
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* @public
|
|
8
|
-
* @param plugin - {@link PluginConfig} object with groups and context
|
|
9
|
-
* @param categories - {@link CategoryConfig} optional user-defined categories
|
|
10
|
-
* @returns {CategoryConfig[]} - expanded and aggregated categories
|
|
6
|
+
* @deprecated Use `axeGroupRefs` to build categories manually instead.
|
|
11
7
|
*
|
|
12
8
|
* @example
|
|
13
|
-
*
|
|
14
|
-
* const
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
9
|
+
* // Instead of:
|
|
10
|
+
* const categories = axeCategories(axePlugin);
|
|
11
|
+
*
|
|
12
|
+
* // Use:
|
|
13
|
+
* const categories = [
|
|
14
|
+
* {
|
|
15
|
+
* slug: 'a11y',
|
|
16
|
+
* title: 'Accessibility',
|
|
17
|
+
* refs: axeGroupRefs(axePlugin),
|
|
18
|
+
* },
|
|
19
|
+
* ];
|
|
18
20
|
*/
|
|
19
21
|
export function axeCategories(plugin, categories) {
|
|
20
22
|
if (!plugin.groups || plugin.groups.length === 0) {
|
|
21
23
|
return categories ?? [];
|
|
22
24
|
}
|
|
23
|
-
validateUrlContext(plugin.context);
|
|
24
25
|
if (!categories) {
|
|
25
|
-
return createCategories(plugin
|
|
26
|
+
return createCategories(plugin);
|
|
26
27
|
}
|
|
27
|
-
return expandCategories(
|
|
28
|
+
return expandCategories(plugin, categories);
|
|
28
29
|
}
|
|
29
|
-
function createCategories(
|
|
30
|
-
return [
|
|
30
|
+
function createCategories(plugin) {
|
|
31
|
+
return [
|
|
32
|
+
{
|
|
33
|
+
slug: 'axe-a11y',
|
|
34
|
+
title: 'Axe Accessibility',
|
|
35
|
+
refs: axeGroupRefs(plugin),
|
|
36
|
+
},
|
|
37
|
+
];
|
|
31
38
|
}
|
|
32
|
-
function expandCategories(
|
|
39
|
+
function expandCategories(plugin, categories) {
|
|
40
|
+
const context = validate(pluginUrlContextSchema, plugin.context);
|
|
33
41
|
if (!shouldExpandForUrls(context.urlCount)) {
|
|
34
42
|
return categories;
|
|
35
43
|
}
|
|
36
44
|
return categories.map(category => expandAggregatedCategory(category, context));
|
|
37
45
|
}
|
|
38
|
-
export function createAggregatedCategory(groups, context) {
|
|
39
|
-
const refs = extractGroupSlugs(groups).flatMap(slug => createCategoryRefs(slug, AXE_PLUGIN_SLUG, context));
|
|
40
|
-
return {
|
|
41
|
-
slug: 'axe-a11y',
|
|
42
|
-
title: 'Axe Accessibility',
|
|
43
|
-
refs,
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
46
|
export function expandAggregatedCategory(category, context) {
|
|
47
47
|
return {
|
|
48
48
|
...category,
|
|
49
49
|
refs: category.refs.flatMap(ref => ref.plugin === AXE_PLUGIN_SLUG ? expandCategoryRefs(ref, context) : [ref]),
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
|
-
export function extractGroupSlugs(groups) {
|
|
53
|
-
const slugs = groups.map(({ slug }) => removeIndex(slug));
|
|
54
|
-
return [...new Set(slugs)].filter(isAxeGroupSlug);
|
|
55
|
-
}
|
|
56
52
|
//# sourceMappingURL=categories.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"categories.js","sourceRoot":"","sources":["../../../src/lib/categories.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"categories.js","sourceRoot":"","sources":["../../../src/lib/categories.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,QAAQ,GACT,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,aAAa,CAC3B,MAAgD,EAChD,UAA6B;IAE7B,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjD,OAAO,UAAU,IAAI,EAAE,CAAC;IAC1B,CAAC;IACD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,gBAAgB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,gBAAgB,CACvB,MAAgD;IAEhD,OAAO;QACL;YACE,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,mBAAmB;YAC1B,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC;SAC3B;KACF,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CACvB,MAAqC,EACrC,UAA4B;IAE5B,MAAM,OAAO,GAAG,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACjE,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3C,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,OAAO,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAC/B,wBAAwB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAC5C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,QAAwB,EACxB,OAAyB;IAEzB,OAAO;QACL,GAAG,QAAQ;QACX,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAChC,GAAG,CAAC,MAAM,KAAK,eAAe,CAAC,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAC1E;KACF,CAAC;AACJ,CAAC"}
|
package/src/lib/config.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export declare const axePluginOptionsSchema: z.ZodObject<{
|
|
|
14
14
|
"best-practice": "best-practice";
|
|
15
15
|
all: "all";
|
|
16
16
|
}>>;
|
|
17
|
+
setupScript: z.ZodOptional<z.ZodString>;
|
|
17
18
|
scoreTargets: z.ZodOptional<z.ZodOptional<z.ZodUnion<readonly [z.ZodOptional<z.ZodNumber>, z.ZodRecord<z.ZodString, z.ZodNonOptional<z.ZodOptional<z.ZodNumber>>>]>>>;
|
|
18
19
|
timeout: z.ZodDefault<z.ZodNumber>;
|
|
19
20
|
}, z.core.$strip>;
|
package/src/lib/config.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { pluginScoreTargetsSchema, positiveIntSchema, } from '@code-pushup/models';
|
|
2
|
+
import { filePathSchema, pluginScoreTargetsSchema, positiveIntSchema, } from '@code-pushup/models';
|
|
3
3
|
import { AXE_DEFAULT_PRESET, DEFAULT_TIMEOUT_MS } from './constants.js';
|
|
4
4
|
export const axePresets = [
|
|
5
5
|
'wcag21aa',
|
|
@@ -13,6 +13,7 @@ export const axePluginOptionsSchema = z
|
|
|
13
13
|
preset: axePresetSchema.default(AXE_DEFAULT_PRESET).meta({
|
|
14
14
|
description: 'Accessibility ruleset preset (default: wcag21aa for WCAG 2.1 Level AA compliance)',
|
|
15
15
|
}),
|
|
16
|
+
setupScript: filePathSchema.optional(),
|
|
16
17
|
scoreTargets: pluginScoreTargetsSchema.optional(),
|
|
17
18
|
timeout: positiveIntSchema.default(DEFAULT_TIMEOUT_MS).meta({
|
|
18
19
|
description: 'Page navigation timeout in milliseconds (default: 30000ms / 30s)',
|
package/src/lib/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAExE,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,UAAU;IACV,UAAU;IACV,eAAe;IACf,KAAK;CACG,CAAC;AAEX,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;AAG/E,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC;KACpC,MAAM,CAAC;IACN,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC;QACvD,WAAW,EACT,mFAAmF;KACtF,CAAC;IACF,YAAY,EAAE,wBAAwB,CAAC,QAAQ,EAAE;IACjD,OAAO,EAAE,iBAAiB,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC;QAC1D,WAAW,EACT,kEAAkE;KACrE,CAAC;CACH,CAAC;KACD,IAAI,CAAC;IACJ,KAAK,EAAE,kBAAkB;IACzB,WAAW,EAAE,0CAA0C;CACxD,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAExE,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,UAAU;IACV,UAAU;IACV,eAAe;IACf,KAAK;CACG,CAAC;AAEX,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;AAG/E,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC;KACpC,MAAM,CAAC;IACN,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC;QACvD,WAAW,EACT,mFAAmF;KACtF,CAAC;IACF,WAAW,EAAE,cAAc,CAAC,QAAQ,EAAE;IACtC,YAAY,EAAE,wBAAwB,CAAC,QAAQ,EAAE;IACjD,OAAO,EAAE,iBAAiB,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC;QAC1D,WAAW,EACT,kEAAkE;KACrE,CAAC;CACH,CAAC;KACD,IAAI,CAAC;IACJ,KAAK,EAAE,kBAAkB;IACzB,WAAW,EAAE,0CAA0C;CACxD,CAAC,CAAC"}
|
package/src/lib/constants.d.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { AxePreset } from './config.js';
|
|
2
|
+
/** Unique identifier for the Axe plugin. */
|
|
2
3
|
export declare const AXE_PLUGIN_SLUG = "axe";
|
|
4
|
+
/** Display title for the Axe plugin. */
|
|
3
5
|
export declare const AXE_PLUGIN_TITLE = "Axe";
|
|
6
|
+
/** Default WCAG preset used when none is specified. */
|
|
4
7
|
export declare const AXE_DEFAULT_PRESET = "wcag21aa";
|
|
8
|
+
/** Default timeout in milliseconds for page operations. */
|
|
5
9
|
export declare const DEFAULT_TIMEOUT_MS = 30000;
|
|
10
|
+
/** Human-readable names for each Axe preset. */
|
|
6
11
|
export declare const AXE_PRESET_NAMES: Record<AxePreset, string>;
|
package/src/lib/constants.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
/** Unique identifier for the Axe plugin. */
|
|
1
2
|
export const AXE_PLUGIN_SLUG = 'axe';
|
|
3
|
+
/** Display title for the Axe plugin. */
|
|
2
4
|
export const AXE_PLUGIN_TITLE = 'Axe';
|
|
5
|
+
/** Default WCAG preset used when none is specified. */
|
|
3
6
|
export const AXE_DEFAULT_PRESET = 'wcag21aa';
|
|
7
|
+
/** Default timeout in milliseconds for page operations. */
|
|
4
8
|
export const DEFAULT_TIMEOUT_MS = 30_000;
|
|
9
|
+
/** Human-readable names for each Axe preset. */
|
|
5
10
|
export const AXE_PRESET_NAMES = {
|
|
6
11
|
wcag21aa: 'WCAG 2.1 AA',
|
|
7
12
|
wcag22aa: 'WCAG 2.2 AA',
|
package/src/lib/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/lib/constants.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/lib/constants.ts"],"names":[],"mappings":"AAEA,4CAA4C;AAC5C,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC;AAErC,wCAAwC;AACxC,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAEtC,uDAAuD;AACvD,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAC;AAE7C,2DAA2D;AAC3D,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAEzC,gDAAgD;AAChD,MAAM,CAAC,MAAM,gBAAgB,GAA8B;IACzD,QAAQ,EAAE,aAAa;IACvB,QAAQ,EAAE,aAAa;IACvB,eAAe,EAAE,gBAAgB;IACjC,GAAG,EAAE,KAAK;CACX,CAAC"}
|
package/src/lib/groups.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export declare const axeWcagPresetSchema: z.ZodEnum<{
|
|
|
12
12
|
wcag22aa: "wcag22aa";
|
|
13
13
|
}>;
|
|
14
14
|
export type AxeWcagPreset = z.infer<typeof axeWcagPresetSchema>;
|
|
15
|
+
/** Returns the WCAG tags for a given preset. */
|
|
15
16
|
export declare function getWcagPresetTags(preset: AxeWcagPreset): AxeWcagTag[];
|
|
16
17
|
export declare const axeCategoryGroupSlugSchema: z.ZodEnum<{
|
|
17
18
|
aria: "aria";
|
|
@@ -29,7 +30,9 @@ export declare const axeCategoryGroupSlugSchema: z.ZodEnum<{
|
|
|
29
30
|
"time-and-media": "time-and-media";
|
|
30
31
|
}>;
|
|
31
32
|
export type AxeCategoryGroupSlug = z.infer<typeof axeCategoryGroupSlugSchema>;
|
|
33
|
+
/** Maps category group slugs to human-readable titles. */
|
|
32
34
|
export declare const CATEGORY_GROUPS: Record<AxeCategoryGroupSlug, string>;
|
|
35
|
+
/** Type guard for valid Axe group slugs. */
|
|
33
36
|
export declare function isAxeGroupSlug(slug: unknown): slug is AxeCategoryGroupSlug;
|
|
34
37
|
export declare const axeGroupSlugSchema: z.ZodEnum<{
|
|
35
38
|
aria: "aria";
|
package/src/lib/groups.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { axePresetSchema } from './config.js';
|
|
3
|
-
|
|
3
|
+
/** WCAG presets for rule loading */
|
|
4
4
|
const axeWcagTags = [
|
|
5
5
|
'wcag2a',
|
|
6
6
|
'wcag21a',
|
|
@@ -18,10 +18,11 @@ const WCAG_PRESET_TAGS = {
|
|
|
18
18
|
wcag21aa: ['wcag2a', 'wcag21a', 'wcag2aa', 'wcag21aa'],
|
|
19
19
|
wcag22aa: ['wcag2a', 'wcag21a', 'wcag2aa', 'wcag21aa', 'wcag22aa'],
|
|
20
20
|
};
|
|
21
|
+
/** Returns the WCAG tags for a given preset. */
|
|
21
22
|
export function getWcagPresetTags(preset) {
|
|
22
23
|
return WCAG_PRESET_TAGS[preset];
|
|
23
24
|
}
|
|
24
|
-
|
|
25
|
+
/** Category groups for all presets */
|
|
25
26
|
const axeCategoryGroupSlugs = [
|
|
26
27
|
'aria',
|
|
27
28
|
'color',
|
|
@@ -40,6 +41,7 @@ const axeCategoryGroupSlugs = [
|
|
|
40
41
|
export const axeCategoryGroupSlugSchema = z
|
|
41
42
|
.enum(axeCategoryGroupSlugs)
|
|
42
43
|
.meta({ title: 'AxeCategoryGroupSlug' });
|
|
44
|
+
/** Maps category group slugs to human-readable titles. */
|
|
43
45
|
export const CATEGORY_GROUPS = {
|
|
44
46
|
aria: 'ARIA',
|
|
45
47
|
color: 'Color & Contrast',
|
|
@@ -55,9 +57,10 @@ export const CATEGORY_GROUPS = {
|
|
|
55
57
|
'text-alternatives': 'Text Alternatives',
|
|
56
58
|
'time-and-media': 'Media',
|
|
57
59
|
};
|
|
60
|
+
/** Type guard for valid Axe group slugs. */
|
|
58
61
|
export function isAxeGroupSlug(slug) {
|
|
59
62
|
return axeCategoryGroupSlugSchema.safeParse(slug).success;
|
|
60
63
|
}
|
|
61
|
-
|
|
64
|
+
// Combined exports
|
|
62
65
|
export const axeGroupSlugSchema = axeCategoryGroupSlugSchema;
|
|
63
66
|
//# sourceMappingURL=groups.js.map
|
package/src/lib/groups.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"groups.js","sourceRoot":"","sources":["../../../src/lib/groups.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,
|
|
1
|
+
{"version":3,"file":"groups.js","sourceRoot":"","sources":["../../../src/lib/groups.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,oCAAoC;AACpC,MAAM,WAAW,GAAG;IAClB,QAAQ;IACR,SAAS;IACT,SAAS;IACT,UAAU;IACV,UAAU;CACF,CAAC;AAEX,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC;KAC9B,IAAI,CAAC,WAAW,CAAC;KACjB,IAAI,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC;AAIjC,MAAM,CAAC,MAAM,mBAAmB,GAAG,eAAe;KAC/C,OAAO,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;KACjC,IAAI,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC;AAIpC,MAAM,gBAAgB,GAAwC;IAC5D,QAAQ,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC;IACtD,QAAQ,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,CAAC;CACnE,CAAC;AAEF,gDAAgD;AAChD,MAAM,UAAU,iBAAiB,CAAC,MAAqB;IACrD,OAAO,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAClC,CAAC;AAED,sCAAsC;AACtC,MAAM,qBAAqB,GAAG;IAC5B,MAAM;IACN,OAAO;IACP,OAAO;IACP,UAAU;IACV,UAAU;IACV,iBAAiB;IACjB,SAAS;IACT,WAAW;IACX,yBAAyB;IACzB,WAAW;IACX,QAAQ;IACR,mBAAmB;IACnB,gBAAgB;CACR,CAAC;AAEX,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC;KACxC,IAAI,CAAC,qBAAqB,CAAC;KAC3B,IAAI,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC,CAAC;AAI3C,0DAA0D;AAC1D,MAAM,CAAC,MAAM,eAAe,GAAyC;IACnE,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,kBAAkB;IACzB,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,UAAU;IACpB,QAAQ,EAAE,UAAU;IACpB,iBAAiB,EAAE,gBAAgB;IACnC,OAAO,EAAE,SAAS;IAClB,SAAS,EAAE,WAAW;IACtB,yBAAyB,EAAE,aAAa;IACxC,SAAS,EAAE,WAAW;IACtB,MAAM,EAAE,QAAQ;IAChB,mBAAmB,EAAE,mBAAmB;IACxC,gBAAgB,EAAE,OAAO;CAC1B,CAAC;AAEF,4CAA4C;AAC5C,MAAM,UAAU,cAAc,CAAC,IAAa;IAC1C,OAAO,0BAA0B,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;AAC5D,CAAC;AAED,mBAAmB;AACnB,MAAM,CAAC,MAAM,kBAAkB,GAAG,0BAA0B,CAAC"}
|
package/src/lib/meta/format.d.ts
CHANGED
package/src/lib/meta/format.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { pluginMetaLogFormatter } from '@code-pushup/utils';
|
|
2
2
|
import { AXE_PLUGIN_TITLE } from '../constants.js';
|
|
3
|
+
/** Formats log messages with the Axe plugin prefix. */
|
|
3
4
|
export const formatMetaLog = pluginMetaLogFormatter(AXE_PLUGIN_TITLE);
|
|
4
5
|
//# sourceMappingURL=format.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../../../src/lib/meta/format.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,MAAM,CAAC,MAAM,aAAa,GAAG,sBAAsB,CAAC,gBAAgB,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../../../src/lib/meta/format.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,uDAAuD;AACvD,MAAM,CAAC,MAAM,aAAa,GAAG,sBAAsB,CAAC,gBAAgB,CAAC,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Audit, Group } from '@code-pushup/models';
|
|
2
2
|
import type { AxePreset } from '../config.js';
|
|
3
|
+
/** Loads and processes Axe rules into audits and groups, expanding for multiple URLs if needed. */
|
|
3
4
|
export declare function processAuditsAndGroups(urls: string[], preset: AxePreset): {
|
|
4
5
|
audits: Audit[];
|
|
5
6
|
groups: Group[];
|
|
@@ -3,6 +3,7 @@ import { expandAuditsForUrls, expandGroupsForUrls, logger, pluralizeToken, shoul
|
|
|
3
3
|
import { AXE_PRESET_NAMES } from '../constants.js';
|
|
4
4
|
import { formatMetaLog } from './format.js';
|
|
5
5
|
import { loadAxeRules, transformRulesToAudits, transformRulesToGroups, } from './transform.js';
|
|
6
|
+
/** Loads and processes Axe rules into audits and groups, expanding for multiple URLs if needed. */
|
|
6
7
|
export function processAuditsAndGroups(urls, preset) {
|
|
7
8
|
const rules = loadAxeRules(preset);
|
|
8
9
|
const ruleIds = rules.map(({ ruleId }) => ruleId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"processing.js","sourceRoot":"","sources":["../../../../src/lib/meta/processing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,MAAM,EACN,cAAc,EACd,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EACL,YAAY,EACZ,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AAExB,MAAM,UAAU,sBAAsB,CACpC,IAAc,EACd,MAAiB;IAMjB,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAC;IAE7C,MAAM,CAAC,IAAI,CACT,aAAa,CACX,UAAU,cAAc,CAAC,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,2BAA2B,CAC1H,CACF,CAAC;IACF,MAAM,CAAC,IAAI,CACT,aAAa,CACX,WAAW,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,sBAAsB,CACxE,CACF,CAAC;IAEF,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACtC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IACrC,CAAC;IAED,MAAM,cAAc,GAAG,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACzD,MAAM,cAAc,GAAG,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACzD,MAAM,CAAC,IAAI,CACT,aAAa,CACX,oBAAoB,MAAM,CAAC,MAAM,MAAM,cAAc,CAAC,MAAM,iBAAiB,MAAM,CAAC,MAAM,MAAM,cAAc,CAAC,MAAM,SAAS,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CACnK,CACF,CAAC;IACF,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC;AACrE,CAAC"}
|
|
1
|
+
{"version":3,"file":"processing.js","sourceRoot":"","sources":["../../../../src/lib/meta/processing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,MAAM,EACN,cAAc,EACd,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EACL,YAAY,EACZ,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AAExB,mGAAmG;AACnG,MAAM,UAAU,sBAAsB,CACpC,IAAc,EACd,MAAiB;IAMjB,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAC;IAE7C,MAAM,CAAC,IAAI,CACT,aAAa,CACX,UAAU,cAAc,CAAC,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,2BAA2B,CAC1H,CACF,CAAC;IACF,MAAM,CAAC,IAAI,CACT,aAAa,CACX,WAAW,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,sBAAsB,CACxE,CACF,CAAC;IAEF,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACtC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IACrC,CAAC;IAED,MAAM,cAAc,GAAG,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACzD,MAAM,cAAc,GAAG,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACzD,MAAM,CAAC,IAAI,CACT,aAAa,CACX,oBAAoB,MAAM,CAAC,MAAM,MAAM,cAAc,CAAC,MAAM,iBAAiB,MAAM,CAAC,MAAM,MAAM,cAAc,CAAC,MAAM,SAAS,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CACnK,CACF,CAAC;IACF,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC;AACrE,CAAC"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import axe from 'axe-core';
|
|
2
2
|
import type { Audit, Group } from '@code-pushup/models';
|
|
3
3
|
import type { AxePreset } from '../config.js';
|
|
4
|
+
/** Loads Axe rules filtered by the specified preset. */
|
|
4
5
|
export declare function loadAxeRules(preset: AxePreset): axe.RuleMetadata[];
|
|
6
|
+
/** Transforms Axe rule metadata into Code PushUp audit definitions. */
|
|
5
7
|
export declare function transformRulesToAudits(rules: axe.RuleMetadata[]): Audit[];
|
|
8
|
+
/** Transforms Axe rules into Code PushUp groups based on accessibility categories. */
|
|
6
9
|
export declare function transformRulesToGroups(rules: axe.RuleMetadata[]): Group[];
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import axe from 'axe-core';
|
|
2
2
|
import { objectToEntries, wrapTags } from '@code-pushup/utils';
|
|
3
3
|
import { CATEGORY_GROUPS, getWcagPresetTags, } from '../groups.js';
|
|
4
|
+
/** Loads Axe rules filtered by the specified preset. */
|
|
4
5
|
export function loadAxeRules(preset) {
|
|
5
6
|
const tags = getPresetTags(preset);
|
|
6
7
|
return tags.length === 0 ? axe.getRules() : axe.getRules(tags);
|
|
7
8
|
}
|
|
9
|
+
/** Transforms Axe rule metadata into Code PushUp audit definitions. */
|
|
8
10
|
export function transformRulesToAudits(rules) {
|
|
9
11
|
return rules.map(rule => ({
|
|
10
12
|
slug: rule.ruleId,
|
|
@@ -13,6 +15,7 @@ export function transformRulesToAudits(rules) {
|
|
|
13
15
|
docsUrl: rule.helpUrl,
|
|
14
16
|
}));
|
|
15
17
|
}
|
|
18
|
+
/** Transforms Axe rules into Code PushUp groups based on accessibility categories. */
|
|
16
19
|
export function transformRulesToGroups(rules) {
|
|
17
20
|
const groups = createCategoryGroups(rules);
|
|
18
21
|
return groups.filter(({ refs }) => refs.length > 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform.js","sourceRoot":"","sources":["../../../../src/lib/meta/transform.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,UAAU,CAAC;AAE3B,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE/D,OAAO,EAEL,eAAe,EACf,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAEtB,MAAM,UAAU,YAAY,CAAC,MAAiB;IAC5C,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACnC,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAAyB;IAC9D,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACxB,IAAI,EAAE,IAAI,CAAC,MAAM;QACjB,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;QAC1B,WAAW,EAAE,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC;QACvC,OAAO,EAAE,IAAI,CAAC,OAAO;KACtB,CAAC,CAAC,CAAC;AACN,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAAyB;IAC9D,MAAM,MAAM,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC3C,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACtD,CAAC;AAED;;;;;GAKG;AACH,SAAS,aAAa,CAAC,MAAiB;IACtC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,UAAU;YACb,OAAO,iBAAiB,CAAC,UAAU,CAAC,CAAC;QACvC,KAAK,UAAU;YACb,OAAO,iBAAiB,CAAC,UAAU,CAAC,CAAC;QACvC,KAAK,eAAe;YAClB,OAAO,CAAC,eAAe,CAAC,CAAC;QAC3B,KAAK,KAAK;YACR,OAAO,EAAE,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAClB,IAAkB,EAClB,KAAa,EACb,KAAyB;IAEzB,OAAO;QACL,IAAI;QACJ,KAAK;QACL,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;KAC/D,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAyB;IACrD,OAAO,eAAe,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE;QAC5D,MAAM,GAAG,GAAG,OAAO,IAAI,EAAE,CAAC;QAC1B,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;QAErE,OAAO,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
1
|
+
{"version":3,"file":"transform.js","sourceRoot":"","sources":["../../../../src/lib/meta/transform.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,UAAU,CAAC;AAE3B,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE/D,OAAO,EAEL,eAAe,EACf,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAEtB,wDAAwD;AACxD,MAAM,UAAU,YAAY,CAAC,MAAiB;IAC5C,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACnC,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACjE,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,sBAAsB,CAAC,KAAyB;IAC9D,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACxB,IAAI,EAAE,IAAI,CAAC,MAAM;QACjB,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;QAC1B,WAAW,EAAE,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC;QACvC,OAAO,EAAE,IAAI,CAAC,OAAO;KACtB,CAAC,CAAC,CAAC;AACN,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,sBAAsB,CAAC,KAAyB;IAC9D,MAAM,MAAM,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC3C,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACtD,CAAC;AAED;;;;;GAKG;AACH,SAAS,aAAa,CAAC,MAAiB;IACtC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,UAAU;YACb,OAAO,iBAAiB,CAAC,UAAU,CAAC,CAAC;QACvC,KAAK,UAAU;YACb,OAAO,iBAAiB,CAAC,UAAU,CAAC,CAAC;QACvC,KAAK,eAAe;YAClB,OAAO,CAAC,eAAe,CAAC,CAAC;QAC3B,KAAK,KAAK;YACR,OAAO,EAAE,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAClB,IAAkB,EAClB,KAAa,EACb,KAAyB;IAEzB,OAAO;QACL,IAAI;QACJ,KAAK;QACL,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;KAC/D,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAyB;IACrD,OAAO,eAAe,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE;QAC5D,MAAM,GAAG,GAAG,OAAO,IAAI,EAAE,CAAC;QAC1B,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;QAErE,OAAO,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AxeResults } from 'axe-core';
|
|
2
2
|
import type { AuditOutputs } from '@code-pushup/models';
|
|
3
|
+
import { type SetupFunction } from './setup.js';
|
|
3
4
|
export type AxeUrlArgs = {
|
|
4
5
|
url: string;
|
|
5
6
|
urlIndex: number;
|
|
@@ -12,5 +13,27 @@ export type AxeUrlResult = {
|
|
|
12
13
|
axeResults: AxeResults;
|
|
13
14
|
auditOutputs: AuditOutputs;
|
|
14
15
|
};
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Manages Playwright browser lifecycle and runs Axe accessibility audits.
|
|
18
|
+
* Handles browser installation, authentication state, and URL analysis.
|
|
19
|
+
*/
|
|
20
|
+
export declare class AxeRunner {
|
|
21
|
+
private browser;
|
|
22
|
+
private browserInstalled;
|
|
23
|
+
private storageState;
|
|
24
|
+
/** Analyzes a URL for accessibility issues using Axe. */
|
|
25
|
+
analyzeUrl(args: AxeUrlArgs): Promise<AxeUrlResult>;
|
|
26
|
+
/** Runs setup script and captures authentication state for reuse. */
|
|
27
|
+
captureAuthState(setupFn: SetupFunction, timeout: number): Promise<void>;
|
|
28
|
+
/** Closes the browser and clears authentication state. */
|
|
29
|
+
close(): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Ensures Chromium browser binary is installed before running accessibility audits.
|
|
32
|
+
*
|
|
33
|
+
* Uses Node's module resolution and npm's bin specification to locate playwright-core CLI,
|
|
34
|
+
* working reliably with all package managers (npm, pnpm, yarn).
|
|
35
|
+
*/
|
|
36
|
+
private installBrowser;
|
|
37
|
+
/** Lazily launches or returns existing Chromium browser instance. */
|
|
38
|
+
private launchBrowser;
|
|
39
|
+
}
|
|
@@ -2,45 +2,108 @@ import { AxeBuilder } from '@axe-core/playwright';
|
|
|
2
2
|
import ansis from 'ansis';
|
|
3
3
|
import { createRequire } from 'node:module';
|
|
4
4
|
import path from 'node:path';
|
|
5
|
-
import { chromium } from 'playwright-core';
|
|
5
|
+
import { chromium, } from 'playwright-core';
|
|
6
6
|
import { executeProcess, formatAsciiTable, indentLines, logger, pluralizeToken, } from '@code-pushup/utils';
|
|
7
|
+
import { runSetup } from './setup.js';
|
|
7
8
|
import { createUrlSuffix, toAuditOutputs } from './transform.js';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const page = await context.newPage();
|
|
9
|
+
/**
|
|
10
|
+
* Manages Playwright browser lifecycle and runs Axe accessibility audits.
|
|
11
|
+
* Handles browser installation, authentication state, and URL analysis.
|
|
12
|
+
*/
|
|
13
|
+
export class AxeRunner {
|
|
14
|
+
browser;
|
|
15
|
+
browserInstalled = false;
|
|
16
|
+
storageState;
|
|
17
|
+
/** Analyzes a URL for accessibility issues using Axe. */
|
|
18
|
+
async analyzeUrl(args) {
|
|
19
|
+
const browser = await this.launchBrowser();
|
|
20
|
+
const { url, urlIndex, urlsCount } = args;
|
|
21
|
+
const prefix = ansis.gray(`[${urlIndex + 1}/${urlsCount}]`);
|
|
22
|
+
return await logger.task(`${prefix} Analyzing URL ${url}`, async () => {
|
|
23
|
+
const context = await browser.newContext({
|
|
24
|
+
...(this.storageState && { storageState: this.storageState }),
|
|
25
|
+
});
|
|
26
26
|
try {
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
const page = await context.newPage();
|
|
28
|
+
try {
|
|
29
|
+
const axeResults = await analyzePage(page, args);
|
|
30
|
+
const auditOutputs = toAuditOutputs(axeResults, createUrlSuffix(url, urlsCount));
|
|
31
|
+
return {
|
|
32
|
+
message: `${prefix} Analyzed URL ${url}`,
|
|
33
|
+
result: { url, axeResults, auditOutputs },
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
finally {
|
|
37
|
+
await page.close();
|
|
38
|
+
}
|
|
33
39
|
}
|
|
34
40
|
finally {
|
|
35
|
-
await
|
|
41
|
+
await context.close();
|
|
36
42
|
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/** Runs setup script and captures authentication state for reuse. */
|
|
46
|
+
async captureAuthState(setupFn, timeout) {
|
|
47
|
+
const browser = await this.launchBrowser();
|
|
48
|
+
const context = await browser.newContext();
|
|
49
|
+
const page = await context.newPage();
|
|
50
|
+
try {
|
|
51
|
+
page.setDefaultTimeout(timeout);
|
|
52
|
+
await runSetup(setupFn, page);
|
|
53
|
+
this.storageState = await context.storageState();
|
|
54
|
+
logger.debug('Captured authentication state from setup script');
|
|
37
55
|
}
|
|
38
56
|
finally {
|
|
57
|
+
await page.close();
|
|
39
58
|
await context.close();
|
|
59
|
+
logger.debug('Closed setup context');
|
|
40
60
|
}
|
|
41
|
-
}
|
|
61
|
+
}
|
|
62
|
+
/** Closes the browser and clears authentication state. */
|
|
63
|
+
async close() {
|
|
64
|
+
this.storageState = undefined;
|
|
65
|
+
this.browserInstalled = false;
|
|
66
|
+
if (this.browser) {
|
|
67
|
+
await this.browser.close();
|
|
68
|
+
this.browser = undefined;
|
|
69
|
+
logger.debug('Closed Chromium browser');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Ensures Chromium browser binary is installed before running accessibility audits.
|
|
74
|
+
*
|
|
75
|
+
* Uses Node's module resolution and npm's bin specification to locate playwright-core CLI,
|
|
76
|
+
* working reliably with all package managers (npm, pnpm, yarn).
|
|
77
|
+
*/
|
|
78
|
+
async installBrowser() {
|
|
79
|
+
if (this.browserInstalled) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
logger.debug('Checking Chromium browser installation ...');
|
|
83
|
+
const require = createRequire(import.meta.url);
|
|
84
|
+
const pkgPath = require.resolve('playwright-core/package.json');
|
|
85
|
+
const pkg = require(pkgPath);
|
|
86
|
+
const cliPath = path.join(path.dirname(pkgPath), pkg.bin['playwright-core']);
|
|
87
|
+
await executeProcess({
|
|
88
|
+
command: 'node',
|
|
89
|
+
args: [cliPath, 'install', 'chromium'],
|
|
90
|
+
});
|
|
91
|
+
this.browserInstalled = true;
|
|
92
|
+
}
|
|
93
|
+
/** Lazily launches or returns existing Chromium browser instance. */
|
|
94
|
+
async launchBrowser() {
|
|
95
|
+
if (this.browser) {
|
|
96
|
+
return this.browser;
|
|
97
|
+
}
|
|
98
|
+
await this.installBrowser();
|
|
99
|
+
this.browser = await logger.task('Launching Chromium browser', async () => ({
|
|
100
|
+
message: 'Launched Chromium browser',
|
|
101
|
+
result: await chromium.launch({ headless: true }),
|
|
102
|
+
}));
|
|
103
|
+
return this.browser;
|
|
104
|
+
}
|
|
42
105
|
}
|
|
43
|
-
async function
|
|
106
|
+
async function analyzePage(page, { url, ruleIds, timeout }) {
|
|
44
107
|
await page.goto(url, {
|
|
45
108
|
waitUntil: 'networkidle',
|
|
46
109
|
timeout,
|
|
@@ -74,32 +137,4 @@ async function runAxeForPage(page, { url, ruleIds, timeout }) {
|
|
|
74
137
|
}
|
|
75
138
|
return results;
|
|
76
139
|
}
|
|
77
|
-
export async function closeBrowser() {
|
|
78
|
-
if (browser) {
|
|
79
|
-
await browser.close();
|
|
80
|
-
browser = undefined;
|
|
81
|
-
logger.debug('Closed Chromium browser');
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Ensures Chromium browser binary is installed before running accessibility audits.
|
|
86
|
-
*
|
|
87
|
-
* Uses Node's module resolution and npm's bin specification to locate playwright-core CLI,
|
|
88
|
-
* working reliably with all package managers (npm, pnpm, yarn).
|
|
89
|
-
*/
|
|
90
|
-
async function ensureBrowserInstalled() {
|
|
91
|
-
if (browserChecked) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
logger.debug('Checking Chromium browser installation ...');
|
|
95
|
-
const require = createRequire(import.meta.url);
|
|
96
|
-
const pkgPath = require.resolve('playwright-core/package.json');
|
|
97
|
-
const pkg = require(pkgPath);
|
|
98
|
-
const cliPath = path.join(path.dirname(pkgPath), pkg.bin['playwright-core']);
|
|
99
|
-
await executeProcess({
|
|
100
|
-
command: 'node',
|
|
101
|
-
args: [cliPath, 'install', 'chromium'],
|
|
102
|
-
});
|
|
103
|
-
browserChecked = true;
|
|
104
|
-
}
|
|
105
140
|
//# sourceMappingURL=run-axe.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-axe.js","sourceRoot":"","sources":["../../../../src/lib/runner/run-axe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,
|
|
1
|
+
{"version":3,"file":"run-axe.js","sourceRoot":"","sources":["../../../../src/lib/runner/run-axe.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import type { RunnerFunction } from '@code-pushup/models';
|
|
2
|
-
|
|
2
|
+
/** Creates a runner function that executes Axe accessibility audits for given URLs. */
|
|
3
|
+
export declare function createRunnerFunction(urls: string[], ruleIds: string[], timeout: number, setupScript?: string): RunnerFunction;
|
package/src/lib/runner/runner.js
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import { addIndex, asyncSequential, formatAsciiTable, logger, pluralizeToken, shouldExpandForUrls, stringifyError, } from '@code-pushup/utils';
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { AxeRunner } from './run-axe.js';
|
|
3
|
+
import { loadSetupScript } from './setup.js';
|
|
4
|
+
/** Creates a runner function that executes Axe accessibility audits for given URLs. */
|
|
5
|
+
export function createRunnerFunction(urls, ruleIds, timeout, setupScript) {
|
|
4
6
|
return async () => {
|
|
7
|
+
const runner = new AxeRunner();
|
|
5
8
|
const urlsCount = urls.length;
|
|
6
9
|
logger.info(`Running Axe accessibility checks for ${pluralizeToken('URL', urlsCount)} ...`);
|
|
7
10
|
try {
|
|
8
|
-
|
|
11
|
+
if (setupScript) {
|
|
12
|
+
const setupFn = await loadSetupScript(setupScript);
|
|
13
|
+
await runner.captureAuthState(setupFn, timeout);
|
|
14
|
+
}
|
|
15
|
+
const results = await asyncSequential(urls, async (url, urlIndex) => runForUrl(runner, { urlsCount, ruleIds, timeout, url, urlIndex }));
|
|
9
16
|
const collectedResults = results.filter(res => res != null);
|
|
10
17
|
const auditOutputs = collectedResults.flatMap(res => res.auditOutputs);
|
|
11
18
|
if (collectedResults.length === 0) {
|
|
@@ -17,14 +24,14 @@ export function createRunnerFunction(urls, ruleIds, timeout) {
|
|
|
17
24
|
return auditOutputs;
|
|
18
25
|
}
|
|
19
26
|
finally {
|
|
20
|
-
await
|
|
27
|
+
await runner.close();
|
|
21
28
|
}
|
|
22
29
|
};
|
|
23
30
|
}
|
|
24
|
-
async function runForUrl(args) {
|
|
31
|
+
async function runForUrl(runner, args) {
|
|
25
32
|
const { url, urlsCount, urlIndex } = args;
|
|
26
33
|
try {
|
|
27
|
-
const result = await
|
|
34
|
+
const result = await runner.analyzeUrl(args);
|
|
28
35
|
if (shouldExpandForUrls(urlsCount)) {
|
|
29
36
|
return {
|
|
30
37
|
...result,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../../src/lib/runner/runner.ts"],"names":[],"mappings":"AACA,OAAO,EACL,QAAQ,EACR,eAAe,EACf,gBAAgB,EAChB,MAAM,EACN,cAAc,EACd,mBAAmB,EACnB,cAAc,GACf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../../src/lib/runner/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Page } from 'playwright-core';
|
|
2
|
+
import { z } from 'zod/v4';
|
|
3
|
+
declare const setupFunctionSchema: z.ZodPipe<z.ZodCustom<unknown, unknown>, z.ZodTransform<z.core.$InferInnerFunctionTypeAsync<z.ZodTuple<readonly [z.ZodCustom<Page, Page>], null>, z.ZodVoid>, unknown>>;
|
|
4
|
+
export type SetupFunction = z.infer<typeof setupFunctionSchema>;
|
|
5
|
+
/** Loads and validates a setup script module from the given path. */
|
|
6
|
+
export declare function loadSetupScript(setupScript: string): Promise<SetupFunction>;
|
|
7
|
+
/** Executes the setup function with the provided Playwright page. */
|
|
8
|
+
export declare function runSetup(setupFn: SetupFunction, page: Page): Promise<void>;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { z } from 'zod/v4';
|
|
3
|
+
import { convertAsyncZodFunctionToSchema, validateAsync, } from '@code-pushup/models';
|
|
4
|
+
import { fileExists, logger } from '@code-pushup/utils';
|
|
5
|
+
const setupFunctionSchema = convertAsyncZodFunctionToSchema(z.function({
|
|
6
|
+
input: [z.custom(val => val != null && typeof val === 'object')],
|
|
7
|
+
output: z.void(),
|
|
8
|
+
})).meta({
|
|
9
|
+
title: 'SetupFunction',
|
|
10
|
+
description: 'Async function that authenticates using a Playwright Page',
|
|
11
|
+
});
|
|
12
|
+
const setupScriptModuleSchema = z
|
|
13
|
+
.object({ default: setupFunctionSchema })
|
|
14
|
+
.meta({
|
|
15
|
+
title: 'SetupScriptModule',
|
|
16
|
+
description: 'ES module with a default export containing the authentication setup function',
|
|
17
|
+
});
|
|
18
|
+
/** Loads and validates a setup script module from the given path. */
|
|
19
|
+
export async function loadSetupScript(setupScript) {
|
|
20
|
+
const absolutePath = path.isAbsolute(setupScript)
|
|
21
|
+
? setupScript
|
|
22
|
+
: path.join(process.cwd(), setupScript);
|
|
23
|
+
if (!(await fileExists(absolutePath))) {
|
|
24
|
+
throw new Error(`Setup script not found: ${absolutePath}`);
|
|
25
|
+
}
|
|
26
|
+
const validModule = await logger.task(`Loading setup script from ${absolutePath}`, async () => {
|
|
27
|
+
const module = await import(absolutePath);
|
|
28
|
+
const validated = await validateAsync(setupScriptModuleSchema, module, {
|
|
29
|
+
filePath: absolutePath,
|
|
30
|
+
});
|
|
31
|
+
return { message: 'Setup script loaded successfully', result: validated };
|
|
32
|
+
});
|
|
33
|
+
return validModule.default;
|
|
34
|
+
}
|
|
35
|
+
/** Executes the setup function with the provided Playwright page. */
|
|
36
|
+
export async function runSetup(setupFn, page) {
|
|
37
|
+
await logger.task('Running authentication setup script', async () => {
|
|
38
|
+
await setupFn(page);
|
|
39
|
+
return { message: 'Authentication setup completed', result: undefined };
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../../src/lib/runner/setup.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAC3B,OAAO,EACL,+BAA+B,EAC/B,aAAa,GACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,mBAAmB,GAAG,+BAA+B,CACzD,CAAC,CAAC,QAAQ,CAAC;IACT,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAO,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC;IACtE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE;CACjB,CAAC,CACH,CAAC,IAAI,CAAC;IACL,KAAK,EAAE,eAAe;IACtB,WAAW,EAAE,2DAA2D;CACzE,CAAC,CAAC;AAGH,MAAM,uBAAuB,GAAG,CAAC;KAC9B,MAAM,CAAC,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC;KACxC,IAAI,CAAC;IACJ,KAAK,EAAE,mBAAmB;IAC1B,WAAW,EACT,8EAA8E;CACjF,CAAC,CAAC;AAEL,qEAAqE;AACrE,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,WAAmB;IAEnB,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAC/C,CAAC,CAAC,WAAW;QACb,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAAC;IAE1C,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,2BAA2B,YAAY,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,IAAI,CACnC,6BAA6B,YAAY,EAAE,EAC3C,KAAK,IAAI,EAAE;QACT,MAAM,MAAM,GAAY,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QACnD,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,uBAAuB,EAAE,MAAM,EAAE;YACrE,QAAQ,EAAE,YAAY;SACvB,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,kCAAkC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC5E,CAAC,CACF,CAAC;IAEF,OAAO,WAAW,CAAC,OAAO,CAAC;AAC7B,CAAC;AAED,qEAAqE;AACrE,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,OAAsB,EACtB,IAAU;IAEV,MAAM,MAAM,CAAC,IAAI,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QAClE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QACpB,OAAO,EAAE,OAAO,EAAE,gCAAgC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC1E,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/src/lib/utils.d.ts
CHANGED
|
@@ -1,4 +1,28 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type
|
|
1
|
+
import { type CategoryRef, type PluginConfig } from '@code-pushup/models';
|
|
2
|
+
import { type AxeGroupSlug } from './groups.js';
|
|
3
|
+
/**
|
|
4
|
+
* @deprecated Use `axeGroupRefs` instead for multi-URL support.
|
|
5
|
+
*/
|
|
3
6
|
export declare function axeGroupRef(groupSlug: AxeGroupSlug, weight?: number): CategoryRef;
|
|
7
|
+
/**
|
|
8
|
+
* @deprecated Use `axeAuditRefs` instead for multi-URL support.
|
|
9
|
+
*/
|
|
4
10
|
export declare function axeAuditRef(auditSlug: string, weight?: number): CategoryRef;
|
|
11
|
+
/**
|
|
12
|
+
* Creates category refs for Axe groups with multi-URL support.
|
|
13
|
+
*
|
|
14
|
+
* @param plugin - Axe plugin instance
|
|
15
|
+
* @param groupSlug - Optional group slug; if omitted, includes all groups
|
|
16
|
+
* @param groupWeight - Optional weight for the ref(s)
|
|
17
|
+
* @returns Array of category refs, expanded for each URL in multi-URL configs
|
|
18
|
+
*/
|
|
19
|
+
export declare function axeGroupRefs(plugin: Pick<PluginConfig, 'groups' | 'context'>, groupSlug?: AxeGroupSlug, groupWeight?: number): CategoryRef[];
|
|
20
|
+
/**
|
|
21
|
+
* Creates category refs for Axe audits with multi-URL support.
|
|
22
|
+
*
|
|
23
|
+
* @param plugin - Axe plugin instance
|
|
24
|
+
* @param auditSlug - Optional audit slug; if omitted, includes all audits
|
|
25
|
+
* @param auditWeight - Optional weight for the ref(s)
|
|
26
|
+
* @returns Array of category refs, expanded for each URL in multi-URL configs
|
|
27
|
+
*/
|
|
28
|
+
export declare function axeAuditRefs(plugin: Pick<PluginConfig, 'audits' | 'context'>, auditSlug?: string, auditWeight?: number): CategoryRef[];
|
package/src/lib/utils.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
+
import { validate, } from '@code-pushup/models';
|
|
2
|
+
import { expandCategoryRefs, extractGroupSlugs, pluginUrlContextSchema, } from '@code-pushup/utils';
|
|
1
3
|
import { AXE_PLUGIN_SLUG } from './constants.js';
|
|
4
|
+
import { isAxeGroupSlug } from './groups.js';
|
|
5
|
+
/**
|
|
6
|
+
* @deprecated Use `axeGroupRefs` instead for multi-URL support.
|
|
7
|
+
*/
|
|
2
8
|
export function axeGroupRef(groupSlug, weight = 1) {
|
|
3
9
|
return {
|
|
4
10
|
plugin: AXE_PLUGIN_SLUG,
|
|
@@ -7,6 +13,9 @@ export function axeGroupRef(groupSlug, weight = 1) {
|
|
|
7
13
|
weight,
|
|
8
14
|
};
|
|
9
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* @deprecated Use `axeAuditRefs` instead for multi-URL support.
|
|
18
|
+
*/
|
|
10
19
|
export function axeAuditRef(auditSlug, weight = 1) {
|
|
11
20
|
return {
|
|
12
21
|
plugin: AXE_PLUGIN_SLUG,
|
|
@@ -15,4 +24,50 @@ export function axeAuditRef(auditSlug, weight = 1) {
|
|
|
15
24
|
weight,
|
|
16
25
|
};
|
|
17
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Creates category refs for Axe groups with multi-URL support.
|
|
29
|
+
*
|
|
30
|
+
* @param plugin - Axe plugin instance
|
|
31
|
+
* @param groupSlug - Optional group slug; if omitted, includes all groups
|
|
32
|
+
* @param groupWeight - Optional weight for the ref(s)
|
|
33
|
+
* @returns Array of category refs, expanded for each URL in multi-URL configs
|
|
34
|
+
*/
|
|
35
|
+
export function axeGroupRefs(plugin, groupSlug, groupWeight) {
|
|
36
|
+
const context = validate(pluginUrlContextSchema, plugin.context);
|
|
37
|
+
if (groupSlug) {
|
|
38
|
+
return expandCategoryRefs({
|
|
39
|
+
slug: groupSlug,
|
|
40
|
+
weight: groupWeight,
|
|
41
|
+
type: 'group',
|
|
42
|
+
plugin: AXE_PLUGIN_SLUG,
|
|
43
|
+
}, context);
|
|
44
|
+
}
|
|
45
|
+
return axeGroupSlugs(plugin).flatMap(slug => expandCategoryRefs({ slug, type: 'group', plugin: AXE_PLUGIN_SLUG }, context));
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Creates category refs for Axe audits with multi-URL support.
|
|
49
|
+
*
|
|
50
|
+
* @param plugin - Axe plugin instance
|
|
51
|
+
* @param auditSlug - Optional audit slug; if omitted, includes all audits
|
|
52
|
+
* @param auditWeight - Optional weight for the ref(s)
|
|
53
|
+
* @returns Array of category refs, expanded for each URL in multi-URL configs
|
|
54
|
+
*/
|
|
55
|
+
export function axeAuditRefs(plugin, auditSlug, auditWeight) {
|
|
56
|
+
const context = validate(pluginUrlContextSchema, plugin.context);
|
|
57
|
+
if (auditSlug) {
|
|
58
|
+
return expandCategoryRefs({
|
|
59
|
+
slug: auditSlug,
|
|
60
|
+
weight: auditWeight,
|
|
61
|
+
type: 'audit',
|
|
62
|
+
plugin: AXE_PLUGIN_SLUG,
|
|
63
|
+
}, context);
|
|
64
|
+
}
|
|
65
|
+
return plugin.audits.flatMap(({ slug }) => expandCategoryRefs({ slug, type: 'audit', plugin: AXE_PLUGIN_SLUG }, context));
|
|
66
|
+
}
|
|
67
|
+
function axeGroupSlugs(plugin) {
|
|
68
|
+
if (!plugin.groups) {
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
return extractGroupSlugs(plugin.groups).filter(isAxeGroupSlug);
|
|
72
|
+
}
|
|
18
73
|
//# sourceMappingURL=utils.js.map
|
package/src/lib/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/lib/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/lib/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,QAAQ,GACT,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAqB,cAAc,EAAE,MAAM,aAAa,CAAC;AAEhE;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,SAAuB,EAAE,MAAM,GAAG,CAAC;IAC7D,OAAO;QACL,MAAM,EAAE,eAAe;QACvB,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,OAAO;QACb,MAAM;KACP,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,SAAiB,EAAE,MAAM,GAAG,CAAC;IACvD,OAAO;QACL,MAAM,EAAE,eAAe;QACvB,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,OAAO;QACb,MAAM;KACP,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAC1B,MAAgD,EAChD,SAAwB,EACxB,WAAoB;IAEpB,MAAM,OAAO,GAAG,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACjE,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,kBAAkB,CACvB;YACE,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,WAAW;YACnB,IAAI,EAAE,OAAO;YACb,MAAM,EAAE,eAAe;SACxB,EACD,OAAO,CACR,CAAC;IACJ,CAAC;IACD,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAC1C,kBAAkB,CAChB,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,EAChD,OAAO,CACR,CACF,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAC1B,MAAgD,EAChD,SAAkB,EAClB,WAAoB;IAEpB,MAAM,OAAO,GAAG,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACjE,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,kBAAkB,CACvB;YACE,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,WAAW;YACnB,IAAI,EAAE,OAAO;YACb,MAAM,EAAE,eAAe;SACxB,EACD,OAAO,CACR,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CACxC,kBAAkB,CAChB,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,EAChD,OAAO,CACR,CACF,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,MAAoC;IACzD,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,iBAAiB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;AACjE,CAAC"}
|