repo-contract 0.7.2 → 0.8.4
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/CHANGELOG.md +134 -73
- package/README.md +4 -0
- package/bin/preset-catalog.d.mts +9 -0
- package/bin/preset-catalog.mjs +42 -1
- package/bin/repo-contract.mjs +6 -2
- package/dist/.dts/helpers/exception-policy.d.ts +6 -6
- package/dist/.dts/helpers/exception-policy.d.ts.map +1 -1
- package/dist/.dts/helpers/glob-match.d.ts +29 -0
- package/dist/.dts/helpers/glob-match.d.ts.map +1 -0
- package/dist/.dts/helpers/index.d.ts +1 -1
- package/dist/.dts/parsing/parse-output.d.ts +1 -1
- package/dist/.dts/presets/dist-no-urls.d.ts +26 -0
- package/dist/.dts/presets/dist-no-urls.d.ts.map +1 -0
- package/dist/.dts/presets/index.d.ts +2 -0
- package/dist/.dts/presets/index.d.ts.map +1 -1
- package/dist/.dts/standard-schema/types.d.ts +2 -2
- package/dist/.dts/types.d.ts +5 -5
- package/dist/.dts/types.d.ts.map +1 -1
- package/dist/chunk-HDKSRSNF.js +108 -0
- package/dist/chunk-HDKSRSNF.js.map +1 -0
- package/dist/helpers.cjs +109 -3
- package/dist/helpers.cjs.map +1 -1
- package/dist/helpers.js +3 -4
- package/dist/helpers.js.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/presets.cjs +214 -0
- package/dist/presets.cjs.map +1 -1
- package/dist/presets.js +110 -1
- package/dist/presets.js.map +1 -1
- package/package.json +27 -22
- package/schemas/evidence.schema.json +2 -2
- package/schemas/verdict.schema.json +2 -2
- package/src/config/validate-config.ts +3 -3
- package/src/helpers/exception-policy.ts +9 -9
- package/src/helpers/glob-match.ts +203 -0
- package/src/helpers/index.ts +1 -1
- package/src/parsing/parse-output.ts +1 -1
- package/src/presets/dist-no-urls.ts +179 -0
- package/src/presets/index.ts +2 -0
- package/src/standard-schema/types.ts +2 -2
- package/src/types.ts +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/presets/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAC9B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/presets/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,YAAY,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAC9B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Hand-vendored from `@standard-schema/spec@1.1.0` (
|
|
2
|
+
* Hand-vendored from `@standard-schema/spec@1.1.0` (standardschema.dev), pinned
|
|
3
3
|
* 2026-09-04 -- see specs/decisions/0012-hand-vendored-standard-schema-support-for-optional-output-validation.md for why this is
|
|
4
4
|
* vendored rather than an installed dependency, and for the version-pin/re-diff process. Pure type
|
|
5
5
|
* declarations, zero runtime code -- assigning any real Zod/Valibot/ArkType (etc.) schema to this
|
|
6
6
|
* type costs nothing at runtime. Only `StandardSchemaV1` (validation) is vendored here -- the
|
|
7
7
|
* separate, optional `StandardJSONSchemaV1` (JSON Schema conversion) extension
|
|
8
|
-
* (
|
|
8
|
+
* (standardschema.dev/json-schema) is out of scope; see the ADR.
|
|
9
9
|
*
|
|
10
10
|
* Upstream's `StandardSchemaV1.Props` actually extends a shared `StandardTypedV1.Props` base
|
|
11
11
|
* (`version`/`vendor`/`types`); this vendored copy inlines those fields directly into one flat
|
package/dist/.dts/types.d.ts
CHANGED
|
@@ -125,11 +125,11 @@ export interface CheckEvidence {
|
|
|
125
125
|
* every configured check's evidence, plus timing for the run as a whole.
|
|
126
126
|
* Says nothing about whether any of it was acceptable; see `Verdict`.
|
|
127
127
|
* Additive fields are a compatible change; changing or removing an existing
|
|
128
|
-
* field requires bumping this version number (see VERSIONING.md).
|
|
128
|
+
* field requires bumping this version number (see `VERSIONING.md`).
|
|
129
129
|
* @public
|
|
130
130
|
*/
|
|
131
131
|
export interface Evidence<TChecks extends CheckSchema = CheckSchema> {
|
|
132
|
-
/** Schema version of this shape; see VERSIONING.md
|
|
132
|
+
/** Schema version of this shape; see `VERSIONING.md`. */
|
|
133
133
|
readonly version: 1;
|
|
134
134
|
/** ISO 8601 timestamp of when the run began. */
|
|
135
135
|
readonly startedAt: string;
|
|
@@ -264,7 +264,7 @@ export interface CheckDefinitionConfig {
|
|
|
264
264
|
readonly format: OutputFormat;
|
|
265
265
|
/**
|
|
266
266
|
* An optional Standard Schema-compliant validator (Zod, Valibot, ArkType, or any other
|
|
267
|
-
* implementation of
|
|
267
|
+
* implementation of standardschema.dev), run once the requested `format` parse
|
|
268
268
|
* itself succeeds. repo-contract never imports a schema library itself --
|
|
269
269
|
* `StandardSchemaV1` is hand-vendored (see `src/standard-schema/types.ts`) purely as a
|
|
270
270
|
* type-level contract, so accepting any consumer's own schema object costs zero new
|
|
@@ -451,14 +451,14 @@ export interface RunRepoContractOptions {
|
|
|
451
451
|
* `outcome` is `"pass"` or `"warn"` -- `"fail"` is the only outcome that
|
|
452
452
|
* fails the run; one failing check never collapses into a single generic
|
|
453
453
|
* message, every check remains individually inspectable under `checks`.
|
|
454
|
-
* Versioned independently of `Evidence` (see VERSIONING.md's
|
|
454
|
+
* Versioned independently of `Evidence` (see `VERSIONING.md`'s
|
|
455
455
|
* schema-versioning policy) -- `version: 2` reflects `checks[id]` changing
|
|
456
456
|
* shape from `{ passed, reason? }` to a full `PolicyResult`
|
|
457
457
|
* (`{ outcome, rationale }`); see ADR 0001.
|
|
458
458
|
* @public
|
|
459
459
|
*/
|
|
460
460
|
export interface Verdict<TChecks extends CheckSchema = CheckSchema> {
|
|
461
|
-
/** Schema version of this shape; see VERSIONING.md
|
|
461
|
+
/** Schema version of this shape; see `VERSIONING.md`. */
|
|
462
462
|
readonly version: 2;
|
|
463
463
|
/** `true` only if every check's `outcome` is `"pass"` or `"warn"`. */
|
|
464
464
|
readonly passed: boolean;
|
package/dist/.dts/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAElE;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,CAAA;AAE1C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,WAAW,GACrB,WAAW,GAAG,WAAW,GAAG,UAAU,GAAG,iBAAiB,GAAG,aAAa,GAAG,SAAS,CAAA;AAExF;;;GAGG;AACH,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;IAC7B,qBAAqB;IACrB,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAA;IACtB,wBAAwB;IACxB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAClB;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;IAC7B,sBAAsB;IACtB,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAA;IACvB,iCAAiC;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED;;;GAGG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,mBAAmB,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAA;AAE1E;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,aAAa;IAC5B,4FAA4F;IAC5F,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;IAChC,0DAA0D;IAC1D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,yEAAyE;IACzE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,kEAAkE;IAClE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,kFAAkF;IAClF,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,mGAAmG;IACnG,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAA;IACtC,6JAA6J;IAC7J,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,4JAA4J;IAC5J,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,0JAA0J;IAC1J,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,6XAA6X;IAC7X,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;IAChC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,CAAA;CACxC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,QAAQ,CAAC,OAAO,SAAS,WAAW,GAAG,WAAW;IACjE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// src/helpers/glob-match.ts
|
|
2
|
+
var MAX_PATTERN_LENGTH = 1e3;
|
|
3
|
+
var MAX_EXPANSIONS = 1024;
|
|
4
|
+
var CLASS_RANGE = /[\s\S]-[\s\S]/g;
|
|
5
|
+
var TOKEN = /\\(.)|\*\*\/|\*\*|\*|\?|\[([^\]]+)\]|[\s\S]/g;
|
|
6
|
+
function findCommaGroup(pattern) {
|
|
7
|
+
const closers = Array.from(pattern, (_char, index) => index).filter(
|
|
8
|
+
(index) => pattern.charAt(index) === "}"
|
|
9
|
+
);
|
|
10
|
+
for (const end of closers) {
|
|
11
|
+
const start = pattern.lastIndexOf("{", end);
|
|
12
|
+
const body = pattern.slice(start + 1, end);
|
|
13
|
+
if (start !== -1 && body.includes(",") && !body.includes("{") && !body.includes("}")) {
|
|
14
|
+
return { start, end, alternatives: body.split(",") };
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return void 0;
|
|
18
|
+
}
|
|
19
|
+
function expandBraces(pattern) {
|
|
20
|
+
const pending = [pattern];
|
|
21
|
+
const done = [];
|
|
22
|
+
const finished = Array.from({ length: MAX_EXPANSIONS }).some(() => {
|
|
23
|
+
const next = pending.pop();
|
|
24
|
+
if (next === void 0) return true;
|
|
25
|
+
if (next.length > MAX_PATTERN_LENGTH) {
|
|
26
|
+
throw new Error(`Glob pattern is longer than ${String(MAX_PATTERN_LENGTH)} characters.`);
|
|
27
|
+
}
|
|
28
|
+
const group = findCommaGroup(next);
|
|
29
|
+
if (group === void 0) {
|
|
30
|
+
done.push(next);
|
|
31
|
+
} else {
|
|
32
|
+
const head = next.slice(0, group.start);
|
|
33
|
+
const tail = next.slice(group.end + 1);
|
|
34
|
+
pending.push(...group.alternatives.map((alternative) => `${head}${alternative}${tail}`));
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
});
|
|
38
|
+
if (!finished) {
|
|
39
|
+
throw new Error(
|
|
40
|
+
`Glob pattern ${JSON.stringify(pattern)} expands to too many brace alternatives.`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return done;
|
|
44
|
+
}
|
|
45
|
+
function tokenize(pattern) {
|
|
46
|
+
return [...pattern.matchAll(TOKEN)].map((match) => {
|
|
47
|
+
const token = match[0];
|
|
48
|
+
const escaped = match[1];
|
|
49
|
+
const members = match[2];
|
|
50
|
+
if (escaped !== void 0) return { kind: "literal", char: escaped };
|
|
51
|
+
if (members !== void 0) {
|
|
52
|
+
const negated = members.startsWith("!") || members.startsWith("^");
|
|
53
|
+
return { kind: "class", negated, members: negated ? members.slice(1) : members };
|
|
54
|
+
}
|
|
55
|
+
switch (token) {
|
|
56
|
+
case "**/":
|
|
57
|
+
return { kind: "globstar-slash" };
|
|
58
|
+
case "**":
|
|
59
|
+
return { kind: "globstar" };
|
|
60
|
+
case "*":
|
|
61
|
+
return { kind: "star" };
|
|
62
|
+
case "?":
|
|
63
|
+
return { kind: "one" };
|
|
64
|
+
default:
|
|
65
|
+
return { kind: "literal", char: token };
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
function classContains(char, members) {
|
|
70
|
+
const ranges = members.match(CLASS_RANGE) ?? [];
|
|
71
|
+
const singles = members.replace(CLASS_RANGE, "");
|
|
72
|
+
return ranges.some((range) => range.charAt(0) <= char && char <= range.charAt(2)) || singles.includes(char);
|
|
73
|
+
}
|
|
74
|
+
function canGo(piece, value, from, to) {
|
|
75
|
+
const char = value.charAt(from);
|
|
76
|
+
switch (piece.kind) {
|
|
77
|
+
case "literal":
|
|
78
|
+
return to === from + 1 && char === piece.char;
|
|
79
|
+
case "one":
|
|
80
|
+
return to === from + 1 && char !== "/";
|
|
81
|
+
case "class":
|
|
82
|
+
return to === from + 1 && char !== "/" && classContains(char, piece.members) !== piece.negated;
|
|
83
|
+
case "star":
|
|
84
|
+
return to >= from && !value.slice(from, to).includes("/");
|
|
85
|
+
case "globstar":
|
|
86
|
+
return to >= from;
|
|
87
|
+
case "globstar-slash":
|
|
88
|
+
return to >= from && (to === from || value.charAt(to - 1) === "/");
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function step(piece, value, current, positions) {
|
|
92
|
+
return positions.map(
|
|
93
|
+
(to) => positions.some((from) => current[from] && canGo(piece, value, from, to))
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
function globMatch(value, pattern) {
|
|
97
|
+
const alternatives = expandBraces(pattern).map(tokenize);
|
|
98
|
+
const positions = Array.from({ length: value.length + 1 }, (_, index) => index);
|
|
99
|
+
return alternatives.some((tokens) => {
|
|
100
|
+
const start = positions.map((position) => position === 0);
|
|
101
|
+
const end = tokens.reduce((current, token) => step(token, value, current, positions), start);
|
|
102
|
+
return end[value.length] === true;
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export { globMatch };
|
|
107
|
+
//# sourceMappingURL=chunk-HDKSRSNF.js.map
|
|
108
|
+
//# sourceMappingURL=chunk-HDKSRSNF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/helpers/glob-match.ts"],"names":[],"mappings":"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","file":"chunk-HDKSRSNF.js","sourcesContent":["/**\n * A small, dependency-free glob matcher -- the replacement for the `minimatch` runtime dependency\n * (see specs/decisions/0017-own-glob-matcher-replaces-minimatch.md). Pure string logic: it reads no\n * environment variable, touches no filesystem, imports nothing, and builds no `RegExp` from its\n * input -- a pattern is tokenized and matched by a position-set simulation that is polynomial in\n * the sizes of the pattern and the value, so no pattern can cause catastrophic backtracking.\n *\n * Supported syntax (exactly what exception-policy category keys use, e.g. `\"security/*\"`):\n * - `*` any run of characters except `/`\n * - `**` any run of characters including `/`; a whole `**` + `/` segment also matches zero segments\n * - `?` exactly one character except `/`\n * - `[abc]`, `[a-z]`, `[!abc]` / `[^abc]` a character class (a reversed range matches nothing)\n * - `{a,b}` alternation (nestable)\n * - `\\x` the literal character `x`\n *\n * Not supported (treated as literal text, never as a special form): extglobs (`+(a|b)`), POSIX\n * classes (`[[:alpha:]]`), dotfile exclusion, case folding.\n */\n\ntype Token =\n | { readonly kind: \"literal\"; readonly char: string }\n | { readonly kind: \"one\" }\n | { readonly kind: \"star\" }\n | { readonly kind: \"globstar\" }\n | { readonly kind: \"globstar-slash\" }\n | { readonly kind: \"class\"; readonly negated: boolean; readonly members: string }\n\n/** Longest pattern accepted. Category keys are short identifiers; a limit also bounds every expansion step. */\nconst MAX_PATTERN_LENGTH = 1000\n\n/** Upper bound on the alternatives one pattern's brace groups may expand to. */\nconst MAX_EXPANSIONS = 1024\n\n/** One `x-y` range inside a class body (a lone or trailing `-` is a literal dash). */\nconst CLASS_RANGE = /[\\s\\S]-[\\s\\S]/g\n\nconst TOKEN = /\\\\(.)|\\*\\*\\/|\\*\\*|\\*|\\?|\\[([^\\]]+)\\]|[\\s\\S]/g\n\n/**\n * Finds the first brace group (scanning closing braces left to right) whose body holds a comma and\n * no braces of its own -- the innermost expandable group. `{x}` (no comma) is never expandable.\n * @param pattern - the glob to search.\n * @returns the group's span and its comma-separated alternatives, or `undefined` when none is left.\n */\nfunction findCommaGroup(\n pattern: string,\n):\n | { readonly start: number; readonly end: number; readonly alternatives: readonly string[] }\n | undefined {\n const closers = Array.from(pattern, (_char, index) => index).filter(\n (index) => pattern.charAt(index) === \"}\",\n )\n for (const end of closers) {\n const start = pattern.lastIndexOf(\"{\", end)\n const body = pattern.slice(start + 1, end)\n if (start !== -1 && body.includes(\",\") && !body.includes(\"{\") && !body.includes(\"}\")) {\n return { start, end, alternatives: body.split(\",\") }\n }\n }\n return undefined\n}\n\n/**\n * Expands every `{a,b}` alternation into the brace-free patterns it stands for.\n * @param pattern - the glob, possibly containing brace groups.\n * @returns every brace-free alternative.\n * @throws {Error} when a pattern exceeds {@link MAX_PATTERN_LENGTH} characters, or the expansion would exceed {@link MAX_EXPANSIONS} patterns.\n */\nfunction expandBraces(pattern: string): readonly string[] {\n const pending = [pattern]\n const done: string[] = []\n const finished = Array.from({ length: MAX_EXPANSIONS }).some(() => {\n const next = pending.pop()\n if (next === undefined) return true\n if (next.length > MAX_PATTERN_LENGTH) {\n throw new Error(`Glob pattern is longer than ${String(MAX_PATTERN_LENGTH)} characters.`)\n }\n const group = findCommaGroup(next)\n if (group === undefined) {\n done.push(next)\n } else {\n const head = next.slice(0, group.start)\n const tail = next.slice(group.end + 1)\n pending.push(...group.alternatives.map((alternative) => `${head}${alternative}${tail}`))\n }\n return false\n })\n if (!finished) {\n throw new Error(\n `Glob pattern ${JSON.stringify(pattern)} expands to too many brace alternatives.`,\n )\n }\n return done\n}\n\n/**\n * Tokenizes one brace-free glob.\n * @param pattern - the brace-free glob.\n * @returns its tokens, in order.\n */\nfunction tokenize(pattern: string): readonly Token[] {\n return [...pattern.matchAll(TOKEN)].map((match): Token => {\n const token = match[0]\n const escaped = match[1]\n const members = match[2]\n if (escaped !== undefined) return { kind: \"literal\", char: escaped }\n if (members !== undefined) {\n const negated = members.startsWith(\"!\") || members.startsWith(\"^\")\n return { kind: \"class\", negated, members: negated ? members.slice(1) : members }\n }\n switch (token) {\n case \"**/\":\n return { kind: \"globstar-slash\" }\n case \"**\":\n return { kind: \"globstar\" }\n case \"*\":\n return { kind: \"star\" }\n case \"?\":\n return { kind: \"one\" }\n default:\n return { kind: \"literal\", char: token }\n }\n })\n}\n\n/**\n * Whether `char` is in a class body such as `a-cx` (ranges and single characters).\n * @param char - the character under test.\n * @param members - the class body without brackets or negation marker.\n * @returns `true` when the class contains `char`.\n */\nfunction classContains(char: string, members: string): boolean {\n const ranges = members.match(CLASS_RANGE) ?? []\n const singles = members.replace(CLASS_RANGE, \"\")\n return (\n ranges.some((range) => range.charAt(0) <= char && char <= range.charAt(2)) ||\n singles.includes(char)\n )\n}\n\n/**\n * Whether one token can consume exactly `value.slice(from, to)`.\n * @param piece - the token.\n * @param value - the value being matched.\n * @param from - where the token starts.\n * @param to - where the token would end.\n * @returns `true` when the token matches that span.\n */\nfunction canGo(piece: Token, value: string, from: number, to: number): boolean {\n const char = value.charAt(from)\n switch (piece.kind) {\n case \"literal\":\n return to === from + 1 && char === piece.char\n case \"one\":\n return to === from + 1 && char !== \"/\"\n case \"class\":\n return to === from + 1 && char !== \"/\" && classContains(char, piece.members) !== piece.negated\n case \"star\":\n return to >= from && !value.slice(from, to).includes(\"/\")\n case \"globstar\":\n return to >= from\n case \"globstar-slash\":\n return to >= from && (to === from || value.charAt(to - 1) === \"/\")\n }\n}\n\n/**\n * Advances the set of reachable value positions across one token.\n * @param piece - the token to consume.\n * @param value - the value being matched.\n * @param current - which positions are reachable before the token.\n * @param positions - `0..value.length`, precomputed once per match.\n * @returns which positions are reachable after the token.\n */\nfunction step(\n piece: Token,\n value: string,\n current: readonly boolean[],\n positions: readonly number[],\n): boolean[] {\n return positions.map((to) =>\n positions.some((from) => current[from] && canGo(piece, value, from, to)),\n )\n}\n\n/**\n * Whether `value` matches the glob `pattern` (see this module's own doc comment for the exact\n * syntax). Nothing is cached: compiling a category glob costs microseconds, and a cache would make a\n * pattern's code paths run only for the first caller.\n * @param value - the string to test (an exception category such as `\"security/xss\"`).\n * @param pattern - the glob to test it against.\n * @returns `true` when the whole of `value` matches `pattern`.\n * @throws {Error} when `pattern` is over 1000 characters, or its brace groups expand to too many alternatives.\n */\nexport function globMatch(value: string, pattern: string): boolean {\n const alternatives = expandBraces(pattern).map(tokenize)\n const positions = Array.from({ length: value.length + 1 }, (_, index) => index)\n return alternatives.some((tokens) => {\n const start = positions.map((position) => position === 0)\n const end = tokens.reduce((current, token) => step(token, value, current, positions), start)\n return end[value.length] === true\n })\n}\n"]}
|
package/dist/helpers.cjs
CHANGED
|
@@ -1,9 +1,115 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var crypto = require('crypto');
|
|
4
|
-
var minimatch = require('minimatch');
|
|
5
4
|
var promises = require('fs/promises');
|
|
6
5
|
|
|
6
|
+
// src/helpers/exception-policy.ts
|
|
7
|
+
|
|
8
|
+
// src/helpers/glob-match.ts
|
|
9
|
+
var MAX_PATTERN_LENGTH = 1e3;
|
|
10
|
+
var MAX_EXPANSIONS = 1024;
|
|
11
|
+
var CLASS_RANGE = /[\s\S]-[\s\S]/g;
|
|
12
|
+
var TOKEN = /\\(.)|\*\*\/|\*\*|\*|\?|\[([^\]]+)\]|[\s\S]/g;
|
|
13
|
+
function findCommaGroup(pattern) {
|
|
14
|
+
const closers = Array.from(pattern, (_char, index) => index).filter(
|
|
15
|
+
(index) => pattern.charAt(index) === "}"
|
|
16
|
+
);
|
|
17
|
+
for (const end of closers) {
|
|
18
|
+
const start = pattern.lastIndexOf("{", end);
|
|
19
|
+
const body = pattern.slice(start + 1, end);
|
|
20
|
+
if (start !== -1 && body.includes(",") && !body.includes("{") && !body.includes("}")) {
|
|
21
|
+
return { start, end, alternatives: body.split(",") };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return void 0;
|
|
25
|
+
}
|
|
26
|
+
function expandBraces(pattern) {
|
|
27
|
+
const pending = [pattern];
|
|
28
|
+
const done = [];
|
|
29
|
+
const finished = Array.from({ length: MAX_EXPANSIONS }).some(() => {
|
|
30
|
+
const next = pending.pop();
|
|
31
|
+
if (next === void 0) return true;
|
|
32
|
+
if (next.length > MAX_PATTERN_LENGTH) {
|
|
33
|
+
throw new Error(`Glob pattern is longer than ${String(MAX_PATTERN_LENGTH)} characters.`);
|
|
34
|
+
}
|
|
35
|
+
const group = findCommaGroup(next);
|
|
36
|
+
if (group === void 0) {
|
|
37
|
+
done.push(next);
|
|
38
|
+
} else {
|
|
39
|
+
const head = next.slice(0, group.start);
|
|
40
|
+
const tail = next.slice(group.end + 1);
|
|
41
|
+
pending.push(...group.alternatives.map((alternative) => `${head}${alternative}${tail}`));
|
|
42
|
+
}
|
|
43
|
+
return false;
|
|
44
|
+
});
|
|
45
|
+
if (!finished) {
|
|
46
|
+
throw new Error(
|
|
47
|
+
`Glob pattern ${JSON.stringify(pattern)} expands to too many brace alternatives.`
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
return done;
|
|
51
|
+
}
|
|
52
|
+
function tokenize(pattern) {
|
|
53
|
+
return [...pattern.matchAll(TOKEN)].map((match) => {
|
|
54
|
+
const token = match[0];
|
|
55
|
+
const escaped = match[1];
|
|
56
|
+
const members = match[2];
|
|
57
|
+
if (escaped !== void 0) return { kind: "literal", char: escaped };
|
|
58
|
+
if (members !== void 0) {
|
|
59
|
+
const negated = members.startsWith("!") || members.startsWith("^");
|
|
60
|
+
return { kind: "class", negated, members: negated ? members.slice(1) : members };
|
|
61
|
+
}
|
|
62
|
+
switch (token) {
|
|
63
|
+
case "**/":
|
|
64
|
+
return { kind: "globstar-slash" };
|
|
65
|
+
case "**":
|
|
66
|
+
return { kind: "globstar" };
|
|
67
|
+
case "*":
|
|
68
|
+
return { kind: "star" };
|
|
69
|
+
case "?":
|
|
70
|
+
return { kind: "one" };
|
|
71
|
+
default:
|
|
72
|
+
return { kind: "literal", char: token };
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
function classContains(char, members) {
|
|
77
|
+
const ranges = members.match(CLASS_RANGE) ?? [];
|
|
78
|
+
const singles = members.replace(CLASS_RANGE, "");
|
|
79
|
+
return ranges.some((range) => range.charAt(0) <= char && char <= range.charAt(2)) || singles.includes(char);
|
|
80
|
+
}
|
|
81
|
+
function canGo(piece, value, from, to) {
|
|
82
|
+
const char = value.charAt(from);
|
|
83
|
+
switch (piece.kind) {
|
|
84
|
+
case "literal":
|
|
85
|
+
return to === from + 1 && char === piece.char;
|
|
86
|
+
case "one":
|
|
87
|
+
return to === from + 1 && char !== "/";
|
|
88
|
+
case "class":
|
|
89
|
+
return to === from + 1 && char !== "/" && classContains(char, piece.members) !== piece.negated;
|
|
90
|
+
case "star":
|
|
91
|
+
return to >= from && !value.slice(from, to).includes("/");
|
|
92
|
+
case "globstar":
|
|
93
|
+
return to >= from;
|
|
94
|
+
case "globstar-slash":
|
|
95
|
+
return to >= from && (to === from || value.charAt(to - 1) === "/");
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function step(piece, value, current, positions) {
|
|
99
|
+
return positions.map(
|
|
100
|
+
(to) => positions.some((from) => current[from] && canGo(piece, value, from, to))
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
function globMatch(value, pattern) {
|
|
104
|
+
const alternatives = expandBraces(pattern).map(tokenize);
|
|
105
|
+
const positions = Array.from({ length: value.length + 1 }, (_, index) => index);
|
|
106
|
+
return alternatives.some((tokens) => {
|
|
107
|
+
const start = positions.map((position) => position === 0);
|
|
108
|
+
const end = tokens.reduce((current, token) => step(token, value, current, positions), start);
|
|
109
|
+
return end[value.length] === true;
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
7
113
|
// src/helpers/exception-policy.ts
|
|
8
114
|
function stricterOf(a, b) {
|
|
9
115
|
if (a.mode === "forbidden" || b.mode === "forbidden") return { mode: "forbidden" };
|
|
@@ -28,7 +134,7 @@ function resolveExceptionPolicy(classification, config, globalDefault) {
|
|
|
28
134
|
const exactMatch = rules.find(([pattern]) => pattern === category);
|
|
29
135
|
if (exactMatch) return exactMatch[1];
|
|
30
136
|
const globMatches = rules.filter(([pattern]) => {
|
|
31
|
-
return pattern !== category &&
|
|
137
|
+
return pattern !== category && globMatch(category, pattern);
|
|
32
138
|
}).map(([, policy]) => policy);
|
|
33
139
|
if (globMatches.length > 0) {
|
|
34
140
|
return globMatches.reduce(stricterOf);
|
|
@@ -107,7 +213,7 @@ function validateExceptionPolicyConfig(config, validRequirements) {
|
|
|
107
213
|
for (const [pattern, policy] of Object.entries(groupPolicy.rules ?? {})) {
|
|
108
214
|
if (pattern === "*") {
|
|
109
215
|
errors.push(
|
|
110
|
-
`config.${group}.rules must not use the literal "*" as a key -- it would be consulted only as an ordinary
|
|
216
|
+
`config.${group}.rules must not use the literal "*" as a key -- it would be consulted only as an ordinary glob (matching the literal one-character category "*", never every category in the group) rather than as the blanket policy \`resolveExceptionPolicy\` already applies whenever the classification's own \`category\` is "*". Omit this key, or use a more specific pattern.`
|
|
111
217
|
);
|
|
112
218
|
}
|
|
113
219
|
validateExceptionPolicyValue(
|