@wirecat/cli-base 0.26.0 → 0.27.1
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 +22 -2
- package/dist/dev/audit.d.ts +64 -0
- package/dist/dev/audit.d.ts.map +1 -0
- package/dist/dev/audit.js +304 -0
- package/dist/dev/audit.js.map +1 -0
- package/dist/dev/lint.d.ts +10 -1
- package/dist/dev/lint.d.ts.map +1 -1
- package/dist/dev/lint.js +18 -6
- package/dist/dev/lint.js.map +1 -1
- package/dist/dev/main.d.ts.map +1 -1
- package/dist/dev/main.js +155 -10
- package/dist/dev/main.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/logging.d.ts +24 -2
- package/dist/logging.d.ts.map +1 -1
- package/dist/logging.js +40 -12
- package/dist/logging.js.map +1 -1
- package/dist/standards/audit.d.ts +40 -0
- package/dist/standards/audit.d.ts.map +1 -0
- package/dist/standards/audit.js +72 -0
- package/dist/standards/audit.js.map +1 -0
- package/dist/standards/index.d.ts +2 -1
- package/dist/standards/index.d.ts.map +1 -1
- package/dist/standards/index.js +2 -1
- package/dist/standards/index.js.map +1 -1
- package/dist/standards/lint.d.ts.map +1 -1
- package/dist/standards/lint.js +6 -0
- package/dist/standards/lint.js.map +1 -1
- package/dist/standards/log.d.ts +11 -0
- package/dist/standards/log.d.ts.map +1 -1
- package/dist/standards/log.js +68 -0
- package/dist/standards/log.js.map +1 -1
- package/dist/standards/vocabulary.d.ts.map +1 -1
- package/dist/standards/vocabulary.js +47 -5
- package/dist/standards/vocabulary.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -50,7 +50,7 @@ streams.stderr // []
|
|
|
50
50
|
| `paths` | config, state and cache in the XDG layout on Linux and macOS (`~/.config`, `~/.local/share`, `~/.cache`) and the `AppData` one on Windows, each overridable by environment variable; `migrateLegacyMacPaths` moves an older release's `~/Library` folders once |
|
|
51
51
|
| `config` | JSON config loading that names the bad field, and an atomic write that locks the directory down |
|
|
52
52
|
| `credentials` | environment → keyring → file, warning once and falling through when the keyring refuses |
|
|
53
|
-
| `logging` | `createRecordLog`: one `LogRecord` per JSON line (OpenTelemetry field names, flat), secrets
|
|
53
|
+
| `logging` | `createRecordLog`: one `LogRecord` per JSON line (OpenTelemetry field names, flat), secrets and content-naming keys redacted at any depth, top-level keys off the allow-list (`LOG_ATTRIBUTE_KEYS` + `allow`) written without their value; `logRecordOf` builds the same record for a writer of its own; a file that cannot be written is reported to `onError`, never thrown |
|
|
54
54
|
| `retry` | full-jitter backoff, and the distinction between "no answer came" and "safe to repeat" |
|
|
55
55
|
| `/testing` | `captureStreams`, `memoryKeyring`, `brokenKeyring`, `fakeClock` |
|
|
56
56
|
| `/commands` | the command registry: `describeProgram`, `annotate`, `flatten`, `refuseJoinedPath`, and `commandsDocument` — the one `commands --json` shape, with its schema — see below |
|
|
@@ -328,6 +328,7 @@ extends:
|
|
|
328
328
|
| `scripts/test-matrix.ts` | `cli-dev test-matrix --program dist/program.js --untested scripts/test-matrix-untested.ts --name max [--check]` |
|
|
329
329
|
|
|
330
330
|
| — | `cli-dev lint --cli dist/bin.js` (or `--commands <file>`): the command tree against the standard |
|
|
331
|
+
| — | `cli-dev audit --cli <bin> --cli <bin> …`: several CLIs against the standard and against each other |
|
|
331
332
|
|
|
332
333
|
`cli-dev lint` reads `<cli> commands --json`, refuses a document not in `commandsDocument`'s shape, and
|
|
333
334
|
judges it by `LINT_RULES` and `VOCABULARY` from `/standards`. Known violations live in
|
|
@@ -339,7 +340,26 @@ Every option needs a role from the vocabulary (`paging`, `output`, `sort`, `mode
|
|
|
339
340
|
named after a field of its entity (`--kind`, `--since-time`, `--before-id`), except a `scope` flag such as
|
|
340
341
|
`--account`; `list-without-query` a `list` with an `output` entity and no query; `query-example` a field example
|
|
341
342
|
or default term that does not run. `--schemas <file>` names a JSON object of the CLI's own JSON Schemas by name; `key-casing` checks their
|
|
342
|
-
keys, cli-base's envelope, error, log record and commands document schemas, and the document as printed.
|
|
343
|
+
keys, cli-base's envelope, error, log record and commands document schemas, and the document as printed. Its entry
|
|
344
|
+
`log_attributes` (`logAttributesJsonSchema(allow)`) is the CLI's log allow-list instead: `log-attribute-key` fails a
|
|
345
|
+
key that names message text, a token or a phone number.
|
|
346
|
+
|
|
347
|
+
`cli-dev audit` reads two or more commands documents (`--cli <bin>` or `--commands <file>`, repeated) and prints a
|
|
348
|
+
scorecard: per CLI and rule, what it found, what the baseline holds, what is overridden, what is new and what was
|
|
349
|
+
fixed; `--json` prints it as the list envelope. Every lint rule judges each CLI alone; `AUDIT_RULES` in `/standards`
|
|
350
|
+
compare them: `required-root` (`REQUIRED_ROOTS`: `commands`, `doctor`, `skill show|install`, `mcp`, `upgrade`),
|
|
351
|
+
`same-path-contract` (a path two CLIs of a parity group share has the same options, value names, output and summary;
|
|
352
|
+
a group covering the whole tree has the same paths), `same-flag-meaning`, `same-entity-schema` (from `--schemas
|
|
353
|
+
<cli>=<file>`) and `same-error-reason` (from `--reasons <cli>=<file>`, a JSON list of `defineReasons` entries). The two
|
|
354
|
+
last rules print `n/a` for a CLI that gave no such file. `PARITY_GROUPS` names who is compared where — `messengers`
|
|
355
|
+
(tg, max) over the whole tree, `all` over the shared roots — and each group's declared `differences`, each with a reason,
|
|
356
|
+
at most 10. Known findings live in `audit/baseline/<rule>.json` (`--baseline`), targets naming the CLIs
|
|
357
|
+
(`max+tg chats list --limit`, `tg: chats grab` for a lint violation); `--write-baseline` rewrites them. `--lint
|
|
358
|
+
<cli>=<dir>` judges that CLI's lint rules by its own `lint/` folder instead. A new finding fails the run — only one
|
|
359
|
+
naming `--for <cli>` when given — and a fixed one is reported, not failed. `AUDIT_BLOCKS` decides whether a new
|
|
360
|
+
cross-CLI divergence fails the run (`"new"`) or only shows (`"never"`); a new lint violation always fails. A document
|
|
361
|
+
from a cli-base before 0.26, with camelCase keys, is read too, and `key-casing` reports it. The weekly `Weekly CLI
|
|
362
|
+
audit` workflow runs it over the five latest published CLIs and rewrites the pinned issue labelled `cli-audit`.
|
|
343
363
|
|
|
344
364
|
`--rules` names a module exporting `CHANGELOG` and `docsRules(root)`; `--program` one exporting
|
|
345
365
|
`createProgram`; `--untested` one exporting `UNTESTED`. A TypeScript module loads on Node 24 as it is.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { CommandsDocument } from "../commands/document.js";
|
|
2
|
+
import { type AuditRule, type ParityGroup, type RequiredRoot } from "../standards/audit.js";
|
|
3
|
+
import { type ErrorReason } from "../standards/errors.js";
|
|
4
|
+
import { type Override } from "../standards/lint.js";
|
|
5
|
+
import type { Vocabulary } from "../standards/vocabulary.js";
|
|
6
|
+
export interface AuditInput {
|
|
7
|
+
document: CommandsDocument;
|
|
8
|
+
/** As the CLI printed it, for `key-casing`. */
|
|
9
|
+
raw: unknown;
|
|
10
|
+
schemas?: Readonly<Record<string, unknown>>;
|
|
11
|
+
reasons?: readonly ErrorReason[];
|
|
12
|
+
/** The CLI's own `lint/` baseline and overrides; its lint rules are then judged by them, not the audit's. */
|
|
13
|
+
lint?: {
|
|
14
|
+
baseline: Readonly<Record<string, readonly string[]>>;
|
|
15
|
+
overrides: readonly Override[];
|
|
16
|
+
budget: number;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export interface Finding {
|
|
20
|
+
rule: string;
|
|
21
|
+
clis: string[];
|
|
22
|
+
/** `<clis> <what>`: `max+tg chats list --limit`, `zm upgrade`, `tg: chats grab` for a lint violation. */
|
|
23
|
+
target: string;
|
|
24
|
+
message: string;
|
|
25
|
+
}
|
|
26
|
+
export interface ScoreRow {
|
|
27
|
+
cli: string;
|
|
28
|
+
rule: string;
|
|
29
|
+
/** False when the CLI gave no input the rule reads: no schemas, no reasons. Its counts are then 0, not a pass. */
|
|
30
|
+
measured: boolean;
|
|
31
|
+
found: number;
|
|
32
|
+
baseline: number;
|
|
33
|
+
overridden: number;
|
|
34
|
+
new: number;
|
|
35
|
+
fixed: number;
|
|
36
|
+
new_targets: string[];
|
|
37
|
+
}
|
|
38
|
+
export interface AuditOptions {
|
|
39
|
+
groups: readonly ParityGroup[];
|
|
40
|
+
roots: readonly RequiredRoot[];
|
|
41
|
+
vocabulary: Vocabulary;
|
|
42
|
+
/** `audit/baseline/<rule>.json`, by rule. */
|
|
43
|
+
baseline: Readonly<Record<string, readonly string[]>>;
|
|
44
|
+
blocks: "new" | "never";
|
|
45
|
+
/** Only new findings that name this CLI block: the one being released. */
|
|
46
|
+
only?: string;
|
|
47
|
+
}
|
|
48
|
+
export interface AuditResult {
|
|
49
|
+
findings: Finding[];
|
|
50
|
+
rows: ScoreRow[];
|
|
51
|
+
/** New findings that fail the run. */
|
|
52
|
+
blocking: Finding[];
|
|
53
|
+
/** What `--write-baseline` writes, by rule. */
|
|
54
|
+
nextBaseline: Record<string, string[]>;
|
|
55
|
+
problems: string[];
|
|
56
|
+
}
|
|
57
|
+
/** A document from cli-base before 0.26 prints camelCase keys; the audit reads both, `key-casing` still reports it. */
|
|
58
|
+
export declare const snakeKeys: (value: unknown) => unknown;
|
|
59
|
+
/** The CLIs a target names: `max+tg chats list` → max, tg; `tg: chats grab` → tg. */
|
|
60
|
+
export declare const clisOf: (target: string) => string[];
|
|
61
|
+
export declare const auditClis: (inputs: readonly AuditInput[], options: AuditOptions, rules?: readonly AuditRule[]) => AuditResult;
|
|
62
|
+
/** One line per CLI and rule that found something, then one total per CLI. */
|
|
63
|
+
export declare const scorecardTable: (rows: readonly ScoreRow[]) => string;
|
|
64
|
+
//# sourceMappingURL=audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/dev/audit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAE/D,OAAO,EAAe,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACxG,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACvE,OAAO,EAA+B,KAAK,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AACjF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAG5D,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,+CAA+C;IAC/C,GAAG,EAAE,OAAO,CAAA;IACZ,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IAC3C,OAAO,CAAC,EAAE,SAAS,WAAW,EAAE,CAAA;IAChC,6GAA6G;IAC7G,IAAI,CAAC,EAAE;QAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;QAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CACjH;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,yGAAyG;IACzG,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,kHAAkH;IAClH,QAAQ,EAAE,OAAO,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,EAAE,CAAA;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,SAAS,WAAW,EAAE,CAAA;IAC9B,KAAK,EAAE,SAAS,YAAY,EAAE,CAAA;IAC9B,UAAU,EAAE,UAAU,CAAA;IACtB,6CAA6C;IAC7C,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAA;IACrD,MAAM,EAAE,KAAK,GAAG,OAAO,CAAA;IACvB,0EAA0E;IAC1E,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,IAAI,EAAE,QAAQ,EAAE,CAAA;IAChB,sCAAsC;IACtC,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,+CAA+C;IAC/C,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IACtC,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAQD,uHAAuH;AACvH,eAAO,MAAM,SAAS,UAAW,OAAO,KAAG,OAM1C,CAAA;AAED,qFAAqF;AACrF,eAAO,MAAM,MAAM,WAAY,MAAM,KAAG,MAAM,EAA+D,CAAA;AAiM7G,eAAO,MAAM,SAAS,WACZ,SAAS,UAAU,EAAE,WACpB,YAAY,UACd,SAAS,SAAS,EAAE,KAC1B,WAwHF,CAAA;AAOD,8EAA8E;AAC9E,eAAO,MAAM,cAAc,SAAU,SAAS,QAAQ,EAAE,KAAG,MAgB1D,CAAA"}
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import { AUDIT_RULES } from "../standards/audit.js";
|
|
2
|
+
import { BASE_REASONS } from "../standards/errors.js";
|
|
3
|
+
import { LINT_RULES, OVERRIDE_BUDGET } from "../standards/lint.js";
|
|
4
|
+
import { judge, kindOf, lintCommands, longName, summaryOf, walk } from "./lint.js";
|
|
5
|
+
const byText = (a, b) => (a < b ? -1 : a > b ? 1 : 0);
|
|
6
|
+
const toSnake = (key) => key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
7
|
+
const VALUE_KEYS = new Set(["default", "implies"]);
|
|
8
|
+
/** A document from cli-base before 0.26 prints camelCase keys; the audit reads both, `key-casing` still reports it. */
|
|
9
|
+
export const snakeKeys = (value) => {
|
|
10
|
+
if (Array.isArray(value))
|
|
11
|
+
return value.map(snakeKeys);
|
|
12
|
+
if (typeof value !== "object" || value === null)
|
|
13
|
+
return value;
|
|
14
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [toSnake(key), VALUE_KEYS.has(key) ? item : snakeKeys(item)]));
|
|
15
|
+
};
|
|
16
|
+
/** The CLIs a target names: `max+tg chats list` → max, tg; `tg: chats grab` → tg. */
|
|
17
|
+
export const clisOf = (target) => (target.split(" ")[0] ?? "").replace(/:$/, "").split("+");
|
|
18
|
+
const named = (clis) => [...clis].sort(byText).join("+");
|
|
19
|
+
const handwritten = (document) => new Map(walk(document.commands)
|
|
20
|
+
.filter((command) => command.origin === "handwritten")
|
|
21
|
+
.map((command) => [command.path.join(" "), command]));
|
|
22
|
+
const requiredRoots = (inputs, roots) => inputs.flatMap(({ document }) => {
|
|
23
|
+
const paths = new Set(walk(document.commands).map((command) => command.path.join(" ")));
|
|
24
|
+
return roots
|
|
25
|
+
.filter((root) => !paths.has(root.path.join(" ")))
|
|
26
|
+
.map((root) => ({
|
|
27
|
+
rule: "required-root",
|
|
28
|
+
clis: [document.cli],
|
|
29
|
+
target: `${document.cli} ${root.path.join(" ")}`,
|
|
30
|
+
message: `no "${root.path.join(" ")}": ${root.meaning}`,
|
|
31
|
+
}));
|
|
32
|
+
});
|
|
33
|
+
const describe = (values) => [...values].map(([cli, value]) => `${cli}: ${value}`).join(", ");
|
|
34
|
+
const optionKinds = (options) => new Map(options.map((option) => [longName(option.flags), kindOf(option)]));
|
|
35
|
+
const shownKind = (kind) => (kind === undefined ? "absent" : kind === "switch" ? kind : `<${kind}>`);
|
|
36
|
+
const samePathContract = (inputs, groups) => {
|
|
37
|
+
const trees = new Map(inputs.map(({ document }) => [document.cli, handwritten(document)]));
|
|
38
|
+
const paths = [...new Set([...trees.values()].flatMap((tree) => [...tree.keys()]))].sort(byText);
|
|
39
|
+
const found = [];
|
|
40
|
+
for (const path of paths) {
|
|
41
|
+
const root = path.split(" ")[0] ?? "";
|
|
42
|
+
const covering = groups.filter((group) => group.covers === "tree" || group.covers.includes(root));
|
|
43
|
+
for (const group of covering.filter((one) => one.covers === "tree")) {
|
|
44
|
+
const present = group.members.filter((cli) => trees.has(cli));
|
|
45
|
+
const having = present.filter((cli) => trees.get(cli)?.has(path));
|
|
46
|
+
if (present.length >= 2 && having.length < present.length)
|
|
47
|
+
found.push({
|
|
48
|
+
rule: "same-path-contract",
|
|
49
|
+
clis: [...present].sort(byText),
|
|
50
|
+
target: `${named(present)} ${path}: presence`,
|
|
51
|
+
message: `only in ${having.join(", ")}`,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
const having = [...new Set(covering.flatMap((group) => group.members))]
|
|
55
|
+
.filter((cli) => trees.get(cli)?.has(path))
|
|
56
|
+
.sort(byText);
|
|
57
|
+
if (having.length < 2)
|
|
58
|
+
continue;
|
|
59
|
+
const commands = new Map(having.map((cli) => [cli, trees.get(cli)?.get(path)]));
|
|
60
|
+
const push = (what, values) => {
|
|
61
|
+
if (new Set(values.values()).size > 1)
|
|
62
|
+
found.push({
|
|
63
|
+
rule: "same-path-contract",
|
|
64
|
+
clis: having,
|
|
65
|
+
target: `${named(having)} ${path}${what}`,
|
|
66
|
+
message: describe(values),
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
const kinds = new Map([...commands].map(([cli, command]) => [cli, optionKinds(command.options)]));
|
|
70
|
+
const flags = [...new Set([...kinds.values()].flatMap((one) => [...one.keys()]))].sort(byText);
|
|
71
|
+
for (const flag of flags)
|
|
72
|
+
push(` ${flag}`, new Map([...kinds].map(([cli, one]) => [cli, shownKind(one.get(flag))])));
|
|
73
|
+
push(": output", new Map([...commands].map(([cli, command]) => [
|
|
74
|
+
cli,
|
|
75
|
+
command.output ? [command.output.entity, command.output.view].filter(Boolean).join("/") : "none",
|
|
76
|
+
])));
|
|
77
|
+
const own = (cli, text) => text.replace(new RegExp(`\\b${cli}\\b`, "g"), "<cli>");
|
|
78
|
+
push(": summary", new Map([...commands].map(([cli, command]) => [cli, JSON.stringify(own(cli, summaryOf(command)))])));
|
|
79
|
+
}
|
|
80
|
+
return found;
|
|
81
|
+
};
|
|
82
|
+
const sameFlagMeaning = (inputs) => {
|
|
83
|
+
const uses = new Map();
|
|
84
|
+
for (const { document } of inputs) {
|
|
85
|
+
const options = [
|
|
86
|
+
...document.global_options,
|
|
87
|
+
...walk(document.commands)
|
|
88
|
+
.filter((command) => command.origin === "handwritten")
|
|
89
|
+
.flatMap((command) => command.options),
|
|
90
|
+
];
|
|
91
|
+
for (const option of options) {
|
|
92
|
+
const name = longName(option.flags);
|
|
93
|
+
if (!name.startsWith("--"))
|
|
94
|
+
continue;
|
|
95
|
+
const byCli = uses.get(name) ?? new Map();
|
|
96
|
+
byCli.set(document.cli, (byCli.get(document.cli) ?? new Set()).add(shownKind(kindOf(option))));
|
|
97
|
+
uses.set(name, byCli);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return [...uses]
|
|
101
|
+
.sort(([a], [b]) => byText(a, b))
|
|
102
|
+
.flatMap(([flag, byCli]) => {
|
|
103
|
+
const signatures = new Map([...byCli].map(([cli, kinds]) => [cli, [...kinds].sort(byText).join(" | ")]));
|
|
104
|
+
if (byCli.size < 2 || new Set(signatures.values()).size < 2)
|
|
105
|
+
return [];
|
|
106
|
+
const clis = [...byCli.keys()].sort(byText);
|
|
107
|
+
return [{ rule: "same-flag-meaning", clis, target: `${named(clis)} ${flag}`, message: describe(signatures) }];
|
|
108
|
+
});
|
|
109
|
+
};
|
|
110
|
+
const canonical = (value) => JSON.stringify(value, (_, item) => typeof item === "object" && item !== null && !Array.isArray(item)
|
|
111
|
+
? Object.fromEntries(Object.entries(item).sort(([a], [b]) => byText(a, b)))
|
|
112
|
+
: item);
|
|
113
|
+
const sameEntitySchema = (inputs) => {
|
|
114
|
+
const schemas = new Map();
|
|
115
|
+
for (const { document, schemas: own } of inputs) {
|
|
116
|
+
if (!own)
|
|
117
|
+
continue;
|
|
118
|
+
const entities = new Set(walk(document.commands).flatMap((command) => [command.output?.entity, command.query?.entity].filter((one) => one !== undefined)));
|
|
119
|
+
for (const entity of entities)
|
|
120
|
+
if (own[entity] !== undefined)
|
|
121
|
+
schemas.set(entity, (schemas.get(entity) ?? new Map()).set(document.cli, canonical(own[entity])));
|
|
122
|
+
}
|
|
123
|
+
return [...schemas]
|
|
124
|
+
.sort(([a], [b]) => byText(a, b))
|
|
125
|
+
.flatMap(([entity, byCli]) => {
|
|
126
|
+
if (byCli.size < 2 || new Set(byCli.values()).size < 2)
|
|
127
|
+
return [];
|
|
128
|
+
const clis = [...byCli.keys()].sort(byText);
|
|
129
|
+
const groups = [...new Set(byCli.values())].map((schema) => [...byCli].filter(([, one]) => one === schema).map(([cli]) => cli));
|
|
130
|
+
return [
|
|
131
|
+
{
|
|
132
|
+
rule: "same-entity-schema",
|
|
133
|
+
clis,
|
|
134
|
+
target: `${named(clis)} entity ${entity}`,
|
|
135
|
+
message: `${groups.length} different schemas: ${groups.map((one) => one.join(", ")).join(" / ")}`,
|
|
136
|
+
},
|
|
137
|
+
];
|
|
138
|
+
});
|
|
139
|
+
};
|
|
140
|
+
const BASE = "cli-base";
|
|
141
|
+
const sameErrorReason = (inputs) => {
|
|
142
|
+
const owned = [
|
|
143
|
+
...BASE_REASONS.map((reason) => ({ owner: BASE, reason })),
|
|
144
|
+
...inputs.flatMap(({ document, reasons }) => (reasons ?? []).map((reason) => ({ owner: document.cli, reason }))),
|
|
145
|
+
];
|
|
146
|
+
const found = [];
|
|
147
|
+
const push = (clis, what, message) => found.push({ rule: "same-error-reason", clis, target: `${named(clis)} ${what}`, message });
|
|
148
|
+
const by = (key) => {
|
|
149
|
+
const groups = new Map();
|
|
150
|
+
for (const entry of owned)
|
|
151
|
+
groups.set(key(entry), [...(groups.get(key(entry)) ?? []), entry]);
|
|
152
|
+
return [...groups].sort(([a], [b]) => byText(a, b));
|
|
153
|
+
};
|
|
154
|
+
for (const [, entries] of by(({ reason }) => `${reason.code} ${reason.message.trim().toLowerCase()}`)) {
|
|
155
|
+
const ids = [...new Set(entries.map(({ reason }) => reason.reason))].sort(byText);
|
|
156
|
+
const clis = [...new Set(entries.map(({ owner }) => owner).filter((owner) => owner !== BASE))].sort(byText);
|
|
157
|
+
if (ids.length > 1 && clis.length > 0)
|
|
158
|
+
push(clis, `reason ${ids.join("=")}`, `one failure under ${ids.length} names: "${entries[0]?.reason.message}"`);
|
|
159
|
+
}
|
|
160
|
+
for (const [id, entries] of by(({ reason }) => reason.reason)) {
|
|
161
|
+
const codes = new Map(entries.map(({ owner, reason }) => [owner, reason.code]));
|
|
162
|
+
const clis = [...codes.keys()].filter((owner) => owner !== BASE).sort(byText);
|
|
163
|
+
if (new Set(codes.values()).size > 1 && clis.length > 0)
|
|
164
|
+
push(clis, `reason ${id}: code`, describe(codes));
|
|
165
|
+
}
|
|
166
|
+
return found;
|
|
167
|
+
};
|
|
168
|
+
const CROSS = {
|
|
169
|
+
"required-root": (inputs, options) => requiredRoots(inputs, options.roots),
|
|
170
|
+
"same-path-contract": (inputs, options) => samePathContract(inputs, options.groups),
|
|
171
|
+
"same-flag-meaning": (inputs) => sameFlagMeaning(inputs),
|
|
172
|
+
"same-entity-schema": (inputs) => sameEntitySchema(inputs),
|
|
173
|
+
"same-error-reason": (inputs) => sameErrorReason(inputs),
|
|
174
|
+
};
|
|
175
|
+
const measuredBy = {
|
|
176
|
+
"same-entity-schema": (input) => input.schemas !== undefined,
|
|
177
|
+
"same-error-reason": (input) => input.reasons !== undefined,
|
|
178
|
+
};
|
|
179
|
+
export const auditClis = (inputs, options, rules = AUDIT_RULES) => {
|
|
180
|
+
const problems = [];
|
|
181
|
+
const clis = inputs.map(({ document }) => document.cli);
|
|
182
|
+
for (const cli of new Set(clis.filter((one, index) => clis.indexOf(one) !== index)))
|
|
183
|
+
problems.push(`${cli} is given twice`);
|
|
184
|
+
const lintIds = LINT_RULES.map((rule) => rule.id);
|
|
185
|
+
const known = new Set([...lintIds, ...rules.map((rule) => rule.id)]);
|
|
186
|
+
for (const rule of Object.keys(options.baseline))
|
|
187
|
+
if (!known.has(rule))
|
|
188
|
+
problems.push(`no lint or audit rule "${rule}" (named in the baseline)`);
|
|
189
|
+
for (const group of options.groups)
|
|
190
|
+
for (const entry of group.differences)
|
|
191
|
+
if (!known.has(entry.rule))
|
|
192
|
+
problems.push(`no audit rule "${entry.rule}" (a difference in ${group.name})`);
|
|
193
|
+
const lint = new Map(inputs.map((input) => [
|
|
194
|
+
input.document.cli,
|
|
195
|
+
lintCommands(input.document, options.vocabulary, LINT_RULES, { raw: input.raw, schemas: input.schemas }),
|
|
196
|
+
]));
|
|
197
|
+
const findings = [
|
|
198
|
+
...inputs.flatMap(({ document }) => (lint.get(document.cli) ?? []).map((violation) => ({
|
|
199
|
+
rule: violation.rule,
|
|
200
|
+
clis: [document.cli],
|
|
201
|
+
target: `${document.cli}: ${violation.target}`,
|
|
202
|
+
message: violation.message,
|
|
203
|
+
}))),
|
|
204
|
+
...rules.flatMap((rule) => {
|
|
205
|
+
const check = CROSS[rule.id];
|
|
206
|
+
if (!check)
|
|
207
|
+
throw new Error(`audit rule "${rule.id}" has no check`);
|
|
208
|
+
return check(inputs, options);
|
|
209
|
+
}),
|
|
210
|
+
];
|
|
211
|
+
const declared = new Map(options.groups.flatMap((group) => group.differences.map((entry) => [`${entry.rule} ${entry.target}`, group.name])));
|
|
212
|
+
const found = new Set(findings.map((finding) => `${finding.rule} ${finding.target}`));
|
|
213
|
+
for (const [key, group] of declared)
|
|
214
|
+
if (!found.has(key))
|
|
215
|
+
problems.push(`stale difference in ${group}, no such divergence — remove it: ${key}`);
|
|
216
|
+
for (const group of options.groups)
|
|
217
|
+
if (group.differences.length > OVERRIDE_BUDGET)
|
|
218
|
+
problems.push(`${group.name} declares ${group.differences.length} differences; the budget is ${OVERRIDE_BUDGET}`);
|
|
219
|
+
const baselined = new Set(Object.entries(options.baseline).flatMap(([rule, targets]) => targets.map((target) => `${rule} ${target}`)));
|
|
220
|
+
const ownLint = (cli, rule) => lintIds.includes(rule) ? inputs.find((input) => input.document.cli === cli)?.lint : undefined;
|
|
221
|
+
const rows = [];
|
|
222
|
+
const blocking = [];
|
|
223
|
+
for (const input of inputs) {
|
|
224
|
+
const cli = input.document.cli;
|
|
225
|
+
for (const rule of [...lintIds, ...rules.map((one) => one.id)]) {
|
|
226
|
+
const mine = findings.filter((finding) => finding.rule === rule && finding.clis.includes(cli));
|
|
227
|
+
const own = ownLint(cli, rule);
|
|
228
|
+
let row;
|
|
229
|
+
if (own) {
|
|
230
|
+
const violations = (lint.get(cli) ?? []).filter((violation) => violation.rule === rule);
|
|
231
|
+
const verdict = judge(violations, { [rule]: own.baseline[rule] ?? [] }, own.overrides, own.budget);
|
|
232
|
+
row = {
|
|
233
|
+
cli,
|
|
234
|
+
rule,
|
|
235
|
+
measured: true,
|
|
236
|
+
found: violations.length,
|
|
237
|
+
baseline: verdict.baselined,
|
|
238
|
+
overridden: verdict.overridden,
|
|
239
|
+
new: verdict.fresh.length,
|
|
240
|
+
fixed: verdict.stale.filter((entry) => entry.in === "baseline").length,
|
|
241
|
+
new_targets: verdict.fresh.map((violation) => `${cli}: ${violation.target}`),
|
|
242
|
+
};
|
|
243
|
+
blocking.push(...mine.filter((finding) => row.new_targets.includes(finding.target)));
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
const open = mine.filter((finding) => !declared.has(`${rule} ${finding.target}`));
|
|
247
|
+
const fresh = open.filter((finding) => !baselined.has(`${rule} ${finding.target}`));
|
|
248
|
+
const here = new Set(mine.map((finding) => finding.target));
|
|
249
|
+
row = {
|
|
250
|
+
cli,
|
|
251
|
+
rule,
|
|
252
|
+
measured: measuredBy[rule]?.(input) ?? true,
|
|
253
|
+
found: mine.length,
|
|
254
|
+
baseline: open.length - fresh.length,
|
|
255
|
+
overridden: mine.length - open.length,
|
|
256
|
+
new: fresh.length,
|
|
257
|
+
fixed: (options.baseline[rule] ?? []).filter((target) => clisOf(target).includes(cli) && (!here.has(target) || declared.has(`${rule} ${target}`))).length,
|
|
258
|
+
new_targets: fresh.map((finding) => finding.target),
|
|
259
|
+
};
|
|
260
|
+
const blocks = lintIds.includes(rule) || options.blocks === "new";
|
|
261
|
+
if (blocks)
|
|
262
|
+
blocking.push(...fresh);
|
|
263
|
+
}
|
|
264
|
+
rows.push(row);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
const selfJudged = new Set(inputs.filter((input) => input.lint).map((input) => input.document.cli));
|
|
268
|
+
const nextBaseline = Object.fromEntries([...lintIds, ...rules.map((rule) => rule.id)].map((rule) => {
|
|
269
|
+
const kept = (options.baseline[rule] ?? []).filter((target) => !clisOf(target).some((cli) => clis.includes(cli)));
|
|
270
|
+
const now = findings
|
|
271
|
+
.filter((finding) => finding.rule === rule && !declared.has(`${rule} ${finding.target}`))
|
|
272
|
+
.filter((finding) => !(lintIds.includes(rule) && selfJudged.has(finding.clis[0] ?? "")))
|
|
273
|
+
.map((finding) => finding.target);
|
|
274
|
+
return [rule, [...new Set([...kept, ...now])].sort(byText)];
|
|
275
|
+
}));
|
|
276
|
+
const unique = new Map(blocking.map((finding) => [`${finding.rule} ${finding.target}`, finding]));
|
|
277
|
+
return {
|
|
278
|
+
findings,
|
|
279
|
+
rows,
|
|
280
|
+
blocking: [...unique.values()].filter((finding) => options.only === undefined || finding.clis.includes(options.only)),
|
|
281
|
+
nextBaseline,
|
|
282
|
+
problems,
|
|
283
|
+
};
|
|
284
|
+
};
|
|
285
|
+
const pad = (cells, widths) => cells
|
|
286
|
+
.map((cell, index) => (index < 2 ? cell.padEnd(widths[index] ?? 0) : cell.padStart(widths[index] ?? 0)))
|
|
287
|
+
.join(" ");
|
|
288
|
+
/** One line per CLI and rule that found something, then one total per CLI. */
|
|
289
|
+
export const scorecardTable = (rows) => {
|
|
290
|
+
const header = ["cli", "rule", "found", "baseline", "overridden", "new", "fixed"];
|
|
291
|
+
const cells = (row) => row.measured
|
|
292
|
+
? [row.cli, row.rule, ...[row.found, row.baseline, row.overridden, row.new, row.fixed].map(String)]
|
|
293
|
+
: [row.cli, row.rule, "n/a", "n/a", "n/a", "n/a", "n/a"];
|
|
294
|
+
const shown = rows.filter((row) => !row.measured || row.found > 0 || row.fixed > 0);
|
|
295
|
+
const totals = [...new Set(rows.map((row) => row.cli))].map((cli) => {
|
|
296
|
+
const mine = rows.filter((row) => row.cli === cli && row.measured);
|
|
297
|
+
const sum = (key) => String(mine.reduce((total, row) => total + row[key], 0));
|
|
298
|
+
return [cli, "total", sum("found"), sum("baseline"), sum("overridden"), sum("new"), sum("fixed")];
|
|
299
|
+
});
|
|
300
|
+
const lines = [header, ...shown.map(cells), ...totals];
|
|
301
|
+
const widths = header.map((_, index) => Math.max(...lines.map((line) => line[index]?.length ?? 0)));
|
|
302
|
+
return lines.map((line) => pad(line, widths).trimEnd()).join("\n");
|
|
303
|
+
};
|
|
304
|
+
//# sourceMappingURL=audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/dev/audit.ts"],"names":[],"mappings":"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"}
|
package/dist/dev/lint.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type CommandsDocument } from "../commands/document.js";
|
|
2
|
+
import type { CommandInfo, OptionInfo } from "../commands/index.js";
|
|
2
3
|
import { type LintRule, type Override } from "../standards/lint.js";
|
|
3
4
|
import type { Vocabulary } from "../standards/vocabulary.js";
|
|
4
5
|
export interface Violation {
|
|
@@ -7,10 +8,18 @@ export interface Violation {
|
|
|
7
8
|
target: string;
|
|
8
9
|
message: string;
|
|
9
10
|
}
|
|
11
|
+
export declare const walk: (commands: readonly CommandInfo[]) => CommandInfo[];
|
|
12
|
+
export declare const longName: (flags: string) => string;
|
|
13
|
+
/** A flag's kind of value: its value name, or `switch`. Two kinds under one name are two meanings. */
|
|
14
|
+
export declare const kindOf: (option: OptionInfo) => string;
|
|
15
|
+
export declare const summaryOf: (command: CommandInfo) => string;
|
|
10
16
|
export interface LintContext {
|
|
11
17
|
/** The commands document as the CLI printed it; parsing drops keys it does not know, so casing is checked here. */
|
|
12
18
|
raw?: unknown;
|
|
13
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* The CLI's own JSON Schemas by name — entities, envelopes — checked by `key-casing` beside cli-base's.
|
|
21
|
+
* `log_attributes` (`logAttributesJsonSchema(allow)`) is the CLI's log allow-list, for `log-attribute-key`.
|
|
22
|
+
*/
|
|
14
23
|
schemas?: Readonly<Record<string, unknown>>;
|
|
15
24
|
}
|
|
16
25
|
/** The schemas cli-base itself defines; every CLI's lint checks them too. */
|
package/dist/dev/lint.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../src/dev/lint.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,gBAAgB,EAA8B,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../src/dev/lint.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,gBAAgB,EAA8B,MAAM,yBAAyB,CAAA;AAC3F,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAInE,OAAO,EAAc,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAI/E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAE5D,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,gHAAgH;IAChH,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;CAChB;AAWD,eAAO,MAAM,IAAI,aAAc,SAAS,WAAW,EAAE,KAAG,WAAW,EACV,CAAA;AAEzD,eAAO,MAAM,QAAQ,UAAW,MAAM,KAAG,MAA8E,CAAA;AAEvH,sGAAsG;AACtG,eAAO,MAAM,MAAM,WAAY,UAAU,KAAG,MAG3C,CAAA;AAED,eAAO,MAAM,SAAS,YAAa,WAAW,KAAG,MACqB,CAAA;AAItE,MAAM,WAAW,WAAW;IAC1B,mHAAmH;IACnH,GAAG,CAAC,EAAE,OAAO,CAAA;IACb;;;OAGG;IACH,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CAC5C;AAOD,6EAA6E;AAC7E,eAAO,MAAM,WAAW,QAAO,MAAM,CAAC,MAAM,EAAE,OAAO,CAOnD,CAAA;AAwCF,sGAAsG;AACtG,eAAO,MAAM,YAAY,SAAU,MAAM,KAAG,MAAM,EAM/C,CAAA;AAoSH,eAAO,MAAM,WAAW,QAAO,MAAM,EAAyB,CAAA;AAE9D,kHAAkH;AAClH,eAAO,MAAM,YAAY,aACb,gBAAgB,cACd,UAAU,UACf,SAAS,QAAQ,EAAE,YACjB,WAAW,KACnB,SAAS,EAUX,CAAA;AAED,MAAM,WAAW,SAAS;IACxB,kEAAkE;IAClE,KAAK,EAAE,SAAS,EAAE,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,qGAAqG;IACrG,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,UAAU,GAAG,WAAW,CAAA;KAAE,EAAE,CAAA;IACvE,yEAAyE;IACzE,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,UAAU,EAAE,OAAO,CAAA;CACpB;AAED,eAAO,MAAM,KAAK,eACJ,SAAS,SAAS,EAAE,YACtB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,aAC1C,SAAS,QAAQ,EAAE,UACtB,MAAM,UACP,SAAS,QAAQ,EAAE,KACzB,SA4BF,CAAA;AAED,+GAA+G;AAC/G,eAAO,MAAM,UAAU,eACT,SAAS,SAAS,EAAE,aACrB,SAAS,QAAQ,EAAE,UACvB,SAAS,QAAQ,EAAE,KACzB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAWzB,CAAA"}
|
package/dist/dev/lint.js
CHANGED
|
@@ -4,7 +4,7 @@ import { exampleProblems } from "../query/registry.js";
|
|
|
4
4
|
import { queryAstSchema, queryNodeSchema } from "../query/types.js";
|
|
5
5
|
import { errorObjectSchema } from "../standards/errors.js";
|
|
6
6
|
import { LINT_RULES } from "../standards/lint.js";
|
|
7
|
-
import { logRecordSchema } from "../standards/log.js";
|
|
7
|
+
import { isContentKey, logAttributesJsonSchema, logRecordSchema } from "../standards/log.js";
|
|
8
8
|
import { itemEnvelopeSchema, listEnvelopeSchema } from "../standards/output.js";
|
|
9
9
|
import { jsonSchemaOf, SNAKE_CASE } from "../standards/registry.js";
|
|
10
10
|
const SUMMARY_LIMIT = 80;
|
|
@@ -14,16 +14,18 @@ const EXAMPLES_MAX = 3;
|
|
|
14
14
|
const SEARCH_ROOT = "search";
|
|
15
15
|
const SEARCH_EVERYTHING = "all";
|
|
16
16
|
const byText = (a, b) => (a < b ? -1 : a > b ? 1 : 0);
|
|
17
|
-
const walk = (commands) => commands.flatMap((one) => [one, ...walk(one.commands)]);
|
|
18
|
-
const longName = (flags) => flags.split(/[ ,|]+/).find((part) => part.startsWith("--")) ?? flags;
|
|
17
|
+
export const walk = (commands) => commands.flatMap((one) => [one, ...walk(one.commands)]);
|
|
18
|
+
export const longName = (flags) => flags.split(/[ ,|]+/).find((part) => part.startsWith("--")) ?? flags;
|
|
19
19
|
/** A flag's kind of value: its value name, or `switch`. Two kinds under one name are two meanings. */
|
|
20
|
-
const kindOf = (option) => {
|
|
20
|
+
export const kindOf = (option) => {
|
|
21
21
|
if (!option.takes_value)
|
|
22
22
|
return "switch";
|
|
23
23
|
return option.flags.match(/[<[]([^>\]]+)[>\]]/)?.[1]?.toLowerCase() ?? "value";
|
|
24
24
|
};
|
|
25
|
-
const summaryOf = (command) => (command.summary ?? command.description.split("\n")[0] ?? "").trim();
|
|
25
|
+
export const summaryOf = (command) => (command.summary ?? command.description.split("\n")[0] ?? "").trim();
|
|
26
26
|
const label = (command) => command.path.join(" ");
|
|
27
|
+
/** The `--schemas` entry holding the CLI's log allow-list; its keys are camelCase, so `key-casing` skips it. */
|
|
28
|
+
const LOG_ATTRIBUTES = "log_attributes";
|
|
27
29
|
/** The schemas cli-base itself defines; every CLI's lint checks them too. */
|
|
28
30
|
export const baseSchemas = () => ({
|
|
29
31
|
list_envelope: jsonSchemaOf(listEnvelopeSchema(v.unknown())),
|
|
@@ -270,7 +272,8 @@ const CHECKS = {
|
|
|
270
272
|
.filter((argument) => argument.description.trim() === "")
|
|
271
273
|
.map((argument) => ({ target: `${label(command)} <${argument.name}>`, message: "argument not described" }))),
|
|
272
274
|
"key-casing": (document, _vocabulary, context) => {
|
|
273
|
-
const
|
|
275
|
+
const { [LOG_ATTRIBUTES]: _camelCase, ...own } = context.schemas ?? {};
|
|
276
|
+
const schemas = { ...baseSchemas(), ...own };
|
|
274
277
|
return [
|
|
275
278
|
...Object.entries(schemas).flatMap(([name, schema]) => schemaKeys(schema, "").map(([key, path]) => ({ key, target: `schema ${name}: ${path}` }))),
|
|
276
279
|
...documentKeys(context.raw ?? document, "").map(([key, path]) => ({ key, target: `commands --json: ${path}` })),
|
|
@@ -329,6 +332,15 @@ const CHECKS = {
|
|
|
329
332
|
.filter((option) => option.description.trim() === "")
|
|
330
333
|
.map((option) => ({ target: `${label(command)} ${longName(option.flags)}`, message: "option not described" }))),
|
|
331
334
|
],
|
|
335
|
+
"log-attribute-key": (_document, _vocabulary, context) => {
|
|
336
|
+
const schema = context.schemas?.[LOG_ATTRIBUTES] ?? logAttributesJsonSchema();
|
|
337
|
+
return schemaKeys(schema, "")
|
|
338
|
+
.filter(([key]) => isContentKey(key))
|
|
339
|
+
.map(([key, path]) => ({
|
|
340
|
+
target: `schema ${LOG_ATTRIBUTES}: ${path}`,
|
|
341
|
+
message: `"${key}" names content or a secret, which no log may carry`,
|
|
342
|
+
}));
|
|
343
|
+
},
|
|
332
344
|
};
|
|
333
345
|
export const lintRuleIds = () => Object.keys(CHECKS);
|
|
334
346
|
/** Every violation, one per rule and target, sorted. Generated commands keep the names of the API they mirror. */
|