@rigour-labs/core 6.2.5 → 6.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/discovery-signals.d.ts +27 -0
- package/dist/discovery-signals.js +96 -0
- package/dist/discovery.d.ts +1 -2
- package/dist/discovery.js +36 -49
- package/dist/discovery.test.js +84 -71
- package/dist/gates/deep-analysis.d.ts +2 -0
- package/dist/gates/deep-analysis.js +5 -1
- package/dist/gates/deep-intent.d.ts +3 -0
- package/dist/gates/deep-intent.js +57 -0
- package/dist/gates/deep-intent.test.d.ts +1 -0
- package/dist/gates/deep-intent.test.js +51 -0
- package/dist/gates/deep-runner.js +1 -0
- package/dist/gates/deprecated-apis-ast.d.ts +8 -0
- package/dist/gates/deprecated-apis-ast.js +25 -0
- package/dist/gates/deprecated-apis-rules-node.js +2 -8
- package/dist/gates/deprecated-apis.js +5 -1
- package/dist/gates/deprecated-apis.test.js +30 -0
- package/dist/gates/frontend-secret-exposure.js +5 -1
- package/dist/gates/frontend-secret-exposure.test.js +20 -0
- package/dist/gates/hallucinated-imports/framework-modules.d.ts +14 -0
- package/dist/gates/hallucinated-imports/framework-modules.js +75 -0
- package/dist/gates/hallucinated-imports/index.js +14 -6
- package/dist/gates/hallucinated-imports/js-resolver.d.ts +16 -12
- package/dist/gates/hallucinated-imports/js-resolver.js +65 -153
- package/dist/gates/hallucinated-imports/ts-path-target.js +16 -0
- package/dist/gates/hallucinated-imports/tsconfig-paths.d.ts +16 -0
- package/dist/gates/hallucinated-imports/tsconfig-paths.js +120 -0
- package/dist/gates/hallucinated-imports-sveltekit.test.d.ts +1 -0
- package/dist/gates/hallucinated-imports-sveltekit.test.js +108 -0
- package/dist/gates/runner.js +5 -0
- package/dist/gates/semantic-bugs.d.ts +23 -0
- package/dist/gates/semantic-bugs.js +48 -0
- package/dist/gates/semantic-bugs.test.d.ts +1 -0
- package/dist/gates/semantic-bugs.test.js +70 -0
- package/dist/gates/side-effect-analysis/index.js +11 -1
- package/dist/gates/side-effect-analysis.test.d.ts +1 -0
- package/dist/gates/side-effect-analysis.test.js +162 -0
- package/dist/gates/side-effect-helpers/pattern-detection.js +35 -7
- package/dist/gates/side-effect-helpers/resource-tracking.js +17 -10
- package/dist/gates/side-effect-helpers/scope-analysis.d.ts +6 -0
- package/dist/gates/side-effect-helpers/scope-analysis.js +20 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +4 -1
- package/dist/inference/sidecar-provider.js +12 -1
- package/dist/inference/types.d.ts +2 -0
- package/dist/semantic/ast.d.ts +29 -0
- package/dist/semantic/ast.js +122 -0
- package/dist/semantic/benchmark.d.ts +16 -0
- package/dist/semantic/benchmark.js +31 -0
- package/dist/semantic/benchmark.test.d.ts +1 -0
- package/dist/semantic/benchmark.test.js +18 -0
- package/dist/semantic/engine.d.ts +8 -0
- package/dist/semantic/engine.js +45 -0
- package/dist/semantic/intent/benchmark.d.ts +31 -0
- package/dist/semantic/intent/benchmark.js +74 -0
- package/dist/semantic/intent/intent-check.d.ts +43 -0
- package/dist/semantic/intent/intent-check.js +72 -0
- package/dist/semantic/intent/intent.test.d.ts +1 -0
- package/dist/semantic/intent/intent.test.js +46 -0
- package/dist/semantic/intent/parallel-reads.d.ts +23 -0
- package/dist/semantic/intent/parallel-reads.js +59 -0
- package/dist/semantic/learn/benchmark.d.ts +20 -0
- package/dist/semantic/learn/benchmark.js +71 -0
- package/dist/semantic/learn/compile.d.ts +4 -0
- package/dist/semantic/learn/compile.js +56 -0
- package/dist/semantic/learn/conditions.d.ts +22 -0
- package/dist/semantic/learn/conditions.js +93 -0
- package/dist/semantic/learn/extract.d.ts +30 -0
- package/dist/semantic/learn/extract.js +122 -0
- package/dist/semantic/learn/git-trees.d.ts +8 -0
- package/dist/semantic/learn/git-trees.js +32 -0
- package/dist/semantic/learn/identity.d.ts +18 -0
- package/dist/semantic/learn/identity.js +97 -0
- package/dist/semantic/learn/learn.d.ts +25 -0
- package/dist/semantic/learn/learn.js +109 -0
- package/dist/semantic/learn/learn.test.d.ts +1 -0
- package/dist/semantic/learn/learn.test.js +67 -0
- package/dist/semantic/learn/store.d.ts +4 -0
- package/dist/semantic/learn/store.js +39 -0
- package/dist/semantic/learn/types.d.ts +468 -0
- package/dist/semantic/learn/types.js +55 -0
- package/dist/semantic/origins.d.ts +42 -0
- package/dist/semantic/origins.js +149 -0
- package/dist/semantic/origins.test.d.ts +1 -0
- package/dist/semantic/origins.test.js +77 -0
- package/dist/semantic/program.d.ts +13 -0
- package/dist/semantic/program.js +62 -0
- package/dist/semantic/rules/credential-redirect.d.ts +2 -0
- package/dist/semantic/rules/credential-redirect.js +209 -0
- package/dist/semantic/rules/degraded-response-cached.d.ts +2 -0
- package/dist/semantic/rules/degraded-response-cached.js +271 -0
- package/dist/semantic/rules/in-memory-aggregation.d.ts +2 -0
- package/dist/semantic/rules/in-memory-aggregation.js +179 -0
- package/dist/semantic/summaries.d.ts +18 -0
- package/dist/semantic/summaries.js +33 -0
- package/dist/semantic/types.d.ts +32 -0
- package/dist/semantic/types.js +1 -0
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.js +1 -0
- package/dist/storage/team-diagnostics.d.ts +22 -0
- package/dist/storage/team-diagnostics.js +58 -0
- package/dist/storage/team-diagnostics.test.d.ts +1 -0
- package/dist/storage/team-diagnostics.test.js +51 -0
- package/dist/storage/team-schema.d.ts +6 -0
- package/dist/storage/team-schema.js +82 -0
- package/dist/storage/team-store.js +25 -72
- package/dist/templates/universal-config.js +4 -0
- package/dist/types/index.d.ts +56 -0
- package/dist/types/index.js +7 -0
- package/package.json +6 -6
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rules learned from a fix: a before/after pair turned into a check.
|
|
3
|
+
*
|
|
4
|
+
* A learned rule is data (`.rigour/rules/<id>.json`), reviewed in pull
|
|
5
|
+
* requests like code. It is kept only when it fires on the code before the
|
|
6
|
+
* fix, is silent on the fixed code, and fires on few other places in the
|
|
7
|
+
* repository; the validation that proved this is stored with it.
|
|
8
|
+
*/
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
/** How a call is recognised: by its name, the declaration it resolves to, or its exact text. */
|
|
11
|
+
export declare const CalleeMatcherSchema: z.ZodObject<{
|
|
12
|
+
level: z.ZodEnum<["name", "declaration", "text"]>;
|
|
13
|
+
key: z.ZodString;
|
|
14
|
+
}, "strip", z.ZodTypeAny, {
|
|
15
|
+
key: string;
|
|
16
|
+
level: "name" | "text" | "declaration";
|
|
17
|
+
}, {
|
|
18
|
+
key: string;
|
|
19
|
+
level: "name" | "text" | "declaration";
|
|
20
|
+
}>;
|
|
21
|
+
/** Narrows a rule to one function in one file: a regression guard for the fixed code. */
|
|
22
|
+
export declare const ScopeSchema: z.ZodObject<{
|
|
23
|
+
file: z.ZodString;
|
|
24
|
+
fn: z.ZodString;
|
|
25
|
+
}, "strip", z.ZodTypeAny, {
|
|
26
|
+
file: string;
|
|
27
|
+
fn: string;
|
|
28
|
+
}, {
|
|
29
|
+
file: string;
|
|
30
|
+
fn: string;
|
|
31
|
+
}>;
|
|
32
|
+
export declare const RequireOptionSchema: z.ZodObject<{
|
|
33
|
+
template: z.ZodLiteral<"require-option">;
|
|
34
|
+
callee: z.ZodObject<{
|
|
35
|
+
level: z.ZodEnum<["name", "declaration", "text"]>;
|
|
36
|
+
key: z.ZodString;
|
|
37
|
+
}, "strip", z.ZodTypeAny, {
|
|
38
|
+
key: string;
|
|
39
|
+
level: "name" | "text" | "declaration";
|
|
40
|
+
}, {
|
|
41
|
+
key: string;
|
|
42
|
+
level: "name" | "text" | "declaration";
|
|
43
|
+
}>;
|
|
44
|
+
argIndex: z.ZodNumber;
|
|
45
|
+
property: z.ZodString;
|
|
46
|
+
value: z.ZodOptional<z.ZodString>;
|
|
47
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
48
|
+
file: z.ZodString;
|
|
49
|
+
fn: z.ZodString;
|
|
50
|
+
}, "strip", z.ZodTypeAny, {
|
|
51
|
+
file: string;
|
|
52
|
+
fn: string;
|
|
53
|
+
}, {
|
|
54
|
+
file: string;
|
|
55
|
+
fn: string;
|
|
56
|
+
}>>;
|
|
57
|
+
}, "strip", z.ZodTypeAny, {
|
|
58
|
+
template: "require-option";
|
|
59
|
+
callee: {
|
|
60
|
+
key: string;
|
|
61
|
+
level: "name" | "text" | "declaration";
|
|
62
|
+
};
|
|
63
|
+
argIndex: number;
|
|
64
|
+
property: string;
|
|
65
|
+
value?: string | undefined;
|
|
66
|
+
scope?: {
|
|
67
|
+
file: string;
|
|
68
|
+
fn: string;
|
|
69
|
+
} | undefined;
|
|
70
|
+
}, {
|
|
71
|
+
template: "require-option";
|
|
72
|
+
callee: {
|
|
73
|
+
key: string;
|
|
74
|
+
level: "name" | "text" | "declaration";
|
|
75
|
+
};
|
|
76
|
+
argIndex: number;
|
|
77
|
+
property: string;
|
|
78
|
+
value?: string | undefined;
|
|
79
|
+
scope?: {
|
|
80
|
+
file: string;
|
|
81
|
+
fn: string;
|
|
82
|
+
} | undefined;
|
|
83
|
+
}>;
|
|
84
|
+
export declare const RequireGuardSchema: z.ZodObject<{
|
|
85
|
+
template: z.ZodLiteral<"require-guard">;
|
|
86
|
+
callee: z.ZodObject<{
|
|
87
|
+
level: z.ZodEnum<["name", "declaration", "text"]>;
|
|
88
|
+
key: z.ZodString;
|
|
89
|
+
}, "strip", z.ZodTypeAny, {
|
|
90
|
+
key: string;
|
|
91
|
+
level: "name" | "text" | "declaration";
|
|
92
|
+
}, {
|
|
93
|
+
key: string;
|
|
94
|
+
level: "name" | "text" | "declaration";
|
|
95
|
+
}>;
|
|
96
|
+
property: z.ZodString;
|
|
97
|
+
guard: z.ZodString;
|
|
98
|
+
/** Apply only where the call's other arguments mention `guard` (e.g. the body carries it). */
|
|
99
|
+
appliesWhenArgsMention: z.ZodBoolean;
|
|
100
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
101
|
+
file: z.ZodString;
|
|
102
|
+
fn: z.ZodString;
|
|
103
|
+
}, "strip", z.ZodTypeAny, {
|
|
104
|
+
file: string;
|
|
105
|
+
fn: string;
|
|
106
|
+
}, {
|
|
107
|
+
file: string;
|
|
108
|
+
fn: string;
|
|
109
|
+
}>>;
|
|
110
|
+
}, "strip", z.ZodTypeAny, {
|
|
111
|
+
template: "require-guard";
|
|
112
|
+
callee: {
|
|
113
|
+
key: string;
|
|
114
|
+
level: "name" | "text" | "declaration";
|
|
115
|
+
};
|
|
116
|
+
property: string;
|
|
117
|
+
guard: string;
|
|
118
|
+
appliesWhenArgsMention: boolean;
|
|
119
|
+
scope?: {
|
|
120
|
+
file: string;
|
|
121
|
+
fn: string;
|
|
122
|
+
} | undefined;
|
|
123
|
+
}, {
|
|
124
|
+
template: "require-guard";
|
|
125
|
+
callee: {
|
|
126
|
+
key: string;
|
|
127
|
+
level: "name" | "text" | "declaration";
|
|
128
|
+
};
|
|
129
|
+
property: string;
|
|
130
|
+
guard: string;
|
|
131
|
+
appliesWhenArgsMention: boolean;
|
|
132
|
+
scope?: {
|
|
133
|
+
file: string;
|
|
134
|
+
fn: string;
|
|
135
|
+
} | undefined;
|
|
136
|
+
}>;
|
|
137
|
+
export declare const LearnedPatternSchema: z.ZodDiscriminatedUnion<"template", [z.ZodObject<{
|
|
138
|
+
template: z.ZodLiteral<"require-option">;
|
|
139
|
+
callee: z.ZodObject<{
|
|
140
|
+
level: z.ZodEnum<["name", "declaration", "text"]>;
|
|
141
|
+
key: z.ZodString;
|
|
142
|
+
}, "strip", z.ZodTypeAny, {
|
|
143
|
+
key: string;
|
|
144
|
+
level: "name" | "text" | "declaration";
|
|
145
|
+
}, {
|
|
146
|
+
key: string;
|
|
147
|
+
level: "name" | "text" | "declaration";
|
|
148
|
+
}>;
|
|
149
|
+
argIndex: z.ZodNumber;
|
|
150
|
+
property: z.ZodString;
|
|
151
|
+
value: z.ZodOptional<z.ZodString>;
|
|
152
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
153
|
+
file: z.ZodString;
|
|
154
|
+
fn: z.ZodString;
|
|
155
|
+
}, "strip", z.ZodTypeAny, {
|
|
156
|
+
file: string;
|
|
157
|
+
fn: string;
|
|
158
|
+
}, {
|
|
159
|
+
file: string;
|
|
160
|
+
fn: string;
|
|
161
|
+
}>>;
|
|
162
|
+
}, "strip", z.ZodTypeAny, {
|
|
163
|
+
template: "require-option";
|
|
164
|
+
callee: {
|
|
165
|
+
key: string;
|
|
166
|
+
level: "name" | "text" | "declaration";
|
|
167
|
+
};
|
|
168
|
+
argIndex: number;
|
|
169
|
+
property: string;
|
|
170
|
+
value?: string | undefined;
|
|
171
|
+
scope?: {
|
|
172
|
+
file: string;
|
|
173
|
+
fn: string;
|
|
174
|
+
} | undefined;
|
|
175
|
+
}, {
|
|
176
|
+
template: "require-option";
|
|
177
|
+
callee: {
|
|
178
|
+
key: string;
|
|
179
|
+
level: "name" | "text" | "declaration";
|
|
180
|
+
};
|
|
181
|
+
argIndex: number;
|
|
182
|
+
property: string;
|
|
183
|
+
value?: string | undefined;
|
|
184
|
+
scope?: {
|
|
185
|
+
file: string;
|
|
186
|
+
fn: string;
|
|
187
|
+
} | undefined;
|
|
188
|
+
}>, z.ZodObject<{
|
|
189
|
+
template: z.ZodLiteral<"require-guard">;
|
|
190
|
+
callee: z.ZodObject<{
|
|
191
|
+
level: z.ZodEnum<["name", "declaration", "text"]>;
|
|
192
|
+
key: z.ZodString;
|
|
193
|
+
}, "strip", z.ZodTypeAny, {
|
|
194
|
+
key: string;
|
|
195
|
+
level: "name" | "text" | "declaration";
|
|
196
|
+
}, {
|
|
197
|
+
key: string;
|
|
198
|
+
level: "name" | "text" | "declaration";
|
|
199
|
+
}>;
|
|
200
|
+
property: z.ZodString;
|
|
201
|
+
guard: z.ZodString;
|
|
202
|
+
/** Apply only where the call's other arguments mention `guard` (e.g. the body carries it). */
|
|
203
|
+
appliesWhenArgsMention: z.ZodBoolean;
|
|
204
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
205
|
+
file: z.ZodString;
|
|
206
|
+
fn: z.ZodString;
|
|
207
|
+
}, "strip", z.ZodTypeAny, {
|
|
208
|
+
file: string;
|
|
209
|
+
fn: string;
|
|
210
|
+
}, {
|
|
211
|
+
file: string;
|
|
212
|
+
fn: string;
|
|
213
|
+
}>>;
|
|
214
|
+
}, "strip", z.ZodTypeAny, {
|
|
215
|
+
template: "require-guard";
|
|
216
|
+
callee: {
|
|
217
|
+
key: string;
|
|
218
|
+
level: "name" | "text" | "declaration";
|
|
219
|
+
};
|
|
220
|
+
property: string;
|
|
221
|
+
guard: string;
|
|
222
|
+
appliesWhenArgsMention: boolean;
|
|
223
|
+
scope?: {
|
|
224
|
+
file: string;
|
|
225
|
+
fn: string;
|
|
226
|
+
} | undefined;
|
|
227
|
+
}, {
|
|
228
|
+
template: "require-guard";
|
|
229
|
+
callee: {
|
|
230
|
+
key: string;
|
|
231
|
+
level: "name" | "text" | "declaration";
|
|
232
|
+
};
|
|
233
|
+
property: string;
|
|
234
|
+
guard: string;
|
|
235
|
+
appliesWhenArgsMention: boolean;
|
|
236
|
+
scope?: {
|
|
237
|
+
file: string;
|
|
238
|
+
fn: string;
|
|
239
|
+
} | undefined;
|
|
240
|
+
}>]>;
|
|
241
|
+
export declare const LearnedRuleSchema: z.ZodObject<{
|
|
242
|
+
id: z.ZodString;
|
|
243
|
+
version: z.ZodLiteral<1>;
|
|
244
|
+
pattern: z.ZodDiscriminatedUnion<"template", [z.ZodObject<{
|
|
245
|
+
template: z.ZodLiteral<"require-option">;
|
|
246
|
+
callee: z.ZodObject<{
|
|
247
|
+
level: z.ZodEnum<["name", "declaration", "text"]>;
|
|
248
|
+
key: z.ZodString;
|
|
249
|
+
}, "strip", z.ZodTypeAny, {
|
|
250
|
+
key: string;
|
|
251
|
+
level: "name" | "text" | "declaration";
|
|
252
|
+
}, {
|
|
253
|
+
key: string;
|
|
254
|
+
level: "name" | "text" | "declaration";
|
|
255
|
+
}>;
|
|
256
|
+
argIndex: z.ZodNumber;
|
|
257
|
+
property: z.ZodString;
|
|
258
|
+
value: z.ZodOptional<z.ZodString>;
|
|
259
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
260
|
+
file: z.ZodString;
|
|
261
|
+
fn: z.ZodString;
|
|
262
|
+
}, "strip", z.ZodTypeAny, {
|
|
263
|
+
file: string;
|
|
264
|
+
fn: string;
|
|
265
|
+
}, {
|
|
266
|
+
file: string;
|
|
267
|
+
fn: string;
|
|
268
|
+
}>>;
|
|
269
|
+
}, "strip", z.ZodTypeAny, {
|
|
270
|
+
template: "require-option";
|
|
271
|
+
callee: {
|
|
272
|
+
key: string;
|
|
273
|
+
level: "name" | "text" | "declaration";
|
|
274
|
+
};
|
|
275
|
+
argIndex: number;
|
|
276
|
+
property: string;
|
|
277
|
+
value?: string | undefined;
|
|
278
|
+
scope?: {
|
|
279
|
+
file: string;
|
|
280
|
+
fn: string;
|
|
281
|
+
} | undefined;
|
|
282
|
+
}, {
|
|
283
|
+
template: "require-option";
|
|
284
|
+
callee: {
|
|
285
|
+
key: string;
|
|
286
|
+
level: "name" | "text" | "declaration";
|
|
287
|
+
};
|
|
288
|
+
argIndex: number;
|
|
289
|
+
property: string;
|
|
290
|
+
value?: string | undefined;
|
|
291
|
+
scope?: {
|
|
292
|
+
file: string;
|
|
293
|
+
fn: string;
|
|
294
|
+
} | undefined;
|
|
295
|
+
}>, z.ZodObject<{
|
|
296
|
+
template: z.ZodLiteral<"require-guard">;
|
|
297
|
+
callee: z.ZodObject<{
|
|
298
|
+
level: z.ZodEnum<["name", "declaration", "text"]>;
|
|
299
|
+
key: z.ZodString;
|
|
300
|
+
}, "strip", z.ZodTypeAny, {
|
|
301
|
+
key: string;
|
|
302
|
+
level: "name" | "text" | "declaration";
|
|
303
|
+
}, {
|
|
304
|
+
key: string;
|
|
305
|
+
level: "name" | "text" | "declaration";
|
|
306
|
+
}>;
|
|
307
|
+
property: z.ZodString;
|
|
308
|
+
guard: z.ZodString;
|
|
309
|
+
/** Apply only where the call's other arguments mention `guard` (e.g. the body carries it). */
|
|
310
|
+
appliesWhenArgsMention: z.ZodBoolean;
|
|
311
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
312
|
+
file: z.ZodString;
|
|
313
|
+
fn: z.ZodString;
|
|
314
|
+
}, "strip", z.ZodTypeAny, {
|
|
315
|
+
file: string;
|
|
316
|
+
fn: string;
|
|
317
|
+
}, {
|
|
318
|
+
file: string;
|
|
319
|
+
fn: string;
|
|
320
|
+
}>>;
|
|
321
|
+
}, "strip", z.ZodTypeAny, {
|
|
322
|
+
template: "require-guard";
|
|
323
|
+
callee: {
|
|
324
|
+
key: string;
|
|
325
|
+
level: "name" | "text" | "declaration";
|
|
326
|
+
};
|
|
327
|
+
property: string;
|
|
328
|
+
guard: string;
|
|
329
|
+
appliesWhenArgsMention: boolean;
|
|
330
|
+
scope?: {
|
|
331
|
+
file: string;
|
|
332
|
+
fn: string;
|
|
333
|
+
} | undefined;
|
|
334
|
+
}, {
|
|
335
|
+
template: "require-guard";
|
|
336
|
+
callee: {
|
|
337
|
+
key: string;
|
|
338
|
+
level: "name" | "text" | "declaration";
|
|
339
|
+
};
|
|
340
|
+
property: string;
|
|
341
|
+
guard: string;
|
|
342
|
+
appliesWhenArgsMention: boolean;
|
|
343
|
+
scope?: {
|
|
344
|
+
file: string;
|
|
345
|
+
fn: string;
|
|
346
|
+
} | undefined;
|
|
347
|
+
}>]>;
|
|
348
|
+
message: z.ZodString;
|
|
349
|
+
severity: z.ZodEnum<["low", "medium", "high"]>;
|
|
350
|
+
source: z.ZodObject<{
|
|
351
|
+
commit: z.ZodOptional<z.ZodString>;
|
|
352
|
+
file: z.ZodString;
|
|
353
|
+
function: z.ZodString;
|
|
354
|
+
}, "strip", z.ZodTypeAny, {
|
|
355
|
+
function: string;
|
|
356
|
+
file: string;
|
|
357
|
+
commit?: string | undefined;
|
|
358
|
+
}, {
|
|
359
|
+
function: string;
|
|
360
|
+
file: string;
|
|
361
|
+
commit?: string | undefined;
|
|
362
|
+
}>;
|
|
363
|
+
validation: z.ZodObject<{
|
|
364
|
+
firesBefore: z.ZodNumber;
|
|
365
|
+
firesAfter: z.ZodNumber;
|
|
366
|
+
maxHits: z.ZodNumber;
|
|
367
|
+
repoHits: z.ZodArray<z.ZodString, "many">;
|
|
368
|
+
}, "strip", z.ZodTypeAny, {
|
|
369
|
+
firesBefore: number;
|
|
370
|
+
firesAfter: number;
|
|
371
|
+
maxHits: number;
|
|
372
|
+
repoHits: string[];
|
|
373
|
+
}, {
|
|
374
|
+
firesBefore: number;
|
|
375
|
+
firesAfter: number;
|
|
376
|
+
maxHits: number;
|
|
377
|
+
repoHits: string[];
|
|
378
|
+
}>;
|
|
379
|
+
}, "strip", z.ZodTypeAny, {
|
|
380
|
+
message: string;
|
|
381
|
+
validation: {
|
|
382
|
+
firesBefore: number;
|
|
383
|
+
firesAfter: number;
|
|
384
|
+
maxHits: number;
|
|
385
|
+
repoHits: string[];
|
|
386
|
+
};
|
|
387
|
+
version: 1;
|
|
388
|
+
id: string;
|
|
389
|
+
severity: "high" | "medium" | "low";
|
|
390
|
+
source: {
|
|
391
|
+
function: string;
|
|
392
|
+
file: string;
|
|
393
|
+
commit?: string | undefined;
|
|
394
|
+
};
|
|
395
|
+
pattern: {
|
|
396
|
+
template: "require-option";
|
|
397
|
+
callee: {
|
|
398
|
+
key: string;
|
|
399
|
+
level: "name" | "text" | "declaration";
|
|
400
|
+
};
|
|
401
|
+
argIndex: number;
|
|
402
|
+
property: string;
|
|
403
|
+
value?: string | undefined;
|
|
404
|
+
scope?: {
|
|
405
|
+
file: string;
|
|
406
|
+
fn: string;
|
|
407
|
+
} | undefined;
|
|
408
|
+
} | {
|
|
409
|
+
template: "require-guard";
|
|
410
|
+
callee: {
|
|
411
|
+
key: string;
|
|
412
|
+
level: "name" | "text" | "declaration";
|
|
413
|
+
};
|
|
414
|
+
property: string;
|
|
415
|
+
guard: string;
|
|
416
|
+
appliesWhenArgsMention: boolean;
|
|
417
|
+
scope?: {
|
|
418
|
+
file: string;
|
|
419
|
+
fn: string;
|
|
420
|
+
} | undefined;
|
|
421
|
+
};
|
|
422
|
+
}, {
|
|
423
|
+
message: string;
|
|
424
|
+
validation: {
|
|
425
|
+
firesBefore: number;
|
|
426
|
+
firesAfter: number;
|
|
427
|
+
maxHits: number;
|
|
428
|
+
repoHits: string[];
|
|
429
|
+
};
|
|
430
|
+
version: 1;
|
|
431
|
+
id: string;
|
|
432
|
+
severity: "high" | "medium" | "low";
|
|
433
|
+
source: {
|
|
434
|
+
function: string;
|
|
435
|
+
file: string;
|
|
436
|
+
commit?: string | undefined;
|
|
437
|
+
};
|
|
438
|
+
pattern: {
|
|
439
|
+
template: "require-option";
|
|
440
|
+
callee: {
|
|
441
|
+
key: string;
|
|
442
|
+
level: "name" | "text" | "declaration";
|
|
443
|
+
};
|
|
444
|
+
argIndex: number;
|
|
445
|
+
property: string;
|
|
446
|
+
value?: string | undefined;
|
|
447
|
+
scope?: {
|
|
448
|
+
file: string;
|
|
449
|
+
fn: string;
|
|
450
|
+
} | undefined;
|
|
451
|
+
} | {
|
|
452
|
+
template: "require-guard";
|
|
453
|
+
callee: {
|
|
454
|
+
key: string;
|
|
455
|
+
level: "name" | "text" | "declaration";
|
|
456
|
+
};
|
|
457
|
+
property: string;
|
|
458
|
+
guard: string;
|
|
459
|
+
appliesWhenArgsMention: boolean;
|
|
460
|
+
scope?: {
|
|
461
|
+
file: string;
|
|
462
|
+
fn: string;
|
|
463
|
+
} | undefined;
|
|
464
|
+
};
|
|
465
|
+
}>;
|
|
466
|
+
export type CalleeMatcher = z.infer<typeof CalleeMatcherSchema>;
|
|
467
|
+
export type LearnedPattern = z.infer<typeof LearnedPatternSchema>;
|
|
468
|
+
export type LearnedRule = z.infer<typeof LearnedRuleSchema>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rules learned from a fix: a before/after pair turned into a check.
|
|
3
|
+
*
|
|
4
|
+
* A learned rule is data (`.rigour/rules/<id>.json`), reviewed in pull
|
|
5
|
+
* requests like code. It is kept only when it fires on the code before the
|
|
6
|
+
* fix, is silent on the fixed code, and fires on few other places in the
|
|
7
|
+
* repository; the validation that proved this is stored with it.
|
|
8
|
+
*/
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
/** How a call is recognised: by its name, the declaration it resolves to, or its exact text. */
|
|
11
|
+
export const CalleeMatcherSchema = z.object({
|
|
12
|
+
level: z.enum(['name', 'declaration', 'text']),
|
|
13
|
+
key: z.string().min(1),
|
|
14
|
+
});
|
|
15
|
+
/** Narrows a rule to one function in one file: a regression guard for the fixed code. */
|
|
16
|
+
export const ScopeSchema = z.object({
|
|
17
|
+
file: z.string().min(1),
|
|
18
|
+
fn: z.string().min(1),
|
|
19
|
+
});
|
|
20
|
+
export const RequireOptionSchema = z.object({
|
|
21
|
+
template: z.literal('require-option'),
|
|
22
|
+
callee: CalleeMatcherSchema,
|
|
23
|
+
argIndex: z.number().int().min(0),
|
|
24
|
+
property: z.string().min(1),
|
|
25
|
+
value: z.string().optional(),
|
|
26
|
+
scope: ScopeSchema.optional(),
|
|
27
|
+
});
|
|
28
|
+
export const RequireGuardSchema = z.object({
|
|
29
|
+
template: z.literal('require-guard'),
|
|
30
|
+
callee: CalleeMatcherSchema,
|
|
31
|
+
property: z.string().min(1),
|
|
32
|
+
guard: z.string().min(1),
|
|
33
|
+
/** Apply only where the call's other arguments mention `guard` (e.g. the body carries it). */
|
|
34
|
+
appliesWhenArgsMention: z.boolean(),
|
|
35
|
+
scope: ScopeSchema.optional(),
|
|
36
|
+
});
|
|
37
|
+
export const LearnedPatternSchema = z.discriminatedUnion('template', [RequireOptionSchema, RequireGuardSchema]);
|
|
38
|
+
export const LearnedRuleSchema = z.object({
|
|
39
|
+
id: z.string().regex(/^[a-z0-9][a-z0-9-]*$/),
|
|
40
|
+
version: z.literal(1),
|
|
41
|
+
pattern: LearnedPatternSchema,
|
|
42
|
+
message: z.string(),
|
|
43
|
+
severity: z.enum(['low', 'medium', 'high']),
|
|
44
|
+
source: z.object({
|
|
45
|
+
commit: z.string().optional(),
|
|
46
|
+
file: z.string(),
|
|
47
|
+
function: z.string(),
|
|
48
|
+
}),
|
|
49
|
+
validation: z.object({
|
|
50
|
+
firesBefore: z.number().int(),
|
|
51
|
+
firesAfter: z.number().int(),
|
|
52
|
+
maxHits: z.number().int(),
|
|
53
|
+
repoHits: z.array(z.string()),
|
|
54
|
+
}),
|
|
55
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where can an expression's value come from?
|
|
3
|
+
*
|
|
4
|
+
* Traces identifiers back through declarations (const/let initializers and
|
|
5
|
+
* reassignments), destructuring (including an element of `Promise.all([...])`),
|
|
6
|
+
* conditionals and `??`/`||`, using checker symbols rather than names. The
|
|
7
|
+
* result is a set of origins: a call, a parameter, an object literal, another
|
|
8
|
+
* literal, or unknown. Unknown origins are kept so rules can stay silent.
|
|
9
|
+
*/
|
|
10
|
+
import ts from 'typescript';
|
|
11
|
+
import { type FunctionLike } from './ast.js';
|
|
12
|
+
export type Origin = {
|
|
13
|
+
kind: 'call';
|
|
14
|
+
node: ts.CallExpression;
|
|
15
|
+
} | {
|
|
16
|
+
kind: 'param';
|
|
17
|
+
fn: FunctionLike;
|
|
18
|
+
index: number;
|
|
19
|
+
node: ts.ParameterDeclaration;
|
|
20
|
+
} | {
|
|
21
|
+
kind: 'object';
|
|
22
|
+
node: ts.ObjectLiteralExpression;
|
|
23
|
+
} | {
|
|
24
|
+
kind: 'literal';
|
|
25
|
+
node: ts.Expression;
|
|
26
|
+
} | {
|
|
27
|
+
kind: 'unknown';
|
|
28
|
+
node: ts.Node;
|
|
29
|
+
};
|
|
30
|
+
export declare function originsOf(checker: ts.TypeChecker, expr: ts.Expression, depth?: number, seen?: Set<ts.Node>): Origin[];
|
|
31
|
+
/** Elements of `Promise.all([...])` / `Promise.allSettled([...])`, else undefined. */
|
|
32
|
+
export declare function promiseAllItems(expr: ts.Expression): ts.NodeArray<ts.Expression> | undefined;
|
|
33
|
+
export interface PropertyValues {
|
|
34
|
+
/** Direct values for the property. */
|
|
35
|
+
values: ts.Expression[];
|
|
36
|
+
/** Spreads whose object could not be resolved; the property may come from them. */
|
|
37
|
+
unresolvedSpreads: ts.Expression[];
|
|
38
|
+
/** Spread expressions that were resolved, in source order. */
|
|
39
|
+
spreads: ts.Expression[];
|
|
40
|
+
}
|
|
41
|
+
/** Values an object literal gives to `key`, following `...spread` of other object literals. */
|
|
42
|
+
export declare function propertyValues(checker: ts.TypeChecker, obj: ts.ObjectLiteralExpression, key: string, depth?: number): PropertyValues;
|