@tangle-network/sandbox 0.0.3

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.
@@ -0,0 +1,449 @@
1
+ import { Et as SecretsManager, Rt as UsageInfo, W as ListSandboxOptions, b as CreateSandboxOptions, d as BatchEvent, f as BatchOptions, gt as SandboxEnvironment, jt as SubscriptionInfo, m as BatchTask, mt as SandboxClientConfig, n as SandboxInstance, p as BatchResult, t as HttpClient } from "./sandbox-D-1E98ow.js";
2
+
3
+ //#region src/client.d.ts
4
+ /**
5
+ * Client for the Tangle Sandbox platform.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { Sandbox } from "@tangle-network/sandbox";
10
+ *
11
+ * const client = new Sandbox({
12
+ * apiKey: "sk_sandbox_...",
13
+ * baseUrl: "https://your-sandbox-api.example.com",
14
+ * });
15
+ *
16
+ * // Create a sandbox
17
+ * const box = await client.create({
18
+ * name: "my-project",
19
+ * sshEnabled: true,
20
+ * });
21
+ *
22
+ * // Execute commands
23
+ * const result = await box.exec("npm install");
24
+ *
25
+ * // Clean up
26
+ * await box.delete();
27
+ * ```
28
+ */
29
+ declare class SandboxClient implements HttpClient {
30
+ private readonly baseUrl;
31
+ private readonly apiKey;
32
+ private readonly timeoutMs;
33
+ private _secrets;
34
+ constructor(config: SandboxClientConfig);
35
+ /**
36
+ * Access the secrets manager for storing and retrieving encrypted secrets.
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * // Create a secret
41
+ * await client.secrets.create("HF_TOKEN", "hf_xxx");
42
+ *
43
+ * // List secrets (names only)
44
+ * const secrets = await client.secrets.list();
45
+ *
46
+ * // Get secret value
47
+ * const value = await client.secrets.get("HF_TOKEN");
48
+ *
49
+ * // Update secret
50
+ * await client.secrets.update("HF_TOKEN", "hf_new_value");
51
+ *
52
+ * // Delete secret
53
+ * await client.secrets.delete("HF_TOKEN");
54
+ * ```
55
+ */
56
+ get secrets(): SecretsManager;
57
+ private _environments;
58
+ /**
59
+ * Access available development environments.
60
+ *
61
+ * @example
62
+ * ```typescript
63
+ * const envs = await client.environments.list();
64
+ * // → [{ id: "universal", description: "Universal environment with all toolchains via Nix", ... }]
65
+ *
66
+ * const sandbox = await client.create({ environment: "universal" });
67
+ * ```
68
+ */
69
+ get environments(): EnvironmentsClient;
70
+ private _teams;
71
+ /**
72
+ * Access team management (collaboration groups, invitations,
73
+ * member roles). Teams scope shared sandboxes — pass `teamId` to
74
+ * `client.create()` to create a sandbox accessible to a team's
75
+ * members.
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * const teams = await client.teams.list();
80
+ * const invite = await client.teams.invite(teams[0].id, {
81
+ * email: "alice@example.com",
82
+ * role: "member",
83
+ * });
84
+ * ```
85
+ */
86
+ get teams(): TeamsClient;
87
+ /**
88
+ * Create a new sandbox.
89
+ *
90
+ * @param options - Configuration for the new sandbox
91
+ * @returns A SandboxInstance representing the created sandbox
92
+ *
93
+ * @example
94
+ * ```typescript
95
+ * const box = await client.create({
96
+ * name: "my-project",
97
+ * environment: "universal",
98
+ * sshEnabled: true,
99
+ * env: { NODE_ENV: "development" },
100
+ * });
101
+ * ```
102
+ */
103
+ create(options?: CreateSandboxOptions): Promise<SandboxInstance>;
104
+ /**
105
+ * List all sandboxes.
106
+ *
107
+ * @param options - Filtering and pagination options
108
+ * @returns Array of SandboxInstance objects
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * // List all running sandboxes
113
+ * const running = await client.list({ status: "running" });
114
+ *
115
+ * // List with pagination
116
+ * const page = await client.list({ limit: 10, offset: 0 });
117
+ * ```
118
+ */
119
+ list(options?: ListSandboxOptions): Promise<SandboxInstance[]>;
120
+ /**
121
+ * Get a sandbox by ID.
122
+ *
123
+ * @param id - The sandbox ID
124
+ * @returns A SandboxInstance or null if not found
125
+ *
126
+ * @example
127
+ * ```typescript
128
+ * const box = await client.get("sandbox_abc123");
129
+ * if (box) {
130
+ * console.log(box.status);
131
+ * }
132
+ * ```
133
+ */
134
+ get(id: string): Promise<SandboxInstance | null>;
135
+ /**
136
+ * Get usage information for the account.
137
+ *
138
+ * @returns Usage statistics for the current billing period
139
+ *
140
+ * @example
141
+ * ```typescript
142
+ * const usage = await client.usage();
143
+ * console.log(`Active sandboxes: ${usage.activeSandboxes}`);
144
+ * console.log(`Compute minutes: ${usage.computeMinutes}`);
145
+ * ```
146
+ */
147
+ usage(): Promise<UsageInfo>;
148
+ /**
149
+ * Get subscription and billing information for the account.
150
+ *
151
+ * @returns Subscription details including plan, credits, and limits
152
+ *
153
+ * @example
154
+ * ```typescript
155
+ * const sub = await client.subscription();
156
+ * console.log(`Plan: ${sub.plan}`);
157
+ * console.log(`Credits: $${sub.creditsAvailableUsd.toFixed(2)}`);
158
+ * ```
159
+ */
160
+ subscription(): Promise<SubscriptionInfo>;
161
+ /**
162
+ * Check if the Sandbox API is available.
163
+ *
164
+ * @returns true if the API is healthy, false otherwise
165
+ */
166
+ health(): Promise<boolean>;
167
+ /**
168
+ * Check if CRIU checkpointing is available on the platform.
169
+ *
170
+ * CRIU enables memory preservation for true pause/resume and fork operations.
171
+ * It requires specific host configuration.
172
+ *
173
+ * @returns CRIU availability status
174
+ *
175
+ * @example
176
+ * ```typescript
177
+ * const status = await client.criuStatus();
178
+ * if (status.available) {
179
+ * console.log(`CRIU ${status.criuVersion} available`);
180
+ * } else {
181
+ * console.log(`CRIU not available: ${status.reason}`);
182
+ * }
183
+ * ```
184
+ */
185
+ criuStatus(): Promise<{
186
+ available: boolean;
187
+ criuVersion?: string;
188
+ reason?: string;
189
+ requirements?: {
190
+ kernel: boolean;
191
+ criu: boolean;
192
+ storageDriver: boolean;
193
+ experimental: boolean;
194
+ };
195
+ }>;
196
+ /**
197
+ * Run multiple tasks in parallel across sandboxes.
198
+ * Returns the aggregated results after all tasks complete.
199
+ *
200
+ * @param tasks - Array of tasks to execute
201
+ * @param options - Batch execution options
202
+ * @returns Aggregated batch results
203
+ *
204
+ * @throws {@link TimeoutError} if the server hasn't begun responding
205
+ * before the deadline (pre-stream timeout).
206
+ * @throws {@link ValidationError} / {@link QuotaError} / other typed
207
+ * SDK errors if the server rejects the request before streaming.
208
+ * @throws `DOMException` with `name === "AbortError"` if
209
+ * `options.signal` fires OR the safety-valve deadline fires
210
+ * AFTER streaming has begun — parseSSEStream can't distinguish
211
+ * the source mid-stream. Callers that need to tell cancel from
212
+ * timeout should check `options.signal?.aborted` in their catch.
213
+ * @throws `Error` with the server message if the stream emits a
214
+ * `batch.failed` event.
215
+ *
216
+ * @example
217
+ * ```typescript
218
+ * const result = await client.runBatch([
219
+ * { id: "task-1", message: "Analyze this file" },
220
+ * { id: "task-2", message: "Generate a summary" },
221
+ * ]);
222
+ * console.log(`Success rate: ${result.successRate}%`);
223
+ * ```
224
+ */
225
+ runBatch(tasks: BatchTask[], options?: BatchOptions): Promise<BatchResult>;
226
+ /**
227
+ * Stream events from a batch execution.
228
+ * Use this for real-time progress updates during batch processing.
229
+ *
230
+ * @param tasks - Array of tasks to execute
231
+ * @param options - Batch execution options
232
+ *
233
+ * @throws {@link TimeoutError} if the server hasn't begun responding
234
+ * before the deadline (pre-stream timeout).
235
+ * @throws {@link ValidationError} / {@link QuotaError} / other typed
236
+ * SDK errors if the server rejects the request before streaming.
237
+ * @throws `DOMException` with `name === "AbortError"` if
238
+ * `options.signal` fires OR the safety-valve deadline fires
239
+ * AFTER streaming has begun. Distinguish via
240
+ * `options.signal?.aborted` in the consumer's catch.
241
+ *
242
+ * @example
243
+ * ```typescript
244
+ * for await (const event of client.streamBatch(tasks)) {
245
+ * if (event.type === "task.completed") {
246
+ * console.log(`Task ${event.data.taskId} completed`);
247
+ * }
248
+ * }
249
+ * ```
250
+ */
251
+ streamBatch(tasks: BatchTask[], options?: BatchOptions): AsyncGenerator<BatchEvent>;
252
+ /**
253
+ * Make an authenticated HTTP request to the API.
254
+ * This is exposed for use by SandboxInstance.
255
+ */
256
+ fetch(path: string, options?: RequestInit): Promise<Response>;
257
+ private parseInfo;
258
+ }
259
+ /**
260
+ * Client for browsing available development environments.
261
+ */
262
+ declare class EnvironmentsClient {
263
+ private readonly client;
264
+ constructor(client: SandboxClient);
265
+ /**
266
+ * List available development environments.
267
+ *
268
+ * @returns Array of available environments with metadata
269
+ *
270
+ * @example
271
+ * ```typescript
272
+ * const envs = await client.environments.list();
273
+ * for (const env of envs) {
274
+ * console.log(`${env.id}: ${env.description}`);
275
+ * }
276
+ * ```
277
+ */
278
+ list(): Promise<SandboxEnvironment[]>;
279
+ /**
280
+ * Get details for a specific environment.
281
+ *
282
+ * @param id - Environment identifier (e.g., "universal")
283
+ */
284
+ get(id: string): Promise<SandboxEnvironment | null>;
285
+ }
286
+ /**
287
+ * Team (collaboration group) record as returned from the API.
288
+ */
289
+ interface Team {
290
+ id: string;
291
+ name: string;
292
+ ownerCustomerId: string;
293
+ orgId: string | null;
294
+ memberCount: number;
295
+ currentUserRole: "owner" | "admin" | "member" | "viewer";
296
+ createdAt: string;
297
+ updatedAt: string;
298
+ }
299
+ interface TeamMember {
300
+ id: string;
301
+ teamId: string;
302
+ customerId: string;
303
+ customerEmail: string;
304
+ customerName: string | null;
305
+ role: "owner" | "admin" | "member" | "viewer";
306
+ status: "active" | "pending" | "removed";
307
+ joinedAt: string | null;
308
+ createdAt: string;
309
+ }
310
+ interface TeamInvitation {
311
+ id: string;
312
+ teamId: string;
313
+ email: string;
314
+ invitedBy: string;
315
+ invitedByEmail: string | null;
316
+ role: "admin" | "member" | "viewer";
317
+ token: string;
318
+ status: "pending" | "accepted" | "expired" | "revoked";
319
+ expiresAt: string;
320
+ createdAt: string;
321
+ }
322
+ interface CreateTeamOptions {
323
+ name: string;
324
+ orgId?: string;
325
+ }
326
+ interface InviteTeamMemberOptions {
327
+ email: string;
328
+ role: "admin" | "member" | "viewer";
329
+ /** Lifetime of the invitation in hours (default 168 = 7 days). */
330
+ ttlHours?: number;
331
+ }
332
+ /**
333
+ * Client for managing teams and team-scoped sharing.
334
+ *
335
+ * Team resources are scoped to the authenticated user's membership —
336
+ * the client never needs to pass an org id explicitly.
337
+ */
338
+ declare class TeamsClient {
339
+ private readonly client;
340
+ constructor(client: SandboxClient);
341
+ list(): Promise<Team[]>;
342
+ create(options: CreateTeamOptions): Promise<Team>;
343
+ get(teamId: string): Promise<Team>;
344
+ update(teamId: string, updates: {
345
+ name?: string;
346
+ }): Promise<Team>;
347
+ delete(teamId: string): Promise<void>;
348
+ leave(teamId: string): Promise<void>;
349
+ listMembers(teamId: string): Promise<TeamMember[]>;
350
+ updateMember(teamId: string, memberId: string, updates: {
351
+ role?: "admin" | "member" | "viewer";
352
+ status?: "active" | "removed";
353
+ }): Promise<TeamMember>;
354
+ removeMember(teamId: string, memberId: string): Promise<void>;
355
+ listInvitations(teamId: string): Promise<TeamInvitation[]>;
356
+ invite(teamId: string, options: InviteTeamMemberOptions): Promise<TeamInvitation>;
357
+ revokeInvitation(invitationId: string): Promise<void>;
358
+ acceptInvitation(token: string): Promise<TeamMember>;
359
+ }
360
+ /**
361
+ * Alias for SandboxClient for cleaner imports.
362
+ */
363
+ //#endregion
364
+ //#region src/errors.d.ts
365
+ /**
366
+ * Sandbox SDK Errors
367
+ *
368
+ * Error classes for the Sandbox client SDK.
369
+ */
370
+ /**
371
+ * Base error class for all Sandbox SDK errors.
372
+ */
373
+ declare class SandboxError extends Error {
374
+ /** HTTP status code if applicable */
375
+ readonly status?: number;
376
+ /** Error code for programmatic handling */
377
+ readonly code: string;
378
+ constructor(message: string, code: string, status?: number);
379
+ }
380
+ /**
381
+ * Authentication failed or API key is invalid.
382
+ */
383
+ declare class AuthError extends SandboxError {
384
+ constructor(message?: string);
385
+ }
386
+ /**
387
+ * The requested resource was not found.
388
+ */
389
+ declare class NotFoundError extends SandboxError {
390
+ /** The resource type that was not found */
391
+ readonly resourceType: string;
392
+ /** The resource ID that was not found */
393
+ readonly resourceId: string;
394
+ constructor(resourceType: string, resourceId: string);
395
+ }
396
+ /**
397
+ * Account quota or rate limit exceeded.
398
+ */
399
+ declare class QuotaError extends SandboxError {
400
+ /** The type of quota that was exceeded */
401
+ readonly quotaType: string;
402
+ /** Current usage */
403
+ readonly current?: number;
404
+ /** Maximum allowed */
405
+ readonly limit?: number;
406
+ constructor(quotaType: string, message?: string, current?: number, limit?: number);
407
+ }
408
+ /**
409
+ * The request was invalid or malformed.
410
+ */
411
+ declare class ValidationError extends SandboxError {
412
+ /** Field-level validation errors */
413
+ readonly fields?: Record<string, string>;
414
+ constructor(message: string, fields?: Record<string, string>);
415
+ }
416
+ /**
417
+ * The sandbox is not in a valid state for the requested operation.
418
+ */
419
+ declare class StateError extends SandboxError {
420
+ /** Current state of the sandbox */
421
+ readonly currentState: string;
422
+ /** Required state for the operation */
423
+ readonly requiredState?: string;
424
+ constructor(message: string, currentState: string, requiredState?: string);
425
+ }
426
+ /**
427
+ * The request timed out.
428
+ */
429
+ declare class TimeoutError extends SandboxError {
430
+ /** Timeout duration in milliseconds */
431
+ readonly timeoutMs: number;
432
+ constructor(timeoutMs: number, message?: string);
433
+ }
434
+ /**
435
+ * A network or connection error occurred.
436
+ */
437
+ declare class NetworkError extends SandboxError {
438
+ /** The underlying error */
439
+ readonly cause?: Error;
440
+ constructor(message: string, cause?: Error);
441
+ }
442
+ /**
443
+ * The server returned an unexpected error.
444
+ */
445
+ declare class ServerError extends SandboxError {
446
+ constructor(message: string, status?: number);
447
+ }
448
+ //#endregion
449
+ export { SandboxError as a, TimeoutError as c, InviteTeamMemberOptions as d, SandboxClient as f, TeamMember as h, QuotaError as i, ValidationError as l, TeamInvitation as m, NetworkError as n, ServerError as o, Team as p, NotFoundError as r, StateError as s, AuthError as t, CreateTeamOptions as u };
@@ -0,0 +1,189 @@
1
+ //#region src/auth/types.d.ts
2
+ /**
3
+ * Auth Types
4
+ *
5
+ * Self-contained type definitions for token issuance.
6
+ * No external dependencies (no zod, no internal packages).
7
+ */
8
+ /**
9
+ * Token scope types for multi-tenant access control.
10
+ *
11
+ * - "session": Access to a single session (requires sid)
12
+ * - "project": Access to all sessions within a project (requires projectId)
13
+ * - "batch": Access to multiple projects (requires projectIds array)
14
+ * - "collaboration": Access to a single collaborative document
15
+ */
16
+ type TokenScope = "session" | "project" | "batch" | "collaboration";
17
+ /**
18
+ * Base token payload fields (common across all scopes).
19
+ */
20
+ interface BaseTokenPayload {
21
+ /** Subject: User ID */
22
+ sub: string;
23
+ /** Product ID (used to look up signing secret) */
24
+ pid: string;
25
+ /** Sandbox runtime ID (optional, for direct routing) */
26
+ cid?: string;
27
+ /** Issued at (Unix timestamp, seconds) */
28
+ iat: number;
29
+ /** Expires at (Unix timestamp, seconds) */
30
+ exp: number;
31
+ }
32
+ interface ReadBaseTokenPayload extends BaseTokenPayload {
33
+ /** Token type for session/project/batch event subscriptions */
34
+ typ: "read";
35
+ }
36
+ /**
37
+ * Session-scoped token payload.
38
+ * Grants access to a single session's events.
39
+ */
40
+ interface SessionScopedTokenPayload extends ReadBaseTokenPayload {
41
+ /** Session ID */
42
+ sid: string;
43
+ projectId?: undefined;
44
+ projectIds?: undefined;
45
+ }
46
+ /**
47
+ * Project-scoped token payload.
48
+ * Grants access to all sessions within a single project.
49
+ */
50
+ interface ProjectScopedTokenPayload extends ReadBaseTokenPayload {
51
+ sid?: undefined;
52
+ /** Project ID */
53
+ projectId: string;
54
+ projectIds?: undefined;
55
+ }
56
+ /**
57
+ * Batch-scoped token payload.
58
+ * Grants access to multiple projects (organization-level access).
59
+ */
60
+ interface BatchScopedTokenPayload extends ReadBaseTokenPayload {
61
+ sid?: undefined;
62
+ projectId?: undefined;
63
+ /** Project IDs */
64
+ projectIds: string[];
65
+ }
66
+ type CollaborationAccess = "read" | "write";
67
+ /**
68
+ * Collaboration-scoped token payload.
69
+ * Grants access to a single collaborative document in one project.
70
+ */
71
+ interface CollaborationTokenPayload extends BaseTokenPayload {
72
+ typ: "collaboration";
73
+ sid: string;
74
+ projectId: string;
75
+ documentId: string;
76
+ access: CollaborationAccess;
77
+ }
78
+ interface IssueCollaborationTokenOptions {
79
+ sessionId: string;
80
+ projectId: string;
81
+ documentId: string;
82
+ access: CollaborationAccess;
83
+ userId: string;
84
+ productId: string;
85
+ sandboxId?: string;
86
+ }
87
+ /**
88
+ * Union of all token payload types.
89
+ */
90
+ type ReadTokenPayload = SessionScopedTokenPayload | ProjectScopedTokenPayload | BatchScopedTokenPayload;
91
+ type AnyTokenPayload = ReadTokenPayload | CollaborationTokenPayload;
92
+ //#endregion
93
+ //#region src/auth/tokens.d.ts
94
+ /**
95
+ * Issue a read token (JWT) for WebSocket authentication.
96
+ *
97
+ * @param signingSecret - The product's signing secret
98
+ * @param payload - Token payload (without iat/exp/typ, those are added)
99
+ * @param ttlMinutes - Token TTL in minutes
100
+ */
101
+ declare function issueReadToken(signingSecret: string, payload: Omit<ReadTokenPayload, "iat" | "exp" | "typ">, ttlMinutes: number): string;
102
+ /**
103
+ * Issue a session-scoped token (JWT) for WebSocket authentication.
104
+ * Grants access to a single session's events.
105
+ */
106
+ declare function issueSessionScopedToken(signingSecret: string, payload: Omit<ReadTokenPayload, "iat" | "exp" | "typ">, ttlMinutes: number): string;
107
+ /**
108
+ * Issue a project-scoped token (JWT) for WebSocket authentication.
109
+ * Grants access to all sessions within a single project.
110
+ */
111
+ declare function issueProjectScopedToken(signingSecret: string, payload: Omit<ReadTokenPayload, "iat" | "exp" | "typ">, ttlMinutes: number): string;
112
+ /**
113
+ * Issue a batch-scoped token (JWT) for WebSocket authentication.
114
+ * Grants access to multiple projects (organization-level access).
115
+ */
116
+ declare function issueBatchScopedToken(signingSecret: string, payload: Omit<ReadTokenPayload, "iat" | "exp" | "typ">, ttlMinutes: number): string;
117
+ /**
118
+ * Issue a collaboration-scoped token (JWT) for collaborative document access.
119
+ * Grants read or write access to a single document in one project.
120
+ */
121
+ declare function issueCollaborationToken(signingSecret: string, payload: IssueCollaborationTokenOptions, ttlMinutes: number): string;
122
+ /**
123
+ * Decode a JWT without verification (to extract claims for lookup).
124
+ * Returns null if the token is malformed.
125
+ */
126
+ declare function decodeToken(token: string): AnyTokenPayload | null;
127
+ /**
128
+ * Get time until token expires (in seconds).
129
+ * Returns negative if expired.
130
+ */
131
+ declare function getTokenTTL(payload: AnyTokenPayload): number;
132
+ /**
133
+ * Check if token is expiring soon (within buffer seconds).
134
+ */
135
+ declare function isTokenExpiringSoon(payload: AnyTokenPayload, bufferSeconds?: number): boolean;
136
+ //#endregion
137
+ //#region src/auth/index.d.ts
138
+ /**
139
+ * Token issuer for application backend services.
140
+ *
141
+ * Use this in your backend to issue read tokens for WebSocket connections.
142
+ */
143
+ declare class ProductTokenIssuer {
144
+ private readonly productId;
145
+ private readonly signingSecret;
146
+ private readonly ttlMinutes;
147
+ constructor(config: {
148
+ productId: string;
149
+ signingSecret: string; /** TTL in minutes for each tier (default: { free: 15, pro: 240 }) */
150
+ ttlMinutes?: {
151
+ free?: number;
152
+ pro?: number;
153
+ enterprise?: number;
154
+ };
155
+ });
156
+ /**
157
+ * Issue a read token for a user session.
158
+ */
159
+ issue(params: {
160
+ userId: string;
161
+ sessionId: string;
162
+ tier?: "free" | "pro" | "enterprise";
163
+ sandboxId?: string;
164
+ }): {
165
+ token: string;
166
+ expiresAt: number;
167
+ };
168
+ /**
169
+ * Issue a collaboration token for a single document.
170
+ */
171
+ issueCollaboration(params: {
172
+ userId: string;
173
+ sessionId: string;
174
+ projectId: string;
175
+ documentId: string;
176
+ access: "read" | "write";
177
+ tier?: "free" | "pro" | "enterprise";
178
+ sandboxId?: string;
179
+ }): {
180
+ token: string;
181
+ expiresAt: number;
182
+ };
183
+ /**
184
+ * Get the TTL in minutes for a tier.
185
+ */
186
+ getTtlMinutes(tier?: "free" | "pro" | "enterprise"): number;
187
+ }
188
+ //#endregion
189
+ export { SessionScopedTokenPayload as _, issueBatchScopedToken as a, issueReadToken as c, BatchScopedTokenPayload as d, CollaborationAccess as f, ReadTokenPayload as g, ProjectScopedTokenPayload as h, isTokenExpiringSoon as i, issueSessionScopedToken as l, IssueCollaborationTokenOptions as m, decodeToken as n, issueCollaborationToken as o, CollaborationTokenPayload as p, getTokenTTL as r, issueProjectScopedToken as s, ProductTokenIssuer as t, AnyTokenPayload as u, TokenScope as v };