@orygn/opa-mcp 0.4.0 → 0.5.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/CHANGELOG.md +339 -3
- package/README.md +71 -72
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +8 -3
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +57 -15
- package/dist/config.js.map +1 -1
- package/dist/lib/bundle-signatures.d.ts +23 -0
- package/dist/lib/bundle-signatures.d.ts.map +1 -0
- package/dist/lib/bundle-signatures.js +152 -0
- package/dist/lib/bundle-signatures.js.map +1 -0
- package/dist/lib/child-env.d.ts +9 -2
- package/dist/lib/child-env.d.ts.map +1 -1
- package/dist/lib/child-env.js +38 -6
- package/dist/lib/child-env.js.map +1 -1
- package/dist/lib/conftest-cli.d.ts +25 -10
- package/dist/lib/conftest-cli.d.ts.map +1 -1
- package/dist/lib/conftest-cli.js +152 -33
- package/dist/lib/conftest-cli.js.map +1 -1
- package/dist/lib/install-id.d.ts.map +1 -1
- package/dist/lib/install-id.js +18 -3
- package/dist/lib/install-id.js.map +1 -1
- package/dist/lib/json-stream.d.ts +26 -0
- package/dist/lib/json-stream.d.ts.map +1 -0
- package/dist/lib/json-stream.js +69 -0
- package/dist/lib/json-stream.js.map +1 -0
- package/dist/lib/opa-cli.d.ts +64 -16
- package/dist/lib/opa-cli.d.ts.map +1 -1
- package/dist/lib/opa-cli.js +98 -28
- package/dist/lib/opa-cli.js.map +1 -1
- package/dist/lib/opa-paths.d.ts +24 -0
- package/dist/lib/opa-paths.d.ts.map +1 -0
- package/dist/lib/opa-paths.js +97 -0
- package/dist/lib/opa-paths.js.map +1 -0
- package/dist/lib/regal-cli.d.ts +16 -1
- package/dist/lib/regal-cli.d.ts.map +1 -1
- package/dist/lib/regal-cli.js +40 -6
- package/dist/lib/regal-cli.js.map +1 -1
- package/dist/lib/rego-ast-walker.d.ts.map +1 -1
- package/dist/lib/rego-ast-walker.js +141 -17
- package/dist/lib/rego-ast-walker.js.map +1 -1
- package/dist/lib/rego-counterexample.d.ts +1 -1
- package/dist/lib/rego-counterexample.d.ts.map +1 -1
- package/dist/lib/rego-counterexample.js +23 -5
- package/dist/lib/rego-counterexample.js.map +1 -1
- package/dist/lib/rego-ir.d.ts +32 -2
- package/dist/lib/rego-ir.d.ts.map +1 -1
- package/dist/lib/rego-smt-encoder.d.ts +53 -5
- package/dist/lib/rego-smt-encoder.d.ts.map +1 -1
- package/dist/lib/rego-smt-encoder.js +192 -26
- package/dist/lib/rego-smt-encoder.js.map +1 -1
- package/dist/lib/rego-type-inferencer.d.ts +1 -1
- package/dist/lib/rego-type-inferencer.d.ts.map +1 -1
- package/dist/lib/rego-type-inferencer.js +3 -3
- package/dist/lib/rego-type-inferencer.js.map +1 -1
- package/dist/lib/rego-verify-engine.d.ts.map +1 -1
- package/dist/lib/rego-verify-engine.js +109 -77
- package/dist/lib/rego-verify-engine.js.map +1 -1
- package/dist/lib/rego-z3.d.ts +10 -0
- package/dist/lib/rego-z3.d.ts.map +1 -1
- package/dist/lib/rego-z3.js +38 -0
- package/dist/lib/rego-z3.js.map +1 -1
- package/dist/lib/security.d.ts +8 -0
- package/dist/lib/security.d.ts.map +1 -1
- package/dist/lib/security.js +130 -54
- package/dist/lib/security.js.map +1 -1
- package/dist/resources/patterns.d.ts +1 -1
- package/dist/resources/patterns.d.ts.map +1 -1
- package/dist/resources/patterns.js +40 -12
- package/dist/resources/patterns.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +10 -2
- package/dist/server.js.map +1 -1
- package/dist/tools/bundles/build.d.ts.map +1 -1
- package/dist/tools/bundles/build.js +12 -4
- package/dist/tools/bundles/build.js.map +1 -1
- package/dist/tools/bundles/sign.d.ts +9 -2
- package/dist/tools/bundles/sign.d.ts.map +1 -1
- package/dist/tools/bundles/sign.js +145 -19
- package/dist/tools/bundles/sign.js.map +1 -1
- package/dist/tools/bundles/verify.d.ts +1 -1
- package/dist/tools/bundles/verify.d.ts.map +1 -1
- package/dist/tools/bundles/verify.js +58 -19
- package/dist/tools/bundles/verify.js.map +1 -1
- package/dist/tools/conftest/pull.d.ts.map +1 -1
- package/dist/tools/conftest/pull.js +24 -10
- package/dist/tools/conftest/pull.js.map +1 -1
- package/dist/tools/conftest/push.d.ts.map +1 -1
- package/dist/tools/conftest/push.js +17 -7
- package/dist/tools/conftest/push.js.map +1 -1
- package/dist/tools/conftest/test.d.ts +10 -6
- package/dist/tools/conftest/test.d.ts.map +1 -1
- package/dist/tools/conftest/test.js +47 -24
- package/dist/tools/conftest/test.js.map +1 -1
- package/dist/tools/conftest/verify.d.ts +10 -6
- package/dist/tools/conftest/verify.d.ts.map +1 -1
- package/dist/tools/conftest/verify.js +30 -18
- package/dist/tools/conftest/verify.js.map +1 -1
- package/dist/tools/evaluation/bench.d.ts +16 -0
- package/dist/tools/evaluation/bench.d.ts.map +1 -1
- package/dist/tools/evaluation/bench.js +30 -5
- package/dist/tools/evaluation/bench.js.map +1 -1
- package/dist/tools/evaluation/exec.d.ts +16 -0
- package/dist/tools/evaluation/exec.d.ts.map +1 -1
- package/dist/tools/evaluation/exec.js +35 -2
- package/dist/tools/evaluation/exec.js.map +1 -1
- package/dist/tools/evaluation/test-multiroot.d.ts +4 -0
- package/dist/tools/evaluation/test-multiroot.d.ts.map +1 -1
- package/dist/tools/evaluation/test-multiroot.js +12 -2
- package/dist/tools/evaluation/test-multiroot.js.map +1 -1
- package/dist/tools/evaluation/test.d.ts +45 -0
- package/dist/tools/evaluation/test.d.ts.map +1 -1
- package/dist/tools/evaluation/test.js +146 -27
- package/dist/tools/evaluation/test.js.map +1 -1
- package/dist/tools/helpers/coverage-gaps.d.ts +11 -3
- package/dist/tools/helpers/coverage-gaps.d.ts.map +1 -1
- package/dist/tools/helpers/coverage-gaps.js +4 -3
- package/dist/tools/helpers/coverage-gaps.js.map +1 -1
- package/dist/tools/helpers/explain-undefined.d.ts +9 -3
- package/dist/tools/helpers/explain-undefined.d.ts.map +1 -1
- package/dist/tools/helpers/explain-undefined.js +83 -51
- package/dist/tools/helpers/explain-undefined.js.map +1 -1
- package/dist/tools/helpers/verify.d.ts.map +1 -1
- package/dist/tools/helpers/verify.js +5 -1
- package/dist/tools/helpers/verify.js.map +1 -1
- package/dist/tools/server-management/_shared.d.ts +15 -4
- package/dist/tools/server-management/_shared.d.ts.map +1 -1
- package/dist/tools/server-management/_shared.js +73 -12
- package/dist/tools/server-management/_shared.js.map +1 -1
- package/dist/tools/server-management/data.d.ts.map +1 -1
- package/dist/tools/server-management/data.js +88 -23
- package/dist/tools/server-management/data.js.map +1 -1
- package/dist/tools/server-management/decisions.d.ts.map +1 -1
- package/dist/tools/server-management/decisions.js +16 -3
- package/dist/tools/server-management/decisions.js.map +1 -1
- package/dist/tools/server-management/policies.d.ts.map +1 -1
- package/dist/tools/server-management/policies.js +44 -7
- package/dist/tools/server-management/policies.js.map +1 -1
- package/dist/tools/server-management/status.d.ts.map +1 -1
- package/dist/tools/server-management/status.js +80 -13
- package/dist/tools/server-management/status.js.map +1 -1
- package/dist/types.d.ts +9 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -1
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import { z } from 'zod';
|
|
10
10
|
import { OpaCli } from '../../lib/opa-cli.js';
|
|
11
11
|
import { err, ok } from '../../lib/errors.js';
|
|
12
|
+
import { parseJsonValues } from '../../lib/json-stream.js';
|
|
12
13
|
import { mapSubprocessFailure, tryParseJson, validatePaths, withToolEnvelope, } from '../../lib/tool-helpers.js';
|
|
13
14
|
const RegoTestInput = {
|
|
14
15
|
paths: z
|
|
@@ -47,7 +48,7 @@ const RegoTestInput = {
|
|
|
47
48
|
.int()
|
|
48
49
|
.min(1)
|
|
49
50
|
.optional()
|
|
50
|
-
.describe('Number of times to repeat
|
|
51
|
+
.describe('Number of times to repeat the suite (`--count N`). Default is 1. Useful for catching flaky tests. OPA stops at the first repetition that fails, so `repetitions` in the output reports how many actually ran, and each test is listed once carrying its worst outcome across them.'),
|
|
51
52
|
timeout: z
|
|
52
53
|
.string()
|
|
53
54
|
.optional()
|
|
@@ -61,11 +62,15 @@ const RegoTestInput = {
|
|
|
61
62
|
.optional()
|
|
62
63
|
.describe('Opt in to OPA v1.0-compatible behaviors (`--v1-compatible`).'),
|
|
63
64
|
};
|
|
65
|
+
/** A test that could not run is neither a pass nor a failure. */
|
|
66
|
+
function isErrored(r) {
|
|
67
|
+
return r.error !== undefined && r.error !== null;
|
|
68
|
+
}
|
|
64
69
|
export function registerRegoTest(server, config) {
|
|
65
70
|
const opa = new OpaCli(config);
|
|
66
71
|
server.registerTool('rego_test', {
|
|
67
72
|
title: 'Run Rego tests',
|
|
68
|
-
description: "Run Rego unit tests with `opa test`. Returns aggregate pass/fail counts plus per-test records. Tests live in `*_test.rego` files; rule names beginning with `test_` are picked up automatically. Use `runPattern` to filter by name regex; when no tests match, the error hint includes the pattern you supplied. Use `threshold` to gate on minimum coverage (returns COVERAGE_BELOW_THRESHOLD on failure). Use `varValues: true` with `verbose: true` to include local variable bindings in the trace -- essential for debugging table-driven tests written with `every tc in cases { ... }` to identify which case caused a failure. When tests use the `
|
|
73
|
+
description: "Run Rego unit tests with `opa test`. Returns aggregate pass/fail/skip/error counts plus per-test records. `errored` counts tests OPA could not evaluate (a rule conflict, a raising built-in); such a test is neither a pass nor a failure, and a suite with any is not passing. Tests live in `*_test.rego` files; rule names beginning with `test_` are picked up automatically. Use `runPattern` to filter by name regex; when no tests match, the error hint includes the pattern you supplied. Use `threshold` to gate on minimum coverage (returns COVERAGE_BELOW_THRESHOLD on failure). Use `varValues: true` with `verbose: true` to include local variable bindings in the trace -- essential for debugging table-driven tests written with `every tc in cases { ... }` to identify which case caused a failure. When tests use the `test_x[case]` parameterized form, OPA reports the rule as a single test whatever the number of cases; `parameterizedGroups` maps the rule name to a record per case and `caseCounts` totals them, so a failing rule says which case failed. Use `ignorePatterns` to exclude generated or fixture files. Use `bundle: true` when testing bundle-structured policy directories. Use `timeout` to raise the per-test limit beyond OPA's default 5s. Note: enabling `coverage` or `threshold` switches OPA to coverage-report output mode -- per-test counts are unavailable but `coverage` and `coveragePct` fields are populated.",
|
|
69
74
|
inputSchema: RegoTestInput,
|
|
70
75
|
annotations: {
|
|
71
76
|
readOnlyHint: true,
|
|
@@ -122,12 +127,13 @@ export function registerRegoTest(server, config) {
|
|
|
122
127
|
* OR one or more tests failed without threshold (stderr has FAIL lines)
|
|
123
128
|
*/
|
|
124
129
|
function handleCoverageMode(stdout, stderr, exitCode, threshold) {
|
|
130
|
+
const coverageData = tryParseJson(stdout);
|
|
125
131
|
if (exitCode === 0) {
|
|
126
|
-
const coverageData = tryParseJson(stdout);
|
|
127
132
|
return ok({
|
|
128
133
|
passed: 0,
|
|
129
134
|
failed: 0,
|
|
130
135
|
skipped: 0,
|
|
136
|
+
errored: 0,
|
|
131
137
|
total: 0,
|
|
132
138
|
results: [],
|
|
133
139
|
coverage: coverageData,
|
|
@@ -147,12 +153,120 @@ function handleCoverageMode(stdout, stderr, exitCode, threshold) {
|
|
|
147
153
|
details: { actualCoverage, requiredThreshold },
|
|
148
154
|
});
|
|
149
155
|
}
|
|
156
|
+
// A suite holding a `todo_` test exits non-zero in coverage mode with an
|
|
157
|
+
// empty stderr, and the coverage report is on stdout as asked for. Reporting
|
|
158
|
+
// that as "one or more tests failed" was wrong twice: nothing failed, and the
|
|
159
|
+
// report the caller wanted was thrown away.
|
|
160
|
+
if (coverageData !== undefined && stderrTrimmed.length === 0) {
|
|
161
|
+
return ok({
|
|
162
|
+
passed: 0,
|
|
163
|
+
failed: 0,
|
|
164
|
+
skipped: 0,
|
|
165
|
+
errored: 0,
|
|
166
|
+
total: 0,
|
|
167
|
+
results: [],
|
|
168
|
+
coverage: coverageData,
|
|
169
|
+
coveragePct: coverageData.coverage,
|
|
170
|
+
thresholdMet: threshold !== undefined ? true : undefined,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
150
173
|
// Test failures in coverage mode (stderr has "package.test_name: FAIL" lines).
|
|
151
174
|
return err('EVAL_ERROR', stderrTrimmed || 'One or more tests failed.', {
|
|
152
175
|
hint: 'Fix the failing tests then re-run. Use verbose: true for trace output.',
|
|
153
|
-
details: {
|
|
176
|
+
details: {
|
|
177
|
+
exitCode,
|
|
178
|
+
// Keep the report when OPA produced one; it is what was asked for.
|
|
179
|
+
...(coverageData !== undefined ? { coveragePct: coverageData.coverage } : {}),
|
|
180
|
+
},
|
|
154
181
|
});
|
|
155
182
|
}
|
|
183
|
+
/**
|
|
184
|
+
* Bucket the cases of a parameterized test under the rule they belong to.
|
|
185
|
+
*
|
|
186
|
+
* OPA reports a `test_x[case]` rule as one record carrying a `sub_results`
|
|
187
|
+
* object, not as one record per case. Looking for a bracketed name meant the
|
|
188
|
+
* grouping never fired on any OPA 1.x run, and the per-case outcomes OPA had
|
|
189
|
+
* already worked out were passed through untouched: a caller saw one failing
|
|
190
|
+
* test and no indication which of its cases failed. The bracketed form is still
|
|
191
|
+
* read, since that is what older versions emitted.
|
|
192
|
+
*/
|
|
193
|
+
function groupParameterized(records) {
|
|
194
|
+
const parameterizedGroups = {};
|
|
195
|
+
const counts = { total: 0, passed: 0, failed: 0, skipped: 0 };
|
|
196
|
+
const add = (baseName, record) => {
|
|
197
|
+
(parameterizedGroups[baseName] ??= []).push(record);
|
|
198
|
+
counts.total++;
|
|
199
|
+
if (record.skip === true)
|
|
200
|
+
counts.skipped++;
|
|
201
|
+
else if (record.fail === true || isErrored(record))
|
|
202
|
+
counts.failed++;
|
|
203
|
+
else
|
|
204
|
+
counts.passed++;
|
|
205
|
+
};
|
|
206
|
+
for (const record of records) {
|
|
207
|
+
if (record.name === undefined)
|
|
208
|
+
continue;
|
|
209
|
+
if (record.sub_results) {
|
|
210
|
+
for (const [caseName, outcome] of Object.entries(record.sub_results)) {
|
|
211
|
+
const caseRecord = {
|
|
212
|
+
name: outcome.name ?? caseName,
|
|
213
|
+
...(record.package !== undefined ? { package: record.package } : {}),
|
|
214
|
+
...(record.location !== undefined ? { location: record.location } : {}),
|
|
215
|
+
...(outcome.fail === true ? { fail: true } : {}),
|
|
216
|
+
...(outcome.skip === true ? { skip: true } : {}),
|
|
217
|
+
};
|
|
218
|
+
add(record.name, caseRecord);
|
|
219
|
+
}
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
// Older OPA named each case in the record itself: `test_x[{"k":"v"}]`.
|
|
223
|
+
const match = /^(test_[a-zA-Z0-9_]+)\[/.exec(record.name);
|
|
224
|
+
if (match)
|
|
225
|
+
add(match[1], record);
|
|
226
|
+
}
|
|
227
|
+
return { parameterizedGroups, caseCounts: counts };
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Collapse the repetitions of `opa test --count N` into one record per test.
|
|
231
|
+
*
|
|
232
|
+
* The flag exists to surface tests that do not behave the same way every time,
|
|
233
|
+
* so a test keeps its worst outcome across the runs: an error beats a failure,
|
|
234
|
+
* a failure beats a pass, and a test skipped in every run stays skipped. The
|
|
235
|
+
* longest duration is kept, since that is the one a timeout would hit.
|
|
236
|
+
*
|
|
237
|
+
* OPA stops repeating once a run fails, so `runs` can be shorter than the
|
|
238
|
+
* requested count; the caller reports the length rather than the request.
|
|
239
|
+
*/
|
|
240
|
+
function mergeRepetitions(runs) {
|
|
241
|
+
const worst = new Map();
|
|
242
|
+
const order = [];
|
|
243
|
+
for (const run of runs) {
|
|
244
|
+
for (const record of run) {
|
|
245
|
+
const key = `${record.package ?? ''}.${record.name ?? ''}`;
|
|
246
|
+
const seen = worst.get(key);
|
|
247
|
+
if (seen === undefined) {
|
|
248
|
+
worst.set(key, { ...record });
|
|
249
|
+
order.push(key);
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
const merged = { ...seen };
|
|
253
|
+
if (record.error !== undefined)
|
|
254
|
+
merged.error = record.error;
|
|
255
|
+
if (record.fail === true)
|
|
256
|
+
merged.fail = true;
|
|
257
|
+
// A test skipped in one run but executed in another is not skipped.
|
|
258
|
+
if (record.skip !== true)
|
|
259
|
+
delete merged.skip;
|
|
260
|
+
if ((record.duration ?? 0) > (merged.duration ?? 0))
|
|
261
|
+
merged.duration = record.duration;
|
|
262
|
+
// An errored record is neither passed nor failed, so drop the weaker mark.
|
|
263
|
+
if (merged.error !== undefined)
|
|
264
|
+
delete merged.fail;
|
|
265
|
+
worst.set(key, merged);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return order.map((key) => worst.get(key));
|
|
269
|
+
}
|
|
156
270
|
/**
|
|
157
271
|
* Handle output from `opa test` without coverage or threshold.
|
|
158
272
|
*
|
|
@@ -166,19 +280,30 @@ function handleCoverageMode(stdout, stderr, exitCode, threshold) {
|
|
|
166
280
|
*/
|
|
167
281
|
function handleTestRecordsMode(stdout, stderr, exitCode, runPattern) {
|
|
168
282
|
let records = [];
|
|
169
|
-
|
|
283
|
+
let repetitions = 1;
|
|
284
|
+
// OPA emits a JSON array. With `--count N` it emits one such array per
|
|
285
|
+
// repetition, back to back, which is neither a single JSON value nor NDJSON;
|
|
286
|
+
// reading only the first form reported a repeated run as no tests at all.
|
|
287
|
+
// Older versions may emit NDJSON (one object per line).
|
|
170
288
|
const arrayParsed = tryParseJson(stdout);
|
|
171
289
|
if (Array.isArray(arrayParsed)) {
|
|
172
290
|
records = arrayParsed;
|
|
173
291
|
}
|
|
174
292
|
else {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
293
|
+
const runs = parseJsonValues(stdout).filter((v) => Array.isArray(v));
|
|
294
|
+
if (runs.length > 0) {
|
|
295
|
+
repetitions = runs.length;
|
|
296
|
+
records = mergeRepetitions(runs);
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
for (const line of stdout.split(/\r?\n/)) {
|
|
300
|
+
const trimmed = line.trim();
|
|
301
|
+
if (trimmed.length === 0)
|
|
302
|
+
continue;
|
|
303
|
+
const parsed = tryParseJson(trimmed);
|
|
304
|
+
if (parsed)
|
|
305
|
+
records.push(parsed);
|
|
306
|
+
}
|
|
182
307
|
}
|
|
183
308
|
}
|
|
184
309
|
if (records.length === 0) {
|
|
@@ -200,30 +325,24 @@ function handleTestRecordsMode(stdout, stderr, exitCode, runPattern) {
|
|
|
200
325
|
});
|
|
201
326
|
}
|
|
202
327
|
// OPA does NOT emit `pass: true` for passing tests; only `fail: true` for
|
|
203
|
-
// failures
|
|
328
|
+
// failures, `skip: true` for todo_* tests, and `error` for a test that could
|
|
329
|
+
// not be evaluated. Passing is what is left after all three: subtracting only
|
|
330
|
+
// failures and skips counted an errored test as a pass.
|
|
204
331
|
const failed = records.filter((r) => r.fail).length;
|
|
205
332
|
const skipped = records.filter((r) => r.skip).length;
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
const parameterizedGroups = {};
|
|
210
|
-
for (const record of records) {
|
|
211
|
-
if (record.name) {
|
|
212
|
-
const match = /^(test_[a-zA-Z0-9_]+)\[/.exec(record.name);
|
|
213
|
-
if (match) {
|
|
214
|
-
const baseName = match[1];
|
|
215
|
-
(parameterizedGroups[baseName] ??= []).push(record);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
333
|
+
const errored = records.filter(isErrored).length;
|
|
334
|
+
const passed = records.length - failed - skipped - errored;
|
|
335
|
+
const { parameterizedGroups, caseCounts } = groupParameterized(records);
|
|
219
336
|
const hasGroups = Object.keys(parameterizedGroups).length > 0;
|
|
220
337
|
return ok({
|
|
221
338
|
passed,
|
|
222
339
|
failed,
|
|
223
340
|
skipped,
|
|
341
|
+
errored,
|
|
224
342
|
total: records.length,
|
|
225
343
|
results: records,
|
|
226
|
-
...(
|
|
344
|
+
...(repetitions > 1 ? { repetitions } : {}),
|
|
345
|
+
...(hasGroups ? { caseCounts, parameterizedGroups } : {}),
|
|
227
346
|
});
|
|
228
347
|
}
|
|
229
348
|
//# sourceMappingURL=test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../../src/tools/evaluation/test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AAEnC,MAAM,aAAa,GAAG;IACpB,KAAK,EAAE,CAAC;SACL,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACP,yFAAyF,CAC1F;IACH,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;IAC5E,QAAQ,EAAE,CAAC;SACR,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,QAAQ,CACP,uKAAuK,CACxK;IACH,UAAU,EAAE,CAAC;SACV,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,+EAA+E,CAAC;IAC5F,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,GAAG,CAAC;SACR,QAAQ,EAAE;SACV,QAAQ,CACP,6KAA6K,CAC9K;IACH,SAAS,EAAE,CAAC;SACT,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,QAAQ,CACP,wRAAwR,CACzR;IACH,cAAc,EAAE,CAAC;SACd,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,QAAQ,EAAE;SACV,QAAQ,CACP,sOAAsO,CACvO;IACH,MAAM,EAAE,CAAC;SACN,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,QAAQ,CACP,gLAAgL,CACjL;IACH,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,EAAE;SACV,QAAQ,CACP,
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../../src/tools/evaluation/test.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,9 +20,17 @@ export interface RegoCoverageGapsOutput {
|
|
|
20
20
|
overallCoverage: number;
|
|
21
21
|
totalFiles: number;
|
|
22
22
|
filesWithGaps: FileCoverageGap[];
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Test counts, present only when OPA reported per-test records.
|
|
25
|
+
*
|
|
26
|
+
* It does not do so in coverage mode: `opa test --coverage` emits the
|
|
27
|
+
* coverage report alone. These were therefore always zero, which reads as
|
|
28
|
+
* "no tests ran" rather than "not reported". Absent means unknown; run
|
|
29
|
+
* `rego_test` without coverage for the counts.
|
|
30
|
+
*/
|
|
31
|
+
testsPassed?: number;
|
|
32
|
+
testsFailed?: number;
|
|
33
|
+
testsSkipped?: number;
|
|
26
34
|
}
|
|
27
35
|
export declare function registerRegoCoverageGaps(server: McpServer, config: Config): void;
|
|
28
36
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coverage-gaps.d.ts","sourceRoot":"","sources":["../../../src/tools/helpers/coverage-gaps.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AA4B9C,UAAU,aAAa;IACrB,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,GAAG,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACpC;AAoBD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,aAAa,EAAE,CAAC;IACjC,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACrC,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,eAAe,EAAE,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"coverage-gaps.d.ts","sourceRoot":"","sources":["../../../src/tools/helpers/coverage-gaps.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AA4B9C,UAAU,aAAa;IACrB,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,GAAG,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACpC;AAoBD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,aAAa,EAAE,CAAC;IACjC,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACrC,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,eAAe,EAAE,CAAC;IACjC;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA0CD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CA8FhF"}
|
|
@@ -100,6 +100,9 @@ export function registerRegoCoverageGaps(server, config) {
|
|
|
100
100
|
// passing records with any status field, so filtering for pass: true
|
|
101
101
|
// always produces zero. Subtraction is the correct approach.
|
|
102
102
|
const testsPassed = testRecords.length - testsFailed - testsSkipped;
|
|
103
|
+
// OPA emits no test records in coverage mode, so reporting three zeros
|
|
104
|
+
// stated that no tests ran when the truth is that it did not say.
|
|
105
|
+
const counts = testRecords.length > 0 ? { testsPassed, testsFailed, testsSkipped } : {};
|
|
103
106
|
const overallCoverage = coverageReport.coverage ?? 0;
|
|
104
107
|
const filesWithGaps = [];
|
|
105
108
|
for (const [file, report] of Object.entries(coverageReport.files ?? {})) {
|
|
@@ -124,9 +127,7 @@ export function registerRegoCoverageGaps(server, config) {
|
|
|
124
127
|
overallCoverage,
|
|
125
128
|
totalFiles: Object.keys(coverageReport.files ?? {}).length,
|
|
126
129
|
filesWithGaps,
|
|
127
|
-
|
|
128
|
-
testsFailed,
|
|
129
|
-
testsSkipped,
|
|
130
|
+
...counts,
|
|
130
131
|
});
|
|
131
132
|
});
|
|
132
133
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coverage-gaps.js","sourceRoot":"","sources":["../../../src/tools/helpers/coverage-gaps.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AAEnC,MAAM,qBAAqB,GAAG;IAC5B,KAAK,EAAE,CAAC;SACL,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACP,qFAAqF,CACtF;IACH,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,GAAG,CAAC;SACR,QAAQ,EAAE;SACV,QAAQ,CACP,uHAAuH,CACxH;IACH,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC;CAC3F,CAAC;
|
|
1
|
+
{"version":3,"file":"coverage-gaps.js","sourceRoot":"","sources":["../../../src/tools/helpers/coverage-gaps.ts"],"names":[],"mappings":"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"}
|
|
@@ -33,9 +33,15 @@ export interface RuleAnalysis {
|
|
|
33
33
|
source: 'trace' | 'standalone-eval';
|
|
34
34
|
}
|
|
35
35
|
export interface RegoExplainUndefinedOutput {
|
|
36
|
-
/**
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Whether the query produced a value.
|
|
38
|
+
*
|
|
39
|
+
* `default` means it produced one only because a `default` rule supplied it:
|
|
40
|
+
* no other definition of the rule matched. The per-rule breakdown says why,
|
|
41
|
+
* which is the same question `undefined` asks.
|
|
42
|
+
*/
|
|
43
|
+
queryResult: 'undefined' | 'defined' | 'default';
|
|
44
|
+
/** Present when queryResult is "defined" or "default". */
|
|
39
45
|
value?: unknown;
|
|
40
46
|
/** Human-readable explanation. */
|
|
41
47
|
summary: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explain-undefined.d.ts","sourceRoot":"","sources":["../../../src/tools/helpers/explain-undefined.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AA6E9C,MAAM,WAAW,eAAe;IAC9B,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,4BAA4B;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,6CAA6C;IAC7C,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,aAAa,CAAC;IACzC,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,SAAS,EAAE,OAAO,CAAC;IACnB,wCAAwC;IACxC,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,sDAAsD;IACtD,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,sEAAsE;IACtE,iBAAiB,EAAE,eAAe,GAAG,IAAI,CAAC;IAC1C,0CAA0C;IAC1C,MAAM,EAAE,OAAO,GAAG,iBAAiB,CAAC;CACrC;AAED,MAAM,WAAW,0BAA0B;IACzC
|
|
1
|
+
{"version":3,"file":"explain-undefined.d.ts","sourceRoot":"","sources":["../../../src/tools/helpers/explain-undefined.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AA6E9C,MAAM,WAAW,eAAe;IAC9B,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,4BAA4B;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,6CAA6C;IAC7C,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,aAAa,CAAC;IACzC,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,SAAS,EAAE,OAAO,CAAC;IACnB,wCAAwC;IACxC,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,sDAAsD;IACtD,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,sEAAsE;IACtE,iBAAiB,EAAE,eAAe,GAAG,IAAI,CAAC;IAC1C,0CAA0C;IAC1C,MAAM,EAAE,OAAO,GAAG,iBAAiB,CAAC;CACrC;AAED,MAAM,WAAW,0BAA0B;IACzC;;;;;;OAMG;IACH,WAAW,EAAE,WAAW,GAAG,SAAS,GAAG,SAAS,CAAC;IACjD,0DAA0D;IAC1D,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,UAAU,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,0BAA0B;IAC1B,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAqMD,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CA2OpF"}
|
|
@@ -75,20 +75,35 @@ function queryToPackageAndRule(query) {
|
|
|
75
75
|
packagePath: parts.slice(0, -1).join('.'),
|
|
76
76
|
};
|
|
77
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* The source row a trace event refers to.
|
|
80
|
+
*
|
|
81
|
+
* OPA does not populate `Node.location` on trace events; the row lives on the
|
|
82
|
+
* event's own `Location`. Reading only the node meant every row comparison fell
|
|
83
|
+
* through to matching on the rule name alone, so all clauses of a multi-clause
|
|
84
|
+
* rule looked present in the trace as soon as any one of them was, and the ones
|
|
85
|
+
* the indexer had eliminated were never evaluated standalone. They came back as
|
|
86
|
+
* `unevaluable` with no blocking condition, which is the answer this tool
|
|
87
|
+
* exists to give.
|
|
88
|
+
*/
|
|
89
|
+
function traceEventRow(ev) {
|
|
90
|
+
return ev.Node?.location?.row ?? ev.Location?.row;
|
|
91
|
+
}
|
|
92
|
+
function matchesRule(ev, ruleName, ruleRow) {
|
|
93
|
+
if (ev.Op?.toLowerCase() !== 'enter')
|
|
94
|
+
return false;
|
|
95
|
+
if (!ev.Node)
|
|
96
|
+
return false;
|
|
97
|
+
if (extractRuleHeadName(ev.Node.head) !== ruleName)
|
|
98
|
+
return false;
|
|
99
|
+
const row = traceEventRow(ev);
|
|
100
|
+
// Disambiguate the clauses of an incremental rule by source row.
|
|
101
|
+
if (ruleRow !== undefined && row !== undefined)
|
|
102
|
+
return row === ruleRow;
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
78
105
|
function ruleAppearsInTrace(ruleName, ruleRow, trace) {
|
|
79
|
-
return trace.some((ev) =>
|
|
80
|
-
if (ev.Op?.toLowerCase() !== 'enter')
|
|
81
|
-
return false;
|
|
82
|
-
if (!ev.Node)
|
|
83
|
-
return false;
|
|
84
|
-
if (extractRuleHeadName(ev.Node.head) !== ruleName)
|
|
85
|
-
return false;
|
|
86
|
-
// When we have source row information, use it to disambiguate incremental rules.
|
|
87
|
-
if (ruleRow !== undefined && ev.Node.location?.row !== undefined) {
|
|
88
|
-
return ev.Node.location.row === ruleRow;
|
|
89
|
-
}
|
|
90
|
-
return true;
|
|
91
|
-
});
|
|
106
|
+
return trace.some((ev) => matchesRule(ev, ruleName, ruleRow));
|
|
92
107
|
}
|
|
93
108
|
function findBlockingRowFromTrace(rule, trace) {
|
|
94
109
|
const ruleName = extractRuleHeadName(rule.head);
|
|
@@ -97,16 +112,7 @@ function findBlockingRowFromTrace(rule, trace) {
|
|
|
97
112
|
if (bodyRows.size === 0)
|
|
98
113
|
return undefined;
|
|
99
114
|
// Locate the Enter event for this specific rule definition.
|
|
100
|
-
const enterIdx = trace.findIndex((ev) =>
|
|
101
|
-
if (ev.Op?.toLowerCase() !== 'enter')
|
|
102
|
-
return false;
|
|
103
|
-
if (extractRuleHeadName(ev.Node?.head) !== ruleName)
|
|
104
|
-
return false;
|
|
105
|
-
if (ruleRow !== undefined && ev.Node?.location?.row !== undefined) {
|
|
106
|
-
return ev.Node.location.row === ruleRow;
|
|
107
|
-
}
|
|
108
|
-
return true;
|
|
109
|
-
});
|
|
115
|
+
const enterIdx = trace.findIndex((ev) => matchesRule(ev, ruleName ?? '', ruleRow));
|
|
110
116
|
if (enterIdx < 0)
|
|
111
117
|
return undefined;
|
|
112
118
|
// Find the first Fail event after the Enter that falls on a body expression row.
|
|
@@ -151,14 +157,25 @@ async function evalConditionStandalone(exprText, evalBase, opa, signal) {
|
|
|
151
157
|
});
|
|
152
158
|
return satisfied ? { result: 'true' } : { result: 'false' };
|
|
153
159
|
}
|
|
154
|
-
|
|
160
|
+
/** Structural equality, enough for the scalars and small literals a default holds. */
|
|
161
|
+
function deepEqual(a, b) {
|
|
162
|
+
if (a === b)
|
|
163
|
+
return true;
|
|
164
|
+
if (a === null || b === null || typeof a !== 'object' || typeof b !== 'object')
|
|
165
|
+
return false;
|
|
166
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
167
|
+
}
|
|
168
|
+
function buildSummary(query, rules, defaultValue, viaDefault) {
|
|
155
169
|
const lines = [];
|
|
170
|
+
const state = viaDefault
|
|
171
|
+
? `falls back to its default value ${JSON.stringify(defaultValue)} because no other definition matched`
|
|
172
|
+
: 'is undefined';
|
|
156
173
|
if (rules.length === 0) {
|
|
157
|
-
lines.push(`${query}
|
|
174
|
+
lines.push(`${query} ${state}: no matching rules found in the analysed source.`);
|
|
158
175
|
}
|
|
159
176
|
else {
|
|
160
177
|
const count = rules.length;
|
|
161
|
-
lines.push(`${query}
|
|
178
|
+
lines.push(`${query} ${state}. ${count} rule definition${count !== 1 ? 's' : ''} analysed:`);
|
|
162
179
|
for (const r of rules) {
|
|
163
180
|
const loc = r.location.row > 0 ? ` (row ${r.location.row})` : '';
|
|
164
181
|
const bc = r.blockingCondition;
|
|
@@ -177,7 +194,7 @@ function buildSummary(query, rules, defaultValue) {
|
|
|
177
194
|
}
|
|
178
195
|
}
|
|
179
196
|
}
|
|
180
|
-
if (defaultValue !== undefined) {
|
|
197
|
+
if (!viaDefault && defaultValue !== undefined) {
|
|
181
198
|
lines.push(`Default value: ${JSON.stringify(defaultValue)}.`);
|
|
182
199
|
}
|
|
183
200
|
return lines.join('\n');
|
|
@@ -188,9 +205,12 @@ export function registerRegoExplainUndefined(server, config) {
|
|
|
188
205
|
server.registerTool('rego_explain_undefined', {
|
|
189
206
|
title: 'Explain why a Rego query is undefined',
|
|
190
207
|
description: 'Diagnose why a fully-qualified Rego query (e.g. "data.authz.allow") produces no ' +
|
|
191
|
-
'value. Combines a plain eval, a full-trace eval, and
|
|
192
|
-
'identify the exact body expression blocking each rule.
|
|
193
|
-
'(trace-based) and indexer elimination (standalone
|
|
208
|
+
'value, or falls back to its default. Combines a plain eval, a full-trace eval, and ' +
|
|
209
|
+
'per-condition AST analysis to identify the exact body expression blocking each rule. ' +
|
|
210
|
+
'Handles both runtime failures (trace-based) and indexer elimination (standalone ' +
|
|
211
|
+
'condition eval). A rule written with `default allow := false` always has a value, so ' +
|
|
212
|
+
'`queryResult` reports `default` for it and the same per-rule breakdown follows: the ' +
|
|
213
|
+
'question "why is allow false" is the question this answers. Returns a structured ' +
|
|
194
214
|
'breakdown of which conditions blocked each rule plus a human-readable summary.',
|
|
195
215
|
inputSchema: RegoExplainUndefinedInput,
|
|
196
216
|
annotations: {
|
|
@@ -237,24 +257,11 @@ export function registerRegoExplainUndefined(server, config) {
|
|
|
237
257
|
}
|
|
238
258
|
const plainJson = tryParseJson(plainResult.stdout);
|
|
239
259
|
const isDefined = (plainJson?.result?.length ?? 0) > 0;
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
summary: `${args.query} is defined with value: ${JSON.stringify(value)}.`,
|
|
246
|
-
rulesFound: 0,
|
|
247
|
-
rules: [],
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
// ── Step 2: eval with --explain=full ──────────────────────────────
|
|
251
|
-
const traceResult = await opa.eval({ ...evalBase, explain: 'full' }, signal);
|
|
252
|
-
const traceSpawnErr = mapSubprocessFailure(traceResult, 'opa');
|
|
253
|
-
if (traceSpawnErr)
|
|
254
|
-
return traceSpawnErr;
|
|
255
|
-
const traceJson = tryParseJson(traceResult.stdout);
|
|
256
|
-
const trace = traceJson?.explanation ?? [];
|
|
257
|
-
// ── Step 3: parse AST(s) ──────────────────────────────────────────
|
|
260
|
+
const definedValue = isDefined
|
|
261
|
+
? plainJson.result[0]
|
|
262
|
+
?.expressions?.[0]?.value
|
|
263
|
+
: undefined;
|
|
264
|
+
// ── Step 2: parse AST(s) ──────────────────────────────────────────
|
|
258
265
|
const asts = [];
|
|
259
266
|
if (args.source) {
|
|
260
267
|
const pr = await opa.parse({ source: args.source, includeLocations: true }, signal);
|
|
@@ -281,7 +288,7 @@ export function registerRegoExplainUndefined(server, config) {
|
|
|
281
288
|
}
|
|
282
289
|
}
|
|
283
290
|
}
|
|
284
|
-
// ── Step
|
|
291
|
+
// ── Step 3: find matching rules ───────────────────────────────────
|
|
285
292
|
const queryParsed = queryToPackageAndRule(args.query);
|
|
286
293
|
const matchedRules = [];
|
|
287
294
|
for (const ast of asts) {
|
|
@@ -295,6 +302,30 @@ export function registerRegoExplainUndefined(server, config) {
|
|
|
295
302
|
}
|
|
296
303
|
}
|
|
297
304
|
}
|
|
305
|
+
// A rule written with `default allow := false` always has a value, so the
|
|
306
|
+
// query is never undefined and the analysis below used to be skipped for
|
|
307
|
+
// the shape most policies are written in. When the value came from the
|
|
308
|
+
// default and nothing else matched, the interesting question is unchanged.
|
|
309
|
+
const defaultRule = matchedRules.find((r) => r.default === true);
|
|
310
|
+
const viaDefault = isDefined &&
|
|
311
|
+
defaultRule !== undefined &&
|
|
312
|
+
deepEqual(defaultRule.head?.value?.value, definedValue);
|
|
313
|
+
if (isDefined && !viaDefault) {
|
|
314
|
+
return ok({
|
|
315
|
+
queryResult: 'defined',
|
|
316
|
+
value: definedValue,
|
|
317
|
+
summary: `${args.query} is defined with value: ${JSON.stringify(definedValue)}.`,
|
|
318
|
+
rulesFound: 0,
|
|
319
|
+
rules: [],
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
// ── Step 4: eval with --explain=full ──────────────────────────────
|
|
323
|
+
const traceResult = await opa.eval({ ...evalBase, explain: 'full' }, signal);
|
|
324
|
+
const traceSpawnErr = mapSubprocessFailure(traceResult, 'opa');
|
|
325
|
+
if (traceSpawnErr)
|
|
326
|
+
return traceSpawnErr;
|
|
327
|
+
const traceJson = tryParseJson(traceResult.stdout);
|
|
328
|
+
const trace = traceJson?.explanation ?? [];
|
|
298
329
|
// ── Step 5: analyse each rule ─────────────────────────────────────
|
|
299
330
|
let defaultValue;
|
|
300
331
|
const rules = [];
|
|
@@ -376,9 +407,10 @@ export function registerRegoExplainUndefined(server, config) {
|
|
|
376
407
|
}
|
|
377
408
|
}
|
|
378
409
|
const nonDefaultRules = rules.filter((r) => !r.isDefault);
|
|
379
|
-
const summary = buildSummary(args.query, nonDefaultRules, defaultValue);
|
|
410
|
+
const summary = buildSummary(args.query, nonDefaultRules, defaultValue, viaDefault);
|
|
380
411
|
return ok({
|
|
381
|
-
queryResult: 'undefined',
|
|
412
|
+
queryResult: viaDefault ? 'default' : 'undefined',
|
|
413
|
+
...(viaDefault ? { value: definedValue } : {}),
|
|
382
414
|
summary,
|
|
383
415
|
rulesFound: nonDefaultRules.length,
|
|
384
416
|
defaultValue,
|