v11y-check 0.18.0 โ 0.19.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/.meta/changelog.json +103 -1
- package/.readyup/kits/default.js +6 -6
- package/.readyup/manifest.json +4 -4
- package/CHANGELOG.md +33 -1
- package/README.md +28 -25
- package/bin/v11y.js +1 -1
- package/dist/esm/bin/route.d.ts +1 -1
- package/dist/esm/bin/route.js +37 -1
- package/dist/esm/cli.d.ts +5 -5
- package/dist/esm/config.d.ts +2 -2
- package/dist/esm/format-actions.d.ts +1 -1
- package/dist/esm/format-check.d.ts +5 -5
- package/dist/esm/format-summary.d.ts +2 -2
- package/dist/esm/format-time.d.ts +1 -3
- package/dist/esm/format-verbose.d.ts +1 -1
- package/dist/esm/generate.d.ts +3 -3
- package/dist/esm/glyphs.d.ts +3 -3
- package/dist/esm/init/initCommand.d.ts +1 -1
- package/dist/esm/init/scaffold.d.ts +12 -16
- package/dist/esm/init/scaffold.js +11 -12
- package/dist/esm/init/updateTemplatesCommand.d.ts +12 -0
- package/dist/esm/init/updateTemplatesCommand.js +14 -0
- package/dist/esm/resolveStyles.d.ts +2 -2
- package/dist/esm/run-audit.d.ts +5 -9
- package/dist/esm/sync.d.ts +8 -8
- package/dist/esm/sync.js +1 -1
- package/dist/esm/tmp.d.ts +1 -3
- package/dist/esm/types.d.ts +4 -6
- package/package.json +4 -3
- package/templates/audit.yaml.template +2 -2
package/.meta/changelog.json
CHANGED
|
@@ -1,4 +1,106 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.19.0",
|
|
4
|
+
"date": "2026-10-01",
|
|
5
|
+
"sections": [
|
|
6
|
+
{
|
|
7
|
+
"title": "๐ Features",
|
|
8
|
+
"audience": "all",
|
|
9
|
+
"items": [
|
|
10
|
+
{
|
|
11
|
+
"description": "Adds `v11y update-templates`, which writes `.github/workflows/audit.yaml` when it is missing or differs from the installed template, prints a diff of the update, and never reads or writes the config file. (#952)",
|
|
12
|
+
"hash": "9fac96675e9fb4dd70407cbfb0e3e0ffa7e83ba4",
|
|
13
|
+
"entry": 2
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"description": "Changes the readyup kits' fix messages for a workflow that differs from its template, or that references a deprecated tag, to recommend `update-templates` rather than `init --force`. (#952)",
|
|
17
|
+
"hash": "9fac96675e9fb4dd70407cbfb0e3e0ffa7e83ba4",
|
|
18
|
+
"entry": 3
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"title": "๐ Bug fixes",
|
|
24
|
+
"audience": "all",
|
|
25
|
+
"items": [
|
|
26
|
+
{
|
|
27
|
+
"description": "Rewords the `v11y-check` README and the message that `v11y` prints for missing build output, which addressed the reader in the second person and used em-dashes and figurative verbs. (#939)",
|
|
28
|
+
"hash": "700bc1f5ef09a8e6167de0bf109940f26eb4c18e",
|
|
29
|
+
"entry": 1
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"description": "Fixes the issue that two comments in the `audit.yaml` workflow generated by `v11y init` did not follow the project's writing rules; the v11y-check kit check reports a previously generated `audit.yaml` as stale until `v11y init --force` regenerates it. (#946)",
|
|
33
|
+
"hash": "dc1c4bd4b05425ed1c2a7d031105c402c3d01f20",
|
|
34
|
+
"entry": 2
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"title": "โป๏ธ Refactoring",
|
|
40
|
+
"audience": "dev",
|
|
41
|
+
"items": [
|
|
42
|
+
{
|
|
43
|
+
"description": "Replaces every `.sort()` call that suppressed `unicorn/no-array-sort` with `toSorted()` and drops the spread copy wherever the source was already an array. (#925)",
|
|
44
|
+
"hash": "4680fb4e865ffce0bd135fac20d49b766b156992",
|
|
45
|
+
"entry": 1
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"title": "๐งช Tests",
|
|
51
|
+
"audience": "dev",
|
|
52
|
+
"items": [
|
|
53
|
+
{
|
|
54
|
+
"description": "Renames the `resolveAuditCiBin` test to `returns a non-empty path to the audit-ci bin`, because the old title claimed that it exercised the fallback, and moves a verbose-hint test from the \"Threshold annotation\" group to the \"Actions footer\" group of `format-check.unit.test.ts`. (#924)",
|
|
55
|
+
"hash": "71a216c8403245b45c42acd06c23ebad09063c1f",
|
|
56
|
+
"entry": 2
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"description": "Moves the helpers in the `format-check`, `format-summary`, and `format-verbose` unit tests below their `describe` blocks and sorts them alphabetically, matching `cli.unit.test.ts` and `run-audit.unit.test.ts`. (#947)",
|
|
60
|
+
"hash": "a0b69c1fa72236e877d1b973140ad6ac40a91018",
|
|
61
|
+
"entry": 2
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"title": "๐ฆ Dependencies",
|
|
67
|
+
"audience": "dev",
|
|
68
|
+
"items": [
|
|
69
|
+
{
|
|
70
|
+
"description": "Adds `esbuild` 0.28.2 to the pnpm catalog and declares it as a devDependency of `nmr`, `release-kit`, and `v11y-check`, because `readyup` declares it only as an optional peer and `rdy compile` failed in those packages once a regenerated lockfile stopped installing it. (#944)",
|
|
71
|
+
"hash": "6dffd5df5bc4209dc225d08390ef2b67fe381f1b",
|
|
72
|
+
"entry": 2
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"title": "๐ Documentation",
|
|
78
|
+
"audience": "dev",
|
|
79
|
+
"items": [
|
|
80
|
+
{
|
|
81
|
+
"description": "Revises the comments in `packages/v11y-check/src` and the `default` readyup kit against the comment-discipline rules, correcting the ones that misstated the code, such as the `@internal Exported for testing` tags on functions that production code calls, and deleting the ones that restated it. (#924)",
|
|
82
|
+
"hash": "71a216c8403245b45c42acd06c23ebad09063c1f",
|
|
83
|
+
"entry": 1
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"description": "Revises the doc comments, code comments, and test titles across `packages/v11y-check`, including its readyup kit, to follow the plain-speech doctrine and writing conventions. (#939)",
|
|
87
|
+
"hash": "700bc1f5ef09a8e6167de0bf109940f26eb4c18e",
|
|
88
|
+
"entry": 2
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"description": "Replaces the inline headings of the `Types` and `Display ID helper` sections in `format-check.ts`, and of the `Helpers` sections in the `format-check`, `format-summary`, and `format-verbose` unit tests, with `// region | โฆ` / `// endregion | โฆ` folds, which the house style reserves for supporting blocks. (#947)",
|
|
92
|
+
"hash": "a0b69c1fa72236e877d1b973140ad6ac40a91018",
|
|
93
|
+
"entry": 1
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"description": "Retitles the `Dependency updates` section of v11y-check's 0.14.1 changelog entry to `๐ฆ Dependencies`, in `.meta/changelog.json` and in the `CHANGELOG.md` rendered from it, so that the next release does not re-emit the retired title. (#950)",
|
|
97
|
+
"hash": "5a4771a1cb1e1b324a9ce3cb64fc3527199946a7",
|
|
98
|
+
"entry": 2
|
|
99
|
+
}
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
]
|
|
103
|
+
},
|
|
2
104
|
{
|
|
3
105
|
"version": "0.18.0",
|
|
4
106
|
"date": "2026-09-18",
|
|
@@ -307,7 +409,7 @@
|
|
|
307
409
|
"date": "2026-08-04",
|
|
308
410
|
"sections": [
|
|
309
411
|
{
|
|
310
|
-
"title": "
|
|
412
|
+
"title": "๐ฆ Dependencies",
|
|
311
413
|
"audience": "dev",
|
|
312
414
|
"items": [{ "description": "Bumped `@williamthorsen/nmr-core` to 0.9.1" }]
|
|
313
415
|
}
|
package/.readyup/kits/default.js
CHANGED
|
@@ -8,13 +8,13 @@ import { existsSync } from "node:fs";
|
|
|
8
8
|
import { join } from "node:path";
|
|
9
9
|
import { defineRdyKit } from "readyup";
|
|
10
10
|
import { fileExists, fileMatchesHash, hasDevDependency, hasMinDevDependencyVersion } from "readyup/check-utils";
|
|
11
|
-
var AUDIT_WORKFLOW_HASH = "
|
|
11
|
+
var AUDIT_WORKFLOW_HASH = "ad969e3fefe603cee04de02e300e6f4d4d9dae9e8e58bddb9db81980115bc260";
|
|
12
12
|
var default_default = defineRdyKit({
|
|
13
13
|
checklists: [
|
|
14
14
|
{
|
|
15
15
|
name: "v11y-check",
|
|
16
16
|
checks: [
|
|
17
|
-
// -- Setup
|
|
17
|
+
// -- Setup --
|
|
18
18
|
{
|
|
19
19
|
name: "v11y-check in devDependencies",
|
|
20
20
|
severity: "error",
|
|
@@ -35,7 +35,7 @@ var default_default = defineRdyKit({
|
|
|
35
35
|
}
|
|
36
36
|
]
|
|
37
37
|
},
|
|
38
|
-
// -- Audit-ci config migration
|
|
38
|
+
// -- Audit-ci config migration --
|
|
39
39
|
{
|
|
40
40
|
name: "audit-ci configs are under .config/audit-ci/",
|
|
41
41
|
severity: "warn",
|
|
@@ -43,7 +43,7 @@ var default_default = defineRdyKit({
|
|
|
43
43
|
check: noLegacyAuditCiDirectory,
|
|
44
44
|
fix: "Move audit-ci configs from .audit-ci/ to .config/audit-ci/ and update references"
|
|
45
45
|
},
|
|
46
|
-
// -- Audit workflow
|
|
46
|
+
// -- Audit workflow --
|
|
47
47
|
{
|
|
48
48
|
name: "audit.yaml workflow exists",
|
|
49
49
|
severity: "warn",
|
|
@@ -54,7 +54,7 @@ var default_default = defineRdyKit({
|
|
|
54
54
|
name: "audit.yaml matches template",
|
|
55
55
|
severity: "warn",
|
|
56
56
|
check: () => fileMatchesHash(".github/workflows/audit.yaml", AUDIT_WORKFLOW_HASH),
|
|
57
|
-
fix: "Run `v11y
|
|
57
|
+
fix: "Run `v11y update-templates` to regenerate audit.yaml from the current template"
|
|
58
58
|
}
|
|
59
59
|
]
|
|
60
60
|
}
|
|
@@ -63,7 +63,7 @@ var default_default = defineRdyKit({
|
|
|
63
63
|
]
|
|
64
64
|
});
|
|
65
65
|
function getMinVersion() {
|
|
66
|
-
const picked = { "version": "0.
|
|
66
|
+
const picked = { "version": "0.19.0" };
|
|
67
67
|
if (typeof picked["version"] !== "string") {
|
|
68
68
|
throw new TypeError("v11y-check/package.json: 'version' must be a string");
|
|
69
69
|
}
|
package/.readyup/manifest.json
CHANGED
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
"esbuildVersion": "0.28.2",
|
|
9
9
|
"inputs": [
|
|
10
10
|
{
|
|
11
|
-
"hash": "
|
|
11
|
+
"hash": "3ca06efb",
|
|
12
12
|
"kind": "module",
|
|
13
13
|
"path": "kits/default.ts"
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
|
-
"hash": "
|
|
16
|
+
"hash": "819284aa",
|
|
17
17
|
"kind": "inline",
|
|
18
18
|
"path": "../package.json",
|
|
19
19
|
"paths": [
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"path": "kits/default.js",
|
|
26
26
|
"readyupVersion": "0.38.0",
|
|
27
27
|
"source": "kits/default.ts",
|
|
28
|
-
"sourceHash": "
|
|
29
|
-
"targetHash": "
|
|
28
|
+
"sourceHash": "3ca06efb",
|
|
29
|
+
"targetHash": "32c10111"
|
|
30
30
|
}
|
|
31
31
|
]
|
|
32
32
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,38 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## 0.19.0 โ 2026-10-01
|
|
6
|
+
|
|
7
|
+
### ๐ Features
|
|
8
|
+
|
|
9
|
+
- Adds `v11y update-templates`, which writes `.github/workflows/audit.yaml` when it is missing or differs from the installed template, prints a diff of the update, and never reads or writes the config file. (#952)
|
|
10
|
+
- Changes the readyup kits' fix messages for a workflow that differs from its template, or that references a deprecated tag, to recommend `update-templates` rather than `init --force`. (#952)
|
|
11
|
+
|
|
12
|
+
### ๐ Bug fixes
|
|
13
|
+
|
|
14
|
+
- Rewords the `v11y-check` README and the message that `v11y` prints for missing build output, which addressed the reader in the second person and used em-dashes and figurative verbs. (#939)
|
|
15
|
+
- Fixes the issue that two comments in the `audit.yaml` workflow generated by `v11y init` did not follow the project's writing rules; the v11y-check kit check reports a previously generated `audit.yaml` as stale until `v11y init --force` regenerates it. (#946)
|
|
16
|
+
|
|
17
|
+
### โป๏ธ Refactoring
|
|
18
|
+
|
|
19
|
+
- Replaces every `.sort()` call that suppressed `unicorn/no-array-sort` with `toSorted()` and drops the spread copy wherever the source was already an array. (#925)
|
|
20
|
+
|
|
21
|
+
### ๐งช Tests
|
|
22
|
+
|
|
23
|
+
- Renames the `resolveAuditCiBin` test to `returns a non-empty path to the audit-ci bin`, because the old title claimed that it exercised the fallback, and moves a verbose-hint test from the "Threshold annotation" group to the "Actions footer" group of `format-check.unit.test.ts`. (#924)
|
|
24
|
+
- Moves the helpers in the `format-check`, `format-summary`, and `format-verbose` unit tests below their `describe` blocks and sorts them alphabetically, matching `cli.unit.test.ts` and `run-audit.unit.test.ts`. (#947)
|
|
25
|
+
|
|
26
|
+
### ๐ฆ Dependencies
|
|
27
|
+
|
|
28
|
+
- Adds `esbuild` 0.28.2 to the pnpm catalog and declares it as a devDependency of `nmr`, `release-kit`, and `v11y-check`, because `readyup` declares it only as an optional peer and `rdy compile` failed in those packages once a regenerated lockfile stopped installing it. (#944)
|
|
29
|
+
|
|
30
|
+
### ๐ Documentation
|
|
31
|
+
|
|
32
|
+
- Revises the comments in `packages/v11y-check/src` and the `default` readyup kit against the comment-discipline rules, correcting the ones that misstated the code, such as the `@internal Exported for testing` tags on functions that production code calls, and deleting the ones that restated it. (#924)
|
|
33
|
+
- Revises the doc comments, code comments, and test titles across `packages/v11y-check`, including its readyup kit, to follow the plain-speech doctrine and writing conventions. (#939)
|
|
34
|
+
- Replaces the inline headings of the `Types` and `Display ID helper` sections in `format-check.ts`, and of the `Helpers` sections in the `format-check`, `format-summary`, and `format-verbose` unit tests, with `// region | โฆ` / `// endregion | โฆ` folds, which the house style reserves for supporting blocks. (#947)
|
|
35
|
+
- Retitles the `Dependency updates` section of v11y-check's 0.14.1 changelog entry to `๐ฆ Dependencies`, in `.meta/changelog.json` and in the `CHANGELOG.md` rendered from it, so that the next release does not re-emit the retired title. (#950)
|
|
36
|
+
|
|
5
37
|
## 0.18.0 โ 2026-09-18
|
|
6
38
|
|
|
7
39
|
### ๐ Features
|
|
@@ -175,7 +207,7 @@ All notable changes to this project will be documented in this file.
|
|
|
175
207
|
|
|
176
208
|
## 0.14.1 โ 2026-08-04
|
|
177
209
|
|
|
178
|
-
###
|
|
210
|
+
### ๐ฆ Dependencies
|
|
179
211
|
|
|
180
212
|
- Bumped `@williamthorsen/nmr-core` to 0.9.1
|
|
181
213
|
|
package/README.md
CHANGED
|
@@ -5,21 +5,17 @@
|
|
|
5
5
|
Wraps [audit-ci](https://github.com/IBM/audit-ci) with a richer config model, typed JSON source of truth, and a sync workflow that automates allowlist management.
|
|
6
6
|
|
|
7
7
|
<!-- section:release-notes -->
|
|
8
|
-
## Release notes โ v0.
|
|
8
|
+
## Release notes โ v0.19.0 (2026-10-01)
|
|
9
9
|
|
|
10
10
|
### ๐ Features
|
|
11
11
|
|
|
12
|
-
-
|
|
12
|
+
- Adds `v11y update-templates`, which writes `.github/workflows/audit.yaml` when it is missing or differs from the installed template, prints a diff of the update, and never reads or writes the config file. (#952)
|
|
13
|
+
- Changes the readyup kits' fix messages for a workflow that differs from its template, or that references a deprecated tag, to recommend `update-templates` rather than `init --force`. (#952)
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
- Adds the `V11Y_CHECK_OUTPUT_STYLE` environment variable, which accepts `auto`, `plain`, or `rich`, overrides that detection, and makes any other value a usage error that exits with code 1.
|
|
16
|
-
- Changes the emoji row markers of rich output: โ replaces ๐จ for an unallowed row, โ
replaces โ ๏ธ for an allowed row, โฉ replaces โน๏ธ for a below-threshold row, ๐งน replaces ๐๏ธ for a stale row, and the `allowed` and `ignored` suffixes of a compact row lose their emoji.
|
|
15
|
+
### ๐ Bug fixes
|
|
17
16
|
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
- Stops `nmr` from printing emoji to a pipe or a CI log: When the output stream is not a terminal or `CI` is set, a verdict reads `PASS`, `FAIL`, `SKIP`, or `NOOP` and a command icon is omitted, so that a log can be searched for a verdict.
|
|
21
|
-
- Adds `--output-style <auto|plain|rich>` to `nmr` and the `NMR_OUTPUT_STYLE` variable, each forcing either style; the flag outranks the variable, a value that names no style exits 1 with a usage error, and neither enters a check-cache key: A rich run and a plain run share a recorded pass.
|
|
22
|
-
- Replaces several rich glyphs, taking the status markers from the set that release-kit and v11y-check print so that one status has one glyph across the three tools: a recalled pass shows โฉ in place of โญ๏ธ, a skipped empty override shows โช in place of โ, a warning and the `--log` refusal show ๐ in place of โ ๏ธ and ๐ญ, the `--log` header shows ๐พ in place of ๐ผ, and `nmr-ensure-prepublish-hooks` reports โ
and โ in place of โ and โ.
|
|
17
|
+
- Rewords the `v11y-check` README and the message that `v11y` prints for missing build output, which addressed the reader in the second person and used em-dashes and figurative verbs. (#939)
|
|
18
|
+
- Fixes the issue that two comments in the `audit.yaml` workflow generated by `v11y init` did not follow the project's writing rules; the v11y-check kit check reports a previously generated `audit.yaml` as stale until `v11y init --force` regenerates it. (#946)
|
|
23
19
|
<!-- /section:release-notes -->
|
|
24
20
|
|
|
25
21
|
## Installation
|
|
@@ -30,7 +26,7 @@ Requires Node.js 24 or later.
|
|
|
30
26
|
pnpm add -D v11y-check
|
|
31
27
|
```
|
|
32
28
|
|
|
33
|
-
The package is `v11y-check`; the bin is `v11y`. The package also
|
|
29
|
+
The package is `v11y-check`; the bin is `v11y`. The package also declares `v11y-check` as a bin alias, so `pnpm exec v11y-check` and `npx v11y-check` continue to work.
|
|
34
30
|
|
|
35
31
|
## Quick start
|
|
36
32
|
|
|
@@ -48,7 +44,7 @@ npx v11y-check sync
|
|
|
48
44
|
npx v11y-check --raw
|
|
49
45
|
```
|
|
50
46
|
|
|
51
|
-
|
|
47
|
+
The tool does not require a config file. When `.config/v11y-check.config.json` is absent, the tool uses built-in defaults: `severityThreshold: 'moderate'` for dev, `severityThreshold: 'low'` for prod, and empty allowlists.
|
|
52
48
|
|
|
53
49
|
## Configuration
|
|
54
50
|
|
|
@@ -78,16 +74,16 @@ The source-of-truth config lives at `.config/v11y-check.config.json`:
|
|
|
78
74
|
|
|
79
75
|
### Fields
|
|
80
76
|
|
|
81
|
-
- **`$schema`** (optional)
|
|
82
|
-
- **`dev`** / **`prod
|
|
83
|
-
- **`severityThreshold`** (optional)
|
|
84
|
-
- **`allowlist
|
|
77
|
+
- **`$schema`** (optional): JSON Schema URL for editor autocomplete and validation. Automatically included by `init` and `sync`.
|
|
78
|
+
- **`dev`** / **`prod`**: Scope-specific settings:
|
|
79
|
+
- **`severityThreshold`** (optional): Fail on advisories at or above this severity. Valid values: `'low'`, `'moderate'`, `'high'`, `'critical'`. When omitted, audit-ci uses its own defaults.
|
|
80
|
+
- **`allowlist`**: Typed advisory entries with `id`, `path`, `url`, and optional `reason` and `addedAt`. `addedAt` is an ISO 8601 UTC datetime (e.g., `2026-04-15T09:30:00.000Z`) populated automatically by `v11y sync` on new entries; existing entries retain whatever value they had. Older `YYYY-MM-DD` values are still accepted.
|
|
85
81
|
|
|
86
82
|
### Output style
|
|
87
83
|
|
|
88
84
|
The `V11Y_CHECK_OUTPUT_STYLE` environment variable sets the style for every command, `init` included: `rich` marks each finding with an emoji, such as โ or โ
, and `plain` prints a word in its place, such as `FAIL` or `PASS`, which a reader of a log can search for. `auto`, the default, defers to detection. Any other value is a usage error that exits with code 1.
|
|
89
85
|
|
|
90
|
-
Detection decides stdout and stderr separately. A stream is plain when `CI` is set to anything other than an empty string or `false`, when the stream is not a terminal, or when `TERM` is `linux`; otherwise it is rich. `--json` output
|
|
86
|
+
Detection decides stdout and stderr separately. A stream is plain when `CI` is set to anything other than an empty string or `false`, when the stream is not a terminal, or when `TERM` is `linux`; otherwise it is rich. `--json` output does not contain any emoji in either style.
|
|
91
87
|
|
|
92
88
|
## CLI reference
|
|
93
89
|
|
|
@@ -99,6 +95,7 @@ Commands:
|
|
|
99
95
|
check (default) Grouped vulnerability check with severity indicators
|
|
100
96
|
sync Synchronize allowlists with current audit findings
|
|
101
97
|
init Scaffold a starter config file and GitHub Actions workflow
|
|
98
|
+
update-templates Update the scaffolded workflow to the current template
|
|
102
99
|
|
|
103
100
|
Scope options:
|
|
104
101
|
--dev Target dev dependencies only
|
|
@@ -125,6 +122,12 @@ Environment:
|
|
|
125
122
|
--force, -f Overwrite an existing workflow (an existing config is never overwritten)
|
|
126
123
|
```
|
|
127
124
|
|
|
125
|
+
### Update-templates options
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
--dry-run, -n Preview changes without writing files
|
|
129
|
+
```
|
|
130
|
+
|
|
128
131
|
### JSON output shape
|
|
129
132
|
|
|
130
133
|
`--json` emits one object per requested scope plus a top-level `summary` block:
|
|
@@ -150,15 +153,15 @@ Environment:
|
|
|
150
153
|
|
|
151
154
|
## Scaffolded GitHub Actions workflow
|
|
152
155
|
|
|
153
|
-
`v11y init` scaffolds `.github/workflows/audit.yaml` alongside the config file. The workflow is a thin caller that delegates to the versioned reusable workflow published at `williamthorsen/node-monorepo-tools/.github/workflows/audit.reusable.yaml@workflow/audit-v1`, so
|
|
156
|
+
`v11y init` scaffolds `.github/workflows/audit.yaml` alongside the config file. The workflow is a thin caller that delegates to the versioned reusable workflow published at `williamthorsen/node-monorepo-tools/.github/workflows/audit.reusable.yaml@workflow/audit-v1`, so the consuming repository tracks the reusable workflow at a stable version tag.
|
|
154
157
|
|
|
155
|
-
The scaffolded workflow triggers on pull requests to `main`/`next`, on a daily schedule, and on manual `workflow_dispatch`. Commit the file into
|
|
158
|
+
The scaffolded workflow triggers on pull requests to `main`/`next`, on a daily schedule, and on manual `workflow_dispatch`. Commit the file into the repository so that the caller runs in CI. If the reusable workflow's caller-side requirements change (for example, the tag bumps), run `v11y update-templates` to refresh the file, which shows what changed and leaves the config file untouched.
|
|
156
159
|
|
|
157
|
-
The reusable workflow installs pnpm with [`pnpm/setup`](https://github.com/pnpm/setup), which installs pnpm 11 or newer only and reads the version from
|
|
160
|
+
The reusable workflow installs pnpm with [`pnpm/setup`](https://github.com/pnpm/setup), which installs pnpm 11 or newer only and reads the version from the repository's `devEngines.packageManager` or `packageManager` field. A repository pinned below that cannot run it.
|
|
158
161
|
|
|
159
162
|
## Readiness checks
|
|
160
163
|
|
|
161
|
-
v11y-check publishes a [readyup](https://www.npmjs.com/package/readyup) kit that checks a consuming repo against the release it has installed: that v11y-check is a devDependency at or above the current version, that audit-ci configs
|
|
164
|
+
v11y-check publishes a [readyup](https://www.npmjs.com/package/readyup) kit that checks a consuming repo against the release that it has installed: that v11y-check is a devDependency at or above the current version, that audit-ci configs are under `.config/audit-ci/`, and that `.github/workflows/audit.yaml` matches the template scaffolded by this package. The kit is included in the package, so it checks against the installed version rather than whatever a repository ref happens to point at.
|
|
162
165
|
|
|
163
166
|
Add `readyup` as a devDependency, then name v11y-check in its config:
|
|
164
167
|
|
|
@@ -172,12 +175,12 @@ export default defineRdyConfig({
|
|
|
172
175
|
```
|
|
173
176
|
|
|
174
177
|
```bash
|
|
175
|
-
rdy run --packages # every kit each listed package publishes
|
|
178
|
+
rdy run --packages # every kit that each listed package publishes
|
|
176
179
|
rdy run --from npm:v11y-check # v11y-check's kit alone, without the config entry
|
|
177
180
|
rdy list --from npm:v11y-check # what v11y-check publishes
|
|
178
181
|
```
|
|
179
182
|
|
|
180
|
-
`--packages` is the form that
|
|
183
|
+
`--packages` is the form that keeps working if v11y-check publishes further kits. Every form needs `readyup` 0.23 or later, and `v11y-check` as a _direct_ devDependency: A strict pnpm layout links only direct dependencies into the project, which leaves a transitive copy unreachable.
|
|
181
184
|
|
|
182
185
|
The kit is no longer reachable through `rdy run --from github:williamthorsen/node-monorepo-tools`. Repos still using that form should switch to one of the invocations above.
|
|
183
186
|
|
|
@@ -185,7 +188,7 @@ The kit is no longer reachable through `rdy run --from github:williamthorsen/nod
|
|
|
185
188
|
|
|
186
189
|
v0.4 introduces breaking changes to the config schema:
|
|
187
190
|
|
|
188
|
-
- **`outDir` removed.** Intermediate audit-ci files are now written to a temp directory and cleaned up automatically. Remove `outDir` from
|
|
191
|
+
- **`outDir` removed.** Intermediate audit-ci files are now written to a temp directory and cleaned up automatically. Remove `outDir` from the config.
|
|
189
192
|
- **Severity booleans replaced by `severityThreshold`.** Replace `"moderate": true` with `"severityThreshold": "moderate"`, `"high": true` with `"severityThreshold": "high"`, etc. Only one threshold per scope is supported.
|
|
190
193
|
- **`generate` subcommand removed.** The `v11y generate` command no longer exists. Flat audit-ci configs are now managed internally.
|
|
191
194
|
- **Config is optional.** All commands now work without a config file, using built-in defaults.
|
|
@@ -195,4 +198,4 @@ To migrate an existing config:
|
|
|
195
198
|
1. Remove the `outDir` field.
|
|
196
199
|
2. Replace severity booleans with `severityThreshold` in each scope.
|
|
197
200
|
3. Optionally add a `$schema` field set to `https://github.com/williamthorsen/node-monorepo-tools/raw/v11y-check-v<version>/packages/v11y-check/schemas/config.json`, with `<version>` replaced by the installed v11y-check version.
|
|
198
|
-
4. Delete any generated `audit-ci.*.json` files that were in
|
|
201
|
+
4. Delete any generated `audit-ci.*.json` files that were in the config directory.
|
package/bin/v11y.js
CHANGED
|
@@ -3,7 +3,7 @@ try {
|
|
|
3
3
|
await import('../dist/esm/bin/v11y.js');
|
|
4
4
|
} catch (error) {
|
|
5
5
|
if (error.code === 'ERR_MODULE_NOT_FOUND') {
|
|
6
|
-
process.stderr.write('v11y: build output not found
|
|
6
|
+
process.stderr.write('v11y: build output not found; run `nmr build` first\n');
|
|
7
7
|
} else {
|
|
8
8
|
process.stderr.write(`v11y: failed to load: ${error.message}\n`);
|
|
9
9
|
}
|
package/dist/esm/bin/route.d.ts
CHANGED
package/dist/esm/bin/route.js
CHANGED
|
@@ -3,9 +3,10 @@ import { parseArgs, readPackageVersion, reportError } from '@williamthorsen/nmr-
|
|
|
3
3
|
import { describeError } from '@williamthorsen/toolbelt.errors';
|
|
4
4
|
import { auditCommand, checkCommand, syncCommand } from "../cli.js";
|
|
5
5
|
import { initCommand } from "../init/initCommand.js";
|
|
6
|
+
import { updateTemplatesCommand } from "../init/updateTemplatesCommand.js";
|
|
6
7
|
import { OUTPUT_STYLE_ENV_VAR, resolveStyles } from "../resolveStyles.js";
|
|
7
8
|
const VERSION = readPackageVersion(import.meta.url);
|
|
8
|
-
const SUBCOMMANDS = ['check', 'init', 'sync'];
|
|
9
|
+
const SUBCOMMANDS = ['check', 'init', 'sync', 'update-templates'];
|
|
9
10
|
const MIN_PREFIX_LENGTH = 3;
|
|
10
11
|
function showHelp() {
|
|
11
12
|
console.info(`
|
|
@@ -16,6 +17,7 @@ Commands:
|
|
|
16
17
|
check (default) Grouped vulnerability check with severity indicators
|
|
17
18
|
sync Synchronize allowlists with current audit findings
|
|
18
19
|
init Scaffold a starter config file and GitHub Actions workflow
|
|
20
|
+
update-templates Update the scaffolded workflow to the current template
|
|
19
21
|
|
|
20
22
|
Scope options:
|
|
21
23
|
--dev Target dev dependencies only
|
|
@@ -63,6 +65,19 @@ Other options:
|
|
|
63
65
|
--help, -h Show this help message
|
|
64
66
|
`);
|
|
65
67
|
}
|
|
68
|
+
function showUpdateTemplatesHelp() {
|
|
69
|
+
console.info(`
|
|
70
|
+
Usage: v11y update-templates [options]
|
|
71
|
+
|
|
72
|
+
Update .github/workflows/audit.yaml to the template of the installed version,
|
|
73
|
+
showing what changed. Creates the workflow when it is missing. Never touches
|
|
74
|
+
the config file.
|
|
75
|
+
|
|
76
|
+
Options:
|
|
77
|
+
--dry-run, -n Preview changes without writing files
|
|
78
|
+
--help, -h Show this help message
|
|
79
|
+
`);
|
|
80
|
+
}
|
|
66
81
|
function parseSharedFlags(flags, styles) {
|
|
67
82
|
const flagSchema = {
|
|
68
83
|
config: { long: '--config', type: 'string' },
|
|
@@ -126,6 +141,9 @@ export async function routeCommand(args) {
|
|
|
126
141
|
if (command === 'sync') {
|
|
127
142
|
return handleSubcommand(args.slice(1), styles, syncCommand, showSyncHelp);
|
|
128
143
|
}
|
|
144
|
+
if (command === 'update-templates') {
|
|
145
|
+
return handleUpdateTemplates(args.slice(1), styles);
|
|
146
|
+
}
|
|
129
147
|
if (command !== undefined && !command.startsWith('-')) {
|
|
130
148
|
const typoMatch = findTypoMatch(command);
|
|
131
149
|
if (typoMatch !== undefined) {
|
|
@@ -181,3 +199,21 @@ function handleInit(flags, styles) {
|
|
|
181
199
|
}
|
|
182
200
|
return initCommand({ dryRun: parsed.flags.dryRun, force: parsed.flags.force, styles });
|
|
183
201
|
}
|
|
202
|
+
function handleUpdateTemplates(flags, styles) {
|
|
203
|
+
if (flags.some((f) => f === '--help' || f === '-h')) {
|
|
204
|
+
showUpdateTemplatesHelp();
|
|
205
|
+
return 0;
|
|
206
|
+
}
|
|
207
|
+
const updateTemplatesFlagSchema = {
|
|
208
|
+
dryRun: { long: '--dry-run', type: 'boolean', short: '-n' },
|
|
209
|
+
};
|
|
210
|
+
let parsed;
|
|
211
|
+
try {
|
|
212
|
+
parsed = parseArgs(flags, updateTemplatesFlagSchema);
|
|
213
|
+
}
|
|
214
|
+
catch (error) {
|
|
215
|
+
reportError(describeError(error));
|
|
216
|
+
return 1;
|
|
217
|
+
}
|
|
218
|
+
return updateTemplatesCommand({ dryRun: parsed.flags.dryRun, styles });
|
|
219
|
+
}
|
package/dist/esm/cli.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { type CommandOptions } from './types.js';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Runs the default audit command (CI mode).
|
|
4
4
|
*
|
|
5
5
|
* Generates config, invokes audit-ci for each scope, and returns a combined exit code.
|
|
6
6
|
*/
|
|
7
7
|
export declare function auditCommand(options: CommandOptions): Promise<number>;
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* Runs the default grouped-check command.
|
|
10
10
|
*
|
|
11
11
|
* Audits each scope without allowlist filtering, cross-references results with
|
|
12
12
|
* the config allowlist, detects stale entries, and produces grouped output.
|
|
@@ -14,10 +14,10 @@ export declare function auditCommand(options: CommandOptions): Promise<number>;
|
|
|
14
14
|
*/
|
|
15
15
|
export declare function checkCommand(options: CommandOptions): Promise<number>;
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
17
|
+
* Runs the `sync` subcommand.
|
|
18
18
|
*
|
|
19
19
|
* Audits each scope in report mode without allowlist filtering, then updates
|
|
20
|
-
* the allowlist to match current findings. When
|
|
21
|
-
* one at the default path.
|
|
20
|
+
* the allowlist to match current findings. When the config file doesn't exist,
|
|
21
|
+
* creates one at the default path.
|
|
22
22
|
*/
|
|
23
23
|
export declare function syncCommand(options: CommandOptions): Promise<number>;
|
package/dist/esm/config.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type V11yCheckConfig } from './types.js';
|
|
2
2
|
/** Default config file path, relative to the working directory. */
|
|
3
3
|
export declare const DEFAULT_CONFIG_PATH = ".config/v11y-check.config.json";
|
|
4
|
-
/**
|
|
4
|
+
/** Discriminates between a config loaded from a file and one built from defaults. */
|
|
5
5
|
export type ConfigSource = 'defaults' | 'file';
|
|
6
6
|
/** Result of loading config, including the source discriminator. */
|
|
7
7
|
export interface LoadConfigResult {
|
|
@@ -11,7 +11,7 @@ export interface LoadConfigResult {
|
|
|
11
11
|
configSource: ConfigSource;
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* Loads and validates the v11y-check config from disk, falling back to defaults.
|
|
15
15
|
*
|
|
16
16
|
* When `configPath` is explicitly provided, the file must exist. When omitted,
|
|
17
17
|
* the default path is tried; if absent, `DEFAULT_CONFIG` is returned.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CheckResult } from './format-check.js';
|
|
2
2
|
import type { AuditScope } from './types.js';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Computes the "Actions:" footer for check output.
|
|
5
5
|
*
|
|
6
6
|
* Returns an empty string when the allowlist is fully current. Otherwise returns
|
|
7
7
|
* a bulleted action list with a verbose hint (when vulns exist) and a sync hint.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type OutputStyle } from '@williamthorsen/nmr-core';
|
|
2
2
|
import type { AuditResult, AuditScope, SeverityThreshold } from './types.js';
|
|
3
|
-
/**
|
|
3
|
+
/** An audit finding that the allowlist admits, with the entry's reason and date. */
|
|
4
4
|
export interface AllowedVuln {
|
|
5
5
|
addedAt?: string | undefined;
|
|
6
6
|
cvss?: {
|
|
@@ -35,19 +35,19 @@ export interface CheckResult {
|
|
|
35
35
|
}
|
|
36
36
|
/** Maps a severity string to its indicator in a style: a colored circle when rich, nothing when plain. */
|
|
37
37
|
export declare function severityIndicator(severity: string | undefined, style: OutputStyle): string;
|
|
38
|
-
/**
|
|
38
|
+
/** Resolves the best display ID for a vulnerability: GHSA ID if available, otherwise the numeric ID. */
|
|
39
39
|
export declare function displayId(vuln: {
|
|
40
40
|
ghsaId?: string | undefined;
|
|
41
41
|
id: string;
|
|
42
42
|
}): string;
|
|
43
|
-
/**
|
|
43
|
+
/** Builds the severity suffix for a finding line, e.g. ` ๐ด critical`. */
|
|
44
44
|
export declare function formatSeveritySuffix(severity: string | undefined, style: OutputStyle): string;
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
46
|
+
* Formats check results as human-readable text output.
|
|
47
47
|
*
|
|
48
48
|
* Produces an intro banner, scoped findings with severity labels and GHSA IDs,
|
|
49
49
|
* and an action hints footer.
|
|
50
50
|
*/
|
|
51
51
|
export declare function formatCheckText(result: CheckResult, scopes: AuditScope[], style: OutputStyle, now?: Date, thresholds?: Partial<Record<AuditScope, SeverityThreshold>>): string;
|
|
52
|
-
/**
|
|
52
|
+
/** Formats check results as a JSON string with a top-level `summary` block derived from the result. */
|
|
53
53
|
export declare function formatCheckJson(result: CheckResult, scopes: AuditScope[]): string;
|
|
@@ -8,10 +8,10 @@ export interface CheckSummary {
|
|
|
8
8
|
count: number;
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
11
|
+
* Derives the headline summary from a check result.
|
|
12
12
|
*
|
|
13
13
|
* Priority is severity-driven: unallowed > allowed > stale > none. The count is the total across
|
|
14
14
|
* the requested scopes for the *active* category only; for `'none'` it is `0`. Below-threshold
|
|
15
|
-
* findings never affect the summary
|
|
15
|
+
* findings never affect the summary: The threshold already excludes them from pass/fail.
|
|
16
16
|
*/
|
|
17
17
|
export declare function deriveSummary(result: CheckResult, scopes: AuditScope[]): CheckSummary;
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Produces a human-readable relative-time string such as "just now", "N minutes ago",
|
|
3
3
|
* "yesterday", "N months ago", "N years ago".
|
|
4
4
|
*
|
|
5
5
|
* Uses millisecond math for units up through weeks to avoid DST/timezone drift on
|
|
6
6
|
* short intervals, and UTC calendar math for months and years.
|
|
7
|
-
*
|
|
8
|
-
* @internal โ exported for test access; consumers should use higher-level formatting helpers.
|
|
9
7
|
*/
|
|
10
8
|
export declare function formatRelativeTime(fromIso: string, now: Date): string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type OutputStyle } from '@williamthorsen/nmr-core';
|
|
2
2
|
import { type CheckResult } from './format-check.js';
|
|
3
3
|
import type { AuditScope, SeverityThreshold } from './types.js';
|
|
4
|
-
/**
|
|
4
|
+
/** Formats the verbose per-vulnerability check output as text. */
|
|
5
5
|
export declare function formatCheckVerboseText(result: CheckResult, scopes: AuditScope[], style: OutputStyle, now?: Date, thresholds?: Partial<Record<AuditScope, SeverityThreshold>>): string;
|
package/dist/esm/generate.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ interface AuditCiFlatConfig {
|
|
|
6
6
|
'show-not-found'?: boolean;
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* Transforms a scope config into the flat JSON structure that audit-ci expects.
|
|
10
10
|
*
|
|
11
11
|
* Translates `severityThreshold` to the corresponding audit-ci boolean,
|
|
12
12
|
* adds scope-specific flags (`skip-dev` for prod, `extra-args: ["--dev"]` for dev),
|
|
@@ -14,10 +14,10 @@ interface AuditCiFlatConfig {
|
|
|
14
14
|
*/
|
|
15
15
|
export declare function buildFlatConfig(scopeConfig: ScopeConfig, scope: AuditScope): AuditCiFlatConfig;
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
17
|
+
* Generates the audit-ci config file for a scope and writes it to disk.
|
|
18
18
|
*
|
|
19
19
|
* The output path is `{outputDir}/audit-ci.{scope}.json`. The caller must
|
|
20
|
-
* ensure `outputDir`
|
|
20
|
+
* ensure that `outputDir` exists.
|
|
21
21
|
*/
|
|
22
22
|
export declare function generateAuditCiConfig(scopeConfig: ScopeConfig, scope: AuditScope, outputDir: string): Promise<string>;
|
|
23
23
|
export {};
|
package/dist/esm/glyphs.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type OutputStyle, type StatusGlyphName } from '@williamthorsen/nmr-core';
|
|
2
2
|
/**
|
|
3
|
-
* Glyphs that name
|
|
4
|
-
*
|
|
3
|
+
* Glyphs that don't name a status; a status marker comes from nmr-core's `STATUS_GLYPHS`. A plain variant is empty
|
|
4
|
+
* for a glyph that a word always follows.
|
|
5
5
|
*/
|
|
6
6
|
export declare const V11Y_GLYPHS: Readonly<Record<"plain" | "rich", Readonly<Record<"audit" | "scopeDev" | "scopeProd" | "severityHigh" | "severityLow" | "severityModerate" | "stale", import("@williamthorsen/toolbelt.terminal/candidate").Glyph>>>>;
|
|
7
7
|
export type V11yGlyphName = keyof (typeof V11Y_GLYPHS)['rich'];
|
|
@@ -9,5 +9,5 @@ export type V11yGlyphName = keyof (typeof V11Y_GLYPHS)['rich'];
|
|
|
9
9
|
export type RowMarkerName = StatusGlyphName | 'stale';
|
|
10
10
|
/** Renders a row marker and a message, padding the marker so that messages align across markers. */
|
|
11
11
|
export declare function formatMarkedLine(style: OutputStyle, name: RowMarkerName, message: string): string;
|
|
12
|
-
/**
|
|
12
|
+
/** Returns the number of cells taken by the widest row marker in a style. */
|
|
13
13
|
export declare function measureRowMarkerColumn(style: OutputStyle): number;
|
|
@@ -5,7 +5,7 @@ interface InitOptions {
|
|
|
5
5
|
styles: StreamStyles;
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Runs the `v11y init` command.
|
|
9
9
|
*
|
|
10
10
|
* Scaffolds the starter config file and the GitHub Actions workflow, then prints next steps.
|
|
11
11
|
* Returns the process exit code (0 for success, 1 if any write failed).
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type WriteResult } from '@williamthorsen/nmr-core';
|
|
2
|
+
export declare const WORKFLOW_PATH = ".github/workflows/audit.yaml";
|
|
2
3
|
interface ScaffoldOptions {
|
|
3
4
|
dryRun: boolean;
|
|
4
5
|
force: boolean;
|
|
@@ -7,30 +8,25 @@ interface ScaffoldResult {
|
|
|
7
8
|
configResult: WriteResult;
|
|
8
9
|
}
|
|
9
10
|
/**
|
|
10
|
-
*
|
|
11
|
+
* Scaffolds the v11y-check config file with sensible defaults, never overwriting an existing one, whose allowlist
|
|
11
12
|
* `v11y sync` maintains.
|
|
12
|
-
*
|
|
13
|
-
* Returns `{ configResult }` to preserve the signature consumed by `syncCommand`, which predates
|
|
14
|
-
* the workflow scaffolding and treats the config result as a named field.
|
|
15
13
|
*/
|
|
16
14
|
export declare function scaffoldConfig({ dryRun }: {
|
|
17
15
|
dryRun: boolean;
|
|
18
16
|
}): ScaffoldResult;
|
|
19
|
-
/**
|
|
17
|
+
/** Copies the bundled audit.yaml.template to `.github/workflows/audit.yaml` in the target repo. */
|
|
20
18
|
export declare function copyWorkflowTemplate(dryRun: boolean, overwrite: boolean): WriteResult;
|
|
21
|
-
/**
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
/** Reads the bundled audit.yaml.template, returning a description of the failure when it cannot. */
|
|
20
|
+
export declare function readWorkflowTemplate(): {
|
|
21
|
+
content: string;
|
|
22
|
+
} | {
|
|
23
|
+
error: string;
|
|
24
|
+
};
|
|
25
|
+
/** Scaffolds the GitHub Actions audit workflow to `.github/workflows/audit.yaml`. */
|
|
27
26
|
export declare function scaffoldWorkflow(dryRun: boolean, overwrite: boolean): WriteResult;
|
|
28
27
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* Writes both the config file and the GitHub Actions workflow. Returns a flat array of write
|
|
32
|
-
* results in the order [config, workflow]. `ScaffoldOptions.force` is translated to `overwrite`
|
|
33
|
-
* for the workflow alone; an existing config is never overwritten.
|
|
28
|
+
* Scaffolds the config file and the GitHub Actions workflow, returning their write results in that order. `force`
|
|
29
|
+
* overwrites the workflow alone; an existing config is never overwritten.
|
|
34
30
|
*/
|
|
35
31
|
export declare function scaffoldFiles({ dryRun, force }: ScaffoldOptions): WriteResult[];
|
|
36
32
|
export {};
|
|
@@ -4,34 +4,33 @@ import { findPackageRoot, writeFileWithCheck } from '@williamthorsen/nmr-core';
|
|
|
4
4
|
import { describeError } from '@williamthorsen/toolbelt.errors';
|
|
5
5
|
import { v11yCheckConfigTemplate } from "./templates.js";
|
|
6
6
|
const CONFIG_PATH = '.config/v11y-check.config.json';
|
|
7
|
-
const WORKFLOW_PATH = '.github/workflows/audit.yaml';
|
|
7
|
+
export const WORKFLOW_PATH = '.github/workflows/audit.yaml';
|
|
8
8
|
export function scaffoldConfig({ dryRun }) {
|
|
9
9
|
const configResult = writeFileWithCheck(CONFIG_PATH, v11yCheckConfigTemplate, { dryRun, overwrite: false });
|
|
10
10
|
return { configResult };
|
|
11
11
|
}
|
|
12
12
|
export function copyWorkflowTemplate(dryRun, overwrite) {
|
|
13
|
+
const template = readWorkflowTemplate();
|
|
14
|
+
if ('error' in template) {
|
|
15
|
+
return { filePath: WORKFLOW_PATH, outcome: 'failed', error: template.error };
|
|
16
|
+
}
|
|
17
|
+
return writeFileWithCheck(WORKFLOW_PATH, template.content, { dryRun, overwrite });
|
|
18
|
+
}
|
|
19
|
+
export function readWorkflowTemplate() {
|
|
13
20
|
let root;
|
|
14
21
|
try {
|
|
15
22
|
root = findPackageRoot(import.meta.url);
|
|
16
23
|
}
|
|
17
24
|
catch (error) {
|
|
18
|
-
|
|
19
|
-
return { filePath: WORKFLOW_PATH, outcome: 'failed', error: `Failed to resolve package root: ${message}` };
|
|
25
|
+
return { error: `Failed to resolve package root: ${describeError(error)}` };
|
|
20
26
|
}
|
|
21
27
|
const templatePath = resolve(root, 'templates', 'audit.yaml.template');
|
|
22
|
-
let content;
|
|
23
28
|
try {
|
|
24
|
-
content
|
|
29
|
+
return { content: readFileSync(templatePath, 'utf8') };
|
|
25
30
|
}
|
|
26
31
|
catch (error) {
|
|
27
|
-
|
|
28
|
-
return {
|
|
29
|
-
filePath: WORKFLOW_PATH,
|
|
30
|
-
outcome: 'failed',
|
|
31
|
-
error: `Failed to read bundled template at ${templatePath}: ${message}`,
|
|
32
|
-
};
|
|
32
|
+
return { error: `Failed to read bundled template at ${templatePath}: ${describeError(error)}` };
|
|
33
33
|
}
|
|
34
|
-
return writeFileWithCheck(WORKFLOW_PATH, content, { dryRun, overwrite });
|
|
35
34
|
}
|
|
36
35
|
export function scaffoldWorkflow(dryRun, overwrite) {
|
|
37
36
|
return copyWorkflowTemplate(dryRun, overwrite);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type StreamStyles } from '@williamthorsen/nmr-core';
|
|
2
|
+
interface UpdateTemplatesOptions {
|
|
3
|
+
dryRun: boolean;
|
|
4
|
+
styles: StreamStyles;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Runs the `v11y update-templates` command and returns the process exit code.
|
|
8
|
+
*
|
|
9
|
+
* Brings the scaffolded audit workflow up to date with the bundled template; the config file is never read or written.
|
|
10
|
+
*/
|
|
11
|
+
export declare function updateTemplatesCommand({ dryRun, styles }: UpdateTemplatesOptions): number;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { printStep, reportTemplateUpdate, updateManagedFile, } from '@williamthorsen/nmr-core';
|
|
2
|
+
import { readWorkflowTemplate, WORKFLOW_PATH } from "./scaffold.js";
|
|
3
|
+
export function updateTemplatesCommand({ dryRun, styles }) {
|
|
4
|
+
if (dryRun) {
|
|
5
|
+
console.info('[dry-run mode]');
|
|
6
|
+
}
|
|
7
|
+
printStep('Updating workflows');
|
|
8
|
+
const template = readWorkflowTemplate();
|
|
9
|
+
const result = 'error' in template
|
|
10
|
+
? { filePath: WORKFLOW_PATH, outcome: 'failed', error: template.error }
|
|
11
|
+
: updateManagedFile(WORKFLOW_PATH, template.content, { dryRun });
|
|
12
|
+
reportTemplateUpdate(result, dryRun, styles);
|
|
13
|
+
return result.outcome === 'failed' ? 1 : 0;
|
|
14
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { type StreamStyles } from '@williamthorsen/nmr-core';
|
|
2
|
-
/** The environment variable
|
|
2
|
+
/** The environment variable that sets the caller's standing style preference: `auto`, `plain`, or `rich`. */
|
|
3
3
|
export declare const OUTPUT_STYLE_ENV_VAR = "V11Y_CHECK_OUTPUT_STYLE";
|
|
4
4
|
export interface ResolveStylesOptions {
|
|
5
5
|
readonly env: Readonly<Record<string, string | undefined>>;
|
|
6
6
|
readonly stderrIsTty: boolean;
|
|
7
7
|
readonly stdoutIsTty: boolean;
|
|
8
8
|
}
|
|
9
|
-
/** Resolves the style of each output stream, reporting a usage error and returning `undefined` when the variable
|
|
9
|
+
/** Resolves the style of each output stream, reporting a usage error and returning `undefined` when the variable doesn't name a setting. */
|
|
10
10
|
export declare function resolveStyles(options: ResolveStylesOptions): StreamStyles | undefined;
|
package/dist/esm/run-audit.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AuditResult } from './types.js';
|
|
2
|
-
/**
|
|
2
|
+
/** Resolves the audit-ci binary path from node_modules. */
|
|
3
3
|
export declare function resolveAuditCiBin(): string;
|
|
4
4
|
/** Result of parsing audit-ci output, including any warnings. */
|
|
5
5
|
export interface ParseResult {
|
|
@@ -7,7 +7,7 @@ export interface ParseResult {
|
|
|
7
7
|
warnings: string[];
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* Parses audit-ci JSON output into typed audit results.
|
|
11
11
|
*
|
|
12
12
|
* Extracts advisories from the JSON, mapping each to an `AuditResult` with
|
|
13
13
|
* the first discovered dependency path. Returns warnings when input is
|
|
@@ -19,7 +19,7 @@ export interface StaleEntriesResult {
|
|
|
19
19
|
entries: string[];
|
|
20
20
|
warnings: string[];
|
|
21
21
|
}
|
|
22
|
-
/**
|
|
22
|
+
/** Extracts stale allowlist entries from audit-ci JSON output. */
|
|
23
23
|
export declare function extractStaleEntries(jsonString: string): StaleEntriesResult;
|
|
24
24
|
/** Options for running audit-ci. */
|
|
25
25
|
interface RunAuditOptions {
|
|
@@ -37,7 +37,7 @@ export interface AuditRunResult {
|
|
|
37
37
|
warnings: string[];
|
|
38
38
|
}
|
|
39
39
|
/**
|
|
40
|
-
*
|
|
40
|
+
* Invokes audit-ci with the given config file in normal (CI) mode.
|
|
41
41
|
*
|
|
42
42
|
* Returns the exit code faithfully. When `json` is true, output is JSON;
|
|
43
43
|
* otherwise audit-ci uses its default text format. Stale overrides are
|
|
@@ -51,10 +51,6 @@ export interface ReportResult {
|
|
|
51
51
|
stderr: string;
|
|
52
52
|
warnings: string[];
|
|
53
53
|
}
|
|
54
|
-
/**
|
|
55
|
-
* Invoke audit-ci in report mode (no allowlist filtering, swallows exit code).
|
|
56
|
-
*
|
|
57
|
-
* Always returns exit code 0. Parses JSON output into typed `AuditResult` objects.
|
|
58
|
-
*/
|
|
54
|
+
/** Invokes audit-ci with JSON output, ignoring its exit code, and parses the advisories into `AuditResult` objects. */
|
|
59
55
|
export declare function runReport({ configPath, cwd, reportType }: Omit<RunAuditOptions, 'json'>): ReportResult;
|
|
60
56
|
export {};
|
package/dist/esm/sync.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AllowlistEntry, AuditResult, AuditScope, V11yCheckConfig } from './types.js';
|
|
2
|
-
/**
|
|
2
|
+
/** Produces a full ISO 8601 UTC datetime string. */
|
|
3
3
|
export declare function formatUtcDatetime(date: Date): string;
|
|
4
|
-
/**
|
|
4
|
+
/** Formats a Date as a human-friendly UTC string for use in reason messages. */
|
|
5
5
|
export declare function formatFriendlyUtc(date: Date): string;
|
|
6
6
|
/** Result of a sync operation for a single scope. */
|
|
7
7
|
export interface SyncResult {
|
|
@@ -11,10 +11,10 @@ export interface SyncResult {
|
|
|
11
11
|
scope: AuditScope;
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* Computes the updated allowlist by diffing audit results against the current entries.
|
|
15
15
|
*
|
|
16
16
|
* New advisories are added with an auto-populated reason. Resolved advisories are removed.
|
|
17
|
-
* Existing entries
|
|
17
|
+
* Existing entries are kept unchanged.
|
|
18
18
|
*/
|
|
19
19
|
export declare function computeSyncDiff(currentAllowlist: AllowlistEntry[], auditResults: AuditResult[], date?: Date): {
|
|
20
20
|
added: AllowlistEntry[];
|
|
@@ -22,19 +22,19 @@ export declare function computeSyncDiff(currentAllowlist: AllowlistEntry[], audi
|
|
|
22
22
|
removed: AllowlistEntry[];
|
|
23
23
|
};
|
|
24
24
|
/**
|
|
25
|
-
*
|
|
25
|
+
* Builds the updated config by replacing the allowlist for the given scope with its entries sorted by ID.
|
|
26
26
|
*
|
|
27
27
|
* Returns a new config object; does not mutate the input.
|
|
28
28
|
*/
|
|
29
29
|
export declare function buildUpdatedConfig(config: V11yCheckConfig, scope: AuditScope, newAllowlist: AllowlistEntry[]): V11yCheckConfig;
|
|
30
30
|
/**
|
|
31
|
-
*
|
|
31
|
+
* Serializes the config to JSON with alphabetically ordered allowlist entry keys.
|
|
32
32
|
*
|
|
33
|
-
* Includes `$schema` when present.
|
|
33
|
+
* Includes `$schema` when present.
|
|
34
34
|
*/
|
|
35
35
|
export declare function serializeConfig(config: V11yCheckConfig): string;
|
|
36
36
|
/**
|
|
37
|
-
*
|
|
37
|
+
* Synchronizes the allowlist for a scope by diffing audit results against the current config.
|
|
38
38
|
*
|
|
39
39
|
* Returns the sync diff and the updated config. Writes the updated config to disk.
|
|
40
40
|
*/
|
package/dist/esm/sync.js
CHANGED
|
@@ -53,7 +53,7 @@ export function computeSyncDiff(currentAllowlist, auditResults, date) {
|
|
|
53
53
|
return { added, kept, removed };
|
|
54
54
|
}
|
|
55
55
|
export function buildUpdatedConfig(config, scope, newAllowlist) {
|
|
56
|
-
const sorted =
|
|
56
|
+
const sorted = newAllowlist.toSorted((a, b) => a.id.localeCompare(b.id));
|
|
57
57
|
return {
|
|
58
58
|
...config,
|
|
59
59
|
[scope]: {
|
package/dist/esm/tmp.d.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Executes a callback with a temporary directory, ensuring cleanup afterward.
|
|
3
3
|
*
|
|
4
4
|
* Creates a unique temp directory under `os.tmpdir()` and removes it
|
|
5
5
|
* (recursively) when the callback completes or throws.
|
|
6
|
-
*
|
|
7
|
-
* @internal Exported for testing.
|
|
8
6
|
*/
|
|
9
7
|
export declare function withTempDir<T>(fn: (tempDir: string) => Promise<T>): Promise<T>;
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -27,7 +27,7 @@ export declare const allowlistEntrySchema: z.ZodObject<{
|
|
|
27
27
|
/** Configuration for a single audit scope (dev or prod). */
|
|
28
28
|
export interface ScopeConfig {
|
|
29
29
|
allowlist: AllowlistEntry[];
|
|
30
|
-
/**
|
|
30
|
+
/** Severity at or above which an advisory fails the audit. */
|
|
31
31
|
severityThreshold?: SeverityThreshold | undefined;
|
|
32
32
|
}
|
|
33
33
|
/** Zod schema for a scope configuration block. */
|
|
@@ -86,7 +86,7 @@ export declare const v11yCheckConfigSchema: z.ZodObject<{
|
|
|
86
86
|
}>>;
|
|
87
87
|
}, z.core.$strict>;
|
|
88
88
|
}, z.core.$strict>;
|
|
89
|
-
/** Built-in defaults used when
|
|
89
|
+
/** Built-in defaults used when the config file isn't present. */
|
|
90
90
|
export declare const DEFAULT_CONFIG: V11yCheckConfig;
|
|
91
91
|
/** A single vulnerability found by audit-ci. */
|
|
92
92
|
export interface AuditResult {
|
|
@@ -112,11 +112,9 @@ export interface CommandOptions {
|
|
|
112
112
|
verbose: boolean;
|
|
113
113
|
}
|
|
114
114
|
/**
|
|
115
|
-
*
|
|
115
|
+
* Determines whether a severity string is at or above the given threshold.
|
|
116
116
|
*
|
|
117
117
|
* Unrecognized or undefined severities are treated as above threshold
|
|
118
|
-
* (conservative
|
|
119
|
-
*
|
|
120
|
-
* @internal Exported for testing.
|
|
118
|
+
* (conservative: An unknown vuln is reported rather than hidden).
|
|
121
119
|
*/
|
|
122
120
|
export declare function isSeverityAtOrAbove(severity: string | undefined, threshold: SeverityThreshold): boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "v11y-check",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Wrap audit-ci with a richer config model, typed JSON source of truth, and sync workflow",
|
|
6
6
|
"keywords": [
|
|
@@ -45,15 +45,16 @@
|
|
|
45
45
|
"templates"
|
|
46
46
|
],
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@williamthorsen/nmr-core": "0.
|
|
48
|
+
"@williamthorsen/nmr-core": "0.13.1",
|
|
49
49
|
"@williamthorsen/toolbelt.errors": "0.8.1",
|
|
50
50
|
"audit-ci": "7.1.0",
|
|
51
|
-
"zod": "4.6.
|
|
51
|
+
"zod": "4.6.5"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@williamthorsen/toolbelt.filesystem": "0.9.1",
|
|
55
55
|
"@williamthorsen/toolbelt.testing": "0.6.1",
|
|
56
56
|
"@williamthorsen/toolbelt.vitest": "0.10.1",
|
|
57
|
+
"esbuild": "0.28.2",
|
|
57
58
|
"readyup": "0.38.0",
|
|
58
59
|
"vitest": "4.1.11"
|
|
59
60
|
},
|
|
@@ -7,7 +7,7 @@ on:
|
|
|
7
7
|
- main
|
|
8
8
|
- next
|
|
9
9
|
|
|
10
|
-
#
|
|
10
|
+
# Run daily. Adjust the cron expression in a repo that needs a different cadence.
|
|
11
11
|
schedule:
|
|
12
12
|
- cron: '0 8 * * *'
|
|
13
13
|
|
|
@@ -16,7 +16,7 @@ on:
|
|
|
16
16
|
# Permissions must be declared here. The GITHUB_TOKEN scope passed to the called
|
|
17
17
|
# reusable workflow is bounded by this caller's permissions block; when omitted,
|
|
18
18
|
# the repository's default workflow permissions apply (read-only here), which would
|
|
19
|
-
# silently deny the
|
|
19
|
+
# silently deny the issue and pull-request writes that the reusable workflow needs.
|
|
20
20
|
permissions:
|
|
21
21
|
contents: read
|
|
22
22
|
issues: write
|