@orygn/opa-mcp 0.0.0 → 0.1.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 +99 -0
- package/LICENSE +21 -0
- package/README.md +622 -2
- package/dist/config.d.ts +58 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +72 -0
- package/dist/config.js.map +1 -0
- package/dist/lib/errors.d.ts +18 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +25 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/logger.d.ts +10 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +57 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/opa-cli.d.ts +226 -0
- package/dist/lib/opa-cli.d.ts.map +1 -0
- package/dist/lib/opa-cli.js +283 -0
- package/dist/lib/opa-cli.js.map +1 -0
- package/dist/lib/opa-client.d.ts +47 -0
- package/dist/lib/opa-client.d.ts.map +1 -0
- package/dist/lib/opa-client.js +101 -0
- package/dist/lib/opa-client.js.map +1 -0
- package/dist/lib/output.d.ts +17 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +21 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/regal-cli.d.ts +65 -0
- package/dist/lib/regal-cli.d.ts.map +1 -0
- package/dist/lib/regal-cli.js +99 -0
- package/dist/lib/regal-cli.js.map +1 -0
- package/dist/lib/security.d.ts +16 -0
- package/dist/lib/security.d.ts.map +1 -0
- package/dist/lib/security.js +64 -0
- package/dist/lib/security.js.map +1 -0
- package/dist/lib/subprocess.d.ts +26 -0
- package/dist/lib/subprocess.d.ts.map +1 -0
- package/dist/lib/subprocess.js +72 -0
- package/dist/lib/subprocess.js.map +1 -0
- package/dist/lib/tool-helpers.d.ts +46 -0
- package/dist/lib/tool-helpers.d.ts.map +1 -0
- package/dist/lib/tool-helpers.js +73 -0
- package/dist/lib/tool-helpers.js.map +1 -0
- package/dist/prompts/index.d.ts +4 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +147 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/resources/index.d.ts +12 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +107 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/resources/patterns.d.ts +9 -0
- package/dist/resources/patterns.d.ts.map +1 -0
- package/dist/resources/patterns.js +375 -0
- package/dist/resources/patterns.js.map +1 -0
- package/dist/resources/style-guide.d.ts +6 -0
- package/dist/resources/style-guide.d.ts.map +1 -0
- package/dist/resources/style-guide.js +187 -0
- package/dist/resources/style-guide.js.map +1 -0
- package/dist/server.d.ts +22 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +82 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/authoring/capabilities.d.ts +11 -0
- package/dist/tools/authoring/capabilities.d.ts.map +1 -0
- package/dist/tools/authoring/capabilities.js +57 -0
- package/dist/tools/authoring/capabilities.js.map +1 -0
- package/dist/tools/authoring/check.d.ts +18 -0
- package/dist/tools/authoring/check.d.ts.map +1 -0
- package/dist/tools/authoring/check.js +71 -0
- package/dist/tools/authoring/check.js.map +1 -0
- package/dist/tools/authoring/deps.d.ts +8 -0
- package/dist/tools/authoring/deps.d.ts.map +1 -0
- package/dist/tools/authoring/deps.js +51 -0
- package/dist/tools/authoring/deps.js.map +1 -0
- package/dist/tools/authoring/format.d.ts +8 -0
- package/dist/tools/authoring/format.d.ts.map +1 -0
- package/dist/tools/authoring/format.js +44 -0
- package/dist/tools/authoring/format.js.map +1 -0
- package/dist/tools/authoring/index.d.ts +11 -0
- package/dist/tools/authoring/index.d.ts.map +1 -0
- package/dist/tools/authoring/index.js +17 -0
- package/dist/tools/authoring/index.js.map +1 -0
- package/dist/tools/authoring/inspect.d.ts +10 -0
- package/dist/tools/authoring/inspect.d.ts.map +1 -0
- package/dist/tools/authoring/inspect.js +47 -0
- package/dist/tools/authoring/inspect.js.map +1 -0
- package/dist/tools/authoring/lint.d.ts +18 -0
- package/dist/tools/authoring/lint.d.ts.map +1 -0
- package/dist/tools/authoring/lint.js +84 -0
- package/dist/tools/authoring/lint.js.map +1 -0
- package/dist/tools/authoring/parse.d.ts +7 -0
- package/dist/tools/authoring/parse.d.ts.map +1 -0
- package/dist/tools/authoring/parse.js +43 -0
- package/dist/tools/authoring/parse.js.map +1 -0
- package/dist/tools/bundles/build.d.ts +8 -0
- package/dist/tools/bundles/build.d.ts.map +1 -0
- package/dist/tools/bundles/build.js +87 -0
- package/dist/tools/bundles/build.js.map +1 -0
- package/dist/tools/bundles/index.d.ts +10 -0
- package/dist/tools/bundles/index.d.ts.map +1 -0
- package/dist/tools/bundles/index.js +7 -0
- package/dist/tools/bundles/index.js.map +1 -0
- package/dist/tools/bundles/sign.d.ts +8 -0
- package/dist/tools/bundles/sign.d.ts.map +1 -0
- package/dist/tools/bundles/sign.js +47 -0
- package/dist/tools/bundles/sign.js.map +1 -0
- package/dist/tools/evaluation/_shared.d.ts +55 -0
- package/dist/tools/evaluation/_shared.d.ts.map +1 -0
- package/dist/tools/evaluation/_shared.js +102 -0
- package/dist/tools/evaluation/_shared.js.map +1 -0
- package/dist/tools/evaluation/bench.d.ts +9 -0
- package/dist/tools/evaluation/bench.d.ts.map +1 -0
- package/dist/tools/evaluation/bench.js +76 -0
- package/dist/tools/evaluation/bench.js.map +1 -0
- package/dist/tools/evaluation/compile.d.ts +11 -0
- package/dist/tools/evaluation/compile.d.ts.map +1 -0
- package/dist/tools/evaluation/compile.js +19 -0
- package/dist/tools/evaluation/compile.js.map +1 -0
- package/dist/tools/evaluation/eval.d.ts +10 -0
- package/dist/tools/evaluation/eval.d.ts.map +1 -0
- package/dist/tools/evaluation/eval.js +35 -0
- package/dist/tools/evaluation/eval.js.map +1 -0
- package/dist/tools/evaluation/index.d.ts +11 -0
- package/dist/tools/evaluation/index.d.ts.map +1 -0
- package/dist/tools/evaluation/index.js +11 -0
- package/dist/tools/evaluation/index.js.map +1 -0
- package/dist/tools/evaluation/test.d.ts +28 -0
- package/dist/tools/evaluation/test.d.ts.map +1 -0
- package/dist/tools/evaluation/test.js +74 -0
- package/dist/tools/evaluation/test.js.map +1 -0
- package/dist/tools/helpers/describe-policy.d.ts +26 -0
- package/dist/tools/helpers/describe-policy.d.ts.map +1 -0
- package/dist/tools/helpers/describe-policy.js +76 -0
- package/dist/tools/helpers/describe-policy.js.map +1 -0
- package/dist/tools/helpers/explain-decision.d.ts +41 -0
- package/dist/tools/helpers/explain-decision.d.ts.map +1 -0
- package/dist/tools/helpers/explain-decision.js +75 -0
- package/dist/tools/helpers/explain-decision.js.map +1 -0
- package/dist/tools/helpers/generate-test-skeleton.d.ts +8 -0
- package/dist/tools/helpers/generate-test-skeleton.d.ts.map +1 -0
- package/dist/tools/helpers/generate-test-skeleton.js +93 -0
- package/dist/tools/helpers/generate-test-skeleton.js.map +1 -0
- package/dist/tools/helpers/index.d.ts +12 -0
- package/dist/tools/helpers/index.d.ts.map +1 -0
- package/dist/tools/helpers/index.js +11 -0
- package/dist/tools/helpers/index.js.map +1 -0
- package/dist/tools/helpers/suggest-fix.d.ts +15 -0
- package/dist/tools/helpers/suggest-fix.d.ts.map +1 -0
- package/dist/tools/helpers/suggest-fix.js +119 -0
- package/dist/tools/helpers/suggest-fix.js.map +1 -0
- package/dist/tools/index.d.ts +31 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +13 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/server-management/_shared.d.ts +9 -0
- package/dist/tools/server-management/_shared.d.ts.map +1 -0
- package/dist/tools/server-management/_shared.js +41 -0
- package/dist/tools/server-management/_shared.js.map +1 -0
- package/dist/tools/server-management/data.d.ts +4 -0
- package/dist/tools/server-management/data.d.ts.map +1 -0
- package/dist/tools/server-management/data.js +90 -0
- package/dist/tools/server-management/data.js.map +1 -0
- package/dist/tools/server-management/decisions.d.ts +4 -0
- package/dist/tools/server-management/decisions.d.ts.map +1 -0
- package/dist/tools/server-management/decisions.js +87 -0
- package/dist/tools/server-management/decisions.js.map +1 -0
- package/dist/tools/server-management/index.d.ts +11 -0
- package/dist/tools/server-management/index.d.ts.map +1 -0
- package/dist/tools/server-management/index.js +11 -0
- package/dist/tools/server-management/index.js.map +1 -0
- package/dist/tools/server-management/policies.d.ts +4 -0
- package/dist/tools/server-management/policies.d.ts.map +1 -0
- package/dist/tools/server-management/policies.js +94 -0
- package/dist/tools/server-management/policies.js.map +1 -0
- package/dist/tools/server-management/status.d.ts +4 -0
- package/dist/tools/server-management/status.d.ts.map +1 -0
- package/dist/tools/server-management/status.js +82 -0
- package/dist/tools/server-management/status.js.map +1 -0
- package/dist/types.d.ts +24 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +82 -4
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wrapper around the local `opa` binary.
|
|
3
|
+
*
|
|
4
|
+
* Tool implementations call into this module rather than spawning
|
|
5
|
+
* subprocesses directly. Every method here builds argv with the flags
|
|
6
|
+
* `opa` actually expects so each tool above can ignore CLI minutiae and
|
|
7
|
+
* just describe its inputs.
|
|
8
|
+
*
|
|
9
|
+
* Inline Rego source is always written to a temp file before invocation.
|
|
10
|
+
* The `-` (read-from-stdin) convention some opa subcommands document is
|
|
11
|
+
* unreliable on Windows, where `-` is treated as a literal filename.
|
|
12
|
+
*
|
|
13
|
+
* The methods do not parse stdout into typed result objects — different
|
|
14
|
+
* tools need different shapes of the same output and a one-size parser
|
|
15
|
+
* would force conversions both ways. Stdout is JSON whenever
|
|
16
|
+
* `--format=json` is set, and tools call `JSON.parse` on it themselves.
|
|
17
|
+
*/
|
|
18
|
+
import { randomUUID } from 'node:crypto';
|
|
19
|
+
import { rm, writeFile } from 'node:fs/promises';
|
|
20
|
+
import { tmpdir } from 'node:os';
|
|
21
|
+
import { join } from 'node:path';
|
|
22
|
+
import { runBinary } from './subprocess.js';
|
|
23
|
+
/**
|
|
24
|
+
* Wrapper around the local `opa` binary.
|
|
25
|
+
*
|
|
26
|
+
* Methods do not throw on `opa` errors — non-zero exit codes are
|
|
27
|
+
* surfaced on the returned `SpawnResult` so tools can map them to
|
|
28
|
+
* structured error envelopes at their layer. They DO throw on
|
|
29
|
+
* caller-side bugs (e.g. an empty `paths` array passed where one is
|
|
30
|
+
* required), since those represent contract violations.
|
|
31
|
+
*/
|
|
32
|
+
export class OpaCli {
|
|
33
|
+
config;
|
|
34
|
+
constructor(config) {
|
|
35
|
+
this.config = config;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Verify the binary is present and report its version.
|
|
39
|
+
* Returns null if the binary is unreachable or output is malformed.
|
|
40
|
+
*/
|
|
41
|
+
async version() {
|
|
42
|
+
const result = await this.run(['version']);
|
|
43
|
+
if (result.exitCode !== 0)
|
|
44
|
+
return null;
|
|
45
|
+
const match = /Version:\s*(\S+)/i.exec(result.stdout);
|
|
46
|
+
return match?.[1] ?? null;
|
|
47
|
+
}
|
|
48
|
+
// ─── Authoring ───────────────────────────────────────────────────────
|
|
49
|
+
/**
|
|
50
|
+
* Format Rego source. Stdout contains the formatted output. Reports
|
|
51
|
+
* `exitCode: 0` even when no changes are needed — callers compare
|
|
52
|
+
* input vs output to detect a no-op.
|
|
53
|
+
*/
|
|
54
|
+
async fmt(input) {
|
|
55
|
+
return this.withTempSource(input.source, (path) => this.run(['fmt', path]));
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Type-check Rego. Returns `exitCode: 0` and empty `stdout` when the
|
|
59
|
+
* policy is valid. On failure, `exitCode` is non-zero and the JSON
|
|
60
|
+
* error report is written to **stderr** (this is OPA's actual
|
|
61
|
+
* behavior — tools must read `stderr`, not `stdout`, for `check`
|
|
62
|
+
* diagnostics). Either inline `source` or one or more `paths` must be
|
|
63
|
+
* provided.
|
|
64
|
+
*/
|
|
65
|
+
async check(input) {
|
|
66
|
+
if (!input.source && !input.paths?.length) {
|
|
67
|
+
throw new Error('opa check requires either source or at least one path');
|
|
68
|
+
}
|
|
69
|
+
const args = ['check', '--format=json'];
|
|
70
|
+
if (input.strict)
|
|
71
|
+
args.push('--strict');
|
|
72
|
+
if (input.capabilities)
|
|
73
|
+
args.push('--capabilities', input.capabilities);
|
|
74
|
+
if (input.schemaDir)
|
|
75
|
+
args.push('--schema', input.schemaDir);
|
|
76
|
+
if (input.source !== undefined) {
|
|
77
|
+
return this.withTempSource(input.source, (path) => this.run([...args, path]));
|
|
78
|
+
}
|
|
79
|
+
args.push(...(input.paths ?? []));
|
|
80
|
+
return this.run(args);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Parse Rego source to a JSON AST. Stdout is the AST as JSON.
|
|
84
|
+
*/
|
|
85
|
+
async parse(input) {
|
|
86
|
+
return this.withTempSource(input.source, (path) => this.run(['parse', '--format=json', path]));
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Inspect a bundle, directory, or single Rego file. Returns its
|
|
90
|
+
* packages, namespaces, manifest, and annotations as JSON on stdout.
|
|
91
|
+
*/
|
|
92
|
+
async inspect(input) {
|
|
93
|
+
return this.run(['inspect', '--format=json', input.target]);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Print available capabilities. With `current=true`, prints the
|
|
97
|
+
* capabilities of the running OPA. With a `version`, prints those of
|
|
98
|
+
* a specific named version. Without either, lists available named
|
|
99
|
+
* versions.
|
|
100
|
+
*/
|
|
101
|
+
async capabilities(input = {}) {
|
|
102
|
+
const args = ['capabilities'];
|
|
103
|
+
if (input.current)
|
|
104
|
+
args.push('--current');
|
|
105
|
+
if (input.version)
|
|
106
|
+
args.push('--version', input.version);
|
|
107
|
+
return this.run(args);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Static dependency analysis for a Rego ref. Stdout is JSON with the
|
|
111
|
+
* `base` and `virtual` document references the ref depends on.
|
|
112
|
+
*/
|
|
113
|
+
async deps(input) {
|
|
114
|
+
if (input.paths.length === 0) {
|
|
115
|
+
throw new Error('opa deps requires at least one path');
|
|
116
|
+
}
|
|
117
|
+
const args = ['deps', '--format=json'];
|
|
118
|
+
for (const path of input.paths) {
|
|
119
|
+
args.push('--data', path);
|
|
120
|
+
}
|
|
121
|
+
args.push(input.ref);
|
|
122
|
+
return this.run(args);
|
|
123
|
+
}
|
|
124
|
+
// ─── Evaluation ──────────────────────────────────────────────────────
|
|
125
|
+
/**
|
|
126
|
+
* Evaluate a query against a policy + input. Stdout is JSON with the
|
|
127
|
+
* standard `{result: [...]}` shape (plus optional explain, profile,
|
|
128
|
+
* coverage, and metrics sections).
|
|
129
|
+
*/
|
|
130
|
+
async eval(input) {
|
|
131
|
+
// Inline source becomes a temp file added to --data.
|
|
132
|
+
if (input.source !== undefined) {
|
|
133
|
+
const { source, ...rest } = input;
|
|
134
|
+
void source;
|
|
135
|
+
return this.withTempSource(input.source, (sourcePath) => this.eval({
|
|
136
|
+
...rest,
|
|
137
|
+
paths: [...(input.paths ?? []), sourcePath],
|
|
138
|
+
}));
|
|
139
|
+
}
|
|
140
|
+
const args = ['eval', '--format=json'];
|
|
141
|
+
for (const path of input.paths ?? [])
|
|
142
|
+
args.push('--data', path);
|
|
143
|
+
if (input.inputPath)
|
|
144
|
+
args.push('--input', input.inputPath);
|
|
145
|
+
if (input.explain)
|
|
146
|
+
args.push('--explain', input.explain);
|
|
147
|
+
if (input.profile)
|
|
148
|
+
args.push('--profile');
|
|
149
|
+
if (input.coverage)
|
|
150
|
+
args.push('--coverage');
|
|
151
|
+
if (input.metrics)
|
|
152
|
+
args.push('--metrics');
|
|
153
|
+
if (input.instrument)
|
|
154
|
+
args.push('--instrument');
|
|
155
|
+
if (input.partial)
|
|
156
|
+
args.push('--partial');
|
|
157
|
+
for (const ref of input.unknowns ?? [])
|
|
158
|
+
args.push('--unknowns', ref);
|
|
159
|
+
if (input.strictBuiltinErrors)
|
|
160
|
+
args.push('--strict-builtin-errors');
|
|
161
|
+
if (input.capabilities)
|
|
162
|
+
args.push('--capabilities', input.capabilities);
|
|
163
|
+
if (input.schemaDir)
|
|
164
|
+
args.push('--schema', input.schemaDir);
|
|
165
|
+
let stdin;
|
|
166
|
+
if (input.input !== undefined) {
|
|
167
|
+
args.push('--stdin-input');
|
|
168
|
+
stdin = JSON.stringify(input.input);
|
|
169
|
+
}
|
|
170
|
+
args.push(input.query);
|
|
171
|
+
return this.run(args, stdin);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Run Rego unit tests. Stdout is JSON with per-test pass/fail.
|
|
175
|
+
*/
|
|
176
|
+
async test(input) {
|
|
177
|
+
if (input.paths.length === 0) {
|
|
178
|
+
throw new Error('opa test requires at least one path');
|
|
179
|
+
}
|
|
180
|
+
const args = ['test', '--format=json'];
|
|
181
|
+
if (input.verbose)
|
|
182
|
+
args.push('--verbose');
|
|
183
|
+
if (input.coverage)
|
|
184
|
+
args.push('--coverage');
|
|
185
|
+
if (input.bench)
|
|
186
|
+
args.push('--bench');
|
|
187
|
+
if (input.runPattern)
|
|
188
|
+
args.push('--run', input.runPattern);
|
|
189
|
+
args.push(...input.paths);
|
|
190
|
+
return this.run(args);
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Benchmark a query. Stdout is JSON with iteration timing statistics.
|
|
194
|
+
*/
|
|
195
|
+
async bench(input) {
|
|
196
|
+
const args = ['bench', '--format=json'];
|
|
197
|
+
for (const path of input.paths ?? [])
|
|
198
|
+
args.push('--data', path);
|
|
199
|
+
if (input.inputPath)
|
|
200
|
+
args.push('--input', input.inputPath);
|
|
201
|
+
if (input.count !== undefined)
|
|
202
|
+
args.push('--count', String(input.count));
|
|
203
|
+
let stdin;
|
|
204
|
+
if (input.input !== undefined) {
|
|
205
|
+
args.push('--stdin-input');
|
|
206
|
+
stdin = JSON.stringify(input.input);
|
|
207
|
+
}
|
|
208
|
+
args.push(input.query);
|
|
209
|
+
return this.run(args, stdin);
|
|
210
|
+
}
|
|
211
|
+
// ─── Bundles ─────────────────────────────────────────────────────────
|
|
212
|
+
/** Build a deployable bundle from policy + data paths. */
|
|
213
|
+
async build(input) {
|
|
214
|
+
if (input.paths.length === 0) {
|
|
215
|
+
throw new Error('opa build requires at least one input path');
|
|
216
|
+
}
|
|
217
|
+
const args = ['build', '-o', input.output];
|
|
218
|
+
if (input.optimize !== undefined)
|
|
219
|
+
args.push('--optimize', String(input.optimize));
|
|
220
|
+
if (input.revision)
|
|
221
|
+
args.push('--revision', input.revision);
|
|
222
|
+
if (input.target)
|
|
223
|
+
args.push('--target', input.target);
|
|
224
|
+
for (const ep of input.entrypoints ?? [])
|
|
225
|
+
args.push('--entrypoint', ep);
|
|
226
|
+
if (input.signingKey)
|
|
227
|
+
args.push('--signing-key', input.signingKey);
|
|
228
|
+
if (input.signingAlg)
|
|
229
|
+
args.push('--signing-alg', input.signingAlg);
|
|
230
|
+
if (input.claimsFile)
|
|
231
|
+
args.push('--claims-file', input.claimsFile);
|
|
232
|
+
if (input.capabilities)
|
|
233
|
+
args.push('--capabilities', input.capabilities);
|
|
234
|
+
args.push(...input.paths);
|
|
235
|
+
return this.run(args);
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Sign a bundle. Writes a `.signatures.json` next to the bundle
|
|
239
|
+
* directory.
|
|
240
|
+
*/
|
|
241
|
+
async sign(input) {
|
|
242
|
+
const args = ['sign', '--signing-key', input.signingKey];
|
|
243
|
+
if (input.signingAlg)
|
|
244
|
+
args.push('--signing-alg', input.signingAlg);
|
|
245
|
+
if (input.claimsFile)
|
|
246
|
+
args.push('--claims-file', input.claimsFile);
|
|
247
|
+
args.push('--bundle', input.bundle);
|
|
248
|
+
return this.run(args);
|
|
249
|
+
}
|
|
250
|
+
// ─── Low-level escape hatch ──────────────────────────────────────────
|
|
251
|
+
/**
|
|
252
|
+
* Run `opa` with the given argv and optional stdin. Tools should
|
|
253
|
+
* prefer the typed methods above, but this exists for the rare cases
|
|
254
|
+
* the typed surface does not yet cover.
|
|
255
|
+
*/
|
|
256
|
+
async run(args, stdin) {
|
|
257
|
+
const opts = {
|
|
258
|
+
args,
|
|
259
|
+
timeoutMs: this.config.subprocessTimeoutMs,
|
|
260
|
+
};
|
|
261
|
+
if (stdin !== undefined)
|
|
262
|
+
opts.stdin = stdin;
|
|
263
|
+
return runBinary(this.config.opaBinary, opts);
|
|
264
|
+
}
|
|
265
|
+
// ─── Internal: temp file management ──────────────────────────────────
|
|
266
|
+
/**
|
|
267
|
+
* Write `source` to a uniquely named `.rego` file in the OS tmp dir,
|
|
268
|
+
* pass its path to `fn`, and remove it on completion (success or
|
|
269
|
+
* failure). The path is unique per call so concurrent invocations do
|
|
270
|
+
* not collide.
|
|
271
|
+
*/
|
|
272
|
+
async withTempSource(source, fn) {
|
|
273
|
+
const path = join(tmpdir(), `orygn-opa-mcp-${randomUUID()}.rego`);
|
|
274
|
+
await writeFile(path, source, 'utf8');
|
|
275
|
+
try {
|
|
276
|
+
return await fn(path);
|
|
277
|
+
}
|
|
278
|
+
finally {
|
|
279
|
+
await rm(path, { force: true });
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
//# sourceMappingURL=opa-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opa-cli.js","sourceRoot":"","sources":["../../src/lib/opa-cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client for a running OPA server (the `opa run --server` REST API).
|
|
3
|
+
*
|
|
4
|
+
* Used by tools in the `opa_*` server-management category. CLI-only
|
|
5
|
+
* tools (`rego_*`) do not touch this module.
|
|
6
|
+
*
|
|
7
|
+
* Connection failures map to `OPA_UNREACHABLE`; 401s map to `OPA_AUTH_FAILED`.
|
|
8
|
+
* Per-tool error mapping happens at the call site.
|
|
9
|
+
*/
|
|
10
|
+
import type { Config } from '../config.js';
|
|
11
|
+
export declare class OpaUnreachableError extends Error {
|
|
12
|
+
readonly url: string;
|
|
13
|
+
constructor(url: string, cause?: unknown);
|
|
14
|
+
}
|
|
15
|
+
export declare class OpaAuthError extends Error {
|
|
16
|
+
constructor();
|
|
17
|
+
}
|
|
18
|
+
export declare class OpaHttpError extends Error {
|
|
19
|
+
readonly status: number;
|
|
20
|
+
readonly body: unknown;
|
|
21
|
+
constructor(status: number, body: unknown);
|
|
22
|
+
}
|
|
23
|
+
export interface RequestOptions {
|
|
24
|
+
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
25
|
+
path: string;
|
|
26
|
+
/**
|
|
27
|
+
* JSON body to serialize. Mutually exclusive with `rawBody`.
|
|
28
|
+
*/
|
|
29
|
+
body?: unknown;
|
|
30
|
+
/**
|
|
31
|
+
* Raw string body sent verbatim. Used for endpoints that accept
|
|
32
|
+
* non-JSON content — notably `PUT /v1/policies/{id}` which expects
|
|
33
|
+
* Rego source as `text/plain`.
|
|
34
|
+
*/
|
|
35
|
+
rawBody?: string;
|
|
36
|
+
/** Content-Type for `rawBody`. Defaults to `text/plain`. */
|
|
37
|
+
rawContentType?: string;
|
|
38
|
+
query?: Record<string, string | number | boolean | undefined>;
|
|
39
|
+
headers?: Record<string, string>;
|
|
40
|
+
}
|
|
41
|
+
export declare class OpaClient {
|
|
42
|
+
private readonly config;
|
|
43
|
+
constructor(config: Config);
|
|
44
|
+
request<T = unknown>(opts: RequestOptions): Promise<T>;
|
|
45
|
+
private buildUrl;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=opa-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opa-client.d.ts","sourceRoot":"","sources":["../../src/lib/opa-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,qBAAa,mBAAoB,SAAQ,KAAK;aAE1B,GAAG,EAAE,MAAM;gBAAX,GAAG,EAAE,MAAM,EAC3B,KAAK,CAAC,EAAE,OAAO;CAMlB;AAED,qBAAa,YAAa,SAAQ,KAAK;;CAKtC;AAED,qBAAa,YAAa,SAAQ,KAAK;aAEnB,MAAM,EAAE,MAAM;aACd,IAAI,EAAE,OAAO;gBADb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO;CAKhC;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IACpD,IAAI,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,qBAAa,SAAS;IACR,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM;IAErC,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IA+D5D,OAAO,CAAC,QAAQ;CAWjB"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
export class OpaUnreachableError extends Error {
|
|
2
|
+
url;
|
|
3
|
+
constructor(url, cause) {
|
|
4
|
+
super(`OPA server unreachable at ${url}`);
|
|
5
|
+
this.url = url;
|
|
6
|
+
this.name = 'OpaUnreachableError';
|
|
7
|
+
if (cause !== undefined)
|
|
8
|
+
this.cause = cause;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export class OpaAuthError extends Error {
|
|
12
|
+
constructor() {
|
|
13
|
+
super('OPA rejected the request with 401 Unauthorized');
|
|
14
|
+
this.name = 'OpaAuthError';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export class OpaHttpError extends Error {
|
|
18
|
+
status;
|
|
19
|
+
body;
|
|
20
|
+
constructor(status, body) {
|
|
21
|
+
super(`OPA returned HTTP ${status}`);
|
|
22
|
+
this.status = status;
|
|
23
|
+
this.body = body;
|
|
24
|
+
this.name = 'OpaHttpError';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export class OpaClient {
|
|
28
|
+
config;
|
|
29
|
+
constructor(config) {
|
|
30
|
+
this.config = config;
|
|
31
|
+
}
|
|
32
|
+
async request(opts) {
|
|
33
|
+
const url = this.buildUrl(opts.path, opts.query);
|
|
34
|
+
const headers = {
|
|
35
|
+
Accept: 'application/json',
|
|
36
|
+
...(opts.headers ?? {}),
|
|
37
|
+
};
|
|
38
|
+
if (this.config.opaToken) {
|
|
39
|
+
headers['Authorization'] = `Bearer ${this.config.opaToken}`;
|
|
40
|
+
}
|
|
41
|
+
let bodyToSend;
|
|
42
|
+
if (opts.rawBody !== undefined) {
|
|
43
|
+
if (opts.body !== undefined) {
|
|
44
|
+
throw new Error('OpaClient.request: pass either `body` or `rawBody`, not both.');
|
|
45
|
+
}
|
|
46
|
+
bodyToSend = opts.rawBody;
|
|
47
|
+
if (!headers['Content-Type']) {
|
|
48
|
+
headers['Content-Type'] = opts.rawContentType ?? 'text/plain';
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else if (opts.body !== undefined) {
|
|
52
|
+
bodyToSend = JSON.stringify(opts.body);
|
|
53
|
+
if (!headers['Content-Type']) {
|
|
54
|
+
headers['Content-Type'] = 'application/json';
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const controller = new AbortController();
|
|
58
|
+
const timer = setTimeout(() => controller.abort(), this.config.httpTimeoutMs);
|
|
59
|
+
const init = {
|
|
60
|
+
method: opts.method,
|
|
61
|
+
headers,
|
|
62
|
+
signal: controller.signal,
|
|
63
|
+
};
|
|
64
|
+
if (bodyToSend !== undefined) {
|
|
65
|
+
init.body = bodyToSend;
|
|
66
|
+
}
|
|
67
|
+
let response;
|
|
68
|
+
try {
|
|
69
|
+
response = await fetch(url, init);
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
throw new OpaUnreachableError(this.config.opaUrl, e);
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
clearTimeout(timer);
|
|
76
|
+
}
|
|
77
|
+
if (response.status === 401) {
|
|
78
|
+
throw new OpaAuthError();
|
|
79
|
+
}
|
|
80
|
+
const contentType = response.headers.get('content-type') ?? '';
|
|
81
|
+
const isJson = contentType.includes('application/json');
|
|
82
|
+
const payload = isJson ? await response.json() : await response.text();
|
|
83
|
+
if (!response.ok) {
|
|
84
|
+
throw new OpaHttpError(response.status, payload);
|
|
85
|
+
}
|
|
86
|
+
return payload;
|
|
87
|
+
}
|
|
88
|
+
buildUrl(path, query) {
|
|
89
|
+
const base = this.config.opaUrl.replace(/\/+$/, '');
|
|
90
|
+
const normalizedPath = path.startsWith('/') ? path : `/${path}`;
|
|
91
|
+
const url = new URL(`${base}${normalizedPath}`);
|
|
92
|
+
if (query) {
|
|
93
|
+
for (const [key, value] of Object.entries(query)) {
|
|
94
|
+
if (value !== undefined)
|
|
95
|
+
url.searchParams.set(key, String(value));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return url.toString();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=opa-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opa-client.js","sourceRoot":"","sources":["../../src/lib/opa-client.ts"],"names":[],"mappings":"AAWA,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAE1B;IADlB,YACkB,GAAW,EAC3B,KAAe;QAEf,KAAK,CAAC,6BAA6B,GAAG,EAAE,CAAC,CAAC;QAH1B,QAAG,GAAH,GAAG,CAAQ;QAI3B,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,IAAI,KAAK,KAAK,SAAS;YAAE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IAC9C,CAAC;CACF;AAED,MAAM,OAAO,YAAa,SAAQ,KAAK;IACrC;QACE,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACxD,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AAED,MAAM,OAAO,YAAa,SAAQ,KAAK;IAEnB;IACA;IAFlB,YACkB,MAAc,EACd,IAAa;QAE7B,KAAK,CAAC,qBAAqB,MAAM,EAAE,CAAC,CAAC;QAHrB,WAAM,GAAN,MAAM,CAAQ;QACd,SAAI,GAAJ,IAAI,CAAS;QAG7B,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AAqBD,MAAM,OAAO,SAAS;IACS;IAA7B,YAA6B,MAAc;QAAd,WAAM,GAAN,MAAM,CAAQ;IAAG,CAAC;IAE/C,KAAK,CAAC,OAAO,CAAc,IAAoB;QAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAEjD,MAAM,OAAO,GAA2B;YACtC,MAAM,EAAE,kBAAkB;YAC1B,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;SACxB,CAAC;QACF,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACzB,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC9D,CAAC;QAED,IAAI,UAA8B,CAAC;QACnC,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC/B,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;YACnF,CAAC;YACD,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC;YAC1B,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;gBAC7B,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,cAAc,IAAI,YAAY,CAAC;YAChE,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACnC,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;gBAC7B,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;YAC/C,CAAC;QACH,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QAE9E,MAAM,IAAI,GAAgB;YACxB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,OAAO;YACP,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC;QACF,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACzB,CAAC;QAED,IAAI,QAAkB,CAAC;QACvB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACvD,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,MAAM,IAAI,YAAY,EAAE,CAAC;QAC3B,CAAC;QAED,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;QAC/D,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;QACxD,MAAM,OAAO,GAAY,MAAM,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAEhF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,YAAY,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACnD,CAAC;QAED,OAAO,OAAY,CAAC;IACtB,CAAC;IAEO,QAAQ,CAAC,IAAY,EAAE,KAA+B;QAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACpD,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;QAChE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,cAAc,EAAE,CAAC,CAAC;QAChD,IAAI,KAAK,EAAE,CAAC;YACV,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACjD,IAAI,KAAK,KAAK,SAAS;oBAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACpE,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC;CACF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format a tool envelope for MCP transport.
|
|
3
|
+
*
|
|
4
|
+
* The MCP SDK expects `{ content: [{ type: 'text', text: string }] }`.
|
|
5
|
+
* We serialize the envelope as JSON and apply size-based truncation.
|
|
6
|
+
*/
|
|
7
|
+
import type { ToolEnvelope } from '../types.js';
|
|
8
|
+
export interface McpToolResult {
|
|
9
|
+
[key: string]: unknown;
|
|
10
|
+
content: Array<{
|
|
11
|
+
type: 'text';
|
|
12
|
+
text: string;
|
|
13
|
+
}>;
|
|
14
|
+
isError?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare function formatEnvelope<T>(envelope: ToolEnvelope<T>, maxBytes: number): McpToolResult;
|
|
17
|
+
//# sourceMappingURL=output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/lib/output.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,WAAW,aAAa;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,CAsB5F"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function formatEnvelope(envelope, maxBytes) {
|
|
2
|
+
let serialized = JSON.stringify(envelope, null, 2);
|
|
3
|
+
if (Buffer.byteLength(serialized, 'utf8') > maxBytes) {
|
|
4
|
+
const truncatedEnvelope = {
|
|
5
|
+
...envelope,
|
|
6
|
+
truncated: true,
|
|
7
|
+
};
|
|
8
|
+
if (truncatedEnvelope.ok && truncatedEnvelope.data !== undefined) {
|
|
9
|
+
truncatedEnvelope.data = {
|
|
10
|
+
__truncated: true,
|
|
11
|
+
message: 'Response exceeded maxResponseBytes. Re-run with narrower scope, or write the output to a file path you specify.',
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
serialized = JSON.stringify(truncatedEnvelope, null, 2);
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
content: [{ type: 'text', text: serialized }],
|
|
18
|
+
isError: !envelope.ok,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/lib/output.ts"],"names":[],"mappings":"AAcA,MAAM,UAAU,cAAc,CAAI,QAAyB,EAAE,QAAgB;IAC3E,IAAI,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAEnD,IAAI,MAAM,CAAC,UAAU,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;QACrD,MAAM,iBAAiB,GAAoB;YACzC,GAAG,QAAQ;YACX,SAAS,EAAE,IAAI;SAChB,CAAC;QACF,IAAI,iBAAiB,CAAC,EAAE,IAAI,iBAAiB,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACjE,iBAAiB,CAAC,IAAI,GAAG;gBACvB,WAAW,EAAE,IAAI;gBACjB,OAAO,EACL,iHAAiH;aAC/G,CAAC;QACT,CAAC;QACD,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;QAC7C,OAAO,EAAE,CAAC,QAAQ,CAAC,EAAE;KACtB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { Config } from '../config.js';
|
|
2
|
+
import { type SpawnResult } from './subprocess.js';
|
|
3
|
+
/** Input for `regal lint`. */
|
|
4
|
+
export interface LintInput {
|
|
5
|
+
/** Inline Rego source. Mutually exclusive with `paths`. */
|
|
6
|
+
source?: string;
|
|
7
|
+
/** Paths to Rego files or directories to lint. */
|
|
8
|
+
paths?: string[];
|
|
9
|
+
/** Path to a Regal config file. */
|
|
10
|
+
configFile?: string;
|
|
11
|
+
/** Disable specific named rules (e.g. `print-or-trace-call`). */
|
|
12
|
+
disable?: string[];
|
|
13
|
+
/** Disable entire rule categories (e.g. `style`, `idiomatic`). */
|
|
14
|
+
disableCategory?: string[];
|
|
15
|
+
/** Enable specific named rules. */
|
|
16
|
+
enable?: string[];
|
|
17
|
+
/** Enable entire rule categories. */
|
|
18
|
+
enableCategory?: string[];
|
|
19
|
+
/** Disable every rule before applying enable* flags. */
|
|
20
|
+
disableAll?: boolean;
|
|
21
|
+
/** Enable every rule (overrides config defaults). */
|
|
22
|
+
enableAll?: boolean;
|
|
23
|
+
/** Glob patterns to skip. */
|
|
24
|
+
ignoreFiles?: string[];
|
|
25
|
+
/**
|
|
26
|
+
* Severity at which Regal returns a non-zero exit code (`error` or
|
|
27
|
+
* `warning`). Defaults to `error` to match Regal's own default.
|
|
28
|
+
*/
|
|
29
|
+
failLevel?: 'error' | 'warning';
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Wrapper around the local `regal` binary.
|
|
33
|
+
*
|
|
34
|
+
* Like `OpaCli`, methods do not throw on Regal-side errors — the exit
|
|
35
|
+
* code on the returned `SpawnResult` is the signal. Inline source is
|
|
36
|
+
* always written to a temp file because `regal lint` does not read
|
|
37
|
+
* from stdin.
|
|
38
|
+
*/
|
|
39
|
+
export declare class RegalCli {
|
|
40
|
+
private readonly config;
|
|
41
|
+
constructor(config: Config);
|
|
42
|
+
/**
|
|
43
|
+
* Verify the binary is present and report its version. Returns null
|
|
44
|
+
* if the binary is unreachable or output is malformed.
|
|
45
|
+
*/
|
|
46
|
+
version(): Promise<string | null>;
|
|
47
|
+
/**
|
|
48
|
+
* Lint Rego source. Stdout is JSON when `--format=json` is set
|
|
49
|
+
* (always, here). Either `source` or one or more `paths` must be
|
|
50
|
+
* provided.
|
|
51
|
+
*
|
|
52
|
+
* Regal's exit codes:
|
|
53
|
+
* - 0 — no findings at or above `failLevel`
|
|
54
|
+
* - 3 — findings present
|
|
55
|
+
* - non-zero other — Regal-internal failure (config error, etc.)
|
|
56
|
+
*/
|
|
57
|
+
lint(input: LintInput): Promise<SpawnResult>;
|
|
58
|
+
/**
|
|
59
|
+
* Run `regal` with the given argv. Tools should prefer the typed
|
|
60
|
+
* methods above; this is the escape hatch.
|
|
61
|
+
*/
|
|
62
|
+
run(args: string[]): Promise<SpawnResult>;
|
|
63
|
+
private withTempSource;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=regal-cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regal-cli.d.ts","sourceRoot":"","sources":["../../src/lib/regal-cli.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9D,8BAA8B;AAC9B,MAAM,WAAW,SAAS;IACxB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,mCAAmC;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,kEAAkE;IAClE,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,qCAAqC;IACrC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,wDAAwD;IACxD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,qDAAqD;IACrD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACjC;AAED;;;;;;;GAOG;AACH,qBAAa,QAAQ;IACP,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM;IAE3C;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAQvC;;;;;;;;;OASG;IACG,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC;IAsBlD;;;OAGG;IACG,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;YAUjC,cAAc;CAS7B"}
|