@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,171 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Typed error hierarchy for IntelMesh API responses
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
/** Base error for all IntelMesh SDK errors. */
|
|
6
|
+
export class IntelMeshError extends Error {
|
|
7
|
+
/** HTTP status code, if applicable. */
|
|
8
|
+
readonly status: number;
|
|
9
|
+
/** Machine-readable error code from the API. */
|
|
10
|
+
readonly code: string;
|
|
11
|
+
|
|
12
|
+
constructor(message: string, status: number, code: string) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.name = 'IntelMeshError';
|
|
15
|
+
this.status = status;
|
|
16
|
+
this.code = code;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** 400 — The request was malformed or invalid. */
|
|
21
|
+
export class ValidationError extends IntelMeshError {
|
|
22
|
+
constructor(message: string, code = 'VALIDATION_ERROR') {
|
|
23
|
+
super(message, 400, code);
|
|
24
|
+
this.name = 'ValidationError';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** 404 — The requested resource was not found. */
|
|
29
|
+
export class NotFoundError extends IntelMeshError {
|
|
30
|
+
constructor(message: string, code = 'NOT_FOUND') {
|
|
31
|
+
super(message, 404, code);
|
|
32
|
+
this.name = 'NotFoundError';
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** 401 — Authentication failed or missing. */
|
|
37
|
+
export class UnauthorizedError extends IntelMeshError {
|
|
38
|
+
constructor(message: string, code = 'UNAUTHORIZED') {
|
|
39
|
+
super(message, 401, code);
|
|
40
|
+
this.name = 'UnauthorizedError';
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** 403 — Authenticated but insufficient permissions. */
|
|
45
|
+
export class ForbiddenError extends IntelMeshError {
|
|
46
|
+
constructor(message: string, code = 'FORBIDDEN') {
|
|
47
|
+
super(message, 403, code);
|
|
48
|
+
this.name = 'ForbiddenError';
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** 500 — Internal server error. */
|
|
53
|
+
export class InternalError extends IntelMeshError {
|
|
54
|
+
constructor(message: string, code = 'INTERNAL_ERROR') {
|
|
55
|
+
super(message, 500, code);
|
|
56
|
+
this.name = 'InternalError';
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** 503 — Service temporarily unavailable. */
|
|
61
|
+
export class UnavailableError extends IntelMeshError {
|
|
62
|
+
constructor(message: string, code = 'UNAVAILABLE') {
|
|
63
|
+
super(message, 503, code);
|
|
64
|
+
this.name = 'UnavailableError';
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Network-level failure (no HTTP response received). */
|
|
69
|
+
export class NetworkError extends IntelMeshError {
|
|
70
|
+
constructor(message: string) {
|
|
71
|
+
super(message, 0, 'NETWORK_ERROR');
|
|
72
|
+
this.name = 'NetworkError';
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Failed to parse the API response body. */
|
|
77
|
+
export class ParseError extends IntelMeshError {
|
|
78
|
+
constructor(message: string) {
|
|
79
|
+
super(message, 0, 'PARSE_ERROR');
|
|
80
|
+
this.name = 'ParseError';
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
// Type guard helpers
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Checks if an error is a NotFoundError.
|
|
90
|
+
* @param error - The error to check.
|
|
91
|
+
* @returns True if the error is a NotFoundError.
|
|
92
|
+
*/
|
|
93
|
+
export function isNotFound(error: unknown): error is NotFoundError {
|
|
94
|
+
return error instanceof NotFoundError;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Checks if an error is a ValidationError.
|
|
99
|
+
* @param error - The error to check.
|
|
100
|
+
* @returns True if the error is a ValidationError.
|
|
101
|
+
*/
|
|
102
|
+
export function isValidation(error: unknown): error is ValidationError {
|
|
103
|
+
return error instanceof ValidationError;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Checks if an error is an UnauthorizedError.
|
|
108
|
+
* @param error - The error to check.
|
|
109
|
+
* @returns True if the error is an UnauthorizedError.
|
|
110
|
+
*/
|
|
111
|
+
export function isUnauthorized(error: unknown): error is UnauthorizedError {
|
|
112
|
+
return error instanceof UnauthorizedError;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Checks if an error is a ForbiddenError.
|
|
117
|
+
* @param error - The error to check.
|
|
118
|
+
* @returns True if the error is a ForbiddenError.
|
|
119
|
+
*/
|
|
120
|
+
export function isForbidden(error: unknown): error is ForbiddenError {
|
|
121
|
+
return error instanceof ForbiddenError;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Checks if an error is a NetworkError.
|
|
126
|
+
* @param error - The error to check.
|
|
127
|
+
* @returns True if the error is a NetworkError.
|
|
128
|
+
*/
|
|
129
|
+
export function isNetwork(error: unknown): error is NetworkError {
|
|
130
|
+
return error instanceof NetworkError;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Checks if an error is any IntelMeshError.
|
|
135
|
+
* @param error - The error to check.
|
|
136
|
+
* @returns True if the error is an IntelMeshError.
|
|
137
|
+
*/
|
|
138
|
+
export function isIntelMeshError(error: unknown): error is IntelMeshError {
|
|
139
|
+
return error instanceof IntelMeshError;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// ---------------------------------------------------------------------------
|
|
143
|
+
// Status code to error mapping
|
|
144
|
+
// ---------------------------------------------------------------------------
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Maps an HTTP status code and error body to a typed error.
|
|
148
|
+
* @param status - The HTTP status code.
|
|
149
|
+
* @param message - The error message from the API.
|
|
150
|
+
* @param code - The machine-readable error code from the API.
|
|
151
|
+
* @returns The appropriate typed error instance.
|
|
152
|
+
*/
|
|
153
|
+
export function mapStatusToError(status: number, message: string, code: string): IntelMeshError {
|
|
154
|
+
switch (status) {
|
|
155
|
+
case 400:
|
|
156
|
+
return new ValidationError(message, code);
|
|
157
|
+
case 401:
|
|
158
|
+
return new UnauthorizedError(message, code);
|
|
159
|
+
case 403:
|
|
160
|
+
return new ForbiddenError(message, code);
|
|
161
|
+
case 404:
|
|
162
|
+
return new NotFoundError(message, code);
|
|
163
|
+
case 503:
|
|
164
|
+
return new UnavailableError(message, code);
|
|
165
|
+
default:
|
|
166
|
+
if (status >= 500) {
|
|
167
|
+
return new InternalError(message, code);
|
|
168
|
+
}
|
|
169
|
+
return new IntelMeshError(message, status, code);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Base HTTP client — fetch wrapper with auth, JSON parsing, error mapping
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
import type { ClientConfig, ErrorResponse, SuccessResponse } from '../types.js';
|
|
6
|
+
import { mapStatusToError, NetworkError, ParseError } from './errors.js';
|
|
7
|
+
|
|
8
|
+
/** HTTP methods supported by the client. */
|
|
9
|
+
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
|
|
10
|
+
|
|
11
|
+
/** Options for a single HTTP request. */
|
|
12
|
+
interface RequestOptions {
|
|
13
|
+
readonly method: HttpMethod;
|
|
14
|
+
readonly path: string;
|
|
15
|
+
readonly body?: unknown;
|
|
16
|
+
readonly query?: Readonly<Record<string, string | number | undefined>>;
|
|
17
|
+
readonly signal?: AbortSignal;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Default request timeout in milliseconds. */
|
|
21
|
+
const DEFAULT_TIMEOUT = 30_000;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Low-level HTTP client for the IntelMesh API.
|
|
25
|
+
* Handles authentication, serialization, and error mapping.
|
|
26
|
+
*/
|
|
27
|
+
export class HttpClient {
|
|
28
|
+
private readonly baseUrl: string;
|
|
29
|
+
private readonly apiKey: string;
|
|
30
|
+
private readonly timeout: number;
|
|
31
|
+
private readonly fetchFn: typeof globalThis.fetch;
|
|
32
|
+
|
|
33
|
+
constructor(config: ClientConfig) {
|
|
34
|
+
this.baseUrl = config.baseUrl.replace(/\/+$/, '');
|
|
35
|
+
this.apiKey = config.apiKey;
|
|
36
|
+
this.timeout = config.timeout ?? DEFAULT_TIMEOUT;
|
|
37
|
+
this.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Executes a GET request and returns the parsed data.
|
|
42
|
+
* @param path - The API path.
|
|
43
|
+
* @param query - Optional query parameters.
|
|
44
|
+
* @returns The response data of type T.
|
|
45
|
+
*/
|
|
46
|
+
async get<T>(path: string, query?: RequestOptions['query']): Promise<T> {
|
|
47
|
+
return this.request<T>({ method: 'GET', path, query });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Executes a POST request and returns the parsed data.
|
|
52
|
+
* @param path - The API path.
|
|
53
|
+
* @param body - The request body.
|
|
54
|
+
* @returns The response data of type T.
|
|
55
|
+
*/
|
|
56
|
+
async post<T>(path: string, body: unknown): Promise<T> {
|
|
57
|
+
return this.request<T>({ method: 'POST', path, body });
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Executes a PUT request and returns the parsed data.
|
|
62
|
+
* @param path - The API path.
|
|
63
|
+
* @param body - The request body.
|
|
64
|
+
* @returns The response data of type T.
|
|
65
|
+
*/
|
|
66
|
+
async put<T>(path: string, body: unknown): Promise<T> {
|
|
67
|
+
return this.request<T>({ method: 'PUT', path, body });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Executes a DELETE request and returns the parsed data.
|
|
72
|
+
* @param path - The API path.
|
|
73
|
+
* @returns The response data of type T.
|
|
74
|
+
*/
|
|
75
|
+
async delete<T>(path: string): Promise<T> {
|
|
76
|
+
return this.request<T>({ method: 'DELETE', path });
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Builds the full URL with query parameters.
|
|
81
|
+
* @param path - The API path.
|
|
82
|
+
* @param query - Optional query parameters.
|
|
83
|
+
* @returns The full URL string.
|
|
84
|
+
*/
|
|
85
|
+
private buildUrl(path: string, query?: RequestOptions['query']): string {
|
|
86
|
+
const url = new URL(`${this.baseUrl}${path}`);
|
|
87
|
+
if (query) {
|
|
88
|
+
for (const [key, value] of Object.entries(query)) {
|
|
89
|
+
if (value !== undefined) {
|
|
90
|
+
url.searchParams.set(key, String(value));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return url.toString();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Executes an HTTP request with timeout, auth, and error handling.
|
|
99
|
+
* @param options - The request options.
|
|
100
|
+
* @returns The parsed response data.
|
|
101
|
+
*/
|
|
102
|
+
private async request<T>(options: RequestOptions): Promise<T> {
|
|
103
|
+
const url = this.buildUrl(options.path, options.query);
|
|
104
|
+
const controller = new AbortController();
|
|
105
|
+
const timer = setTimeout(() => {
|
|
106
|
+
controller.abort();
|
|
107
|
+
}, this.timeout);
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
const response = await this.executeFetch(url, options, controller.signal);
|
|
111
|
+
return await this.handleResponse<T>(response);
|
|
112
|
+
} catch (error: unknown) {
|
|
113
|
+
throw this.wrapError(error);
|
|
114
|
+
} finally {
|
|
115
|
+
clearTimeout(timer);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Calls fetch with the configured headers and body.
|
|
121
|
+
* @param url - The full URL.
|
|
122
|
+
* @param options - The request options.
|
|
123
|
+
* @param signal - The abort signal.
|
|
124
|
+
* @returns The fetch Response.
|
|
125
|
+
*/
|
|
126
|
+
private async executeFetch(
|
|
127
|
+
url: string,
|
|
128
|
+
options: RequestOptions,
|
|
129
|
+
signal: AbortSignal,
|
|
130
|
+
): Promise<Response> {
|
|
131
|
+
const headers: Record<string, string> = {
|
|
132
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
133
|
+
Accept: 'application/json',
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
if (options.body !== undefined) {
|
|
137
|
+
headers['Content-Type'] = 'application/json';
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return this.fetchFn(url, {
|
|
141
|
+
method: options.method,
|
|
142
|
+
headers,
|
|
143
|
+
body: options.body !== undefined ? JSON.stringify(options.body) : undefined,
|
|
144
|
+
signal,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Parses the response and throws typed errors for non-2xx status.
|
|
150
|
+
* @param response - The fetch Response.
|
|
151
|
+
* @returns The parsed data.
|
|
152
|
+
*/
|
|
153
|
+
private async handleResponse<T>(response: Response): Promise<T> {
|
|
154
|
+
const text = await response.text();
|
|
155
|
+
|
|
156
|
+
if (!response.ok) {
|
|
157
|
+
this.throwApiError(response.status, text);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const parsed = this.parseJson(text) as SuccessResponse<T>;
|
|
161
|
+
return parsed.data;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Parses and throws an API error from the response body.
|
|
166
|
+
* @param status - The HTTP status code.
|
|
167
|
+
* @param text - The raw response body.
|
|
168
|
+
*/
|
|
169
|
+
private throwApiError(status: number, text: string): never {
|
|
170
|
+
try {
|
|
171
|
+
const body = JSON.parse(text) as ErrorResponse;
|
|
172
|
+
throw mapStatusToError(status, body.error.message, body.error.code);
|
|
173
|
+
} catch (error: unknown) {
|
|
174
|
+
if (error instanceof Error && 'status' in error) throw error;
|
|
175
|
+
throw mapStatusToError(status, text || `HTTP ${String(status)}`, 'UNKNOWN');
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Safely parses JSON with a typed parse error.
|
|
181
|
+
* @param text - The raw JSON text.
|
|
182
|
+
* @returns The parsed JSON object.
|
|
183
|
+
*/
|
|
184
|
+
private parseJson(text: string): unknown {
|
|
185
|
+
try {
|
|
186
|
+
return JSON.parse(text) as unknown;
|
|
187
|
+
} catch {
|
|
188
|
+
throw new ParseError(`Failed to parse response: ${text.slice(0, 200)}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Wraps unexpected errors into NetworkError.
|
|
194
|
+
* @param error - The caught error.
|
|
195
|
+
* @returns A NetworkError or the original error.
|
|
196
|
+
*/
|
|
197
|
+
private wrapError(error: unknown): unknown {
|
|
198
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
199
|
+
return new NetworkError('Request timed out');
|
|
200
|
+
}
|
|
201
|
+
if (error instanceof Error && 'status' in error) {
|
|
202
|
+
return error;
|
|
203
|
+
}
|
|
204
|
+
if (error instanceof Error) {
|
|
205
|
+
return new NetworkError(error.message);
|
|
206
|
+
}
|
|
207
|
+
return new NetworkError('Unknown network error');
|
|
208
|
+
}
|
|
209
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Main IntelMesh client — facade that creates resource instances
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
import type { ClientConfig } from '../types.js';
|
|
6
|
+
import { HttpClient } from './http.js';
|
|
7
|
+
import { APIKeys } from '../resources/apikeys.js';
|
|
8
|
+
import { Audit } from '../resources/audit.js';
|
|
9
|
+
import { Evaluations } from '../resources/evaluations.js';
|
|
10
|
+
import { Events } from '../resources/events.js';
|
|
11
|
+
import { Lists } from '../resources/lists.js';
|
|
12
|
+
import { Phases } from '../resources/phases.js';
|
|
13
|
+
import { Rules } from '../resources/rules.js';
|
|
14
|
+
import { Scores } from '../resources/scores.js';
|
|
15
|
+
import { Scopes } from '../resources/scopes.js';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Main IntelMesh SDK client.
|
|
19
|
+
* Provides access to all API resources through typed sub-clients.
|
|
20
|
+
*/
|
|
21
|
+
export class IntelMesh {
|
|
22
|
+
/** Event ingestion and simulation. */
|
|
23
|
+
readonly events: Events;
|
|
24
|
+
/** Rule management and versioning. */
|
|
25
|
+
readonly rules: Rules;
|
|
26
|
+
/** Pipeline phase management. */
|
|
27
|
+
readonly phases: Phases;
|
|
28
|
+
/** Scope management. */
|
|
29
|
+
readonly scopes: Scopes;
|
|
30
|
+
/** Named list management. */
|
|
31
|
+
readonly lists: Lists;
|
|
32
|
+
/** Score management. */
|
|
33
|
+
readonly scores: Scores;
|
|
34
|
+
/** API key management. */
|
|
35
|
+
readonly apiKeys: APIKeys;
|
|
36
|
+
/** Evaluation log inspection. */
|
|
37
|
+
readonly evaluations: Evaluations;
|
|
38
|
+
/** Audit log access. */
|
|
39
|
+
readonly audit: Audit;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Creates a new IntelMesh client instance.
|
|
43
|
+
* @param config - Client configuration with baseUrl and apiKey.
|
|
44
|
+
*/
|
|
45
|
+
constructor(config: ClientConfig) {
|
|
46
|
+
const http = new HttpClient(config);
|
|
47
|
+
this.events = new Events(http);
|
|
48
|
+
this.rules = new Rules(http);
|
|
49
|
+
this.phases = new Phases(http);
|
|
50
|
+
this.scopes = new Scopes(http);
|
|
51
|
+
this.lists = new Lists(http);
|
|
52
|
+
this.scores = new Scores(http);
|
|
53
|
+
this.apiKeys = new APIKeys(http);
|
|
54
|
+
this.evaluations = new Evaluations(http);
|
|
55
|
+
this.audit = new Audit(http);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Async cursor-based pagination iterator
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
import type { PaginatedResponse, PaginationParams } from '../types.js';
|
|
6
|
+
|
|
7
|
+
/** Function that fetches a single page of results. */
|
|
8
|
+
type PageFetcher<T> = (params: PaginationParams) => Promise<PaginatedResponse<T>>;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Creates an async iterator that automatically follows cursor pagination.
|
|
12
|
+
* @param fetcher - Function to fetch a single page.
|
|
13
|
+
* @param params - Initial pagination parameters.
|
|
14
|
+
* @yields {T} Individual items from paginated responses.
|
|
15
|
+
* @returns An async iterable of individual items.
|
|
16
|
+
*/
|
|
17
|
+
export async function* paginate<T>(
|
|
18
|
+
fetcher: PageFetcher<T>,
|
|
19
|
+
params: PaginationParams = {},
|
|
20
|
+
): AsyncGenerator<T, void, undefined> {
|
|
21
|
+
let cursor = params.cursor;
|
|
22
|
+
let hasMore = true;
|
|
23
|
+
|
|
24
|
+
while (hasMore) {
|
|
25
|
+
const page = await fetcher({ cursor, limit: params.limit });
|
|
26
|
+
|
|
27
|
+
for (const item of page.items) {
|
|
28
|
+
yield item;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (page.next_cursor) {
|
|
32
|
+
cursor = page.next_cursor;
|
|
33
|
+
} else {
|
|
34
|
+
hasMore = false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Collects all items from an async iterator into an array.
|
|
41
|
+
* @param iter - The async iterable to collect from.
|
|
42
|
+
* @returns An array of all items.
|
|
43
|
+
*/
|
|
44
|
+
export async function collectAll<T>(iter: AsyncIterable<T>): Promise<T[]> {
|
|
45
|
+
const results: T[] = [];
|
|
46
|
+
for await (const item of iter) {
|
|
47
|
+
results.push(item);
|
|
48
|
+
}
|
|
49
|
+
return results;
|
|
50
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Auto-generated types placeholder
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// The swagger.json is Swagger 2.0 format, which openapi-typescript does not support.
|
|
5
|
+
// Once the API spec is converted to OpenAPI 3.x, regenerate with:
|
|
6
|
+
// npx openapi-typescript ../docs/swagger.json -o src/generated/types.ts
|
|
7
|
+
//
|
|
8
|
+
// In the meantime, all API types are manually defined in src/types.ts
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
export type GeneratedPlaceholder = Record<string, never>;
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// @intelmesh/sdk — Public API exports
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
// Main client
|
|
6
|
+
export { IntelMesh } from './client/intelmesh.js';
|
|
7
|
+
|
|
8
|
+
// HTTP client (for advanced usage)
|
|
9
|
+
export { HttpClient } from './client/http.js';
|
|
10
|
+
|
|
11
|
+
// Error types and helpers
|
|
12
|
+
export {
|
|
13
|
+
IntelMeshError,
|
|
14
|
+
ValidationError,
|
|
15
|
+
NotFoundError,
|
|
16
|
+
UnauthorizedError,
|
|
17
|
+
ForbiddenError,
|
|
18
|
+
InternalError,
|
|
19
|
+
UnavailableError,
|
|
20
|
+
NetworkError,
|
|
21
|
+
ParseError,
|
|
22
|
+
isNotFound,
|
|
23
|
+
isValidation,
|
|
24
|
+
isUnauthorized,
|
|
25
|
+
isForbidden,
|
|
26
|
+
isNetwork,
|
|
27
|
+
isIntelMeshError,
|
|
28
|
+
mapStatusToError,
|
|
29
|
+
} from './client/errors.js';
|
|
30
|
+
|
|
31
|
+
// Pagination
|
|
32
|
+
export { paginate, collectAll } from './client/pagination.js';
|
|
33
|
+
|
|
34
|
+
// Resources
|
|
35
|
+
export { Events } from './resources/events.js';
|
|
36
|
+
export { Rules } from './resources/rules.js';
|
|
37
|
+
export { Phases } from './resources/phases.js';
|
|
38
|
+
export { Scopes } from './resources/scopes.js';
|
|
39
|
+
export { Lists } from './resources/lists.js';
|
|
40
|
+
export { Scores } from './resources/scores.js';
|
|
41
|
+
export { APIKeys } from './resources/apikeys.js';
|
|
42
|
+
export { Evaluations } from './resources/evaluations.js';
|
|
43
|
+
export { Audit } from './resources/audit.js';
|
|
44
|
+
|
|
45
|
+
// Builders
|
|
46
|
+
export { EventBuilder } from './builders/event.js';
|
|
47
|
+
export { RuleBuilder } from './builders/rule.js';
|
|
48
|
+
|
|
49
|
+
// Provision
|
|
50
|
+
export { Provisioner } from './provision/index.js';
|
|
51
|
+
export { ProvisionRuleBuilder } from './provision/index.js';
|
|
52
|
+
|
|
53
|
+
// Testkit
|
|
54
|
+
export { Harness, withHarness } from './testkit/index.js';
|
|
55
|
+
export type { HarnessConfig } from './testkit/index.js';
|
|
56
|
+
export { EventAssertion } from './testkit/index.js';
|
|
57
|
+
|
|
58
|
+
// Types
|
|
59
|
+
export type {
|
|
60
|
+
// Core domain
|
|
61
|
+
Severity,
|
|
62
|
+
Flow,
|
|
63
|
+
Decision,
|
|
64
|
+
ScoreOperation,
|
|
65
|
+
ListMutation,
|
|
66
|
+
Actions,
|
|
67
|
+
Rule,
|
|
68
|
+
RuleVersion,
|
|
69
|
+
Phase,
|
|
70
|
+
Scope,
|
|
71
|
+
List,
|
|
72
|
+
Score,
|
|
73
|
+
APIKey,
|
|
74
|
+
EvaluationLog,
|
|
75
|
+
RuleTrace,
|
|
76
|
+
PhaseTrace,
|
|
77
|
+
PipelineTrace,
|
|
78
|
+
// Requests
|
|
79
|
+
IngestRequest,
|
|
80
|
+
CreateRuleRequest,
|
|
81
|
+
UpdateRuleRequest,
|
|
82
|
+
CreatePhaseRequest,
|
|
83
|
+
UpdatePhaseRequest,
|
|
84
|
+
CreateScopeRequest,
|
|
85
|
+
UpdateScopeRequest,
|
|
86
|
+
CreateListRequest,
|
|
87
|
+
UpdateListRequest,
|
|
88
|
+
AddItemsRequest,
|
|
89
|
+
BulkImportRequest,
|
|
90
|
+
SetScoreRequest,
|
|
91
|
+
CreateAPIKeyRequest,
|
|
92
|
+
CreateAPIKeyResponse,
|
|
93
|
+
UpdateAPIKeyRequest,
|
|
94
|
+
// Results
|
|
95
|
+
IngestResult,
|
|
96
|
+
Mutation,
|
|
97
|
+
// Pagination
|
|
98
|
+
PaginatedResponse,
|
|
99
|
+
PaginationParams,
|
|
100
|
+
// Envelope
|
|
101
|
+
SuccessResponse,
|
|
102
|
+
ErrorBody,
|
|
103
|
+
ErrorResponse,
|
|
104
|
+
// Config
|
|
105
|
+
ClientConfig,
|
|
106
|
+
} from './types.js';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Provision module — public exports
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
export { Provisioner } from './provisioner.js';
|
|
6
|
+
export { ProvisionRuleBuilder } from './rule-builder.js';
|