@intelmesh/sdk 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/.github/scripts/compute-disttag.sh +47 -0
- package/.github/workflows/release.yml +206 -0
- package/.husky/commit-msg +1 -0
- package/.husky/pre-commit +2 -0
- package/.prettierrc +8 -0
- package/CLAUDE.md +37 -0
- package/LICENSE +21 -0
- package/commitlint.config.cjs +3 -0
- package/dist/index.d.ts +1293 -0
- package/dist/index.js +1651 -0
- package/docs/superpowers/plans/2026-04-10-release-pipeline.md +798 -0
- package/docs/superpowers/specs/2026-04-10-release-pipeline-design.md +309 -0
- package/eslint.config.mjs +38 -0
- package/package.json +72 -0
- package/src/builders/event.ts +72 -0
- package/src/builders/rule.ts +143 -0
- package/src/client/errors.ts +171 -0
- package/src/client/http.ts +209 -0
- package/src/client/intelmesh.ts +57 -0
- package/src/client/pagination.ts +50 -0
- package/src/generated/types.ts +11 -0
- package/src/index.ts +106 -0
- package/src/provision/index.ts +6 -0
- package/src/provision/provisioner.ts +326 -0
- package/src/provision/rule-builder.ts +193 -0
- package/src/resources/apikeys.ts +63 -0
- package/src/resources/audit.ts +29 -0
- package/src/resources/evaluations.ts +38 -0
- package/src/resources/events.ts +61 -0
- package/src/resources/lists.ts +91 -0
- package/src/resources/phases.ts +71 -0
- package/src/resources/rules.ts +98 -0
- package/src/resources/scopes.ts +71 -0
- package/src/resources/scores.ts +63 -0
- package/src/testkit/assertion.ts +76 -0
- package/src/testkit/harness.ts +252 -0
- package/src/testkit/index.ts +7 -0
- package/src/types.ts +330 -0
- package/tests/client/errors.test.ts +159 -0
- package/tests/provision/provisioner.test.ts +311 -0
- package/tests/scripts/compute-disttag.test.ts +178 -0
- package/tests/testkit/harness.test.ts +291 -0
- package/tsconfig.eslint.json +8 -0
- package/tsconfig.json +29 -0
- package/vitest.config.ts +14 -0
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Provisioner — declarative resource provisioning for IntelMesh
|
|
3
|
+
// Mirrors the Go SDK's provision.Provisioner exactly.
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
|
|
6
|
+
import type { IntelMesh } from '../client/intelmesh.js';
|
|
7
|
+
import { ProvisionRuleBuilder } from './rule-builder.js';
|
|
8
|
+
|
|
9
|
+
/** Resource kinds in provisioning order. */
|
|
10
|
+
const STEP_PHASE = 0 as const;
|
|
11
|
+
const STEP_SCOPE = 1 as const;
|
|
12
|
+
const STEP_LIST = 2 as const;
|
|
13
|
+
const STEP_RULE = 3 as const;
|
|
14
|
+
|
|
15
|
+
type StepKind = typeof STEP_PHASE | typeof STEP_SCOPE | typeof STEP_LIST | typeof STEP_RULE;
|
|
16
|
+
|
|
17
|
+
/** A single resource to create during apply. */
|
|
18
|
+
interface Step {
|
|
19
|
+
readonly kind: StepKind;
|
|
20
|
+
readonly name: string;
|
|
21
|
+
readonly position: number;
|
|
22
|
+
readonly applicableWhen: string;
|
|
23
|
+
readonly jsonPath: string;
|
|
24
|
+
readonly ruleBuilder: ProvisionRuleBuilder | undefined;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Builds and executes a declarative resource plan against the IntelMesh API.
|
|
29
|
+
* Resources are created in dependency order (phases, scopes, lists, rules)
|
|
30
|
+
* and torn down in reverse.
|
|
31
|
+
*/
|
|
32
|
+
export class Provisioner {
|
|
33
|
+
private readonly client: IntelMesh;
|
|
34
|
+
private readonly steps: Step[] = [];
|
|
35
|
+
|
|
36
|
+
private readonly phases = new Map<string, string>();
|
|
37
|
+
private readonly scopes = new Map<string, string>();
|
|
38
|
+
private readonly lists = new Map<string, string>();
|
|
39
|
+
private readonly rules = new Map<string, string>();
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Creates a new Provisioner backed by the given SDK client.
|
|
43
|
+
* @param client - The IntelMesh client instance.
|
|
44
|
+
*/
|
|
45
|
+
constructor(client: IntelMesh) {
|
|
46
|
+
this.client = client;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Registers a pipeline phase to be created.
|
|
51
|
+
* @param name - The phase name.
|
|
52
|
+
* @param position - The phase position (execution order).
|
|
53
|
+
* @returns This provisioner for chaining.
|
|
54
|
+
*/
|
|
55
|
+
phase(name: string, position: number): this {
|
|
56
|
+
this.steps.push({
|
|
57
|
+
kind: STEP_PHASE,
|
|
58
|
+
name,
|
|
59
|
+
position,
|
|
60
|
+
applicableWhen: '',
|
|
61
|
+
jsonPath: '',
|
|
62
|
+
ruleBuilder: undefined,
|
|
63
|
+
});
|
|
64
|
+
return this;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Registers a pipeline phase with an applicable_when CEL expression.
|
|
69
|
+
* @param name - The phase name.
|
|
70
|
+
* @param position - The phase position (execution order).
|
|
71
|
+
* @param applicableWhen - CEL expression controlling when this phase runs.
|
|
72
|
+
* @returns This provisioner for chaining.
|
|
73
|
+
*/
|
|
74
|
+
phaseWithFilter(name: string, position: number, applicableWhen: string): this {
|
|
75
|
+
this.steps.push({
|
|
76
|
+
kind: STEP_PHASE,
|
|
77
|
+
name,
|
|
78
|
+
position,
|
|
79
|
+
applicableWhen,
|
|
80
|
+
jsonPath: '',
|
|
81
|
+
ruleBuilder: undefined,
|
|
82
|
+
});
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Registers a scope to be created.
|
|
88
|
+
* @param name - The scope name.
|
|
89
|
+
* @param jsonPath - The JSON path expression.
|
|
90
|
+
* @returns This provisioner for chaining.
|
|
91
|
+
*/
|
|
92
|
+
scope(name: string, jsonPath: string): this {
|
|
93
|
+
this.steps.push({
|
|
94
|
+
kind: STEP_SCOPE,
|
|
95
|
+
name,
|
|
96
|
+
position: 0,
|
|
97
|
+
applicableWhen: '',
|
|
98
|
+
jsonPath,
|
|
99
|
+
ruleBuilder: undefined,
|
|
100
|
+
});
|
|
101
|
+
return this;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Registers a named list to be created.
|
|
106
|
+
* @param name - The list name.
|
|
107
|
+
* @returns This provisioner for chaining.
|
|
108
|
+
*/
|
|
109
|
+
list(name: string): this {
|
|
110
|
+
this.steps.push({
|
|
111
|
+
kind: STEP_LIST,
|
|
112
|
+
name,
|
|
113
|
+
position: 0,
|
|
114
|
+
applicableWhen: '',
|
|
115
|
+
jsonPath: '',
|
|
116
|
+
ruleBuilder: undefined,
|
|
117
|
+
});
|
|
118
|
+
return this;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Starts building a rule and returns a ProvisionRuleBuilder.
|
|
123
|
+
* @param name - The rule name.
|
|
124
|
+
* @returns A rule builder for chaining.
|
|
125
|
+
*/
|
|
126
|
+
rule(name: string): ProvisionRuleBuilder {
|
|
127
|
+
return new ProvisionRuleBuilder(this, name);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Adds a completed rule step from the rule builder.
|
|
132
|
+
* @param rb - The completed rule builder.
|
|
133
|
+
* @returns This provisioner for chaining.
|
|
134
|
+
* @internal
|
|
135
|
+
*/
|
|
136
|
+
_addRuleStep(rb: ProvisionRuleBuilder): this {
|
|
137
|
+
this.steps.push({
|
|
138
|
+
kind: STEP_RULE,
|
|
139
|
+
name: rb.ruleName,
|
|
140
|
+
position: 0,
|
|
141
|
+
applicableWhen: '',
|
|
142
|
+
jsonPath: '',
|
|
143
|
+
ruleBuilder: rb,
|
|
144
|
+
});
|
|
145
|
+
return this;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Creates all registered resources via the API in registration order.
|
|
150
|
+
* Throws on the first failure.
|
|
151
|
+
*/
|
|
152
|
+
async apply(): Promise<void> {
|
|
153
|
+
for (const step of this.steps) {
|
|
154
|
+
await this.applyStep(step);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Deletes all created resources in reverse dependency order:
|
|
160
|
+
* rules, lists, scopes, phases.
|
|
161
|
+
* Collects errors but continues deleting; throws the first error at the end.
|
|
162
|
+
*/
|
|
163
|
+
async teardown(): Promise<void> {
|
|
164
|
+
let firstError: Error | undefined;
|
|
165
|
+
|
|
166
|
+
const record = (err: unknown): void => {
|
|
167
|
+
if (!firstError && err instanceof Error) {
|
|
168
|
+
firstError = err;
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
await this.deleteAll(this.rules, (id) => this.client.rules.delete(id), record);
|
|
173
|
+
await this.deleteAll(this.lists, (id) => this.client.lists.delete(id), record);
|
|
174
|
+
await this.deleteAll(this.scopes, (id) => this.client.scopes.delete(id), record);
|
|
175
|
+
await this.deleteAll(this.phases, (id) => this.client.phases.delete(id), record);
|
|
176
|
+
|
|
177
|
+
if (firstError) {
|
|
178
|
+
throw firstError;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Returns the provisioned ID for the named phase.
|
|
184
|
+
* @param name - The phase name.
|
|
185
|
+
* @returns The phase ID, or empty string if not found.
|
|
186
|
+
*/
|
|
187
|
+
phaseId(name: string): string {
|
|
188
|
+
return this.phases.get(name) ?? '';
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Returns the provisioned ID for the named list.
|
|
193
|
+
* @param name - The list name.
|
|
194
|
+
* @returns The list ID, or empty string if not found.
|
|
195
|
+
*/
|
|
196
|
+
listId(name: string): string {
|
|
197
|
+
return this.lists.get(name) ?? '';
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Returns the provisioned ID for the named scope.
|
|
202
|
+
* @param name - The scope name.
|
|
203
|
+
* @returns The scope ID, or empty string if not found.
|
|
204
|
+
*/
|
|
205
|
+
scopeId(name: string): string {
|
|
206
|
+
return this.scopes.get(name) ?? '';
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Returns the provisioned ID for the named rule.
|
|
211
|
+
* @param name - The rule name.
|
|
212
|
+
* @returns The rule ID, or empty string if not found.
|
|
213
|
+
*/
|
|
214
|
+
ruleId(name: string): string {
|
|
215
|
+
return this.rules.get(name) ?? '';
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Dispatches a single step to the appropriate creator.
|
|
220
|
+
* @param step
|
|
221
|
+
*/
|
|
222
|
+
private async applyStep(step: Step): Promise<void> {
|
|
223
|
+
switch (step.kind) {
|
|
224
|
+
case STEP_PHASE:
|
|
225
|
+
return this.createPhase(step);
|
|
226
|
+
case STEP_SCOPE:
|
|
227
|
+
return this.createScope(step);
|
|
228
|
+
case STEP_LIST:
|
|
229
|
+
return this.createList(step);
|
|
230
|
+
case STEP_RULE:
|
|
231
|
+
return this.createRule(step);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Creates a phase and stores its ID.
|
|
237
|
+
* @param step
|
|
238
|
+
*/
|
|
239
|
+
private async createPhase(step: Step): Promise<void> {
|
|
240
|
+
const req: { name: string; position: number; applicable_when?: string } = {
|
|
241
|
+
name: step.name,
|
|
242
|
+
position: step.position,
|
|
243
|
+
};
|
|
244
|
+
if (step.applicableWhen) {
|
|
245
|
+
req.applicable_when = step.applicableWhen;
|
|
246
|
+
}
|
|
247
|
+
const phase = await this.client.phases.create(req);
|
|
248
|
+
this.phases.set(step.name, phase.id);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Creates a scope and stores its ID.
|
|
253
|
+
* @param step
|
|
254
|
+
*/
|
|
255
|
+
private async createScope(step: Step): Promise<void> {
|
|
256
|
+
const scope = await this.client.scopes.create({
|
|
257
|
+
name: step.name,
|
|
258
|
+
json_path: step.jsonPath,
|
|
259
|
+
});
|
|
260
|
+
this.scopes.set(step.name, scope.id);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Creates a list and stores its ID.
|
|
265
|
+
* @param step
|
|
266
|
+
*/
|
|
267
|
+
private async createList(step: Step): Promise<void> {
|
|
268
|
+
const list = await this.client.lists.create({
|
|
269
|
+
name: step.name,
|
|
270
|
+
description: '',
|
|
271
|
+
});
|
|
272
|
+
this.lists.set(step.name, list.id);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Creates a rule after resolving its phase name to an ID.
|
|
277
|
+
* @param step
|
|
278
|
+
*/
|
|
279
|
+
private async createRule(step: Step): Promise<void> {
|
|
280
|
+
const rb = step.ruleBuilder;
|
|
281
|
+
if (!rb) {
|
|
282
|
+
throw new Error(`provision: rule step "${step.name}" has no builder`);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const phaseID = this.phases.get(rb.phaseName);
|
|
286
|
+
if (!phaseID) {
|
|
287
|
+
throw new Error(`provision rule "${rb.ruleName}": phase not found: ${rb.phaseName}`);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const rule = await this.client.rules.create({
|
|
291
|
+
name: rb.ruleName,
|
|
292
|
+
phase_id: phaseID,
|
|
293
|
+
priority: rb.rulePriority,
|
|
294
|
+
applicable_when: rb.applicable,
|
|
295
|
+
expression: rb.expression,
|
|
296
|
+
actions: rb.buildActions(),
|
|
297
|
+
enabled: true,
|
|
298
|
+
dry_run: rb.isDryRun,
|
|
299
|
+
});
|
|
300
|
+
this.rules.set(rb.ruleName, rule.id);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Deletes all resources in a map, recording errors.
|
|
305
|
+
* @param ids
|
|
306
|
+
* @param deleteFn
|
|
307
|
+
* @param record
|
|
308
|
+
*/
|
|
309
|
+
private async deleteAll(
|
|
310
|
+
ids: Map<string, string>,
|
|
311
|
+
deleteFn: (id: string) => Promise<void>,
|
|
312
|
+
record: (err: unknown) => void,
|
|
313
|
+
): Promise<void> {
|
|
314
|
+
for (const [name, id] of ids) {
|
|
315
|
+
try {
|
|
316
|
+
await deleteFn(id);
|
|
317
|
+
} catch (err: unknown) {
|
|
318
|
+
record(
|
|
319
|
+
err instanceof Error
|
|
320
|
+
? new Error(`deleting ${name} (${id}): ${err.message}`)
|
|
321
|
+
: new Error(`deleting ${name} (${id}): unknown error`),
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Fluent RuleBuilder for provisioner — mirrors Go SDK's provision.RuleBuilder
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
import type { Actions, Decision, Flow, ListMutation, ScoreOperation, Severity } from '../types.js';
|
|
6
|
+
import type { Provisioner } from './provisioner.js';
|
|
7
|
+
|
|
8
|
+
/** Internal mutation specification. */
|
|
9
|
+
interface MutationSpec {
|
|
10
|
+
readonly mutationType: string;
|
|
11
|
+
readonly listName: string;
|
|
12
|
+
readonly valuePath: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Fluent builder for constructing rules within a Provisioner.
|
|
17
|
+
* Returned by `Provisioner.rule()`, completed by calling `.done()`.
|
|
18
|
+
*/
|
|
19
|
+
export class ProvisionRuleBuilder {
|
|
20
|
+
private readonly parent: Provisioner;
|
|
21
|
+
|
|
22
|
+
/** @internal */ readonly ruleName: string;
|
|
23
|
+
/** @internal */ phaseName = '';
|
|
24
|
+
/** @internal */ rulePriority = 0;
|
|
25
|
+
/** @internal */ applicable = '';
|
|
26
|
+
/** @internal */ expression = '';
|
|
27
|
+
/** @internal */ ruleDecision: Decision | undefined;
|
|
28
|
+
/** @internal */ ruleScore: ScoreOperation | undefined;
|
|
29
|
+
/** @internal */ ruleFlow: Flow | undefined;
|
|
30
|
+
/** @internal */ ruleMutations: MutationSpec[] = [];
|
|
31
|
+
/** @internal */ isDryRun = false;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Constructs a new ProvisionRuleBuilder.
|
|
35
|
+
* @param parent
|
|
36
|
+
* @param name
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
39
|
+
constructor(parent: Provisioner, name: string) {
|
|
40
|
+
this.parent = parent;
|
|
41
|
+
this.ruleName = name;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Sets the phase for the rule (by provisioner name, not ID).
|
|
46
|
+
* @param name - The phase name as registered with the provisioner.
|
|
47
|
+
* @returns This builder for chaining.
|
|
48
|
+
*/
|
|
49
|
+
inPhase(name: string): this {
|
|
50
|
+
this.phaseName = name;
|
|
51
|
+
return this;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Sets the rule priority (lower number = higher priority).
|
|
56
|
+
* @param p - The priority value.
|
|
57
|
+
* @returns This builder for chaining.
|
|
58
|
+
*/
|
|
59
|
+
priority(p: number): this {
|
|
60
|
+
this.rulePriority = p;
|
|
61
|
+
return this;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Sets the applicability expression.
|
|
66
|
+
* @param expr - The CEL expression for applicability.
|
|
67
|
+
* @returns This builder for chaining.
|
|
68
|
+
*/
|
|
69
|
+
applicableWhen(expr: string): this {
|
|
70
|
+
this.applicable = expr;
|
|
71
|
+
return this;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Sets the matching expression.
|
|
76
|
+
* @param expr - The CEL expression for matching.
|
|
77
|
+
* @returns This builder for chaining.
|
|
78
|
+
*/
|
|
79
|
+
when(expr: string): this {
|
|
80
|
+
this.expression = expr;
|
|
81
|
+
return this;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Sets the decision action and severity.
|
|
86
|
+
* @param action - The action string (e.g. "block").
|
|
87
|
+
* @param severity - The severity level.
|
|
88
|
+
* @returns This builder for chaining.
|
|
89
|
+
*/
|
|
90
|
+
decide(action: string, severity: Severity): this {
|
|
91
|
+
this.ruleDecision = { action, severity };
|
|
92
|
+
return this;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Adds a score delta for the rule.
|
|
97
|
+
* @param delta - The score points to add.
|
|
98
|
+
* @returns This builder for chaining.
|
|
99
|
+
*/
|
|
100
|
+
addScore(delta: number): this {
|
|
101
|
+
this.ruleScore = { add: delta };
|
|
102
|
+
return this;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Sets flow to halt.
|
|
107
|
+
* @returns This builder for chaining.
|
|
108
|
+
*/
|
|
109
|
+
halt(): this {
|
|
110
|
+
this.ruleFlow = 'halt';
|
|
111
|
+
return this;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Sets flow to continue.
|
|
116
|
+
* @returns This builder for chaining.
|
|
117
|
+
*/
|
|
118
|
+
continue(): this {
|
|
119
|
+
this.ruleFlow = 'continue';
|
|
120
|
+
return this;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Sets flow to skip_phase.
|
|
125
|
+
* @returns This builder for chaining.
|
|
126
|
+
*/
|
|
127
|
+
skipPhase(): this {
|
|
128
|
+
this.ruleFlow = 'skip_phase';
|
|
129
|
+
return this;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Adds a list mutation to the rule.
|
|
134
|
+
* @param mutType - The mutation type (e.g. "list.add").
|
|
135
|
+
* @param listName - The list name.
|
|
136
|
+
* @param valuePath - The value path expression.
|
|
137
|
+
* @returns This builder for chaining.
|
|
138
|
+
*/
|
|
139
|
+
mutateList(mutType: string, listName: string, valuePath: string): this {
|
|
140
|
+
this.ruleMutations.push({ mutationType: mutType, listName, valuePath });
|
|
141
|
+
return this;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Enables dry-run mode for the rule.
|
|
146
|
+
* @returns This builder for chaining.
|
|
147
|
+
*/
|
|
148
|
+
dryRun(): this {
|
|
149
|
+
this.isDryRun = true;
|
|
150
|
+
return this;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Finishes building the rule and returns to the parent provisioner.
|
|
155
|
+
* @returns The parent Provisioner for chaining.
|
|
156
|
+
*/
|
|
157
|
+
done(): Provisioner {
|
|
158
|
+
return this.parent._addRuleStep(this);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Constructs the SDK Actions from the builder state.
|
|
163
|
+
* @returns The Actions object for the API request.
|
|
164
|
+
* @internal
|
|
165
|
+
*/
|
|
166
|
+
buildActions(): Actions {
|
|
167
|
+
const actions: {
|
|
168
|
+
decision?: Decision;
|
|
169
|
+
score?: ScoreOperation;
|
|
170
|
+
flow?: Flow;
|
|
171
|
+
mutations?: ListMutation[];
|
|
172
|
+
} = {};
|
|
173
|
+
|
|
174
|
+
if (this.ruleDecision) {
|
|
175
|
+
actions.decision = this.ruleDecision;
|
|
176
|
+
}
|
|
177
|
+
if (this.ruleScore) {
|
|
178
|
+
actions.score = this.ruleScore;
|
|
179
|
+
}
|
|
180
|
+
if (this.ruleFlow) {
|
|
181
|
+
actions.flow = this.ruleFlow;
|
|
182
|
+
}
|
|
183
|
+
if (this.ruleMutations.length > 0) {
|
|
184
|
+
actions.mutations = this.ruleMutations.map((m) => ({
|
|
185
|
+
type: m.mutationType,
|
|
186
|
+
target: m.listName,
|
|
187
|
+
value_path: m.valuePath,
|
|
188
|
+
}));
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return actions;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// API Keys resource — CRUD
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
import type { HttpClient } from '../client/http.js';
|
|
6
|
+
import type {
|
|
7
|
+
APIKey,
|
|
8
|
+
CreateAPIKeyRequest,
|
|
9
|
+
CreateAPIKeyResponse,
|
|
10
|
+
PaginatedResponse,
|
|
11
|
+
PaginationParams,
|
|
12
|
+
UpdateAPIKeyRequest,
|
|
13
|
+
} from '../types.js';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Resource for API key management.
|
|
17
|
+
*/
|
|
18
|
+
export class APIKeys {
|
|
19
|
+
private readonly http: HttpClient;
|
|
20
|
+
|
|
21
|
+
constructor(http: HttpClient) {
|
|
22
|
+
this.http = http;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Lists all API keys with cursor-based pagination.
|
|
27
|
+
* @param params - Optional pagination parameters.
|
|
28
|
+
* @returns A paginated list of API keys.
|
|
29
|
+
*/
|
|
30
|
+
async list(params: PaginationParams = {}): Promise<PaginatedResponse<APIKey>> {
|
|
31
|
+
return this.http.get<PaginatedResponse<APIKey>>('/api/v1/api-keys', {
|
|
32
|
+
cursor: params.cursor,
|
|
33
|
+
limit: params.limit,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Creates a new API key. The plain key is returned only at creation time.
|
|
39
|
+
* @param request - The API key creation payload.
|
|
40
|
+
* @returns The created API key with the plain key value.
|
|
41
|
+
*/
|
|
42
|
+
async create(request: CreateAPIKeyRequest): Promise<CreateAPIKeyResponse> {
|
|
43
|
+
return this.http.post<CreateAPIKeyResponse>('/api/v1/api-keys', request);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Updates an existing API key by ID.
|
|
48
|
+
* @param id - The API key ID.
|
|
49
|
+
* @param request - The update payload.
|
|
50
|
+
* @returns The updated API key.
|
|
51
|
+
*/
|
|
52
|
+
async update(id: string, request: UpdateAPIKeyRequest): Promise<APIKey> {
|
|
53
|
+
return this.http.put<APIKey>(`/api/v1/api-keys/${id}`, request);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Deletes an API key by ID.
|
|
58
|
+
* @param id - The API key ID.
|
|
59
|
+
*/
|
|
60
|
+
async delete(id: string): Promise<void> {
|
|
61
|
+
await this.http.delete<unknown>(`/api/v1/api-keys/${id}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Audit resource — list
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
import type { HttpClient } from '../client/http.js';
|
|
6
|
+
import type { EvaluationLog, PaginatedResponse, PaginationParams } from '../types.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Resource for audit log access.
|
|
10
|
+
*/
|
|
11
|
+
export class Audit {
|
|
12
|
+
private readonly http: HttpClient;
|
|
13
|
+
|
|
14
|
+
constructor(http: HttpClient) {
|
|
15
|
+
this.http = http;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Lists audit logs with cursor-based pagination.
|
|
20
|
+
* @param params - Optional pagination parameters.
|
|
21
|
+
* @returns A paginated list of audit entries.
|
|
22
|
+
*/
|
|
23
|
+
async list(params: PaginationParams = {}): Promise<PaginatedResponse<EvaluationLog>> {
|
|
24
|
+
return this.http.get<PaginatedResponse<EvaluationLog>>('/api/v1/audit', {
|
|
25
|
+
cursor: params.cursor,
|
|
26
|
+
limit: params.limit,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Evaluations resource — list, get
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
import type { HttpClient } from '../client/http.js';
|
|
6
|
+
import type { EvaluationLog, PaginatedResponse, PaginationParams } from '../types.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Resource for evaluation log inspection.
|
|
10
|
+
*/
|
|
11
|
+
export class Evaluations {
|
|
12
|
+
private readonly http: HttpClient;
|
|
13
|
+
|
|
14
|
+
constructor(http: HttpClient) {
|
|
15
|
+
this.http = http;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Lists evaluation logs with cursor-based pagination.
|
|
20
|
+
* @param params - Optional pagination parameters.
|
|
21
|
+
* @returns A paginated list of evaluation logs.
|
|
22
|
+
*/
|
|
23
|
+
async list(params: PaginationParams = {}): Promise<PaginatedResponse<EvaluationLog>> {
|
|
24
|
+
return this.http.get<PaginatedResponse<EvaluationLog>>('/api/v1/evaluations', {
|
|
25
|
+
cursor: params.cursor,
|
|
26
|
+
limit: params.limit,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Retrieves a single evaluation log by ID.
|
|
32
|
+
* @param id - The evaluation log ID.
|
|
33
|
+
* @returns The evaluation log with full pipeline trace.
|
|
34
|
+
*/
|
|
35
|
+
async get(id: string): Promise<EvaluationLog> {
|
|
36
|
+
return this.http.get<EvaluationLog>(`/api/v1/evaluations/${id}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Events resource — ingest, ingestAsync, ingestOnly, simulate
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
import type { HttpClient } from '../client/http.js';
|
|
6
|
+
import type { IngestRequest, IngestResult, SuccessResponse } from '../types.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Resource for event ingestion operations.
|
|
10
|
+
*/
|
|
11
|
+
export class Events {
|
|
12
|
+
private readonly http: HttpClient;
|
|
13
|
+
|
|
14
|
+
constructor(http: HttpClient) {
|
|
15
|
+
this.http = http;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Ingests an event synchronously and returns the decision.
|
|
20
|
+
* @param request - The ingest request payload.
|
|
21
|
+
* @returns The ingestion result with decision and score.
|
|
22
|
+
*/
|
|
23
|
+
async ingest(request: IngestRequest): Promise<IngestResult> {
|
|
24
|
+
return this.http.post<IngestResult>('/api/v1/events/ingest', request);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Ingests an event asynchronously (fire-and-forget with acknowledgement).
|
|
29
|
+
* @param request - The ingest request payload.
|
|
30
|
+
* @returns The event ID assigned by the server.
|
|
31
|
+
*/
|
|
32
|
+
async ingestAsync(request: IngestRequest): Promise<string> {
|
|
33
|
+
const result = await this.http.post<SuccessResponse<{ event_id: string }>>(
|
|
34
|
+
'/api/v1/events/ingest-async',
|
|
35
|
+
request,
|
|
36
|
+
);
|
|
37
|
+
return result.data.event_id;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Ingests an event for storage only, without evaluation.
|
|
42
|
+
* @param request - The ingest request payload.
|
|
43
|
+
* @returns The event ID assigned by the server.
|
|
44
|
+
*/
|
|
45
|
+
async ingestOnly(request: IngestRequest): Promise<string> {
|
|
46
|
+
const result = await this.http.post<SuccessResponse<{ event_id: string }>>(
|
|
47
|
+
'/api/v1/events/ingest-only',
|
|
48
|
+
request,
|
|
49
|
+
);
|
|
50
|
+
return result.data.event_id;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Simulates event evaluation without persisting (dry-run).
|
|
55
|
+
* @param request - The ingest request payload.
|
|
56
|
+
* @returns The simulated result with decision and trace.
|
|
57
|
+
*/
|
|
58
|
+
async simulate(request: IngestRequest): Promise<IngestResult> {
|
|
59
|
+
return this.http.post<IngestResult>('/api/v1/events/simulate', request);
|
|
60
|
+
}
|
|
61
|
+
}
|