@ax-hub/sdk 0.0.1
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 +107 -0
- package/LICENSE +201 -0
- package/README.md +276 -0
- package/dist/cli/doctor.cjs +2 -0
- package/dist/cli/doctor.d.cts +12 -0
- package/dist/cli/doctor.d.ts +12 -0
- package/dist/cli/doctor.js +2 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +2193 -0
- package/dist/index.d.ts +2193 -0
- package/dist/index.js +1 -0
- package/package.json +89 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,2193 @@
|
|
|
1
|
+
interface FieldError {
|
|
2
|
+
name: string;
|
|
3
|
+
code: string;
|
|
4
|
+
message?: string;
|
|
5
|
+
}
|
|
6
|
+
interface RetryInfo {
|
|
7
|
+
afterMs: number;
|
|
8
|
+
}
|
|
9
|
+
interface AxHubErrorInit {
|
|
10
|
+
message: string;
|
|
11
|
+
code: string;
|
|
12
|
+
category: string;
|
|
13
|
+
httpStatus: number;
|
|
14
|
+
retryable: boolean;
|
|
15
|
+
requestId: string;
|
|
16
|
+
resource?: string;
|
|
17
|
+
fields?: FieldError[];
|
|
18
|
+
retry?: RetryInfo;
|
|
19
|
+
docUrl?: string;
|
|
20
|
+
cause?: unknown;
|
|
21
|
+
}
|
|
22
|
+
declare class AxHubError extends Error {
|
|
23
|
+
readonly code: string;
|
|
24
|
+
readonly category: string;
|
|
25
|
+
readonly httpStatus: number;
|
|
26
|
+
readonly retryable: boolean;
|
|
27
|
+
readonly requestId: string;
|
|
28
|
+
readonly resource?: string;
|
|
29
|
+
readonly fields?: FieldError[];
|
|
30
|
+
readonly retry?: RetryInfo;
|
|
31
|
+
readonly docUrl?: string;
|
|
32
|
+
constructor(init: AxHubErrorInit);
|
|
33
|
+
toJSON(): Record<string, unknown>;
|
|
34
|
+
toString(): string;
|
|
35
|
+
}
|
|
36
|
+
declare function formatErrorMessage(err: AxHubError): string;
|
|
37
|
+
declare class ValidationError extends AxHubError {
|
|
38
|
+
}
|
|
39
|
+
declare class UnauthenticatedError extends AxHubError {
|
|
40
|
+
}
|
|
41
|
+
declare class PermissionDeniedError extends AxHubError {
|
|
42
|
+
}
|
|
43
|
+
declare class NotFoundError extends AxHubError {
|
|
44
|
+
}
|
|
45
|
+
declare class ConflictError extends AxHubError {
|
|
46
|
+
}
|
|
47
|
+
declare class PreconditionFailedError extends AxHubError {
|
|
48
|
+
}
|
|
49
|
+
declare class RateLimitedError extends AxHubError {
|
|
50
|
+
}
|
|
51
|
+
declare class InternalServerError extends AxHubError {
|
|
52
|
+
}
|
|
53
|
+
declare class UnavailableError extends AxHubError {
|
|
54
|
+
}
|
|
55
|
+
declare class SlugTakenError extends ConflictError {
|
|
56
|
+
}
|
|
57
|
+
declare class AlreadyMemberError extends ConflictError {
|
|
58
|
+
}
|
|
59
|
+
declare class AlreadyDeletedError extends ConflictError {
|
|
60
|
+
}
|
|
61
|
+
declare class TokenMissingError extends UnauthenticatedError {
|
|
62
|
+
}
|
|
63
|
+
declare class TokenExpiredError extends UnauthenticatedError {
|
|
64
|
+
}
|
|
65
|
+
declare class TokenInvalidError extends UnauthenticatedError {
|
|
66
|
+
}
|
|
67
|
+
declare class NotAdminError extends PermissionDeniedError {
|
|
68
|
+
}
|
|
69
|
+
declare class ForbiddenError extends PermissionDeniedError {
|
|
70
|
+
}
|
|
71
|
+
declare class PermanentlyDeletedError extends NotFoundError {
|
|
72
|
+
}
|
|
73
|
+
declare class InvitationExpiredError extends NotFoundError {
|
|
74
|
+
}
|
|
75
|
+
declare class AlreadyRevokedError extends ConflictError {
|
|
76
|
+
}
|
|
77
|
+
declare class AlreadySettledError extends ConflictError {
|
|
78
|
+
}
|
|
79
|
+
declare class AlreadyActiveError extends ConflictError {
|
|
80
|
+
}
|
|
81
|
+
declare class AlreadyInactiveError extends ConflictError {
|
|
82
|
+
}
|
|
83
|
+
declare class AlreadyAccessedError extends ConflictError {
|
|
84
|
+
}
|
|
85
|
+
declare class NotDeletedError extends ConflictError {
|
|
86
|
+
}
|
|
87
|
+
declare class LastAdminError extends ConflictError {
|
|
88
|
+
}
|
|
89
|
+
declare class PendingExistsError extends ConflictError {
|
|
90
|
+
}
|
|
91
|
+
declare class InvalidStateTransitionError extends ConflictError {
|
|
92
|
+
}
|
|
93
|
+
declare class SchemaNameTakenError extends ConflictError {
|
|
94
|
+
}
|
|
95
|
+
declare class DomainTakenError extends ConflictError {
|
|
96
|
+
}
|
|
97
|
+
declare class DuplicateError extends ConflictError {
|
|
98
|
+
}
|
|
99
|
+
declare class InvalidValueError extends ValidationError {
|
|
100
|
+
}
|
|
101
|
+
declare class RequiredError extends ValidationError {
|
|
102
|
+
}
|
|
103
|
+
declare class EmptyError extends ValidationError {
|
|
104
|
+
}
|
|
105
|
+
declare class BadRequestError extends ValidationError {
|
|
106
|
+
}
|
|
107
|
+
declare class NotMemberError extends PermissionDeniedError {
|
|
108
|
+
}
|
|
109
|
+
declare class NotAllowedError extends PermissionDeniedError {
|
|
110
|
+
}
|
|
111
|
+
declare class AppUnavailableError extends UnavailableError {
|
|
112
|
+
}
|
|
113
|
+
declare class NetworkError extends AxHubError {
|
|
114
|
+
}
|
|
115
|
+
declare class TimeoutError extends AxHubError {
|
|
116
|
+
}
|
|
117
|
+
declare class DecodeError extends AxHubError {
|
|
118
|
+
}
|
|
119
|
+
declare class AbortError extends AxHubError {
|
|
120
|
+
}
|
|
121
|
+
declare class InvalidPathError extends AxHubError {
|
|
122
|
+
}
|
|
123
|
+
declare class StreamConsumedError extends AxHubError {
|
|
124
|
+
}
|
|
125
|
+
declare class TenantSlugRequiredError extends AxHubError {
|
|
126
|
+
}
|
|
127
|
+
declare class PoolStaleError extends UnauthenticatedError {
|
|
128
|
+
}
|
|
129
|
+
declare class WebhookVerificationError extends ValidationError {
|
|
130
|
+
}
|
|
131
|
+
interface OAuthErrorInit {
|
|
132
|
+
code: string;
|
|
133
|
+
description?: string;
|
|
134
|
+
uri?: string;
|
|
135
|
+
httpStatus: number;
|
|
136
|
+
retryable: boolean;
|
|
137
|
+
requestId: string;
|
|
138
|
+
}
|
|
139
|
+
declare class OAuthError extends AxHubError {
|
|
140
|
+
readonly description?: string;
|
|
141
|
+
readonly uri?: string;
|
|
142
|
+
constructor(init: OAuthErrorInit);
|
|
143
|
+
}
|
|
144
|
+
declare class InvalidGrantError extends OAuthError {
|
|
145
|
+
}
|
|
146
|
+
declare class AccessDeniedError extends OAuthError {
|
|
147
|
+
}
|
|
148
|
+
declare class AuthorizationPendingError extends OAuthError {
|
|
149
|
+
}
|
|
150
|
+
declare class SlowDownError extends OAuthError {
|
|
151
|
+
}
|
|
152
|
+
declare class ExpiredTokenError extends OAuthError {
|
|
153
|
+
}
|
|
154
|
+
declare class DeviceFlowDeniedError extends AccessDeniedError {
|
|
155
|
+
}
|
|
156
|
+
declare class DeviceFlowTimeoutError extends ExpiredTokenError {
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
declare function isOAuthPath(path: string): boolean;
|
|
160
|
+
interface DispatchContext {
|
|
161
|
+
path: string;
|
|
162
|
+
status: number;
|
|
163
|
+
body: unknown;
|
|
164
|
+
fallbackRequestId: string;
|
|
165
|
+
}
|
|
166
|
+
declare function dispatch(ctx: DispatchContext): AxHubError;
|
|
167
|
+
|
|
168
|
+
declare const brand: unique symbol;
|
|
169
|
+
type Branded<T, B extends string> = T & {
|
|
170
|
+
readonly [brand]: B;
|
|
171
|
+
};
|
|
172
|
+
type AppId = Branded<string, 'AppId'>;
|
|
173
|
+
type AppID = AppId;
|
|
174
|
+
type DeploymentId = Branded<string, 'DeploymentId'>;
|
|
175
|
+
type DeploymentID = DeploymentId;
|
|
176
|
+
type TenantId = Branded<string, 'TenantId'>;
|
|
177
|
+
type TenantID = TenantId;
|
|
178
|
+
type TenantSlug = Branded<string, 'TenantSlug'>;
|
|
179
|
+
type AppSlug = Branded<string, 'AppSlug'>;
|
|
180
|
+
type PatId = Branded<string, 'PatId'>;
|
|
181
|
+
type PATID = PatId;
|
|
182
|
+
type UserId = Branded<string, 'UserId'>;
|
|
183
|
+
type UserID = UserId;
|
|
184
|
+
type RequestId = Branded<string, 'RequestId'>;
|
|
185
|
+
type ResourceID = Branded<string, 'ResourceID'>;
|
|
186
|
+
type ConnectorID = Branded<string, 'ConnectorID'>;
|
|
187
|
+
type SubjectID = Branded<string, 'SubjectID'>;
|
|
188
|
+
type GrantID = Branded<string, 'GrantID'>;
|
|
189
|
+
type TagID = Branded<string, 'TagID'>;
|
|
190
|
+
type AuditEventID = Branded<string, 'AuditEventID'>;
|
|
191
|
+
type TableID = Branded<string, 'TableID'>;
|
|
192
|
+
declare function asAppId(s: string): AppId;
|
|
193
|
+
declare function asDeploymentId(s: string): DeploymentId;
|
|
194
|
+
declare function asTenantId(s: string): TenantId;
|
|
195
|
+
declare function asTenantSlug(s: string): TenantSlug;
|
|
196
|
+
declare function asAppSlug(s: string): AppSlug;
|
|
197
|
+
declare function asPatId(s: string): PatId;
|
|
198
|
+
declare function asUserId(s: string): UserId;
|
|
199
|
+
declare function asRequestId(s: string): RequestId;
|
|
200
|
+
/**
|
|
201
|
+
* Runtime-validating branded ID factories. SDK methods still accept plain
|
|
202
|
+
* strings; these factories are for callers who want validation plus
|
|
203
|
+
* compile-time brand separation in their own code.
|
|
204
|
+
*/
|
|
205
|
+
declare const id: {
|
|
206
|
+
tenant(value: string): TenantID;
|
|
207
|
+
tenantSlug(value: string): TenantSlug;
|
|
208
|
+
app(value: string): AppID;
|
|
209
|
+
appSlug(value: string): AppSlug;
|
|
210
|
+
user(value: string): UserID;
|
|
211
|
+
deployment(value: string): DeploymentID;
|
|
212
|
+
pat(value: string): PATID;
|
|
213
|
+
resource(value: string): ResourceID;
|
|
214
|
+
connector(value: string): ConnectorID;
|
|
215
|
+
subject(value: string): SubjectID;
|
|
216
|
+
grant(value: string): GrantID;
|
|
217
|
+
tag(value: string): TagID;
|
|
218
|
+
auditEvent(value: string): AuditEventID;
|
|
219
|
+
table(value: string): TableID;
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
interface Logger {
|
|
223
|
+
debug(obj: object, msg?: string): void;
|
|
224
|
+
info(obj: object, msg?: string): void;
|
|
225
|
+
warn(obj: object, msg?: string): void;
|
|
226
|
+
error(obj: object, msg?: string): void;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
declare function parseRetryAfter(header: string | null | undefined): number;
|
|
230
|
+
type RateLimitStrategy = 'sleep' | 'throw';
|
|
231
|
+
|
|
232
|
+
interface RetryPolicy {
|
|
233
|
+
maxAttempts: number;
|
|
234
|
+
baseMs: number;
|
|
235
|
+
capMs: number;
|
|
236
|
+
jitter: () => number;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
type FetchLike = typeof fetch;
|
|
240
|
+
type TokenType = 'pat' | 'jwt';
|
|
241
|
+
type AuthRing = 'admin' | 'data' | 'public';
|
|
242
|
+
interface AuthProvider {
|
|
243
|
+
headersFor(ring: AuthRing): Record<string, string>;
|
|
244
|
+
onUnauthorized(): Promise<boolean>;
|
|
245
|
+
}
|
|
246
|
+
interface HttpClientOptions {
|
|
247
|
+
baseUrl: string;
|
|
248
|
+
auth: AuthProvider;
|
|
249
|
+
fetch?: FetchLike;
|
|
250
|
+
logger?: Logger;
|
|
251
|
+
debug?: boolean;
|
|
252
|
+
timeoutMs?: number;
|
|
253
|
+
idempotencyKey?: {
|
|
254
|
+
autoGenerate?: boolean;
|
|
255
|
+
generator?: () => string;
|
|
256
|
+
};
|
|
257
|
+
retryPolicy?: RetryPolicy;
|
|
258
|
+
rateLimitStrategy?: RateLimitStrategy;
|
|
259
|
+
}
|
|
260
|
+
interface RequestInit2 {
|
|
261
|
+
ring: AuthRing;
|
|
262
|
+
query?: Record<string, string | number | boolean | undefined>;
|
|
263
|
+
body?: unknown;
|
|
264
|
+
parseBody?: boolean;
|
|
265
|
+
signal?: AbortSignal;
|
|
266
|
+
idempotent?: boolean;
|
|
267
|
+
rawResponse?: boolean;
|
|
268
|
+
headers?: Record<string, string>;
|
|
269
|
+
timeoutMs?: number;
|
|
270
|
+
idempotencyKey?: string | false;
|
|
271
|
+
}
|
|
272
|
+
declare class HttpClient {
|
|
273
|
+
readonly baseUrl: string;
|
|
274
|
+
readonly auth: AuthProvider;
|
|
275
|
+
readonly fetch: FetchLike;
|
|
276
|
+
readonly logger: Logger;
|
|
277
|
+
readonly debug: boolean;
|
|
278
|
+
readonly timeoutMs: number;
|
|
279
|
+
readonly idempotencyKey: Required<NonNullable<HttpClientOptions['idempotencyKey']>>;
|
|
280
|
+
readonly retryPolicy: RetryPolicy;
|
|
281
|
+
readonly rateLimitStrategy: RateLimitStrategy;
|
|
282
|
+
constructor(opts: HttpClientOptions);
|
|
283
|
+
request<T>(method: string, path: string, init: RequestInit2): Promise<T>;
|
|
284
|
+
private requestOnce;
|
|
285
|
+
private parseSuccess;
|
|
286
|
+
private safeParseJson;
|
|
287
|
+
private buildUrl;
|
|
288
|
+
private buildHeaders;
|
|
289
|
+
private resolveIdempotencyKey;
|
|
290
|
+
private withStableIdempotencyKey;
|
|
291
|
+
private logRequest;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
interface ParsedFrame {
|
|
295
|
+
id?: string;
|
|
296
|
+
event?: string;
|
|
297
|
+
data: string;
|
|
298
|
+
}
|
|
299
|
+
type StreamItem<T> = {
|
|
300
|
+
type: 'item';
|
|
301
|
+
value: T;
|
|
302
|
+
id: string | undefined;
|
|
303
|
+
} | {
|
|
304
|
+
type: 'gap';
|
|
305
|
+
sinceId: string | undefined;
|
|
306
|
+
missingCount?: number;
|
|
307
|
+
} | {
|
|
308
|
+
type: 'decode-skip';
|
|
309
|
+
frame: ParsedFrame;
|
|
310
|
+
error: AxHubError;
|
|
311
|
+
};
|
|
312
|
+
interface SSEStream<T> extends AsyncIterable<StreamItem<T>> {
|
|
313
|
+
dispose(): void;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
interface PaginatedList<T> {
|
|
317
|
+
items: T[];
|
|
318
|
+
nextCursor: string | null;
|
|
319
|
+
total: number;
|
|
320
|
+
}
|
|
321
|
+
interface ListOptions {
|
|
322
|
+
pageSize?: number;
|
|
323
|
+
cursor?: string;
|
|
324
|
+
}
|
|
325
|
+
interface ListAllOptions extends ListOptions {
|
|
326
|
+
signal?: AbortSignal;
|
|
327
|
+
}
|
|
328
|
+
type ListAllItem<T> = {
|
|
329
|
+
type: 'item';
|
|
330
|
+
value: T;
|
|
331
|
+
} | {
|
|
332
|
+
type: 'drift';
|
|
333
|
+
addedSince: number;
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
interface RequestOptions {
|
|
337
|
+
signal?: AbortSignal;
|
|
338
|
+
timeoutMs?: number;
|
|
339
|
+
idempotencyKey?: string | false;
|
|
340
|
+
}
|
|
341
|
+
interface PageRequestOptions extends ListOptions, RequestOptions {
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
interface GatewayEngine {
|
|
345
|
+
name: 'postgres' | 'mysql' | string;
|
|
346
|
+
capabilities: string[];
|
|
347
|
+
}
|
|
348
|
+
interface GatewayConnector {
|
|
349
|
+
id: string;
|
|
350
|
+
engine: string;
|
|
351
|
+
name: string;
|
|
352
|
+
[key: string]: unknown;
|
|
353
|
+
}
|
|
354
|
+
interface GatewayResource {
|
|
355
|
+
id: string;
|
|
356
|
+
connectorId: string;
|
|
357
|
+
name: string;
|
|
358
|
+
[key: string]: unknown;
|
|
359
|
+
}
|
|
360
|
+
interface GatewayQueryInput {
|
|
361
|
+
resourceId?: string;
|
|
362
|
+
connectorId?: string;
|
|
363
|
+
path?: string;
|
|
364
|
+
sql: string;
|
|
365
|
+
params?: unknown[];
|
|
366
|
+
rowLimit?: number;
|
|
367
|
+
}
|
|
368
|
+
interface GatewayQueryResult<Row = Record<string, unknown>> {
|
|
369
|
+
rows: Row[];
|
|
370
|
+
rowCount: number;
|
|
371
|
+
auditEventId?: string;
|
|
372
|
+
}
|
|
373
|
+
declare class GatewayClient {
|
|
374
|
+
private readonly http;
|
|
375
|
+
constructor(http: HttpClient);
|
|
376
|
+
scoped(tenantSlug: string): TenantGatewayClient;
|
|
377
|
+
}
|
|
378
|
+
declare class TenantGatewayClient {
|
|
379
|
+
readonly engines: GatewayEnginesClient;
|
|
380
|
+
readonly connectors: GatewayConnectorsClient;
|
|
381
|
+
readonly resources: GatewayResourcesClient;
|
|
382
|
+
readonly query: GatewayQueryClient;
|
|
383
|
+
constructor(http: HttpClient, tenantSlug: string);
|
|
384
|
+
}
|
|
385
|
+
declare class GatewayEnginesClient {
|
|
386
|
+
private readonly http;
|
|
387
|
+
private readonly base;
|
|
388
|
+
constructor(http: HttpClient, base: string);
|
|
389
|
+
list(opts?: RequestOptions): Promise<GatewayEngine[]>;
|
|
390
|
+
}
|
|
391
|
+
declare class GatewayCrud<T extends {
|
|
392
|
+
id: string;
|
|
393
|
+
}> {
|
|
394
|
+
protected readonly http: HttpClient;
|
|
395
|
+
protected readonly base: string;
|
|
396
|
+
constructor(http: HttpClient, base: string);
|
|
397
|
+
list(opts?: PageRequestOptions): Promise<PaginatedList<T>>;
|
|
398
|
+
get(id: string, opts?: RequestOptions): Promise<T>;
|
|
399
|
+
create(input: Record<string, unknown>, opts?: RequestOptions): Promise<T>;
|
|
400
|
+
update(id: string, patch: Record<string, unknown>, opts?: RequestOptions): Promise<T>;
|
|
401
|
+
delete(id: string, opts?: RequestOptions): Promise<void>;
|
|
402
|
+
}
|
|
403
|
+
declare class GatewayConnectorsClient extends GatewayCrud<GatewayConnector> {
|
|
404
|
+
}
|
|
405
|
+
declare class GatewayResourcesClient extends GatewayCrud<GatewayResource> {
|
|
406
|
+
}
|
|
407
|
+
declare class GatewayQueryClient {
|
|
408
|
+
private readonly http;
|
|
409
|
+
private readonly base;
|
|
410
|
+
constructor(http: HttpClient, base: string);
|
|
411
|
+
run<Row extends Record<string, unknown> = Record<string, unknown>>(input: GatewayQueryInput, opts?: RequestOptions): Promise<GatewayQueryResult<Row>>;
|
|
412
|
+
stream<Row extends Record<string, unknown> = Record<string, unknown>>(input: GatewayQueryInput, opts?: RequestOptions): SSEStream<Row>;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
interface AuditEvent {
|
|
416
|
+
id: string;
|
|
417
|
+
type?: string;
|
|
418
|
+
actorId?: string;
|
|
419
|
+
hash?: string;
|
|
420
|
+
prevHash?: string;
|
|
421
|
+
createdAt?: string;
|
|
422
|
+
[key: string]: unknown;
|
|
423
|
+
}
|
|
424
|
+
interface EmitAuditEventInput {
|
|
425
|
+
type: string;
|
|
426
|
+
actorId?: string;
|
|
427
|
+
resource?: string;
|
|
428
|
+
payload?: unknown;
|
|
429
|
+
}
|
|
430
|
+
interface IntegrityCheckResult {
|
|
431
|
+
ok: boolean;
|
|
432
|
+
checked: number;
|
|
433
|
+
brokenAt?: string;
|
|
434
|
+
}
|
|
435
|
+
interface AnonymizeInput {
|
|
436
|
+
subjectId?: string;
|
|
437
|
+
actorId?: string;
|
|
438
|
+
anonymizedId?: string;
|
|
439
|
+
reason?: string;
|
|
440
|
+
}
|
|
441
|
+
declare class AuditClient {
|
|
442
|
+
private readonly http;
|
|
443
|
+
readonly events: AuditEventsClient;
|
|
444
|
+
readonly server: AuditServerClient;
|
|
445
|
+
constructor(http: HttpClient);
|
|
446
|
+
scoped(tenantSlug: string): TenantAuditClient;
|
|
447
|
+
integrityCheck(tenantSlug: string, opts?: RequestOptions): Promise<IntegrityCheckResult>;
|
|
448
|
+
anonymize(tenantSlug: string, input: AnonymizeInput, opts?: RequestOptions): Promise<AuditEvent | void>;
|
|
449
|
+
}
|
|
450
|
+
declare class TenantAuditClient {
|
|
451
|
+
private readonly http;
|
|
452
|
+
private readonly tenantSlug;
|
|
453
|
+
readonly events: AuditEventsForTenantClient;
|
|
454
|
+
readonly server: AuditServerForTenantClient;
|
|
455
|
+
constructor(http: HttpClient, tenantSlug: string);
|
|
456
|
+
integrityCheck(opts?: RequestOptions): Promise<IntegrityCheckResult>;
|
|
457
|
+
anonymize(input: AnonymizeInput, opts?: RequestOptions): Promise<AuditEvent | void>;
|
|
458
|
+
}
|
|
459
|
+
declare class AuditEventsClient {
|
|
460
|
+
private readonly http;
|
|
461
|
+
constructor(http: HttpClient);
|
|
462
|
+
forTenant(tenantSlug: string): AuditEventsForTenantClient;
|
|
463
|
+
}
|
|
464
|
+
declare class AuditEventsForTenantClient {
|
|
465
|
+
private readonly http;
|
|
466
|
+
private readonly tenantSlug;
|
|
467
|
+
constructor(http: HttpClient, tenantSlug: string);
|
|
468
|
+
list(opts?: PageRequestOptions & {
|
|
469
|
+
type?: string;
|
|
470
|
+
}): Promise<PaginatedList<AuditEvent>>;
|
|
471
|
+
get(eventId: string, opts?: RequestOptions): Promise<AuditEvent>;
|
|
472
|
+
}
|
|
473
|
+
declare class AuditServerClient {
|
|
474
|
+
private readonly http;
|
|
475
|
+
constructor(http: HttpClient);
|
|
476
|
+
forTenant(tenantSlug: string): AuditServerForTenantClient;
|
|
477
|
+
}
|
|
478
|
+
declare class AuditServerForTenantClient {
|
|
479
|
+
private readonly http;
|
|
480
|
+
private readonly tenantSlug;
|
|
481
|
+
constructor(http: HttpClient, tenantSlug: string);
|
|
482
|
+
emit(input: EmitAuditEventInput, opts?: RequestOptions): Promise<AuditEvent>;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
interface AuthzTag {
|
|
486
|
+
id: string;
|
|
487
|
+
name: string;
|
|
488
|
+
parentId?: string;
|
|
489
|
+
[key: string]: unknown;
|
|
490
|
+
}
|
|
491
|
+
interface AuthzSubject {
|
|
492
|
+
id: string;
|
|
493
|
+
type: string;
|
|
494
|
+
externalId?: string;
|
|
495
|
+
[key: string]: unknown;
|
|
496
|
+
}
|
|
497
|
+
interface AuthzGrant {
|
|
498
|
+
id: string;
|
|
499
|
+
subjectId: string;
|
|
500
|
+
resource: string;
|
|
501
|
+
action: string;
|
|
502
|
+
effect: 'allow' | 'deny';
|
|
503
|
+
[key: string]: unknown;
|
|
504
|
+
}
|
|
505
|
+
interface DecideInput {
|
|
506
|
+
subjectId: string;
|
|
507
|
+
resource: string;
|
|
508
|
+
action: string;
|
|
509
|
+
context?: Record<string, unknown>;
|
|
510
|
+
}
|
|
511
|
+
interface DecideResult {
|
|
512
|
+
allowed: boolean;
|
|
513
|
+
reason?: string;
|
|
514
|
+
matchedGrantId?: string;
|
|
515
|
+
}
|
|
516
|
+
declare class AuthzClient {
|
|
517
|
+
private readonly http;
|
|
518
|
+
constructor(http: HttpClient);
|
|
519
|
+
scoped(tenantSlug: string): TenantAuthzClient;
|
|
520
|
+
}
|
|
521
|
+
declare class TenantAuthzClient {
|
|
522
|
+
readonly tags: Crud<AuthzTag>;
|
|
523
|
+
readonly subjects: Crud<AuthzSubject>;
|
|
524
|
+
readonly grants: Crud<AuthzGrant>;
|
|
525
|
+
readonly evaluator: AuthzEvaluatorClient;
|
|
526
|
+
constructor(http: HttpClient, tenantSlug: string);
|
|
527
|
+
}
|
|
528
|
+
declare class Crud<T extends {
|
|
529
|
+
id: string;
|
|
530
|
+
}> {
|
|
531
|
+
private readonly http;
|
|
532
|
+
private readonly base;
|
|
533
|
+
constructor(http: HttpClient, base: string);
|
|
534
|
+
list(opts?: PageRequestOptions): Promise<PaginatedList<T>>;
|
|
535
|
+
get(id: string, opts?: RequestOptions): Promise<T>;
|
|
536
|
+
create(input: Record<string, unknown>, opts?: RequestOptions): Promise<T>;
|
|
537
|
+
update(id: string, patch: Record<string, unknown>, opts?: RequestOptions): Promise<T>;
|
|
538
|
+
delete(id: string, opts?: RequestOptions): Promise<void>;
|
|
539
|
+
}
|
|
540
|
+
declare class AuthzEvaluatorClient {
|
|
541
|
+
private readonly http;
|
|
542
|
+
private readonly base;
|
|
543
|
+
private readonly ttlMs;
|
|
544
|
+
private readonly cache;
|
|
545
|
+
constructor(http: HttpClient, base: string, ttlMs?: number);
|
|
546
|
+
decide(input: DecideInput, opts?: RequestOptions): Promise<DecideResult>;
|
|
547
|
+
decideMany(inputs: DecideInput[], opts?: RequestOptions): Promise<DecideResult[]>;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
interface Tenant {
|
|
551
|
+
id: string;
|
|
552
|
+
slug: string;
|
|
553
|
+
name: string;
|
|
554
|
+
plan?: string;
|
|
555
|
+
createdAt?: string;
|
|
556
|
+
updatedAt?: string;
|
|
557
|
+
[key: string]: unknown;
|
|
558
|
+
}
|
|
559
|
+
interface CreateTenantInput {
|
|
560
|
+
slug: string;
|
|
561
|
+
name: string;
|
|
562
|
+
plan?: string;
|
|
563
|
+
}
|
|
564
|
+
interface UpdateTenantInput {
|
|
565
|
+
name?: string;
|
|
566
|
+
plan?: string;
|
|
567
|
+
}
|
|
568
|
+
interface TenantMember {
|
|
569
|
+
id: string;
|
|
570
|
+
userId: string;
|
|
571
|
+
role: string;
|
|
572
|
+
status?: string;
|
|
573
|
+
[key: string]: unknown;
|
|
574
|
+
}
|
|
575
|
+
interface TenantInvitation {
|
|
576
|
+
id: string;
|
|
577
|
+
email: string;
|
|
578
|
+
role: string;
|
|
579
|
+
status: string;
|
|
580
|
+
reason?: string;
|
|
581
|
+
[key: string]: unknown;
|
|
582
|
+
}
|
|
583
|
+
interface InviteTenantMemberInput {
|
|
584
|
+
email: string;
|
|
585
|
+
role: string;
|
|
586
|
+
reason?: string;
|
|
587
|
+
}
|
|
588
|
+
interface BulkInviteResult {
|
|
589
|
+
accepted: TenantInvitation[];
|
|
590
|
+
rejected: Array<{
|
|
591
|
+
email: string;
|
|
592
|
+
reason: string;
|
|
593
|
+
}>;
|
|
594
|
+
}
|
|
595
|
+
interface EmailDomain {
|
|
596
|
+
domain: string;
|
|
597
|
+
verified?: boolean;
|
|
598
|
+
[key: string]: unknown;
|
|
599
|
+
}
|
|
600
|
+
interface TenantIconUploadResult {
|
|
601
|
+
uploadUrl: string;
|
|
602
|
+
getUrl: string;
|
|
603
|
+
expiresAt?: string;
|
|
604
|
+
}
|
|
605
|
+
declare class TenantsClient {
|
|
606
|
+
private readonly http;
|
|
607
|
+
constructor(http: HttpClient);
|
|
608
|
+
scoped(tenantIdOrSlug: string): TenantScopedTenantsClient;
|
|
609
|
+
create(input: CreateTenantInput, opts?: RequestOptions): Promise<Tenant>;
|
|
610
|
+
list(opts?: PageRequestOptions): Promise<PaginatedList<Tenant>>;
|
|
611
|
+
get(tenantIdOrSlug: string, opts?: RequestOptions): Promise<Tenant>;
|
|
612
|
+
update(tenantIdOrSlug: string, patch: UpdateTenantInput, opts?: RequestOptions): Promise<Tenant>;
|
|
613
|
+
delete(tenantIdOrSlug: string, opts?: RequestOptions): Promise<void>;
|
|
614
|
+
signIconUploadURL(tenantIdOrSlug: string, input: {
|
|
615
|
+
contentType: string;
|
|
616
|
+
}, opts?: RequestOptions): Promise<TenantIconUploadResult>;
|
|
617
|
+
get members(): TenantMembersClient;
|
|
618
|
+
get invitations(): TenantInvitationsClient;
|
|
619
|
+
get emailDomains(): TenantEmailDomainsClient;
|
|
620
|
+
}
|
|
621
|
+
declare class TenantScopedTenantsClient {
|
|
622
|
+
readonly members: TenantMembersForTenantClient;
|
|
623
|
+
readonly invitations: TenantInvitationsForTenantClient;
|
|
624
|
+
readonly emailDomains: TenantEmailDomainsForTenantClient;
|
|
625
|
+
constructor(http: HttpClient, tenantIdOrSlug: string);
|
|
626
|
+
}
|
|
627
|
+
declare class TenantMembersClient {
|
|
628
|
+
private readonly http;
|
|
629
|
+
constructor(http: HttpClient);
|
|
630
|
+
forTenant(tenantIdOrSlug: string): TenantMembersForTenantClient;
|
|
631
|
+
}
|
|
632
|
+
declare class TenantMembersForTenantClient {
|
|
633
|
+
private readonly http;
|
|
634
|
+
private readonly tenant;
|
|
635
|
+
constructor(http: HttpClient, tenant: string);
|
|
636
|
+
list(opts?: PageRequestOptions): Promise<PaginatedList<TenantMember>>;
|
|
637
|
+
update(membershipId: string, patch: {
|
|
638
|
+
role?: string;
|
|
639
|
+
}, opts?: RequestOptions): Promise<TenantMember>;
|
|
640
|
+
deactivate(membershipId: string, opts?: RequestOptions): Promise<TenantMember>;
|
|
641
|
+
reactivate(membershipId: string, opts?: RequestOptions): Promise<TenantMember>;
|
|
642
|
+
}
|
|
643
|
+
declare class TenantInvitationsClient {
|
|
644
|
+
private readonly http;
|
|
645
|
+
constructor(http: HttpClient);
|
|
646
|
+
forTenant(tenantIdOrSlug: string): TenantInvitationsForTenantClient;
|
|
647
|
+
}
|
|
648
|
+
declare class TenantInvitationsForTenantClient {
|
|
649
|
+
private readonly http;
|
|
650
|
+
private readonly tenant;
|
|
651
|
+
constructor(http: HttpClient, tenant: string);
|
|
652
|
+
list(opts?: PageRequestOptions): Promise<PaginatedList<TenantInvitation>>;
|
|
653
|
+
create(input: InviteTenantMemberInput, opts?: RequestOptions): Promise<TenantInvitation>;
|
|
654
|
+
bulkCreate(inputs: InviteTenantMemberInput[], opts?: RequestOptions): Promise<BulkInviteResult>;
|
|
655
|
+
delete(invitationId: string, opts?: RequestOptions): Promise<void>;
|
|
656
|
+
}
|
|
657
|
+
declare class TenantEmailDomainsClient {
|
|
658
|
+
private readonly http;
|
|
659
|
+
constructor(http: HttpClient);
|
|
660
|
+
forTenant(tenantIdOrSlug: string): TenantEmailDomainsForTenantClient;
|
|
661
|
+
}
|
|
662
|
+
declare class TenantEmailDomainsForTenantClient {
|
|
663
|
+
private readonly http;
|
|
664
|
+
private readonly tenant;
|
|
665
|
+
constructor(http: HttpClient, tenant: string);
|
|
666
|
+
list(opts?: RequestOptions): Promise<EmailDomain[]>;
|
|
667
|
+
create(input: {
|
|
668
|
+
domain: string;
|
|
669
|
+
}, opts?: RequestOptions): Promise<EmailDomain>;
|
|
670
|
+
delete(domain: string, opts?: RequestOptions): Promise<void>;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
interface EnvVar {
|
|
674
|
+
key: string;
|
|
675
|
+
value: string;
|
|
676
|
+
createdAt: string;
|
|
677
|
+
updatedAt: string;
|
|
678
|
+
}
|
|
679
|
+
declare class AppsEnvVarsMixin {
|
|
680
|
+
private readonly http;
|
|
681
|
+
constructor(http: HttpClient);
|
|
682
|
+
/**
|
|
683
|
+
* List all env vars for an app.
|
|
684
|
+
*
|
|
685
|
+
* @example happy
|
|
686
|
+
* const vars = await sdk.apps.listEnvVars('app_abc')
|
|
687
|
+
* for (const v of vars) console.log(v.key, '=', v.value)
|
|
688
|
+
*/
|
|
689
|
+
listEnvVars(appId: string): Promise<EnvVar[]>;
|
|
690
|
+
/**
|
|
691
|
+
* Create or overwrite an env var. Key must match `^[A-Z_][A-Z0-9_]*$` —
|
|
692
|
+
* validation happens client-side before any network round-trip.
|
|
693
|
+
*
|
|
694
|
+
* @example happy
|
|
695
|
+
* await sdk.apps.setEnvVar('app_abc', 'DATABASE_URL', 'postgres://...')
|
|
696
|
+
*
|
|
697
|
+
* @example failure
|
|
698
|
+
* try { await sdk.apps.setEnvVar('app_abc', 'database url', 'x') }
|
|
699
|
+
* catch (e) { if (e instanceof ValidationError) /* fix key *\/ }
|
|
700
|
+
*/
|
|
701
|
+
setEnvVar(appId: string, key: string, value: string): Promise<void>;
|
|
702
|
+
/**
|
|
703
|
+
* Fetch a single env var by key.
|
|
704
|
+
*
|
|
705
|
+
* @example happy
|
|
706
|
+
* const v = await sdk.apps.getEnvVar('app_abc', 'DATABASE_URL')
|
|
707
|
+
*
|
|
708
|
+
* @example failure
|
|
709
|
+
* try { await sdk.apps.getEnvVar('app_abc', 'NOT_SET') }
|
|
710
|
+
* catch (e) { if (e instanceof NotFoundError) /* not set *\/ }
|
|
711
|
+
*/
|
|
712
|
+
getEnvVar(appId: string, key: string): Promise<EnvVar>;
|
|
713
|
+
/**
|
|
714
|
+
* Remove an env var. Idempotent: deleting a missing key returns 404 which
|
|
715
|
+
* the SDK throws as `NotFoundError`. Callers that want fire-and-forget
|
|
716
|
+
* delete should ignore that specific class.
|
|
717
|
+
*
|
|
718
|
+
* @example happy
|
|
719
|
+
* await sdk.apps.deleteEnvVar('app_abc', 'OLD_KEY')
|
|
720
|
+
*/
|
|
721
|
+
deleteEnvVar(appId: string, key: string): Promise<void>;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
interface AppResponse {
|
|
725
|
+
id: string;
|
|
726
|
+
tenantId: string;
|
|
727
|
+
ownerId: string;
|
|
728
|
+
slug: string;
|
|
729
|
+
name: string;
|
|
730
|
+
description?: string;
|
|
731
|
+
iconUrl?: string;
|
|
732
|
+
schemaName: string;
|
|
733
|
+
status: 'active' | 'deleted' | 'permanently_deleted';
|
|
734
|
+
visibility: 'private' | 'tenant' | 'public';
|
|
735
|
+
publicationStatus: 'draft' | 'pending_review' | 'approved';
|
|
736
|
+
likeCount: number;
|
|
737
|
+
subscriberCount: number;
|
|
738
|
+
createdAt: string;
|
|
739
|
+
updatedAt: string;
|
|
740
|
+
deletedAt: string | null;
|
|
741
|
+
}
|
|
742
|
+
interface CreateAppInput {
|
|
743
|
+
slug: string;
|
|
744
|
+
name: string;
|
|
745
|
+
description?: string;
|
|
746
|
+
iconUrl?: string;
|
|
747
|
+
visibility?: 'private' | 'tenant' | 'public';
|
|
748
|
+
}
|
|
749
|
+
interface UpdateAppInput {
|
|
750
|
+
name?: string;
|
|
751
|
+
description?: string;
|
|
752
|
+
iconUrl?: string;
|
|
753
|
+
visibility?: 'private' | 'tenant' | 'public';
|
|
754
|
+
}
|
|
755
|
+
declare class AppsCrudMixin {
|
|
756
|
+
private readonly http;
|
|
757
|
+
private readonly defaultTenantSlug?;
|
|
758
|
+
private readonly defaultTenantId?;
|
|
759
|
+
constructor(http: HttpClient, defaultTenantSlug?: string | undefined, defaultTenantId?: string | undefined);
|
|
760
|
+
private withTenantQuery;
|
|
761
|
+
/**
|
|
762
|
+
* Create a new app in the caller's tenant.
|
|
763
|
+
*
|
|
764
|
+
* @example happy
|
|
765
|
+
* const app = await sdk.apps.create({ slug: 'my-app', name: 'My App' })
|
|
766
|
+
*
|
|
767
|
+
* @example failure
|
|
768
|
+
* try { await sdk.apps.create({ slug: 'taken', name: 'X' }) }
|
|
769
|
+
* catch (e) {
|
|
770
|
+
* if (e instanceof SlugTakenError) // pick a different slug
|
|
771
|
+
* }
|
|
772
|
+
*/
|
|
773
|
+
create(input: CreateAppInput): Promise<AppResponse>;
|
|
774
|
+
/**
|
|
775
|
+
* List apps in the caller's tenant, paginated.
|
|
776
|
+
*
|
|
777
|
+
* @example happy
|
|
778
|
+
* const page = await sdk.apps.list({ pageSize: 50 })
|
|
779
|
+
* console.log(page.total, page.items.length)
|
|
780
|
+
*
|
|
781
|
+
* @example failure
|
|
782
|
+
* // permission denied (not a tenant member):
|
|
783
|
+
* try { await sdk.apps.list() }
|
|
784
|
+
* catch (e) { if (e instanceof PermissionDeniedError) /* request grant *\/ }
|
|
785
|
+
*/
|
|
786
|
+
list(opts?: ListOptions): Promise<PaginatedList<AppResponse>>;
|
|
787
|
+
/**
|
|
788
|
+
* Iterate every app across all pages. Yields each item; emits a
|
|
789
|
+
* `{type:'drift', addedSince:N}` item if backend's total grows mid-scan.
|
|
790
|
+
*
|
|
791
|
+
* @example happy
|
|
792
|
+
* for await (const it of sdk.apps.listAll({ pageSize: 100 })) {
|
|
793
|
+
* if (it.type === 'item') process(it.value)
|
|
794
|
+
* else if (it.type === 'drift') console.warn(`${it.addedSince} added during scan`)
|
|
795
|
+
* }
|
|
796
|
+
*/
|
|
797
|
+
listAll(opts?: ListAllOptions): AsyncGenerator<ListAllItem<AppResponse>>;
|
|
798
|
+
/**
|
|
799
|
+
* Fetch a single app by ID.
|
|
800
|
+
*
|
|
801
|
+
* @example happy
|
|
802
|
+
* const app = await sdk.apps.get('app_abc')
|
|
803
|
+
*
|
|
804
|
+
* @example failure
|
|
805
|
+
* try { await sdk.apps.get('app_does_not_exist') }
|
|
806
|
+
* catch (e) {
|
|
807
|
+
* if (e instanceof NotFoundError) /* abort or pick different app *\/
|
|
808
|
+
* if (e instanceof PermanentlyDeletedError) /* 410 — irrecoverable *\/
|
|
809
|
+
* }
|
|
810
|
+
*/
|
|
811
|
+
get(appId: string): Promise<AppResponse>;
|
|
812
|
+
/**
|
|
813
|
+
* Partial-update an app.
|
|
814
|
+
*
|
|
815
|
+
* @example happy
|
|
816
|
+
* const app = await sdk.apps.update('app_abc', { name: 'Renamed' })
|
|
817
|
+
*
|
|
818
|
+
* @example failure
|
|
819
|
+
* try { await sdk.apps.update('app_x', { visibility: 'public' }) }
|
|
820
|
+
* catch (e) {
|
|
821
|
+
* if (e instanceof ConflictError) /* requires publication approval *\/
|
|
822
|
+
* if (e instanceof PermissionDeniedError) /* not owner / admin *\/
|
|
823
|
+
* }
|
|
824
|
+
*/
|
|
825
|
+
update(appId: string, patch: UpdateAppInput): Promise<AppResponse>;
|
|
826
|
+
/**
|
|
827
|
+
* Soft-delete an app. Calling delete twice is safe — second call returns
|
|
828
|
+
* `AlreadyDeletedError` (409). The app row stays in DB for the retention
|
|
829
|
+
* window and can be hard-purged by platform admin separately.
|
|
830
|
+
*
|
|
831
|
+
* @example happy
|
|
832
|
+
* await sdk.apps.delete('app_abc') // first call OK
|
|
833
|
+
*
|
|
834
|
+
* @example failure
|
|
835
|
+
* try { await sdk.apps.delete('app_abc') }
|
|
836
|
+
* catch (e) { if (e instanceof AlreadyDeletedError) /* already deleted *\/ }
|
|
837
|
+
*/
|
|
838
|
+
delete(appId: string): Promise<void>;
|
|
839
|
+
/**
|
|
840
|
+
* Hard-delete (purge) an app. Requires the app to be soft-deleted first —
|
|
841
|
+
* calling on an active app returns `NotDeletedError` (409). Irreversible:
|
|
842
|
+
* physical schema + rows are dropped server-side.
|
|
843
|
+
*
|
|
844
|
+
* @example happy
|
|
845
|
+
* await sdk.apps.delete('app_abc') // soft-delete first
|
|
846
|
+
* await sdk.apps.permanent('app_abc') // then hard-purge
|
|
847
|
+
*
|
|
848
|
+
* @example failure
|
|
849
|
+
* try { await sdk.apps.permanent('app_active') }
|
|
850
|
+
* catch (e) { if (e instanceof NotDeletedError) /* must soft-delete first *\/ }
|
|
851
|
+
*/
|
|
852
|
+
permanent(appId: string): Promise<void>;
|
|
853
|
+
/**
|
|
854
|
+
* Get a presigned PUT URL for uploading the app icon. The caller must
|
|
855
|
+
* `PUT` the binary directly to `uploadUrl` with the matching `Content-Type`
|
|
856
|
+
* header; `getUrl` is the public/CDN URL where the icon will be served after
|
|
857
|
+
* upload completes.
|
|
858
|
+
*
|
|
859
|
+
* Unsupported MIME types are rejected with 400.
|
|
860
|
+
*
|
|
861
|
+
* @example happy
|
|
862
|
+
* const { uploadUrl, getUrl } = await sdk.apps.signIconUploadURL('app_abc', { contentType: 'image/png' })
|
|
863
|
+
* await fetch(uploadUrl, { method: 'PUT', body: imageBlob, headers: { 'Content-Type': 'image/png' } })
|
|
864
|
+
* await sdk.apps.update('app_abc', { iconUrl: getUrl })
|
|
865
|
+
*/
|
|
866
|
+
signIconUploadURL(appId: string, input: SignIconUploadInput): Promise<SignIconUploadResult>;
|
|
867
|
+
/**
|
|
868
|
+
* Get a presigned PUT URL for the dark-mode app icon. Same semantics as
|
|
869
|
+
* `signIconUploadURL` but writes to the `icon_dark_url` field.
|
|
870
|
+
*
|
|
871
|
+
* @example happy
|
|
872
|
+
* const { uploadUrl } = await sdk.apps.signIconDarkUploadURL('app_abc', { contentType: 'image/svg+xml' })
|
|
873
|
+
*/
|
|
874
|
+
signIconDarkUploadURL(appId: string, input: SignIconUploadInput): Promise<SignIconUploadResult>;
|
|
875
|
+
private signIconImpl;
|
|
876
|
+
/**
|
|
877
|
+
* List apps the caller has been granted access to (not necessarily owned).
|
|
878
|
+
* Useful for "apps in my dashboard" type views.
|
|
879
|
+
*
|
|
880
|
+
* Backend route is `/api/v1/users/me/apps` — surfaced here under `sdk.apps`
|
|
881
|
+
* to avoid a `sdk.users.*` namespace just for this one method (eng review #3).
|
|
882
|
+
*
|
|
883
|
+
* @example happy
|
|
884
|
+
* const mine = await sdk.apps.listMine()
|
|
885
|
+
* for (const a of mine) console.log(a.slug, a.publicationStatus)
|
|
886
|
+
*/
|
|
887
|
+
listMine(): Promise<AppResponse[]>;
|
|
888
|
+
}
|
|
889
|
+
interface SignIconUploadInput {
|
|
890
|
+
/** MIME type of the asset, e.g. `image/png`. Backend rejects unsupported types. */
|
|
891
|
+
contentType: string;
|
|
892
|
+
}
|
|
893
|
+
interface SignIconUploadResult {
|
|
894
|
+
/** Presigned PUT URL the caller uploads the binary to. Expires shortly. */
|
|
895
|
+
uploadUrl: string;
|
|
896
|
+
/** Public/CDN URL the icon will be served from once upload completes. */
|
|
897
|
+
getUrl: string;
|
|
898
|
+
/** ISO timestamp when the presigned URL expires. */
|
|
899
|
+
expiresAt?: string;
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
interface AppAccess {
|
|
903
|
+
id: string;
|
|
904
|
+
appId: string;
|
|
905
|
+
userId: string;
|
|
906
|
+
grantedAt: string;
|
|
907
|
+
}
|
|
908
|
+
declare class AppsAccessMixin {
|
|
909
|
+
private readonly http;
|
|
910
|
+
constructor(http: HttpClient);
|
|
911
|
+
/**
|
|
912
|
+
* Self-grant access to an app. Caller must have authenticated identity and
|
|
913
|
+
* the app must be reachable (own tenant, or `public` visibility).
|
|
914
|
+
*
|
|
915
|
+
* Backend convention: owner always has implicit access — calling this on a
|
|
916
|
+
* self-owned app returns `AlreadyAccessedError` (409). Second-time grants
|
|
917
|
+
* also return `AlreadyAccessedError`. Private apps for non-members return
|
|
918
|
+
* `AccessDeniedError` (403).
|
|
919
|
+
*
|
|
920
|
+
* @example happy
|
|
921
|
+
* const grant = await sdk.apps.access.grant('app_abc')
|
|
922
|
+
* console.log(grant.grantedAt)
|
|
923
|
+
*
|
|
924
|
+
* @example failure
|
|
925
|
+
* try { await sdk.apps.access.grant('app_abc') }
|
|
926
|
+
* catch (e) {
|
|
927
|
+
* if (e instanceof AlreadyAccessedError) /* already have access *\/
|
|
928
|
+
* if (e instanceof AccessDeniedError) /* private app, no membership *\/
|
|
929
|
+
* }
|
|
930
|
+
*/
|
|
931
|
+
grant(appId: string): Promise<AppAccess>;
|
|
932
|
+
/**
|
|
933
|
+
* Revoke own access to an app. Backend route is `DELETE /apps/{id}/access/me`
|
|
934
|
+
* (the `/me` suffix mirrors the self-revoke convention).
|
|
935
|
+
*
|
|
936
|
+
* Idempotent at the SDK level only insofar as the backend treats a missing
|
|
937
|
+
* grant as 404 — callers wanting fire-and-forget should ignore `NotFoundError`.
|
|
938
|
+
*
|
|
939
|
+
* @example happy
|
|
940
|
+
* await sdk.apps.access.revoke('app_abc')
|
|
941
|
+
*
|
|
942
|
+
* @example failure
|
|
943
|
+
* try { await sdk.apps.access.revoke('app_abc') }
|
|
944
|
+
* catch (e) { if (e instanceof NotFoundError) /* no grant to revoke *\/ }
|
|
945
|
+
*/
|
|
946
|
+
revoke(appId: string): Promise<void>;
|
|
947
|
+
/**
|
|
948
|
+
* Fetch caller's own access record for the app. Returns `null` if the caller
|
|
949
|
+
* has no grant (backend returns 404 — SDK normalizes to null for ergonomics).
|
|
950
|
+
*
|
|
951
|
+
* @example happy
|
|
952
|
+
* const grant = await sdk.apps.access.me('app_abc')
|
|
953
|
+
* if (grant) console.log('have access since', grant.grantedAt)
|
|
954
|
+
* else console.log('no access')
|
|
955
|
+
*/
|
|
956
|
+
me(appId: string): Promise<AppAccess | null>;
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
interface AppCategory {
|
|
960
|
+
id: string;
|
|
961
|
+
tenantId?: string;
|
|
962
|
+
slug: string;
|
|
963
|
+
name: string;
|
|
964
|
+
description?: string;
|
|
965
|
+
[key: string]: unknown;
|
|
966
|
+
}
|
|
967
|
+
interface CreateCategoryInput {
|
|
968
|
+
slug: string;
|
|
969
|
+
name: string;
|
|
970
|
+
description?: string;
|
|
971
|
+
}
|
|
972
|
+
declare class AppsCategoriesMixin {
|
|
973
|
+
private readonly http;
|
|
974
|
+
constructor(http: HttpClient);
|
|
975
|
+
list(tenantIdOrSlug: string, opts?: PageRequestOptions): Promise<PaginatedList<AppCategory>>;
|
|
976
|
+
create(tenantIdOrSlug: string, input: CreateCategoryInput, opts?: RequestOptions): Promise<AppCategory>;
|
|
977
|
+
get(tenantIdOrSlug: string, categoryId: string, opts?: RequestOptions): Promise<AppCategory>;
|
|
978
|
+
update(tenantIdOrSlug: string, categoryId: string, patch: Partial<CreateCategoryInput>, opts?: RequestOptions): Promise<AppCategory>;
|
|
979
|
+
delete(tenantIdOrSlug: string, categoryId: string, opts?: RequestOptions): Promise<void>;
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
interface Comment {
|
|
983
|
+
id: string;
|
|
984
|
+
appId: string;
|
|
985
|
+
authorId: string;
|
|
986
|
+
body: string;
|
|
987
|
+
createdAt: string;
|
|
988
|
+
updatedAt: string;
|
|
989
|
+
deletedAt: string | null;
|
|
990
|
+
}
|
|
991
|
+
interface AddCommentInput {
|
|
992
|
+
body: string;
|
|
993
|
+
}
|
|
994
|
+
declare class AppsCommentsMixin {
|
|
995
|
+
private readonly http;
|
|
996
|
+
constructor(http: HttpClient);
|
|
997
|
+
/**
|
|
998
|
+
* Add a comment to an app. Body length is validated client-side (1-500 chars).
|
|
999
|
+
*
|
|
1000
|
+
* @example happy
|
|
1001
|
+
* const c = await sdk.apps.comments.add('app_abc', { body: 'looks great!' })
|
|
1002
|
+
*
|
|
1003
|
+
* @example failure
|
|
1004
|
+
* try { await sdk.apps.comments.add('app_x', { body: '' }) }
|
|
1005
|
+
* catch (e) { if (e instanceof ValidationError) /* fix body length *\/ }
|
|
1006
|
+
*/
|
|
1007
|
+
add(appId: string, input: AddCommentInput): Promise<Comment>;
|
|
1008
|
+
/**
|
|
1009
|
+
* List comments on an app, newest first.
|
|
1010
|
+
*
|
|
1011
|
+
* @example happy
|
|
1012
|
+
* const page = await sdk.apps.comments.list('app_abc', { pageSize: 50 })
|
|
1013
|
+
*/
|
|
1014
|
+
list(appId: string, opts?: ListOptions): Promise<PaginatedList<Comment>>;
|
|
1015
|
+
/**
|
|
1016
|
+
* Iterate every comment across pages. Emits a `{type:'drift'}` event when
|
|
1017
|
+
* the backend's total grows mid-scan (new comment added during iteration).
|
|
1018
|
+
*
|
|
1019
|
+
* @example happy
|
|
1020
|
+
* for await (const it of sdk.apps.comments.listAll('app_abc', { pageSize: 100 })) {
|
|
1021
|
+
* if (it.type === 'item') process(it.value)
|
|
1022
|
+
* else if (it.type === 'drift') console.warn(`${it.addedSince} new comments during scan`)
|
|
1023
|
+
* }
|
|
1024
|
+
*/
|
|
1025
|
+
listAll(appId: string, opts?: ListAllOptions): AsyncGenerator<ListAllItem<Comment>>;
|
|
1026
|
+
/**
|
|
1027
|
+
* Delete a comment by ID. Author can delete own; platform/app admins can
|
|
1028
|
+
* delete any. Backend route is global (`/comments/{id}`) — appId is implicit
|
|
1029
|
+
* from the comment row.
|
|
1030
|
+
*
|
|
1031
|
+
* @example happy
|
|
1032
|
+
* await sdk.apps.comments.delete('cmt_abc')
|
|
1033
|
+
*
|
|
1034
|
+
* @example failure
|
|
1035
|
+
* try { await sdk.apps.comments.delete('cmt_other_user') }
|
|
1036
|
+
* catch (e) {
|
|
1037
|
+
* if (e instanceof PermissionDeniedError) /* not author / not admin *\/
|
|
1038
|
+
* if (e instanceof AlreadyDeletedError) /* already deleted *\/
|
|
1039
|
+
* }
|
|
1040
|
+
*/
|
|
1041
|
+
delete(commentId: string): Promise<void>;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
interface DiscoverAppsOptions extends PageRequestOptions {
|
|
1045
|
+
q?: string;
|
|
1046
|
+
category?: string;
|
|
1047
|
+
sort?: 'newest' | 'likes' | 'subscribers' | 'name';
|
|
1048
|
+
visibility?: 'private' | 'tenant' | 'public';
|
|
1049
|
+
}
|
|
1050
|
+
declare class AppsDiscoverMixin {
|
|
1051
|
+
private readonly http;
|
|
1052
|
+
private readonly defaultTenantSlug?;
|
|
1053
|
+
constructor(http: HttpClient, defaultTenantSlug?: string | undefined);
|
|
1054
|
+
search(opts?: DiscoverAppsOptions): Promise<PaginatedList<AppResponse>>;
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
interface GitConnection {
|
|
1058
|
+
connected: true;
|
|
1059
|
+
id: string;
|
|
1060
|
+
appId: string;
|
|
1061
|
+
repoFullName: string;
|
|
1062
|
+
branch: string;
|
|
1063
|
+
installationId: string;
|
|
1064
|
+
connectedAt: string;
|
|
1065
|
+
}
|
|
1066
|
+
interface GitConnectionSetup {
|
|
1067
|
+
connected: false;
|
|
1068
|
+
installUrl: string;
|
|
1069
|
+
}
|
|
1070
|
+
type GitConnectionStatus = GitConnection | GitConnectionSetup;
|
|
1071
|
+
interface ConnectGitInput {
|
|
1072
|
+
repoFullName: string;
|
|
1073
|
+
branch: string;
|
|
1074
|
+
installationId: string;
|
|
1075
|
+
}
|
|
1076
|
+
interface UpdateGitConnectionInput {
|
|
1077
|
+
branch: string;
|
|
1078
|
+
}
|
|
1079
|
+
interface GithubInstallStart {
|
|
1080
|
+
redirectUrl: string;
|
|
1081
|
+
}
|
|
1082
|
+
interface InstallStartInput {
|
|
1083
|
+
redirectUri?: string;
|
|
1084
|
+
}
|
|
1085
|
+
declare class AppsGitMixin {
|
|
1086
|
+
private readonly http;
|
|
1087
|
+
constructor(http: HttpClient);
|
|
1088
|
+
/**
|
|
1089
|
+
* Fetch the current GitHub repository connection for an app.
|
|
1090
|
+
*/
|
|
1091
|
+
get(appId: string): Promise<GitConnectionStatus>;
|
|
1092
|
+
/**
|
|
1093
|
+
* Connect a GitHub repository to an app. Requires a prior GitHub App
|
|
1094
|
+
* installation (see `installStart`). The `repoFullName` follows GitHub's
|
|
1095
|
+
* `owner/repo` convention; `branch` must exist on the remote.
|
|
1096
|
+
*
|
|
1097
|
+
* @example happy
|
|
1098
|
+
* const conn = await sdk.apps.git.connect('app_abc', {
|
|
1099
|
+
* repoFullName: 'my-org/my-repo',
|
|
1100
|
+
* branch: 'main',
|
|
1101
|
+
* installationId: '12345',
|
|
1102
|
+
* })
|
|
1103
|
+
*
|
|
1104
|
+
* @example failure
|
|
1105
|
+
* try { await sdk.apps.git.connect('app_x', { repoFullName: 'invalid', branch: '', installationId: '' }) }
|
|
1106
|
+
* catch (e) { if (e instanceof ValidationError) /* fix repo / branch *\/ }
|
|
1107
|
+
*/
|
|
1108
|
+
connect(appId: string, input: ConnectGitInput): Promise<GitConnection>;
|
|
1109
|
+
/**
|
|
1110
|
+
* Update the auto-deploy branch for an existing GitHub connection.
|
|
1111
|
+
*/
|
|
1112
|
+
update(appId: string, input: UpdateGitConnectionInput): Promise<GitConnection>;
|
|
1113
|
+
/**
|
|
1114
|
+
* Disconnect the app's GitHub repository link.
|
|
1115
|
+
*/
|
|
1116
|
+
disconnect(appId: string): Promise<void>;
|
|
1117
|
+
/**
|
|
1118
|
+
* Start the GitHub App installation OAuth flow. Returns a redirect URL the
|
|
1119
|
+
* caller (typically a CLI / web flow) must open in a browser. After the user
|
|
1120
|
+
* approves, GitHub posts back to AX Hub with the installation ID, which can
|
|
1121
|
+
* then be used in `connect`.
|
|
1122
|
+
*
|
|
1123
|
+
* @example happy
|
|
1124
|
+
* const { redirectUrl } = await sdk.apps.git.installStart('app_abc', {
|
|
1125
|
+
* redirectUri: 'http://localhost:3000/gh/callback',
|
|
1126
|
+
* })
|
|
1127
|
+
* open(redirectUrl)
|
|
1128
|
+
*/
|
|
1129
|
+
installStart(appId: string, input?: InstallStartInput): Promise<GithubInstallStart>;
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
interface LikeResult {
|
|
1133
|
+
inserted: boolean;
|
|
1134
|
+
}
|
|
1135
|
+
interface UnlikeResult {
|
|
1136
|
+
deleted: boolean;
|
|
1137
|
+
}
|
|
1138
|
+
interface LikeStatus {
|
|
1139
|
+
liked: boolean;
|
|
1140
|
+
}
|
|
1141
|
+
declare class AppsLikesMixin {
|
|
1142
|
+
private readonly http;
|
|
1143
|
+
constructor(http: HttpClient);
|
|
1144
|
+
/**
|
|
1145
|
+
* Like an app. Idempotent — second call returns `{ inserted: false }`. The
|
|
1146
|
+
* app's denormalized `likeCount` is updated server-side only when
|
|
1147
|
+
* `inserted = true`.
|
|
1148
|
+
*
|
|
1149
|
+
* @example happy
|
|
1150
|
+
* const { inserted } = await sdk.apps.likes.like('app_abc')
|
|
1151
|
+
* if (inserted) console.log('first time like')
|
|
1152
|
+
*/
|
|
1153
|
+
like(appId: string): Promise<LikeResult>;
|
|
1154
|
+
/**
|
|
1155
|
+
* Unlike an app. Idempotent — second call returns `{ deleted: false }`.
|
|
1156
|
+
*
|
|
1157
|
+
* @example happy
|
|
1158
|
+
* const { deleted } = await sdk.apps.likes.unlike('app_abc')
|
|
1159
|
+
*/
|
|
1160
|
+
unlike(appId: string): Promise<UnlikeResult>;
|
|
1161
|
+
/**
|
|
1162
|
+
* Check if caller has liked the app.
|
|
1163
|
+
*
|
|
1164
|
+
* @example happy
|
|
1165
|
+
* const { liked } = await sdk.apps.likes.me('app_abc')
|
|
1166
|
+
*/
|
|
1167
|
+
me(appId: string): Promise<LikeStatus>;
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
interface OAuthClient {
|
|
1171
|
+
id: string;
|
|
1172
|
+
appId: string;
|
|
1173
|
+
name: string;
|
|
1174
|
+
clientId: string;
|
|
1175
|
+
redirectUris: string[];
|
|
1176
|
+
scopes: string[];
|
|
1177
|
+
createdAt: string;
|
|
1178
|
+
}
|
|
1179
|
+
/**
|
|
1180
|
+
* Returned ONLY by `create`. The `clientSecret` is the raw secret — backend
|
|
1181
|
+
* stores a hash and never returns it again on subsequent `list`/`get`. PAT
|
|
1182
|
+
* pattern: store this immediately on the agent side; losing it requires
|
|
1183
|
+
* creating a new client.
|
|
1184
|
+
*/
|
|
1185
|
+
interface OAuthClientWithSecret extends OAuthClient {
|
|
1186
|
+
/** Raw secret. Surfaced exactly once; backend persists only the hash. */
|
|
1187
|
+
clientSecret: string;
|
|
1188
|
+
}
|
|
1189
|
+
interface CreateOAuthClientInput {
|
|
1190
|
+
name: string;
|
|
1191
|
+
redirectUris: string[];
|
|
1192
|
+
scopes: string[];
|
|
1193
|
+
type?: 'public' | 'confidential';
|
|
1194
|
+
tokenEndpointAuthMethod?: 'client_secret_basic' | 'client_secret_post' | 'none';
|
|
1195
|
+
allowedGrantTypes?: string[];
|
|
1196
|
+
}
|
|
1197
|
+
declare class AppsOAuthClientsMixin {
|
|
1198
|
+
private readonly http;
|
|
1199
|
+
constructor(http: HttpClient);
|
|
1200
|
+
/**
|
|
1201
|
+
* Create an OAuth client for an app. The `clientSecret` field in the response
|
|
1202
|
+
* is the **raw secret** — surfaced exactly once. Store it immediately; backend
|
|
1203
|
+
* keeps only a hash. Lose it and the client must be deleted + recreated.
|
|
1204
|
+
*
|
|
1205
|
+
* Empty `scopes` is rejected client-side (400 `empty_scopes` server-side).
|
|
1206
|
+
*
|
|
1207
|
+
* @example happy
|
|
1208
|
+
* const c = await sdk.apps.oauthClients.create('app_abc', {
|
|
1209
|
+
* name: 'web-app',
|
|
1210
|
+
* redirectUris: ['https://myapp.com/cb'],
|
|
1211
|
+
* scopes: ['read', 'write'],
|
|
1212
|
+
* })
|
|
1213
|
+
* storeSecret(c.clientSecret) // ONLY chance to capture it
|
|
1214
|
+
*
|
|
1215
|
+
* @example failure
|
|
1216
|
+
* try { await sdk.apps.oauthClients.create('app_x', { name: '', redirectUris: [], scopes: [] }) }
|
|
1217
|
+
* catch (e) { if (e instanceof ValidationError) /* fix inputs *\/ }
|
|
1218
|
+
*/
|
|
1219
|
+
create(appId: string, input: CreateOAuthClientInput): Promise<OAuthClientWithSecret>;
|
|
1220
|
+
/**
|
|
1221
|
+
* Delete an OAuth client by ID. Backend route is global (`/oauth-clients/{id}`).
|
|
1222
|
+
* After this, any tokens issued via this client become unusable.
|
|
1223
|
+
*
|
|
1224
|
+
* @example happy
|
|
1225
|
+
* await sdk.apps.oauthClients.delete('oac_abc')
|
|
1226
|
+
*/
|
|
1227
|
+
delete(clientId: string): Promise<void>;
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
type PublicationRequestStatus = 'pending' | 'approved' | 'rejected';
|
|
1231
|
+
interface PublicationRequest {
|
|
1232
|
+
id: string;
|
|
1233
|
+
appId: string;
|
|
1234
|
+
requesterId: string;
|
|
1235
|
+
reason?: string;
|
|
1236
|
+
status: PublicationRequestStatus;
|
|
1237
|
+
reviewerId?: string;
|
|
1238
|
+
reviewerComment?: string;
|
|
1239
|
+
createdAt: string;
|
|
1240
|
+
updatedAt: string;
|
|
1241
|
+
settledAt?: string | null;
|
|
1242
|
+
}
|
|
1243
|
+
interface SubmitPublicationInput {
|
|
1244
|
+
reason?: string;
|
|
1245
|
+
}
|
|
1246
|
+
interface UnpublishInput {
|
|
1247
|
+
comment?: string;
|
|
1248
|
+
}
|
|
1249
|
+
declare class AppsPublicationMixin {
|
|
1250
|
+
private readonly http;
|
|
1251
|
+
constructor(http: HttpClient);
|
|
1252
|
+
/**
|
|
1253
|
+
* Submit an app for public release review. Owner-only. The app must be in
|
|
1254
|
+
* `draft` or previously-rejected state; second submit while pending returns
|
|
1255
|
+
* `PendingExistsError` (409).
|
|
1256
|
+
*
|
|
1257
|
+
* @example happy
|
|
1258
|
+
* const pr = await sdk.apps.publication.submit('app_abc', { reason: 'Ready for v1' })
|
|
1259
|
+
* console.log(pr.status) // 'pending'
|
|
1260
|
+
*
|
|
1261
|
+
* @example failure
|
|
1262
|
+
* try { await sdk.apps.publication.submit('app_abc') }
|
|
1263
|
+
* catch (e) { if (e instanceof PendingExistsError) /* already pending review *\/ }
|
|
1264
|
+
*/
|
|
1265
|
+
submit(appId: string, input?: SubmitPublicationInput): Promise<PublicationRequest>;
|
|
1266
|
+
/**
|
|
1267
|
+
* List publication-request history for an app, newest first.
|
|
1268
|
+
*
|
|
1269
|
+
* @example happy
|
|
1270
|
+
* const page = await sdk.apps.publication.list('app_abc', { pageSize: 20 })
|
|
1271
|
+
* for (const pr of page.items) console.log(pr.status, pr.reviewerComment)
|
|
1272
|
+
*/
|
|
1273
|
+
list(appId: string, opts?: ListOptions): Promise<PaginatedList<PublicationRequest>>;
|
|
1274
|
+
/**
|
|
1275
|
+
* Take a published app off the public catalog. Owner / admin only. App must
|
|
1276
|
+
* be in `approved` + `public` state; otherwise `InvalidStateTransitionError`.
|
|
1277
|
+
*
|
|
1278
|
+
* @example happy
|
|
1279
|
+
* const app = await sdk.apps.publication.unpublish('app_abc', { comment: 'Maintenance' })
|
|
1280
|
+
* console.log(app.publicationStatus, app.visibility) // 'draft', 'tenant'
|
|
1281
|
+
*
|
|
1282
|
+
* @example failure
|
|
1283
|
+
* try { await sdk.apps.publication.unpublish('app_x') }
|
|
1284
|
+
* catch (e) { if (e instanceof InvalidStateTransitionError) /* not currently public *\/ }
|
|
1285
|
+
*/
|
|
1286
|
+
unpublish(appId: string, input?: UnpublishInput): Promise<AppResponse>;
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
type ColumnType = 'text' | 'int' | 'bigint' | 'float' | 'numeric' | 'bool' | 'timestamp' | 'timestamptz' | 'json' | 'jsonb' | 'uuid';
|
|
1290
|
+
interface TableColumn {
|
|
1291
|
+
name: string;
|
|
1292
|
+
type: ColumnType;
|
|
1293
|
+
nullable?: boolean;
|
|
1294
|
+
default?: string | number | boolean | null;
|
|
1295
|
+
}
|
|
1296
|
+
interface AppTable {
|
|
1297
|
+
appId: string;
|
|
1298
|
+
schemaName: string;
|
|
1299
|
+
tableName: string;
|
|
1300
|
+
ownerColumn: string;
|
|
1301
|
+
columns: TableColumn[];
|
|
1302
|
+
createdAt: string;
|
|
1303
|
+
updatedAt: string;
|
|
1304
|
+
}
|
|
1305
|
+
interface TableIndex {
|
|
1306
|
+
name: string;
|
|
1307
|
+
columns: string[];
|
|
1308
|
+
unique?: boolean;
|
|
1309
|
+
}
|
|
1310
|
+
interface TableConstraint {
|
|
1311
|
+
name: string;
|
|
1312
|
+
type: string;
|
|
1313
|
+
columns?: string[];
|
|
1314
|
+
}
|
|
1315
|
+
interface TableSchema extends AppTable {
|
|
1316
|
+
indexes: TableIndex[];
|
|
1317
|
+
constraints: TableConstraint[];
|
|
1318
|
+
rowCount?: number;
|
|
1319
|
+
sizeBytes?: number;
|
|
1320
|
+
}
|
|
1321
|
+
type GrantPrincipalType = 'user' | 'tenant' | 'app';
|
|
1322
|
+
type GrantScope = 'read' | 'write' | 'delete' | 'admin';
|
|
1323
|
+
interface TableGrant {
|
|
1324
|
+
id: string;
|
|
1325
|
+
appId: string;
|
|
1326
|
+
tableName: string;
|
|
1327
|
+
principalType: GrantPrincipalType;
|
|
1328
|
+
principalId: string;
|
|
1329
|
+
scopes: GrantScope[];
|
|
1330
|
+
createdAt: string;
|
|
1331
|
+
}
|
|
1332
|
+
interface CreateTableInput {
|
|
1333
|
+
name: string;
|
|
1334
|
+
ownerColumn: string;
|
|
1335
|
+
columns: TableColumn[];
|
|
1336
|
+
}
|
|
1337
|
+
interface AddColumnInput {
|
|
1338
|
+
name: string;
|
|
1339
|
+
type: ColumnType;
|
|
1340
|
+
nullable?: boolean;
|
|
1341
|
+
default?: string | number | boolean | null;
|
|
1342
|
+
}
|
|
1343
|
+
interface AddGrantInput {
|
|
1344
|
+
principalType: GrantPrincipalType;
|
|
1345
|
+
principalId: string;
|
|
1346
|
+
scopes: GrantScope[];
|
|
1347
|
+
}
|
|
1348
|
+
declare class AppsTablesMixin {
|
|
1349
|
+
private readonly http;
|
|
1350
|
+
constructor(http: HttpClient);
|
|
1351
|
+
/**
|
|
1352
|
+
* List all tables in an app's schema.
|
|
1353
|
+
*
|
|
1354
|
+
* @example happy
|
|
1355
|
+
* const tables = await sdk.apps.tables.list('app_abc')
|
|
1356
|
+
* for (const t of tables) console.log(t.tableName, t.columns.length)
|
|
1357
|
+
*/
|
|
1358
|
+
list(appId: string): Promise<AppTable[]>;
|
|
1359
|
+
/**
|
|
1360
|
+
* Create a new table. Name must match `^[a-z][a-z0-9_]{0,62}$` — validation
|
|
1361
|
+
* happens client-side before any network round-trip. ownerColumn must be
|
|
1362
|
+
* present in `columns`.
|
|
1363
|
+
*
|
|
1364
|
+
* @example happy
|
|
1365
|
+
* const t = await sdk.apps.tables.create('app_abc', {
|
|
1366
|
+
* name: 'tasks',
|
|
1367
|
+
* ownerColumn: 'user_id',
|
|
1368
|
+
* columns: [
|
|
1369
|
+
* { name: 'user_id', type: 'uuid', nullable: false },
|
|
1370
|
+
* { name: 'title', type: 'text', nullable: false },
|
|
1371
|
+
* { name: 'done', type: 'bool', default: false },
|
|
1372
|
+
* ],
|
|
1373
|
+
* })
|
|
1374
|
+
*
|
|
1375
|
+
* @example failure
|
|
1376
|
+
* try { await sdk.apps.tables.create('app_x', { name: 'tasks', ownerColumn: 'u', columns: [] }) }
|
|
1377
|
+
* catch (e) { if (e instanceof SchemaNameTakenError) /* table name taken *\/ }
|
|
1378
|
+
*/
|
|
1379
|
+
create(appId: string, input: CreateTableInput): Promise<AppTable>;
|
|
1380
|
+
/**
|
|
1381
|
+
* Drop a table. Irreversible — backend permanently removes the physical
|
|
1382
|
+
* table on success.
|
|
1383
|
+
*
|
|
1384
|
+
* @example happy
|
|
1385
|
+
* await sdk.apps.tables.delete('app_abc', 'tasks_old')
|
|
1386
|
+
*/
|
|
1387
|
+
delete(appId: string, tableName: string): Promise<void>;
|
|
1388
|
+
/**
|
|
1389
|
+
* Add a column to an existing table. Column name must be unique within the
|
|
1390
|
+
* table; duplicate names return 400 `duplicate`.
|
|
1391
|
+
*
|
|
1392
|
+
* @example happy
|
|
1393
|
+
* await sdk.apps.tables.addColumn('app_abc', 'tasks', { name: 'priority', type: 'int', default: 0 })
|
|
1394
|
+
*/
|
|
1395
|
+
addColumn(appId: string, tableName: string, input: AddColumnInput): Promise<TableColumn>;
|
|
1396
|
+
/**
|
|
1397
|
+
* Drop a column. Cannot drop the `ownerColumn` — backend returns 409
|
|
1398
|
+
* `cannot_drop_owner_column`.
|
|
1399
|
+
*
|
|
1400
|
+
* @example happy
|
|
1401
|
+
* await sdk.apps.tables.dropColumn('app_abc', 'tasks', 'priority')
|
|
1402
|
+
*/
|
|
1403
|
+
dropColumn(appId: string, tableName: string, columnName: string): Promise<void>;
|
|
1404
|
+
/**
|
|
1405
|
+
* List grants on a table.
|
|
1406
|
+
*
|
|
1407
|
+
* @example happy
|
|
1408
|
+
* const grants = await sdk.apps.tables.listGrants('app_abc', 'tasks')
|
|
1409
|
+
*/
|
|
1410
|
+
listGrants(appId: string, tableName: string): Promise<TableGrant[]>;
|
|
1411
|
+
/**
|
|
1412
|
+
* Grant access on a table to a principal (user/tenant/app). Cross-tenant
|
|
1413
|
+
* grants are rejected with 403 (a tenant can only grant to its own members).
|
|
1414
|
+
*
|
|
1415
|
+
* @example happy
|
|
1416
|
+
* const g = await sdk.apps.tables.addGrant('app_abc', 'tasks', {
|
|
1417
|
+
* principalType: 'user',
|
|
1418
|
+
* principalId: 'usr_xyz',
|
|
1419
|
+
* scopes: ['read', 'write'],
|
|
1420
|
+
* })
|
|
1421
|
+
*
|
|
1422
|
+
* @example failure
|
|
1423
|
+
* try { await sdk.withTenant('other').apps.tables.addGrant('app_abc', 'tasks', {...}) }
|
|
1424
|
+
* catch (e) { if (e instanceof PermissionDeniedError) /* cross-tenant *\/ }
|
|
1425
|
+
*/
|
|
1426
|
+
addGrant(appId: string, tableName: string, input: AddGrantInput): Promise<TableGrant>;
|
|
1427
|
+
/**
|
|
1428
|
+
* Revoke a table grant by ID.
|
|
1429
|
+
*
|
|
1430
|
+
* @example happy
|
|
1431
|
+
* await sdk.apps.tables.revokeGrant('app_abc', 'tasks', 'gnt_abc')
|
|
1432
|
+
*
|
|
1433
|
+
* @example failure
|
|
1434
|
+
* try { await sdk.apps.tables.revokeGrant('app_abc', 'tasks', 'gnt_abc') }
|
|
1435
|
+
* catch (e) { if (e instanceof AlreadyRevokedError) /* already gone *\/ }
|
|
1436
|
+
*/
|
|
1437
|
+
revokeGrant(appId: string, tableName: string, grantId: string): Promise<void>;
|
|
1438
|
+
/**
|
|
1439
|
+
* Inspect physical schema details for a dynamic table: columns, indexes,
|
|
1440
|
+
* constraints, and optional storage stats.
|
|
1441
|
+
*
|
|
1442
|
+
* @example happy
|
|
1443
|
+
* const schema = await sdk.apps.tables.inspect('app_abc', 'orders')
|
|
1444
|
+
* console.log(schema.indexes.map((i) => i.name))
|
|
1445
|
+
*/
|
|
1446
|
+
inspect(appId: string, tableName: string): Promise<TableSchema>;
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
interface AppTemplate {
|
|
1450
|
+
id: string;
|
|
1451
|
+
slug: string;
|
|
1452
|
+
name: string;
|
|
1453
|
+
description?: string;
|
|
1454
|
+
[key: string]: unknown;
|
|
1455
|
+
}
|
|
1456
|
+
declare class AppsTemplatesMixin {
|
|
1457
|
+
private readonly http;
|
|
1458
|
+
private readonly defaultTenantSlug?;
|
|
1459
|
+
constructor(http: HttpClient, defaultTenantSlug?: string | undefined);
|
|
1460
|
+
list(opts?: PageRequestOptions): Promise<PaginatedList<AppTemplate>>;
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
declare class AppsClient {
|
|
1464
|
+
private readonly crud;
|
|
1465
|
+
private readonly envVars;
|
|
1466
|
+
readonly publication: AppsPublicationMixin;
|
|
1467
|
+
readonly access: AppsAccessMixin;
|
|
1468
|
+
readonly categories: AppsCategoriesMixin;
|
|
1469
|
+
readonly discover: AppsDiscoverMixin;
|
|
1470
|
+
readonly likes: AppsLikesMixin;
|
|
1471
|
+
readonly comments: AppsCommentsMixin;
|
|
1472
|
+
readonly oauthClients: AppsOAuthClientsMixin;
|
|
1473
|
+
readonly git: AppsGitMixin;
|
|
1474
|
+
readonly tables: AppsTablesMixin;
|
|
1475
|
+
readonly templates: AppsTemplatesMixin;
|
|
1476
|
+
constructor(http: HttpClient, defaultTenantSlug?: string, defaultTenantId?: string);
|
|
1477
|
+
create: (...args: Parameters<AppsCrudMixin["create"]>) => Promise<AppResponse>;
|
|
1478
|
+
list: (...args: Parameters<AppsCrudMixin["list"]>) => Promise<PaginatedList<AppResponse>>;
|
|
1479
|
+
listAll: (...args: Parameters<AppsCrudMixin["listAll"]>) => AsyncGenerator<ListAllItem<AppResponse>, any, any>;
|
|
1480
|
+
get: (...args: Parameters<AppsCrudMixin["get"]>) => Promise<AppResponse>;
|
|
1481
|
+
update: (...args: Parameters<AppsCrudMixin["update"]>) => Promise<AppResponse>;
|
|
1482
|
+
delete: (...args: Parameters<AppsCrudMixin["delete"]>) => Promise<void>;
|
|
1483
|
+
permanent: (...args: Parameters<AppsCrudMixin["permanent"]>) => Promise<void>;
|
|
1484
|
+
signIconUploadURL: (...args: Parameters<AppsCrudMixin["signIconUploadURL"]>) => Promise<SignIconUploadResult>;
|
|
1485
|
+
signIconDarkUploadURL: (...args: Parameters<AppsCrudMixin["signIconDarkUploadURL"]>) => Promise<SignIconUploadResult>;
|
|
1486
|
+
/**
|
|
1487
|
+
* List apps the caller has been granted access to (not necessarily owned).
|
|
1488
|
+
* Wraps `GET /users/me/apps`. Distinct from {@link list} which returns all
|
|
1489
|
+
* apps in the resolved tenant; `listMine` is per-user scoped via the auth
|
|
1490
|
+
* principal in the token.
|
|
1491
|
+
*
|
|
1492
|
+
* @example happy
|
|
1493
|
+
* const accessible = await sdk.apps.listMine()
|
|
1494
|
+
* for (const a of accessible) console.log(a.slug)
|
|
1495
|
+
*/
|
|
1496
|
+
listMine: (...args: Parameters<AppsCrudMixin["listMine"]>) => Promise<AppResponse[]>;
|
|
1497
|
+
listEnvVars: (...args: Parameters<AppsEnvVarsMixin["listEnvVars"]>) => Promise<EnvVar[]>;
|
|
1498
|
+
setEnvVar: (...args: Parameters<AppsEnvVarsMixin["setEnvVar"]>) => Promise<void>;
|
|
1499
|
+
getEnvVar: (...args: Parameters<AppsEnvVarsMixin["getEnvVar"]>) => Promise<EnvVar>;
|
|
1500
|
+
deleteEnvVar: (...args: Parameters<AppsEnvVarsMixin["deleteEnvVar"]>) => Promise<void>;
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
type ColumnPrimitive = 'uuid' | 'string' | 'number' | 'integer' | 'boolean' | 'timestamp' | 'json';
|
|
1504
|
+
type EnumColumn<V extends readonly string[]> = {
|
|
1505
|
+
type: 'enum';
|
|
1506
|
+
values: V;
|
|
1507
|
+
};
|
|
1508
|
+
type ColumnDef = ColumnPrimitive | EnumColumn<readonly string[]>;
|
|
1509
|
+
type SchemaShape = Record<string, ColumnDef>;
|
|
1510
|
+
interface DataColumn<Name extends string = string, Def extends ColumnDef = ColumnDef> {
|
|
1511
|
+
table: string;
|
|
1512
|
+
name: Name;
|
|
1513
|
+
def: Def;
|
|
1514
|
+
}
|
|
1515
|
+
interface DataTableSchema<Row extends Record<string, unknown> = Record<string, unknown>> {
|
|
1516
|
+
table: string;
|
|
1517
|
+
columns: SchemaShape;
|
|
1518
|
+
cols: {
|
|
1519
|
+
[K in keyof Row & string]: DataColumn<K>;
|
|
1520
|
+
};
|
|
1521
|
+
}
|
|
1522
|
+
type ColumnValue<D extends ColumnDef> = D extends {
|
|
1523
|
+
type: 'enum';
|
|
1524
|
+
values: readonly (infer V)[];
|
|
1525
|
+
} ? V : D extends 'number' | 'integer' ? number : D extends 'boolean' ? boolean : unknown;
|
|
1526
|
+
type RowFromSchema<S extends SchemaShape> = {
|
|
1527
|
+
[K in keyof S & string]: ColumnValue<S[K]>;
|
|
1528
|
+
};
|
|
1529
|
+
declare function defineSchema<const S extends SchemaShape>(input: {
|
|
1530
|
+
table: string;
|
|
1531
|
+
columns: S;
|
|
1532
|
+
}): DataTableSchema<RowFromSchema<S>>;
|
|
1533
|
+
|
|
1534
|
+
type QueryExpr = {
|
|
1535
|
+
op: 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'like';
|
|
1536
|
+
column: string;
|
|
1537
|
+
value: unknown;
|
|
1538
|
+
} | {
|
|
1539
|
+
op: 'in';
|
|
1540
|
+
column: string;
|
|
1541
|
+
values: unknown[];
|
|
1542
|
+
} | {
|
|
1543
|
+
op: 'and' | 'or';
|
|
1544
|
+
clauses: QueryExpr[];
|
|
1545
|
+
} | {
|
|
1546
|
+
op: 'not';
|
|
1547
|
+
clause: QueryExpr;
|
|
1548
|
+
} | {
|
|
1549
|
+
op: 'raw';
|
|
1550
|
+
sql: string;
|
|
1551
|
+
params?: unknown[];
|
|
1552
|
+
};
|
|
1553
|
+
declare function escapeLike(value: string): string;
|
|
1554
|
+
declare function raw(sql: string, params?: unknown[]): QueryExpr;
|
|
1555
|
+
declare function and(...clauses: QueryExpr[]): QueryExpr;
|
|
1556
|
+
declare function or(...clauses: QueryExpr[]): QueryExpr;
|
|
1557
|
+
declare function not(clause: QueryExpr): QueryExpr;
|
|
1558
|
+
declare function where<T>(column: DataColumn<string> | string): {
|
|
1559
|
+
eq: (value: T) => QueryExpr;
|
|
1560
|
+
ne: (value: T) => QueryExpr;
|
|
1561
|
+
gt: (value: T) => QueryExpr;
|
|
1562
|
+
gte: (value: T) => QueryExpr;
|
|
1563
|
+
lt: (value: T) => QueryExpr;
|
|
1564
|
+
lte: (value: T) => QueryExpr;
|
|
1565
|
+
in: (values: T[]) => QueryExpr;
|
|
1566
|
+
like: {
|
|
1567
|
+
contains: (value: string) => QueryExpr;
|
|
1568
|
+
startsWith: (value: string) => QueryExpr;
|
|
1569
|
+
endsWith: (value: string) => QueryExpr;
|
|
1570
|
+
raw: (value: string) => QueryExpr;
|
|
1571
|
+
};
|
|
1572
|
+
};
|
|
1573
|
+
|
|
1574
|
+
interface DataListOptions extends ListOptions, RequestOptions {
|
|
1575
|
+
where?: QueryExpr;
|
|
1576
|
+
orderBy?: string;
|
|
1577
|
+
}
|
|
1578
|
+
interface DataCountOptions extends RequestOptions {
|
|
1579
|
+
where?: QueryExpr;
|
|
1580
|
+
}
|
|
1581
|
+
interface DataBulkResult<Row = unknown> {
|
|
1582
|
+
items: Row[];
|
|
1583
|
+
count: number;
|
|
1584
|
+
}
|
|
1585
|
+
declare class DataClient {
|
|
1586
|
+
private readonly http;
|
|
1587
|
+
constructor(http: HttpClient);
|
|
1588
|
+
table<Row extends Record<string, unknown> = Record<string, unknown>>(tenantSlug: string, appSlug: string, table: string | DataTableSchema<Row>): DataTableClient<Row>;
|
|
1589
|
+
scoped(tenantSlug: string): TenantDataFactory;
|
|
1590
|
+
}
|
|
1591
|
+
declare class TenantDataFactory {
|
|
1592
|
+
private readonly data;
|
|
1593
|
+
private readonly tenantSlug;
|
|
1594
|
+
constructor(data: DataClient, tenantSlug: string);
|
|
1595
|
+
app(appSlug: string): AppDataFactory;
|
|
1596
|
+
}
|
|
1597
|
+
declare class AppDataFactory {
|
|
1598
|
+
private readonly data;
|
|
1599
|
+
private readonly tenantSlug;
|
|
1600
|
+
private readonly appSlug;
|
|
1601
|
+
constructor(data: DataClient, tenantSlug: string, appSlug: string);
|
|
1602
|
+
table<Row extends Record<string, unknown> = Record<string, unknown>>(table: string | DataTableSchema<Row>): DataTableClient<Row>;
|
|
1603
|
+
}
|
|
1604
|
+
declare class DataTableClient<Row extends Record<string, unknown> = Record<string, unknown>> {
|
|
1605
|
+
private readonly http;
|
|
1606
|
+
private readonly tenantSlug;
|
|
1607
|
+
private readonly appSlug;
|
|
1608
|
+
private readonly tableName;
|
|
1609
|
+
constructor(http: HttpClient, tenantSlug: string, appSlug: string, tableName: string);
|
|
1610
|
+
private path;
|
|
1611
|
+
list(opts?: DataListOptions): Promise<PaginatedList<Row>>;
|
|
1612
|
+
listAll(opts?: DataListOptions): AsyncGenerator<ListAllItem<Row>>;
|
|
1613
|
+
count(opts?: DataCountOptions): Promise<number>;
|
|
1614
|
+
get(id: string, opts?: RequestOptions): Promise<Row>;
|
|
1615
|
+
insert(row: Partial<Row>, opts?: RequestOptions): Promise<Row>;
|
|
1616
|
+
insertMany(rows: Array<Partial<Row>>, opts?: RequestOptions): Promise<DataBulkResult<Row>>;
|
|
1617
|
+
update(id: string, patch: Partial<Row>, opts?: RequestOptions): Promise<Row>;
|
|
1618
|
+
delete(id: string, opts?: RequestOptions): Promise<void>;
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
declare class TenantScopedClient {
|
|
1622
|
+
readonly slug: string;
|
|
1623
|
+
private readonly root;
|
|
1624
|
+
readonly apps: TenantScopedAppsClient;
|
|
1625
|
+
constructor(slug: string, scopedRoot: AxHubClient, root: AxHubClient);
|
|
1626
|
+
get tenants(): TenantScopedTenantsClient;
|
|
1627
|
+
get authz(): TenantAuthzClient;
|
|
1628
|
+
get audit(): TenantAuditClient;
|
|
1629
|
+
get gateway(): TenantGatewayClient;
|
|
1630
|
+
app(appSlug: string): AppScopedClient;
|
|
1631
|
+
}
|
|
1632
|
+
declare class TenantScopedAppsClient {
|
|
1633
|
+
private readonly tenantSlug;
|
|
1634
|
+
private readonly http;
|
|
1635
|
+
constructor(tenantSlug: string, http: HttpClient);
|
|
1636
|
+
create(input: CreateAppInput, opts?: RequestOptions): Promise<AppResponse>;
|
|
1637
|
+
list(opts?: PageRequestOptions): Promise<PaginatedList<AppResponse>>;
|
|
1638
|
+
listAll(opts?: PageRequestOptions): AsyncGenerator<ListAllItem<AppResponse>>;
|
|
1639
|
+
get(appId: string, opts?: RequestOptions): Promise<AppResponse>;
|
|
1640
|
+
update(appId: string, patch: UpdateAppInput, opts?: RequestOptions): Promise<AppResponse>;
|
|
1641
|
+
delete(appId: string, opts?: RequestOptions): Promise<void>;
|
|
1642
|
+
}
|
|
1643
|
+
declare class AppScopedClient {
|
|
1644
|
+
readonly tenantSlug: string;
|
|
1645
|
+
readonly appSlug: string;
|
|
1646
|
+
private readonly root;
|
|
1647
|
+
readonly data: AppScopedDataClient;
|
|
1648
|
+
readonly tables: AppScopedTablesClient;
|
|
1649
|
+
constructor(tenantSlug: string, appSlug: string, root: AxHubClient);
|
|
1650
|
+
}
|
|
1651
|
+
declare class AppScopedDataClient {
|
|
1652
|
+
private readonly tenantSlug;
|
|
1653
|
+
private readonly appSlug;
|
|
1654
|
+
private readonly rootData;
|
|
1655
|
+
constructor(tenantSlug: string, appSlug: string, rootData: DataClient);
|
|
1656
|
+
table<Row extends Record<string, unknown> = Record<string, unknown>>(table: string | DataTableSchema<Row>): DataTableClient<Row>;
|
|
1657
|
+
}
|
|
1658
|
+
declare class AppScopedTablesClient {
|
|
1659
|
+
private readonly tenantSlug;
|
|
1660
|
+
private readonly appSlug;
|
|
1661
|
+
private readonly http;
|
|
1662
|
+
constructor(tenantSlug: string, appSlug: string, http: HttpClient);
|
|
1663
|
+
create(input: unknown, opts?: RequestOptions): Promise<unknown>;
|
|
1664
|
+
inspect(tableName: string, opts?: RequestOptions): Promise<unknown>;
|
|
1665
|
+
}
|
|
1666
|
+
|
|
1667
|
+
type DeploymentStatus = 'queued' | 'building' | 'deploying' | 'succeeded' | 'failed' | 'cancelled' | 'rolled_back';
|
|
1668
|
+
interface DeploymentResponse {
|
|
1669
|
+
id: string;
|
|
1670
|
+
appId: string;
|
|
1671
|
+
status: DeploymentStatus;
|
|
1672
|
+
triggerSource: string;
|
|
1673
|
+
startedAt: string | null;
|
|
1674
|
+
completedAt: string | null;
|
|
1675
|
+
url: string | null;
|
|
1676
|
+
errorMessage: string | null;
|
|
1677
|
+
createdAt: string;
|
|
1678
|
+
updatedAt: string;
|
|
1679
|
+
}
|
|
1680
|
+
interface CreateDeploymentInput {
|
|
1681
|
+
ref?: string;
|
|
1682
|
+
}
|
|
1683
|
+
interface BuildLogEvent {
|
|
1684
|
+
ts: string;
|
|
1685
|
+
line: string;
|
|
1686
|
+
}
|
|
1687
|
+
interface PodLogEvent {
|
|
1688
|
+
ts: string;
|
|
1689
|
+
line: string;
|
|
1690
|
+
}
|
|
1691
|
+
interface PodEventEvent {
|
|
1692
|
+
type: 'Normal' | 'Warning';
|
|
1693
|
+
reason: string;
|
|
1694
|
+
message: string;
|
|
1695
|
+
ts: string;
|
|
1696
|
+
}
|
|
1697
|
+
declare class DeploymentsClient {
|
|
1698
|
+
private readonly http;
|
|
1699
|
+
constructor(http: HttpClient);
|
|
1700
|
+
/**
|
|
1701
|
+
* Trigger a new deployment. Returns immediately with the deployment row
|
|
1702
|
+
* in `queued` or `building` state; use `streamBuildLogs` or polling
|
|
1703
|
+
* `get()` to observe progression.
|
|
1704
|
+
*
|
|
1705
|
+
* @example happy
|
|
1706
|
+
* const dep = await sdk.deployments.create('app_abc', { ref: 'main' })
|
|
1707
|
+
*
|
|
1708
|
+
* @example failure
|
|
1709
|
+
* try { await sdk.deployments.create('app_abc') }
|
|
1710
|
+
* catch (e) {
|
|
1711
|
+
* if (e instanceof ConflictError) /* in-progress deploy exists *\/
|
|
1712
|
+
* if (e instanceof PreconditionFailedError) /* git connection missing *\/
|
|
1713
|
+
* }
|
|
1714
|
+
*/
|
|
1715
|
+
create(appId: string, input?: CreateDeploymentInput): Promise<DeploymentResponse>;
|
|
1716
|
+
/**
|
|
1717
|
+
* List deployments for an app, newest first.
|
|
1718
|
+
*
|
|
1719
|
+
* @example happy
|
|
1720
|
+
* const page = await sdk.deployments.list('app_abc', { pageSize: 20 })
|
|
1721
|
+
*/
|
|
1722
|
+
list(appId: string, opts?: ListOptions): Promise<PaginatedList<DeploymentResponse>>;
|
|
1723
|
+
listAll(appId: string, opts?: ListAllOptions): AsyncGenerator<ListAllItem<DeploymentResponse>>;
|
|
1724
|
+
/**
|
|
1725
|
+
* Fetch a single deployment. Use to poll terminal status without streaming.
|
|
1726
|
+
*
|
|
1727
|
+
* @example happy
|
|
1728
|
+
* const dep = await sdk.deployments.get('app_abc', 'dep_123')
|
|
1729
|
+
* if (dep.status === 'succeeded') console.log(dep.url)
|
|
1730
|
+
*/
|
|
1731
|
+
get(appId: string, did: string): Promise<DeploymentResponse>;
|
|
1732
|
+
/**
|
|
1733
|
+
* Cancel an in-progress deployment. Best-effort — if the deployment has
|
|
1734
|
+
* already transitioned to a terminal state when the request arrives, the
|
|
1735
|
+
* route returns 204 on acceptance. Idempotent.
|
|
1736
|
+
*
|
|
1737
|
+
* @example happy
|
|
1738
|
+
* await sdk.deployments.cancel('app_abc', 'dep_123')
|
|
1739
|
+
*/
|
|
1740
|
+
cancel(appId: string, did: string): Promise<void>;
|
|
1741
|
+
/**
|
|
1742
|
+
* Rollback to a prior succeeded deployment's image. Creates a new
|
|
1743
|
+
* deployment rollback action; original deployment is unaffected. Backend
|
|
1744
|
+
* returns 204 when the request is accepted.
|
|
1745
|
+
*
|
|
1746
|
+
* @example happy
|
|
1747
|
+
* await sdk.deployments.rollback('app_abc', 'dep_old_succeeded')
|
|
1748
|
+
*
|
|
1749
|
+
* @example failure
|
|
1750
|
+
* try { await sdk.deployments.rollback('app_abc', 'dep_never_succeeded') }
|
|
1751
|
+
* catch (e) {
|
|
1752
|
+
* if (e instanceof PreconditionFailedError) /* no image to rollback to *\/
|
|
1753
|
+
* }
|
|
1754
|
+
*/
|
|
1755
|
+
rollback(appId: string, did: string): Promise<void>;
|
|
1756
|
+
/**
|
|
1757
|
+
* Stream Cloud Build log lines for a deployment via SSE. Returns an
|
|
1758
|
+
* AsyncIterable that yields `{type:'item', value}`, `{type:'gap'}` (on
|
|
1759
|
+
* reconnect when ring buffer rolled), or `{type:'decode-skip'}` (single
|
|
1760
|
+
* malformed frame). Iterator completes when the deployment reaches a
|
|
1761
|
+
* terminal state.
|
|
1762
|
+
*
|
|
1763
|
+
* @example happy
|
|
1764
|
+
* const ctrl = new AbortController()
|
|
1765
|
+
* for await (const ev of sdk.deployments.streamBuildLogs(appId, did, { signal: ctrl.signal })) {
|
|
1766
|
+
* if (ev.type === 'item') process.stdout.write(ev.value.line + '\n')
|
|
1767
|
+
* }
|
|
1768
|
+
*
|
|
1769
|
+
* @example failure
|
|
1770
|
+
* try {
|
|
1771
|
+
* for await (const _ of sdk.deployments.streamBuildLogs(appId, did)) {}
|
|
1772
|
+
* } catch (e) {
|
|
1773
|
+
* if (e instanceof StreamConsumedError) /* iterating twice — forbidden *\/
|
|
1774
|
+
* }
|
|
1775
|
+
*/
|
|
1776
|
+
streamBuildLogs(appId: string, did: string, opts?: {
|
|
1777
|
+
signal?: AbortSignal;
|
|
1778
|
+
}): SSEStream<BuildLogEvent>;
|
|
1779
|
+
/**
|
|
1780
|
+
* Stream runtime pod stdout/stderr after deploy succeeds. Same iterator
|
|
1781
|
+
* semantics as `streamBuildLogs`. Ring buffer cap = 200 most recent lines.
|
|
1782
|
+
*
|
|
1783
|
+
* @example happy
|
|
1784
|
+
* for await (const ev of sdk.deployments.streamPodLogs(appId, did)) {
|
|
1785
|
+
* if (ev.type === 'item') console.log(ev.value.line)
|
|
1786
|
+
* }
|
|
1787
|
+
*/
|
|
1788
|
+
streamPodLogs(appId: string, did: string, opts?: {
|
|
1789
|
+
signal?: AbortSignal;
|
|
1790
|
+
}): SSEStream<PodLogEvent>;
|
|
1791
|
+
/**
|
|
1792
|
+
* Stream Kubernetes pod events (Normal / Warning — CrashLoopBackOff,
|
|
1793
|
+
* OOMKilled, ImagePullBackOff, ...). Use for self-heal signal detection.
|
|
1794
|
+
*
|
|
1795
|
+
* @example happy
|
|
1796
|
+
* for await (const ev of sdk.deployments.streamPodEvents(appId, did)) {
|
|
1797
|
+
* if (ev.type === 'item' && ev.value.type === 'Warning') {
|
|
1798
|
+
* console.warn(ev.value.reason, ev.value.message)
|
|
1799
|
+
* }
|
|
1800
|
+
* }
|
|
1801
|
+
*/
|
|
1802
|
+
streamPodEvents(appId: string, did: string, opts?: {
|
|
1803
|
+
signal?: AbortSignal;
|
|
1804
|
+
}): SSEStream<PodEventEvent>;
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1807
|
+
interface IssuePersonalAccessTokenInput {
|
|
1808
|
+
name: string;
|
|
1809
|
+
expiresInDays?: number;
|
|
1810
|
+
}
|
|
1811
|
+
interface IssuePersonalAccessTokenResult {
|
|
1812
|
+
patId: string;
|
|
1813
|
+
name: string;
|
|
1814
|
+
rawToken: string;
|
|
1815
|
+
createdAt: string;
|
|
1816
|
+
expiresAt: string | null;
|
|
1817
|
+
}
|
|
1818
|
+
interface PATSummary {
|
|
1819
|
+
id: string;
|
|
1820
|
+
name: string;
|
|
1821
|
+
createdAt: string;
|
|
1822
|
+
expiresAt: string | null;
|
|
1823
|
+
lastUsedAt: string | null;
|
|
1824
|
+
}
|
|
1825
|
+
interface MeResponse {
|
|
1826
|
+
userId: string;
|
|
1827
|
+
email: string;
|
|
1828
|
+
name?: string;
|
|
1829
|
+
platformAdmin?: boolean;
|
|
1830
|
+
tenants?: Array<{
|
|
1831
|
+
tenantId: string;
|
|
1832
|
+
tenantSlug: string;
|
|
1833
|
+
role: string;
|
|
1834
|
+
isActive: boolean;
|
|
1835
|
+
iconUrl?: string;
|
|
1836
|
+
}>;
|
|
1837
|
+
[key: string]: unknown;
|
|
1838
|
+
}
|
|
1839
|
+
interface OAuthTokenResponse {
|
|
1840
|
+
accessToken: string;
|
|
1841
|
+
tokenType: string;
|
|
1842
|
+
expiresIn?: number;
|
|
1843
|
+
refreshToken?: string;
|
|
1844
|
+
scope?: string;
|
|
1845
|
+
raw: Record<string, unknown>;
|
|
1846
|
+
}
|
|
1847
|
+
interface DeviceAuthorizationResponse {
|
|
1848
|
+
deviceCode: string;
|
|
1849
|
+
userCode: string;
|
|
1850
|
+
verificationUri: string;
|
|
1851
|
+
verificationUriComplete?: string;
|
|
1852
|
+
expiresIn: number;
|
|
1853
|
+
interval: number;
|
|
1854
|
+
raw: Record<string, unknown>;
|
|
1855
|
+
}
|
|
1856
|
+
interface IdentityProvider {
|
|
1857
|
+
id: string;
|
|
1858
|
+
tenantId?: string;
|
|
1859
|
+
provider: string;
|
|
1860
|
+
type: 'oidc' | 'oauth2' | 'saml' | string;
|
|
1861
|
+
enabled?: boolean;
|
|
1862
|
+
[key: string]: unknown;
|
|
1863
|
+
}
|
|
1864
|
+
interface SystemOAuthClient {
|
|
1865
|
+
id: string;
|
|
1866
|
+
clientId?: string;
|
|
1867
|
+
tenantId?: string;
|
|
1868
|
+
name?: string;
|
|
1869
|
+
redirectUris?: string[];
|
|
1870
|
+
scopes?: string[];
|
|
1871
|
+
[key: string]: unknown;
|
|
1872
|
+
}
|
|
1873
|
+
declare class IdentityClient {
|
|
1874
|
+
private readonly http;
|
|
1875
|
+
readonly pat: IdentityPATClient;
|
|
1876
|
+
readonly meClient: IdentityMeClient;
|
|
1877
|
+
readonly oauth: IdentityOAuthClient;
|
|
1878
|
+
readonly oidc: IdentityOIDCClient;
|
|
1879
|
+
readonly deviceCode: IdentityDeviceCodeClient;
|
|
1880
|
+
readonly idp: IdentityProviderClient;
|
|
1881
|
+
readonly systemOAuthClients: IdentitySystemOAuthClientsClient;
|
|
1882
|
+
constructor(http: HttpClient, defaultTenantSlug?: string);
|
|
1883
|
+
/** @deprecated Use sdk.identity.pat.issue(). Kept until 1.0 RC migration. */
|
|
1884
|
+
issuePersonalAccessToken(input: IssuePersonalAccessTokenInput, opts?: RequestOptions): Promise<IssuePersonalAccessTokenResult>;
|
|
1885
|
+
/** @deprecated Use sdk.identity.pat.list(). Kept until 1.0 RC migration. */
|
|
1886
|
+
listPersonalAccessTokens(opts?: RequestOptions): Promise<PATSummary[]>;
|
|
1887
|
+
/** @deprecated Use sdk.identity.pat.revoke(). Kept until 1.0 RC migration. */
|
|
1888
|
+
revokePersonalAccessToken(patId: string, opts?: RequestOptions): Promise<void>;
|
|
1889
|
+
me(opts?: RequestOptions): Promise<MeResponse>;
|
|
1890
|
+
}
|
|
1891
|
+
declare class IdentityPATClient {
|
|
1892
|
+
private readonly http;
|
|
1893
|
+
private readonly defaultTenantSlug?;
|
|
1894
|
+
constructor(http: HttpClient, defaultTenantSlug?: string | undefined);
|
|
1895
|
+
private tenantQuery;
|
|
1896
|
+
issue(input: IssuePersonalAccessTokenInput, opts?: RequestOptions): Promise<IssuePersonalAccessTokenResult>;
|
|
1897
|
+
list(opts?: RequestOptions): Promise<PATSummary[]>;
|
|
1898
|
+
revoke(patId: string, opts?: RequestOptions): Promise<void>;
|
|
1899
|
+
}
|
|
1900
|
+
declare class IdentityMeClient {
|
|
1901
|
+
private readonly http;
|
|
1902
|
+
constructor(http: HttpClient);
|
|
1903
|
+
get(opts?: RequestOptions): Promise<MeResponse>;
|
|
1904
|
+
}
|
|
1905
|
+
declare class IdentityOAuthClient {
|
|
1906
|
+
private readonly http;
|
|
1907
|
+
private readonly defaultTenantSlug?;
|
|
1908
|
+
constructor(http: HttpClient, defaultTenantSlug?: string | undefined);
|
|
1909
|
+
private tenantQuery;
|
|
1910
|
+
authorizeUrl(input: {
|
|
1911
|
+
clientId: string;
|
|
1912
|
+
redirectUri: string;
|
|
1913
|
+
scope?: string;
|
|
1914
|
+
state?: string;
|
|
1915
|
+
codeChallenge?: string;
|
|
1916
|
+
codeChallengeMethod?: string;
|
|
1917
|
+
}): string;
|
|
1918
|
+
exchangeCode(input: {
|
|
1919
|
+
code: string;
|
|
1920
|
+
clientId: string;
|
|
1921
|
+
redirectUri: string;
|
|
1922
|
+
codeVerifier: string;
|
|
1923
|
+
clientSecret?: string;
|
|
1924
|
+
}, opts?: RequestOptions): Promise<OAuthTokenResponse>;
|
|
1925
|
+
refreshTokens(input: {
|
|
1926
|
+
refreshToken: string;
|
|
1927
|
+
clientId?: string;
|
|
1928
|
+
clientSecret?: string;
|
|
1929
|
+
}, opts?: RequestOptions): Promise<OAuthTokenResponse>;
|
|
1930
|
+
revoke(input: {
|
|
1931
|
+
token: string;
|
|
1932
|
+
tokenTypeHint?: string;
|
|
1933
|
+
clientId?: string;
|
|
1934
|
+
}, opts?: RequestOptions): Promise<void>;
|
|
1935
|
+
userinfo(opts?: RequestOptions): Promise<Record<string, unknown>>;
|
|
1936
|
+
getClient(clientId: string, opts?: RequestOptions): Promise<SystemOAuthClient>;
|
|
1937
|
+
revokeOwnGrant(clientId: string, opts?: RequestOptions): Promise<void>;
|
|
1938
|
+
}
|
|
1939
|
+
declare class IdentityOIDCClient {
|
|
1940
|
+
private readonly http;
|
|
1941
|
+
private readonly defaultTenantSlug?;
|
|
1942
|
+
constructor(http: HttpClient, defaultTenantSlug?: string | undefined);
|
|
1943
|
+
private tenantQuery;
|
|
1944
|
+
discovery(opts?: RequestOptions): Promise<Record<string, unknown>>;
|
|
1945
|
+
jwks(opts?: RequestOptions): Promise<Record<string, unknown>>;
|
|
1946
|
+
providers(opts?: RequestOptions): Promise<IdentityProvider[]>;
|
|
1947
|
+
startURL(providerId: string, input?: {
|
|
1948
|
+
redirectTo?: string;
|
|
1949
|
+
state?: string;
|
|
1950
|
+
}, opts?: RequestOptions): Promise<string>;
|
|
1951
|
+
exchangeCallback(input: {
|
|
1952
|
+
code: string;
|
|
1953
|
+
state?: string;
|
|
1954
|
+
provider?: string;
|
|
1955
|
+
}, opts?: RequestOptions): Promise<OAuthTokenResponse>;
|
|
1956
|
+
}
|
|
1957
|
+
declare class IdentityDeviceCodeClient {
|
|
1958
|
+
private readonly http;
|
|
1959
|
+
private readonly defaultTenantSlug?;
|
|
1960
|
+
constructor(http: HttpClient, defaultTenantSlug?: string | undefined);
|
|
1961
|
+
private tenantQuery;
|
|
1962
|
+
request(input: {
|
|
1963
|
+
clientId: string;
|
|
1964
|
+
scope?: string;
|
|
1965
|
+
}, opts?: RequestOptions): Promise<DeviceAuthorizationResponse>;
|
|
1966
|
+
poll(input: {
|
|
1967
|
+
deviceCode: string;
|
|
1968
|
+
clientId: string;
|
|
1969
|
+
intervalMs?: number;
|
|
1970
|
+
signal?: AbortSignal;
|
|
1971
|
+
}, opts?: RequestOptions): Promise<OAuthTokenResponse>;
|
|
1972
|
+
}
|
|
1973
|
+
declare class IdentityProviderClient {
|
|
1974
|
+
private readonly http;
|
|
1975
|
+
constructor(http: HttpClient);
|
|
1976
|
+
list(tenantId: string, opts?: RequestOptions): Promise<IdentityProvider[]>;
|
|
1977
|
+
create(tenantId: string, input: Record<string, unknown>, opts?: RequestOptions): Promise<IdentityProvider>;
|
|
1978
|
+
enable(tenantId: string, providerId: string, opts?: RequestOptions): Promise<IdentityProvider>;
|
|
1979
|
+
disable(tenantId: string, providerId: string, opts?: RequestOptions): Promise<IdentityProvider>;
|
|
1980
|
+
}
|
|
1981
|
+
declare class IdentitySystemOAuthClientsClient {
|
|
1982
|
+
private readonly http;
|
|
1983
|
+
constructor(http: HttpClient);
|
|
1984
|
+
get(clientId: string, opts?: RequestOptions): Promise<SystemOAuthClient>;
|
|
1985
|
+
create(input: Record<string, unknown>, opts?: RequestOptions): Promise<SystemOAuthClient>;
|
|
1986
|
+
delete(clientId: string, opts?: RequestOptions): Promise<void>;
|
|
1987
|
+
}
|
|
1988
|
+
|
|
1989
|
+
interface SettlePublicationInput {
|
|
1990
|
+
comment?: string;
|
|
1991
|
+
}
|
|
1992
|
+
declare class PublicationRequestsClient {
|
|
1993
|
+
private readonly http;
|
|
1994
|
+
constructor(http: HttpClient);
|
|
1995
|
+
/**
|
|
1996
|
+
* Fetch a single publication request by ID. Visible to the requester
|
|
1997
|
+
* (owner) and reviewers/admins.
|
|
1998
|
+
*
|
|
1999
|
+
* @example happy
|
|
2000
|
+
* const pr = await sdk.publicationRequests.get('pr_abc')
|
|
2001
|
+
*
|
|
2002
|
+
* @example failure
|
|
2003
|
+
* try { await sdk.publicationRequests.get('pr_missing') }
|
|
2004
|
+
* catch (e) { if (e instanceof NotFoundError) /* abort *\/ }
|
|
2005
|
+
*/
|
|
2006
|
+
get(prId: string): Promise<PublicationRequest>;
|
|
2007
|
+
/**
|
|
2008
|
+
* Approve a publication request. Requires the `publication_reviewer` role;
|
|
2009
|
+
* non-reviewers get `PermissionDeniedError`. Approving an already-settled
|
|
2010
|
+
* request returns `AlreadySettledError` (409).
|
|
2011
|
+
*
|
|
2012
|
+
* Side effects (server-side): the app's `publicationStatus = 'approved'`,
|
|
2013
|
+
* `visibility = 'public'`, and an `AppPublished` event is emitted.
|
|
2014
|
+
*
|
|
2015
|
+
* @example happy
|
|
2016
|
+
* const pr = await sdk.publicationRequests.approve('pr_abc', { comment: 'LGTM' })
|
|
2017
|
+
* console.log(pr.status) // 'approved'
|
|
2018
|
+
*
|
|
2019
|
+
* @example failure
|
|
2020
|
+
* try { await sdk.publicationRequests.approve('pr_settled') }
|
|
2021
|
+
* catch (e) {
|
|
2022
|
+
* if (e instanceof AlreadySettledError) /* already approved/rejected *\/
|
|
2023
|
+
* if (e instanceof PermissionDeniedError) /* not a reviewer *\/
|
|
2024
|
+
* }
|
|
2025
|
+
*/
|
|
2026
|
+
approve(prId: string, input?: SettlePublicationInput): Promise<PublicationRequest>;
|
|
2027
|
+
/**
|
|
2028
|
+
* Reject a publication request. Same role + idempotency rules as `approve`.
|
|
2029
|
+
* App state unchanged; requester can resubmit after addressing the comment.
|
|
2030
|
+
*
|
|
2031
|
+
* @example happy
|
|
2032
|
+
* const pr = await sdk.publicationRequests.reject('pr_abc', { comment: 'Add screenshots' })
|
|
2033
|
+
* console.log(pr.status) // 'rejected'
|
|
2034
|
+
*/
|
|
2035
|
+
reject(prId: string, input?: SettlePublicationInput): Promise<PublicationRequest>;
|
|
2036
|
+
private settle;
|
|
2037
|
+
/**
|
|
2038
|
+
* List all pending publication requests across the tenant. Platform admin
|
|
2039
|
+
* only — non-admins get `PermissionDeniedError`.
|
|
2040
|
+
*
|
|
2041
|
+
* @example happy
|
|
2042
|
+
* const page = await sdk.publicationRequests.listPending({ pageSize: 20 })
|
|
2043
|
+
* for (const pr of page.items) console.log(pr.appId, pr.requesterId, pr.reason)
|
|
2044
|
+
*
|
|
2045
|
+
* @example failure
|
|
2046
|
+
* try { await sdk.publicationRequests.listPending() }
|
|
2047
|
+
* catch (e) { if (e instanceof NotAdminError) /* not platform admin *\/ }
|
|
2048
|
+
*/
|
|
2049
|
+
listPending(opts?: ListOptions): Promise<PaginatedList<PublicationRequest>>;
|
|
2050
|
+
}
|
|
2051
|
+
|
|
2052
|
+
/**
|
|
2053
|
+
* Default production base URL for AX Hub. Override via `baseUrl` for staging,
|
|
2054
|
+
* local dev, or self-hosted environments. Also overridable via env var
|
|
2055
|
+
* `AX_HUB_BASE_URL` (caller wires this if desired).
|
|
2056
|
+
*/
|
|
2057
|
+
declare const DEFAULT_BASE_URL = "https://axhub-api.jocodingax.ai";
|
|
2058
|
+
interface AxHubClientOptions {
|
|
2059
|
+
/**
|
|
2060
|
+
* Backend root URL. Defaults to {@link DEFAULT_BASE_URL}. Override for
|
|
2061
|
+
* staging / self-hosted / local dev.
|
|
2062
|
+
*/
|
|
2063
|
+
baseUrl?: string;
|
|
2064
|
+
token?: string;
|
|
2065
|
+
tokenType?: TokenType;
|
|
2066
|
+
/**
|
|
2067
|
+
* JWT refresh callback. Called when an admin-ring request returns 401.
|
|
2068
|
+
* Should return the new JWT, or throw to surface the 401 to the caller.
|
|
2069
|
+
*/
|
|
2070
|
+
onRefresh?: () => Promise<string>;
|
|
2071
|
+
defaultTenantSlug?: string;
|
|
2072
|
+
defaultTenantId?: string;
|
|
2073
|
+
logger?: Logger;
|
|
2074
|
+
debug?: boolean;
|
|
2075
|
+
fetch?: FetchLike;
|
|
2076
|
+
timeoutMs?: number;
|
|
2077
|
+
idempotencyKey?: {
|
|
2078
|
+
autoGenerate?: boolean;
|
|
2079
|
+
generator?: () => string;
|
|
2080
|
+
};
|
|
2081
|
+
retryPolicy?: RetryPolicy;
|
|
2082
|
+
rateLimitStrategy?: RateLimitStrategy;
|
|
2083
|
+
}
|
|
2084
|
+
interface AxHubInternalOptions {
|
|
2085
|
+
__sharedHttp: HttpClient;
|
|
2086
|
+
defaultTenantSlug: string;
|
|
2087
|
+
defaultTenantId?: string;
|
|
2088
|
+
logger: Logger;
|
|
2089
|
+
}
|
|
2090
|
+
declare class AxHubClient {
|
|
2091
|
+
readonly http: HttpClient;
|
|
2092
|
+
readonly defaultTenantSlug?: string;
|
|
2093
|
+
readonly defaultTenantId?: string;
|
|
2094
|
+
readonly logger: Logger;
|
|
2095
|
+
private _apps?;
|
|
2096
|
+
private _audit?;
|
|
2097
|
+
private _authz?;
|
|
2098
|
+
private _data?;
|
|
2099
|
+
private _deployments?;
|
|
2100
|
+
private _gateway?;
|
|
2101
|
+
private _identity?;
|
|
2102
|
+
private _publicationRequests?;
|
|
2103
|
+
private _tenants?;
|
|
2104
|
+
constructor(opts: AxHubClientOptions | AxHubInternalOptions);
|
|
2105
|
+
resolveTenantSlug(perCall?: string): string;
|
|
2106
|
+
get apps(): AppsClient;
|
|
2107
|
+
get audit(): AuditClient;
|
|
2108
|
+
get authz(): AuthzClient;
|
|
2109
|
+
get data(): DataClient;
|
|
2110
|
+
get deployments(): DeploymentsClient;
|
|
2111
|
+
get gateway(): GatewayClient;
|
|
2112
|
+
get identity(): IdentityClient;
|
|
2113
|
+
get tenants(): TenantsClient;
|
|
2114
|
+
/**
|
|
2115
|
+
* Admin namespace for publication-request review workflow. Separated from
|
|
2116
|
+
* `sdk.apps.publication` (which is owner-scoped: submit/list/unpublish own
|
|
2117
|
+
* app) because approve/reject/listPending act on requests cross-app and
|
|
2118
|
+
* require reviewer/platform-admin roles.
|
|
2119
|
+
*
|
|
2120
|
+
* @example happy
|
|
2121
|
+
* const pr = await sdk.publicationRequests.approve('pr_abc', { comment: 'LGTM' })
|
|
2122
|
+
*/
|
|
2123
|
+
get publicationRequests(): PublicationRequestsClient;
|
|
2124
|
+
/**
|
|
2125
|
+
* Returns a new AxHubClient scoped to the given tenant. The new client
|
|
2126
|
+
* shares the same underlying HttpClient (and therefore auth + retry state)
|
|
2127
|
+
* but reports `defaultTenantSlug = tenantSlug` for path templating.
|
|
2128
|
+
*
|
|
2129
|
+
* Resource clients (`apps`, `deployments`, `identity`) on the scoped
|
|
2130
|
+
* client are independent instances — they do NOT alias the parent's. This
|
|
2131
|
+
* matters when a caller passes `sdk.apps` and `sdk.withTenant('x').apps`
|
|
2132
|
+
* around: they are distinct references, lazy-initialized on first access.
|
|
2133
|
+
*
|
|
2134
|
+
* @example happy
|
|
2135
|
+
* const other = sdk.withTenant('analytics')
|
|
2136
|
+
* await other.apps.create({ slug: 'dashboard', name: 'Dashboard' })
|
|
2137
|
+
*
|
|
2138
|
+
* @example failure
|
|
2139
|
+
* // The scoped client inherits auth — if the token is not a member of
|
|
2140
|
+
* // the target tenant, the first call surfaces PermissionDeniedError.
|
|
2141
|
+
*/
|
|
2142
|
+
withTenant(tenantSlug: string): AxHubClient;
|
|
2143
|
+
/**
|
|
2144
|
+
* Recommended tenant-scoped surface. Path-tenant routes receive the slug
|
|
2145
|
+
* automatically, while root-only routes (OAuth token, JWKS, /me) remain on
|
|
2146
|
+
* the root client.
|
|
2147
|
+
*
|
|
2148
|
+
* @example happy
|
|
2149
|
+
* const acme = sdk.tenant('acme')
|
|
2150
|
+
* await acme.apps.create({ slug: 'crm', name: 'CRM' })
|
|
2151
|
+
* await acme.app('crm').data.table('orders').list()
|
|
2152
|
+
*/
|
|
2153
|
+
tenant(tenantSlug: string): TenantScopedClient;
|
|
2154
|
+
}
|
|
2155
|
+
|
|
2156
|
+
interface StaticTokenAuthOptions {
|
|
2157
|
+
token: string;
|
|
2158
|
+
tokenType: TokenType;
|
|
2159
|
+
onRefresh?: () => Promise<string>;
|
|
2160
|
+
}
|
|
2161
|
+
declare class StaticTokenAuth implements AuthProvider {
|
|
2162
|
+
private token;
|
|
2163
|
+
readonly tokenType: TokenType;
|
|
2164
|
+
private readonly onRefresh?;
|
|
2165
|
+
private refreshing;
|
|
2166
|
+
constructor(opts: StaticTokenAuthOptions);
|
|
2167
|
+
currentToken(): string;
|
|
2168
|
+
headersFor(ring: AuthRing): Record<string, string>;
|
|
2169
|
+
onUnauthorized(): Promise<boolean>;
|
|
2170
|
+
}
|
|
2171
|
+
declare class NoAuth implements AuthProvider {
|
|
2172
|
+
headersFor(_ring: AuthRing): Record<string, string>;
|
|
2173
|
+
onUnauthorized(): Promise<boolean>;
|
|
2174
|
+
}
|
|
2175
|
+
|
|
2176
|
+
type WebhookVerifyReason = 'signature_mismatch' | 'timestamp_skew' | 'malformed_signature' | 'missing_secret' | 'replay';
|
|
2177
|
+
interface VerifyWebhookInput {
|
|
2178
|
+
rawBody: Buffer | Uint8Array | string;
|
|
2179
|
+
signature: string;
|
|
2180
|
+
secret: string;
|
|
2181
|
+
tolerance?: number;
|
|
2182
|
+
timestamp?: string;
|
|
2183
|
+
replayCache?: Set<string>;
|
|
2184
|
+
now?: () => number;
|
|
2185
|
+
}
|
|
2186
|
+
interface VerifyWebhookResult {
|
|
2187
|
+
ok: boolean;
|
|
2188
|
+
reason?: WebhookVerifyReason;
|
|
2189
|
+
}
|
|
2190
|
+
declare function signWebhook(rawBody: Buffer | Uint8Array | string, secret: string, timestamp?: string): string;
|
|
2191
|
+
declare function verifyWebhook(input: VerifyWebhookInput): VerifyWebhookResult;
|
|
2192
|
+
|
|
2193
|
+
export { AbortError, AccessDeniedError, type AddColumnInput, type AddCommentInput, type AddGrantInput, AlreadyAccessedError, AlreadyActiveError, AlreadyDeletedError, AlreadyInactiveError, AlreadyMemberError, AlreadyRevokedError, AlreadySettledError, type AnonymizeInput, type AppAccess, type AppCategory, type AppID, type AppId, type AppResponse, AppScopedClient, AppScopedDataClient, type AppSlug, type AppTable, type AppTemplate, AppUnavailableError, AppsClient, AuditClient, type AuditEvent, type AuditEventID, type AuthProvider, type AuthRing, AuthorizationPendingError, AuthzClient, type AuthzGrant, type AuthzSubject, type AuthzTag, AxHubClient, type AxHubClientOptions, AxHubError, type AxHubErrorInit, BadRequestError, type Branded, type BuildLogEvent, type BulkInviteResult, type ColumnType, type Comment, ConflictError, type ConnectGitInput, type ConnectorID, type CreateAppInput, type CreateCategoryInput, type CreateDeploymentInput, type CreateOAuthClientInput, type CreateTableInput, type CreateTenantInput, DEFAULT_BASE_URL, type DataBulkResult, DataClient, type DataCountOptions, type DataListOptions, DataTableClient, type DataTableSchema, type DecideInput, type DecideResult, DecodeError, type DeploymentID, type DeploymentId, type DeploymentResponse, type DeploymentStatus, DeploymentsClient, type DeviceAuthorizationResponse, DeviceFlowDeniedError, DeviceFlowTimeoutError, type DiscoverAppsOptions, type DispatchContext, DomainTakenError, DuplicateError, type EmailDomain, type EmitAuditEventInput, EmptyError, type EnvVar, ExpiredTokenError, type FetchLike, type FieldError, ForbiddenError, GatewayClient, type GatewayConnector, type GatewayEngine, type GatewayQueryInput, type GatewayQueryResult, type GatewayResource, type GitConnection, type GitConnectionSetup, type GitConnectionStatus, type GithubInstallStart, type GrantID, type GrantPrincipalType, type GrantScope, IdentityClient, IdentityDeviceCodeClient, IdentityMeClient, IdentityOAuthClient, IdentityOIDCClient, IdentityPATClient, type IdentityProvider, IdentityProviderClient, IdentitySystemOAuthClientsClient, type InstallStartInput, type IntegrityCheckResult, InternalServerError, InvalidGrantError, InvalidPathError, InvalidStateTransitionError, InvalidValueError, InvitationExpiredError, type InviteTenantMemberInput, type IssuePersonalAccessTokenInput, type IssuePersonalAccessTokenResult, LastAdminError, type LikeResult, type LikeStatus, type ListAllItem, type ListAllOptions, type ListOptions, type Logger, type MeResponse, NetworkError, NoAuth, NotAdminError, NotAllowedError, NotDeletedError, NotFoundError, NotMemberError, type OAuthClient, type OAuthClientWithSecret, OAuthError, type OAuthErrorInit, type OAuthTokenResponse, type PATID, type PATSummary, type PaginatedList, type ParsedFrame, type PatId, PendingExistsError, PermanentlyDeletedError, PermissionDeniedError, type PodEventEvent, type PodLogEvent, PoolStaleError, PreconditionFailedError, type PublicationRequest, type PublicationRequestStatus, PublicationRequestsClient, type QueryExpr, type RateLimitStrategy, RateLimitedError, type RequestId, RequiredError, type ResourceID, type RetryInfo, type SSEStream, SchemaNameTakenError, type SettlePublicationInput, type SignIconUploadInput, type SignIconUploadResult, SlowDownError, SlugTakenError, StaticTokenAuth, StreamConsumedError, type StreamItem, type SubjectID, type SubmitPublicationInput, type SystemOAuthClient, type TableColumn, type TableConstraint, type TableGrant, type TableID, type TableIndex, type TableSchema, type TagID, type Tenant, type TenantID, type TenantId, type TenantInvitation, type TenantMember, TenantScopedAppsClient, TenantScopedClient, type TenantSlug, TenantSlugRequiredError, TenantsClient, TimeoutError, TokenExpiredError, TokenInvalidError, TokenMissingError, type TokenType, UnauthenticatedError, UnavailableError, type UnlikeResult, type UnpublishInput, type UpdateAppInput, type UpdateGitConnectionInput, type UpdateTenantInput, type UserID, type UserId, ValidationError, type VerifyWebhookInput, type VerifyWebhookResult, WebhookVerificationError, type WebhookVerifyReason, and, asAppId, asAppSlug, asDeploymentId, asPatId, asRequestId, asTenantId, asTenantSlug, asUserId, defineSchema, dispatch, escapeLike, formatErrorMessage, id, isOAuthPath, not, or, parseRetryAfter, raw, signWebhook, verifyWebhook, where };
|