@meshagent/meshagent 0.5.19 → 0.6.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.
Files changed (62) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/browser/agent-client.d.ts +15 -7
  3. package/dist/browser/agent-client.js +52 -14
  4. package/dist/browser/api_keys.d.ts +13 -0
  5. package/dist/browser/api_keys.js +185 -0
  6. package/dist/browser/data-types.d.ts +6 -0
  7. package/dist/browser/data-types.js +20 -1
  8. package/dist/browser/entrypoint.d.ts +1423 -1464
  9. package/dist/browser/helpers.d.ts +9 -7
  10. package/dist/browser/helpers.js +18 -5
  11. package/dist/browser/index.d.ts +3 -0
  12. package/dist/browser/index.js +3 -0
  13. package/dist/browser/lk-client.d.ts +18 -0
  14. package/dist/browser/lk-client.js +24 -0
  15. package/dist/browser/lk-protocol.d.ts +22 -0
  16. package/dist/browser/lk-protocol.js +37 -0
  17. package/dist/browser/meshagent-client.d.ts +392 -0
  18. package/dist/browser/meshagent-client.js +1051 -0
  19. package/dist/browser/participant-token.d.ts +179 -7
  20. package/dist/browser/participant-token.js +373 -21
  21. package/dist/browser/stream-controller.js +3 -14
  22. package/dist/esm/agent-client.d.ts +15 -7
  23. package/dist/esm/agent-client.js +52 -14
  24. package/dist/esm/api_keys.d.ts +13 -0
  25. package/dist/esm/api_keys.js +175 -0
  26. package/dist/esm/data-types.d.ts +6 -0
  27. package/dist/esm/data-types.js +18 -0
  28. package/dist/esm/entrypoint.d.ts +1423 -1464
  29. package/dist/esm/helpers.d.ts +9 -7
  30. package/dist/esm/helpers.js +19 -6
  31. package/dist/esm/index.d.ts +3 -0
  32. package/dist/esm/index.js +3 -0
  33. package/dist/esm/lk-client.d.ts +18 -0
  34. package/dist/esm/lk-client.js +19 -0
  35. package/dist/esm/lk-protocol.d.ts +22 -0
  36. package/dist/esm/lk-protocol.js +33 -0
  37. package/dist/esm/meshagent-client.d.ts +392 -0
  38. package/dist/esm/meshagent-client.js +1047 -0
  39. package/dist/esm/participant-token.d.ts +179 -7
  40. package/dist/esm/participant-token.js +357 -20
  41. package/dist/esm/stream-controller.js +3 -14
  42. package/dist/node/agent-client.d.ts +15 -7
  43. package/dist/node/agent-client.js +52 -14
  44. package/dist/node/api_keys.d.ts +13 -0
  45. package/dist/node/api_keys.js +185 -0
  46. package/dist/node/data-types.d.ts +6 -0
  47. package/dist/node/data-types.js +20 -1
  48. package/dist/node/entrypoint.d.ts +1423 -1464
  49. package/dist/node/helpers.d.ts +9 -7
  50. package/dist/node/helpers.js +18 -5
  51. package/dist/node/index.d.ts +3 -0
  52. package/dist/node/index.js +3 -0
  53. package/dist/node/lk-client.d.ts +18 -0
  54. package/dist/node/lk-client.js +24 -0
  55. package/dist/node/lk-protocol.d.ts +22 -0
  56. package/dist/node/lk-protocol.js +37 -0
  57. package/dist/node/meshagent-client.d.ts +392 -0
  58. package/dist/node/meshagent-client.js +1051 -0
  59. package/dist/node/participant-token.d.ts +179 -7
  60. package/dist/node/participant-token.js +373 -21
  61. package/dist/node/stream-controller.js +3 -14
  62. package/package.json +6 -3
@@ -0,0 +1,1051 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Meshagent = void 0;
4
+ const helpers_1 = require("./helpers");
5
+ const requirement_1 = require("./requirement");
6
+ const participant_token_1 = require("./participant-token");
7
+ function pruneUndefinedValues(value) {
8
+ if (Array.isArray(value)) {
9
+ const prunedItems = value
10
+ .map((item) => pruneUndefinedValues(item))
11
+ .filter((item) => item !== undefined);
12
+ return prunedItems;
13
+ }
14
+ if (value === null || value === undefined) {
15
+ return value === undefined ? undefined : null;
16
+ }
17
+ if (typeof value === "object") {
18
+ const result = {};
19
+ for (const [key, entryValue] of Object.entries(value)) {
20
+ if (entryValue === undefined) {
21
+ continue;
22
+ }
23
+ result[key] = pruneUndefinedValues(entryValue);
24
+ }
25
+ return result;
26
+ }
27
+ return value;
28
+ }
29
+ function serializeServiceSpec(service) {
30
+ return pruneUndefinedValues(service);
31
+ }
32
+ class Meshagent {
33
+ constructor({ baseUrl, token } = {}) {
34
+ const resolvedBaseUrl = (0, helpers_1.meshagentBaseUrl)(baseUrl).replace(/\/+$/, "");
35
+ this.baseUrl = resolvedBaseUrl || "https://api.meshagent.com";
36
+ const envToken = typeof process !== "undefined" ? process.env?.MESHAGENT_API_KEY : undefined;
37
+ this.token = token ?? envToken ?? undefined;
38
+ }
39
+ buildUrl(path, query) {
40
+ const url = new URL(path, this.baseUrl);
41
+ if (query) {
42
+ for (const [key, value] of Object.entries(query)) {
43
+ if (value === undefined || value === null) {
44
+ continue;
45
+ }
46
+ url.searchParams.set(key, String(value));
47
+ }
48
+ }
49
+ return url.toString();
50
+ }
51
+ async request(path, options) {
52
+ const { method = "GET", query, json, body, headers, action, responseType = "json" } = options;
53
+ const url = this.buildUrl(path, query);
54
+ const finalHeaders = {};
55
+ if (this.token) {
56
+ finalHeaders["Authorization"] = `Bearer ${this.token}`;
57
+ }
58
+ if (headers) {
59
+ for (const [key, value] of Object.entries(headers)) {
60
+ finalHeaders[key] = value;
61
+ }
62
+ }
63
+ let requestBody = undefined;
64
+ if (json !== undefined && json !== null) {
65
+ requestBody = JSON.stringify(json);
66
+ finalHeaders["Content-Type"] = "application/json";
67
+ }
68
+ else if (body !== undefined && body !== null) {
69
+ if (body instanceof ArrayBuffer) {
70
+ requestBody = new Uint8Array(body);
71
+ }
72
+ else {
73
+ requestBody = body;
74
+ }
75
+ }
76
+ const response = await fetch(url, {
77
+ method,
78
+ headers: finalHeaders,
79
+ body: requestBody ?? undefined,
80
+ });
81
+ if (!response.ok) {
82
+ let message;
83
+ try {
84
+ message = await response.text();
85
+ }
86
+ catch {
87
+ message = "<unable to read body>";
88
+ }
89
+ throw new requirement_1.RoomException(`Failed to ${action}. Status code: ${response.status}, body: ${message}`);
90
+ }
91
+ switch (responseType) {
92
+ case "json":
93
+ if (response.status === 204) {
94
+ return {};
95
+ }
96
+ return (await response.json());
97
+ case "text":
98
+ return (await response.text());
99
+ case "arrayBuffer":
100
+ return new Uint8Array(await response.arrayBuffer());
101
+ case "void":
102
+ default:
103
+ return undefined;
104
+ }
105
+ }
106
+ parseRoomShare(data) {
107
+ if (!data || typeof data !== "object") {
108
+ throw new requirement_1.RoomException("Invalid room share payload: expected object");
109
+ }
110
+ const { id, project_id: projectId, projectId: projectIdAlt, settings } = data;
111
+ if (typeof id !== "string") {
112
+ throw new requirement_1.RoomException("Invalid room share payload: missing id");
113
+ }
114
+ const finalProjectId = typeof projectIdAlt === "string" ? projectIdAlt : typeof projectId === "string" ? projectId : undefined;
115
+ if (!finalProjectId) {
116
+ throw new requirement_1.RoomException("Invalid room share payload: missing project id");
117
+ }
118
+ return {
119
+ id,
120
+ projectId: finalProjectId,
121
+ settings: (settings && typeof settings === "object") ? settings : {},
122
+ };
123
+ }
124
+ parseRoomShareConnectionInfo(data) {
125
+ if (!data || typeof data !== "object") {
126
+ throw new requirement_1.RoomException("Invalid room share connection payload");
127
+ }
128
+ const { jwt, room_name: roomNameRaw, roomName, project_id: projectIdRaw, projectId, settings, room_url: roomUrlRaw, roomUrl } = data;
129
+ if (typeof jwt !== "string") {
130
+ throw new requirement_1.RoomException("Invalid room share connection payload: missing jwt");
131
+ }
132
+ const roomNameValue = typeof roomName === "string" ? roomName : roomNameRaw;
133
+ const projectIdValue = typeof projectId === "string" ? projectId : projectIdRaw;
134
+ const roomUrlValue = typeof roomUrl === "string" ? roomUrl : roomUrlRaw;
135
+ if (typeof roomNameValue !== "string" || typeof projectIdValue !== "string" || typeof roomUrlValue !== "string") {
136
+ throw new requirement_1.RoomException("Invalid room share connection payload: missing fields");
137
+ }
138
+ return {
139
+ jwt,
140
+ roomName: roomNameValue,
141
+ projectId: projectIdValue,
142
+ settings: (settings && typeof settings === "object") ? settings : {},
143
+ roomUrl: roomUrlValue,
144
+ };
145
+ }
146
+ parseRoomSession(data) {
147
+ if (!data || typeof data !== "object") {
148
+ throw new requirement_1.RoomException("Invalid room session payload");
149
+ }
150
+ const { id, room_id: roomIdRaw, roomId, room_name: roomNameRaw, roomName, created_at: createdRaw, createdAt, is_active: isActiveRaw, isActive, participants } = data;
151
+ if (typeof id !== "string") {
152
+ throw new requirement_1.RoomException("Invalid room session payload: missing id");
153
+ }
154
+ const roomNameValue = typeof roomName === "string" ? roomName : roomNameRaw;
155
+ if (typeof roomNameValue !== "string") {
156
+ throw new requirement_1.RoomException("Invalid room session payload: missing room name");
157
+ }
158
+ const created = typeof createdAt === "string" ? createdAt : createdRaw;
159
+ if (typeof created !== "string") {
160
+ throw new requirement_1.RoomException("Invalid room session payload: missing created_at");
161
+ }
162
+ const isActiveValue = typeof isActive === "boolean" ? isActive : isActiveRaw;
163
+ if (typeof isActiveValue !== "boolean") {
164
+ throw new requirement_1.RoomException("Invalid room session payload: missing is_active");
165
+ }
166
+ return {
167
+ id,
168
+ roomId: typeof roomId === "string" ? roomId : typeof roomIdRaw === "string" ? roomIdRaw : undefined,
169
+ roomName: roomNameValue,
170
+ createdAt: new Date(created),
171
+ isActive: isActiveValue,
172
+ participants: participants && typeof participants === "object" ? participants : undefined,
173
+ };
174
+ }
175
+ parseRoom(data) {
176
+ if (!data || typeof data !== "object") {
177
+ throw new requirement_1.RoomException("Invalid room payload");
178
+ }
179
+ const { id, name, metadata } = data;
180
+ if (typeof id !== "string" || typeof name !== "string") {
181
+ throw new requirement_1.RoomException("Invalid room payload: missing id or name");
182
+ }
183
+ return {
184
+ id,
185
+ name,
186
+ metadata: metadata && typeof metadata === "object" ? metadata : {},
187
+ };
188
+ }
189
+ parseProjectRoomGrant(data) {
190
+ if (!data || typeof data !== "object") {
191
+ throw new requirement_1.RoomException("Invalid room grant payload");
192
+ }
193
+ const roomData = data.room;
194
+ const room = this.parseRoom(roomData);
195
+ const userId = data.user_id ?? data.userId;
196
+ if (typeof userId !== "string") {
197
+ throw new requirement_1.RoomException("Invalid room grant payload: missing user_id");
198
+ }
199
+ const permissionsRaw = data.permissions;
200
+ const permissions = permissionsRaw && typeof permissionsRaw === "object" ? participant_token_1.ApiScope.fromJSON(permissionsRaw) : new participant_token_1.ApiScope();
201
+ return { room, userId, permissions };
202
+ }
203
+ parseProjectRoomGrantCount(data) {
204
+ const roomData = (data && typeof data === "object") ? (data.room ?? { id: data.room_id, name: data.room_name, metadata: data.metadata ?? {} }) : undefined;
205
+ if (!roomData) {
206
+ throw new requirement_1.RoomException("Invalid room grant count payload: missing room");
207
+ }
208
+ const room = this.parseRoom(roomData);
209
+ const count = data.count;
210
+ if (typeof count !== "number") {
211
+ throw new requirement_1.RoomException("Invalid room grant count payload: missing count");
212
+ }
213
+ return { room, count };
214
+ }
215
+ parseProjectUserGrantCount(data) {
216
+ if (!data || typeof data !== "object") {
217
+ throw new requirement_1.RoomException("Invalid room grant user count payload");
218
+ }
219
+ const { user_id: userIdRaw, userId, count, first_name: firstNameRaw, firstName, last_name: lastNameRaw, lastName, email } = data;
220
+ const userIdValue = typeof userId === "string" ? userId : userIdRaw;
221
+ if (typeof userIdValue !== "string") {
222
+ throw new requirement_1.RoomException("Invalid room grant user count payload: missing user_id");
223
+ }
224
+ if (typeof count !== "number") {
225
+ throw new requirement_1.RoomException("Invalid room grant user count payload: missing count");
226
+ }
227
+ if (typeof email !== "string") {
228
+ throw new requirement_1.RoomException("Invalid room grant user count payload: missing email");
229
+ }
230
+ return {
231
+ userId: userIdValue,
232
+ count,
233
+ firstName: typeof firstName === "string" ? firstName : firstNameRaw,
234
+ lastName: typeof lastName === "string" ? lastName : lastNameRaw,
235
+ email,
236
+ };
237
+ }
238
+ parseBalance(data) {
239
+ if (!data || typeof data !== "object") {
240
+ throw new requirement_1.RoomException("Invalid balance payload");
241
+ }
242
+ const balanceValue = data.balance;
243
+ if (typeof balanceValue !== "number") {
244
+ throw new requirement_1.RoomException("Invalid balance payload: missing balance");
245
+ }
246
+ const threshold = data.auto_recharge_threshold ?? data.autoRechargeThreshold;
247
+ const amount = data.auto_recharge_amount ?? data.autoRechargeAmount;
248
+ const lastRechargeRaw = data.last_recharge ?? data.lastRecharge;
249
+ return {
250
+ balance: balanceValue,
251
+ autoRechargeThreshold: typeof threshold === "number" ? threshold : null,
252
+ autoRechargeAmount: typeof amount === "number" ? amount : null,
253
+ lastRecharge: typeof lastRechargeRaw === "string" ? new Date(lastRechargeRaw) : null,
254
+ };
255
+ }
256
+ parseTransaction(data) {
257
+ if (!data || typeof data !== "object") {
258
+ throw new requirement_1.RoomException("Invalid transaction payload");
259
+ }
260
+ const { id, amount, reference, referenceType, reference_type: referenceTypeRaw, description, created_at: createdAtRaw, createdAt } = data;
261
+ if (typeof id !== "string" || typeof amount !== "number" || typeof description !== "string") {
262
+ throw new requirement_1.RoomException("Invalid transaction payload: missing fields");
263
+ }
264
+ const createdValue = typeof createdAt === "string" ? createdAt : createdAtRaw;
265
+ if (typeof createdValue !== "string") {
266
+ throw new requirement_1.RoomException("Invalid transaction payload: missing created_at");
267
+ }
268
+ const referenceTypeValue = typeof referenceType === "string" ? referenceType : referenceTypeRaw;
269
+ return {
270
+ id,
271
+ amount,
272
+ reference: typeof reference === "string" ? reference : null,
273
+ referenceType: typeof referenceTypeValue === "string" ? referenceTypeValue : null,
274
+ description,
275
+ createdAt: new Date(createdValue),
276
+ };
277
+ }
278
+ parseSecret(data) {
279
+ if (!data || typeof data !== "object") {
280
+ throw new requirement_1.RoomException("Invalid secret payload");
281
+ }
282
+ const type = data.type;
283
+ if (type === "docker") {
284
+ const server = data.server;
285
+ const username = data.username;
286
+ const password = data.password;
287
+ if (typeof server !== "string" || typeof username !== "string" || typeof password !== "string") {
288
+ throw new requirement_1.RoomException("Invalid docker secret payload");
289
+ }
290
+ return {
291
+ id: typeof data.id === "string" ? data.id : undefined,
292
+ name: data.name,
293
+ type: "docker",
294
+ server,
295
+ username,
296
+ password,
297
+ email: typeof data.email === "string" ? data.email : undefined,
298
+ };
299
+ }
300
+ if (type === "keys") {
301
+ const record = data.data;
302
+ if (!record || typeof record !== "object") {
303
+ throw new requirement_1.RoomException("Invalid keys secret payload");
304
+ }
305
+ return {
306
+ id: typeof data.id === "string" ? data.id : undefined,
307
+ name: data.name,
308
+ type: "keys",
309
+ data: record,
310
+ };
311
+ }
312
+ throw new requirement_1.RoomException(`Unknown secret type: ${type}`);
313
+ }
314
+ toSecretPayload(secret) {
315
+ if (secret.type === "docker") {
316
+ return {
317
+ name: secret.name,
318
+ type: secret.type,
319
+ data: {
320
+ server: secret.server,
321
+ username: secret.username,
322
+ password: secret.password,
323
+ email: secret.email ?? "none@example.com",
324
+ },
325
+ };
326
+ }
327
+ return {
328
+ name: secret.name,
329
+ type: secret.type,
330
+ data: { ...secret.data },
331
+ };
332
+ }
333
+ parseOAuthClient(data) {
334
+ if (!data || typeof data !== "object") {
335
+ throw new requirement_1.RoomException("Invalid OAuth client payload");
336
+ }
337
+ const { client_id: clientIdRaw, clientId, client_secret: clientSecretRaw, clientSecret, grant_types: grantTypesRaw, grantTypes, response_types: responseTypesRaw, responseTypes, redirect_uris: redirectUrisRaw, redirectUris, scope, project_id: projectIdRaw, projectId, metadata } = data;
338
+ const clientIdValue = typeof clientId === "string" ? clientId : clientIdRaw;
339
+ const clientSecretValue = typeof clientSecret === "string" ? clientSecret : clientSecretRaw;
340
+ const grantTypesValue = Array.isArray(grantTypes) ? grantTypes : grantTypesRaw;
341
+ const responseTypesValue = Array.isArray(responseTypes) ? responseTypes : responseTypesRaw;
342
+ const redirectUrisValue = Array.isArray(redirectUris) ? redirectUris : redirectUrisRaw;
343
+ const projectIdValue = typeof projectId === "string" ? projectId : projectIdRaw;
344
+ if (typeof clientIdValue !== "string" ||
345
+ typeof clientSecretValue !== "string" ||
346
+ !Array.isArray(grantTypesValue) ||
347
+ !Array.isArray(responseTypesValue) ||
348
+ !Array.isArray(redirectUrisValue) ||
349
+ typeof scope !== "string" ||
350
+ typeof projectIdValue !== "string") {
351
+ throw new requirement_1.RoomException("Invalid OAuth client payload: missing required fields");
352
+ }
353
+ return {
354
+ clientId: clientIdValue,
355
+ clientSecret: clientSecretValue,
356
+ grantTypes: grantTypesValue.map(String),
357
+ responseTypes: responseTypesValue.map(String),
358
+ redirectUris: redirectUrisValue.map(String),
359
+ scope,
360
+ projectId: projectIdValue,
361
+ metadata: metadata && typeof metadata === "object" ? metadata : {},
362
+ };
363
+ }
364
+ parseRoomConnectionInfo(data) {
365
+ if (!data || typeof data !== "object") {
366
+ throw new requirement_1.RoomException("Invalid room connection payload");
367
+ }
368
+ const { jwt, room_name: roomNameRaw, roomName, project_id: projectIdRaw, projectId, room_url: roomUrlRaw, roomUrl } = data;
369
+ const roomNameValue = typeof roomName === "string" ? roomName : roomNameRaw;
370
+ const projectIdValue = typeof projectId === "string" ? projectId : projectIdRaw;
371
+ const roomUrlValue = typeof roomUrl === "string" ? roomUrl : roomUrlRaw;
372
+ if (typeof jwt !== "string" || typeof roomNameValue !== "string" || typeof projectIdValue !== "string" || typeof roomUrlValue !== "string") {
373
+ throw new requirement_1.RoomException("Invalid room connection payload: missing fields");
374
+ }
375
+ return { jwt, roomName: roomNameValue, projectId: projectIdValue, roomUrl: roomUrlValue };
376
+ }
377
+ encodePathComponent(value) {
378
+ return encodeURIComponent(value);
379
+ }
380
+ async upload({ projectId, path, data }) {
381
+ let body = data;
382
+ if (data instanceof ArrayBuffer) {
383
+ body = new Uint8Array(data);
384
+ }
385
+ await this.request(`/projects/${projectId}/storage/upload`, {
386
+ method: "POST",
387
+ query: { path },
388
+ body,
389
+ headers: { "Content-Type": "application/octet-stream" },
390
+ action: "upload file",
391
+ responseType: "void",
392
+ });
393
+ }
394
+ async download({ projectId, path }) {
395
+ return await this.request(`/projects/${projectId}/storage/download`, {
396
+ method: "GET",
397
+ query: { path },
398
+ action: "download file",
399
+ responseType: "arrayBuffer",
400
+ });
401
+ }
402
+ async getProjectRole(projectId) {
403
+ const payload = await this.request(`/accounts/projects/${projectId}/role`, {
404
+ action: "fetch project role",
405
+ });
406
+ const role = payload?.role;
407
+ if (role !== "member" && role !== "admin" && role !== "developer") {
408
+ throw new requirement_1.RoomException("Invalid role payload");
409
+ }
410
+ return role;
411
+ }
412
+ async createShare(projectId, settings) {
413
+ return await this.request(`/accounts/projects/${projectId}/shares`, {
414
+ method: "POST",
415
+ json: { settings: settings ?? {} },
416
+ action: "create share",
417
+ });
418
+ }
419
+ async deleteShare(projectId, shareId) {
420
+ await this.request(`/accounts/projects/${projectId}/shares/${shareId}`, {
421
+ method: "DELETE",
422
+ action: "delete share",
423
+ responseType: "void",
424
+ });
425
+ }
426
+ async updateShare(projectId, shareId, settings) {
427
+ await this.request(`/accounts/projects/${projectId}/shares/${shareId}`, {
428
+ method: "PUT",
429
+ json: { settings: settings ?? {} },
430
+ action: "update share",
431
+ responseType: "void",
432
+ });
433
+ }
434
+ async listShares(projectId) {
435
+ const data = await this.request(`/accounts/projects/${projectId}/shares`, {
436
+ action: "list shares",
437
+ });
438
+ const shares = Array.isArray(data?.shares) ? data.shares : [];
439
+ return shares.map((item) => this.parseRoomShare(item));
440
+ }
441
+ async connectShare(shareId) {
442
+ const data = await this.request(`/shares/${shareId}/connect`, {
443
+ method: "POST",
444
+ json: {},
445
+ action: "connect share",
446
+ });
447
+ return this.parseRoomShareConnectionInfo(data);
448
+ }
449
+ async createProject(name, settings) {
450
+ return await this.request(`/accounts/projects`, {
451
+ method: "POST",
452
+ json: { name, settings },
453
+ action: "create project",
454
+ });
455
+ }
456
+ async addUserToProject(projectId, userId, options = {}) {
457
+ const { isAdmin = false, isDeveloper = false } = options;
458
+ return await this.request(`/accounts/projects/${projectId}/users`, {
459
+ method: "POST",
460
+ json: {
461
+ project_id: projectId,
462
+ user_id: userId,
463
+ is_admin: isAdmin,
464
+ is_developer: isDeveloper,
465
+ },
466
+ action: "add user to project",
467
+ });
468
+ }
469
+ async removeUserFromProject(projectId, userId) {
470
+ return await this.request(`/accounts/projects/${projectId}/users/${userId}`, {
471
+ method: "DELETE",
472
+ action: "remove user from project",
473
+ });
474
+ }
475
+ async updateProjectSettings(projectId, settings) {
476
+ return await this.request(`/accounts/projects/${projectId}/settings`, {
477
+ method: "PUT",
478
+ json: settings,
479
+ action: "update project settings",
480
+ });
481
+ }
482
+ async getUsersInProject(projectId) {
483
+ return await this.request(`/accounts/projects/${projectId}/users`, {
484
+ action: "fetch project users",
485
+ });
486
+ }
487
+ async getUserProfile(userId) {
488
+ return await this.request(`/accounts/profiles/${userId}`, {
489
+ action: "fetch user profile",
490
+ });
491
+ }
492
+ async updateUserProfile(userId, firstName, lastName) {
493
+ return await this.request(`/accounts/profiles/${userId}`, {
494
+ method: "PUT",
495
+ json: { first_name: firstName, last_name: lastName },
496
+ action: "update user profile",
497
+ });
498
+ }
499
+ async listProjects() {
500
+ return await this.request(`/accounts/projects`, {
501
+ action: "list projects",
502
+ });
503
+ }
504
+ async getProject(projectId) {
505
+ return await this.request(`/accounts/projects/${projectId}`, {
506
+ action: "get project",
507
+ });
508
+ }
509
+ async createApiKey(projectId, name, description) {
510
+ return await this.request(`/accounts/projects/${projectId}/api-keys`, {
511
+ method: "POST",
512
+ json: { name, description },
513
+ action: "create api key",
514
+ });
515
+ }
516
+ async deleteApiKey(projectId, id) {
517
+ await this.request(`/accounts/projects/${projectId}/api-keys/${id}`, {
518
+ method: "DELETE",
519
+ action: "delete api key",
520
+ responseType: "void",
521
+ });
522
+ }
523
+ async listApiKeys(projectId) {
524
+ return await this.request(`/accounts/projects/${projectId}/api-keys`, {
525
+ action: "list api keys",
526
+ });
527
+ }
528
+ async getPricing() {
529
+ return await this.request(`/pricing`, {
530
+ action: "fetch pricing data",
531
+ });
532
+ }
533
+ async getStatus(projectId) {
534
+ const data = await this.request(`/accounts/projects/${projectId}/status`, {
535
+ action: "fetch project status",
536
+ });
537
+ const enabled = data?.["enabled"];
538
+ if (typeof enabled !== "boolean") {
539
+ throw new requirement_1.RoomException("Invalid status payload: expected boolean 'enabled'");
540
+ }
541
+ return enabled;
542
+ }
543
+ async getBalance(projectId) {
544
+ const data = await this.request(`/accounts/projects/${projectId}/balance`, {
545
+ action: "fetch balance",
546
+ });
547
+ return this.parseBalance(data);
548
+ }
549
+ async getRecentTransactions(projectId) {
550
+ const data = await this.request(`/accounts/projects/${projectId}/transactions`, {
551
+ action: "fetch transactions",
552
+ });
553
+ const list = Array.isArray(data?.transactions) ? data.transactions : [];
554
+ return list.map((item) => this.parseTransaction(item));
555
+ }
556
+ async setAutoRecharge({ projectId, enabled, amount, threshold }) {
557
+ await this.request(`/accounts/projects/${projectId}/recharge`, {
558
+ method: "POST",
559
+ json: { enabled, amount, threshold },
560
+ action: "update auto recharge settings",
561
+ responseType: "void",
562
+ });
563
+ }
564
+ async getCheckoutUrl(projectId, { successUrl, cancelUrl }) {
565
+ const data = await this.request(`/accounts/projects/${projectId}/subscription`, {
566
+ method: "POST",
567
+ json: { success_url: successUrl, cancel_url: cancelUrl },
568
+ action: "create subscription checkout",
569
+ });
570
+ const url = data?.["checkout_url"];
571
+ if (typeof url !== "string") {
572
+ throw new requirement_1.RoomException("Invalid subscription payload: expected 'checkout_url' string");
573
+ }
574
+ return url;
575
+ }
576
+ async getCreditsCheckoutUrl(projectId, { successUrl, cancelUrl, quantity }) {
577
+ const data = await this.request(`/accounts/projects/${projectId}/credits`, {
578
+ method: "POST",
579
+ json: { success_url: successUrl, cancel_url: cancelUrl, quantity },
580
+ action: "create credits checkout",
581
+ });
582
+ const url = data?.["checkout_url"];
583
+ if (typeof url !== "string") {
584
+ throw new requirement_1.RoomException("Invalid credits payload: expected 'checkout_url' string");
585
+ }
586
+ return url;
587
+ }
588
+ async getSubscription(projectId) {
589
+ return await this.request(`/accounts/projects/${projectId}/subscription`, {
590
+ action: "fetch subscription",
591
+ });
592
+ }
593
+ async getUsage(projectId, options = {}) {
594
+ const { start, end, interval, report } = options;
595
+ const data = await this.request(`/accounts/projects/${projectId}/usage`, {
596
+ query: {
597
+ start: start ? start.toISOString() : undefined,
598
+ end: end ? end.toISOString() : undefined,
599
+ interval,
600
+ report,
601
+ },
602
+ action: "retrieve usage",
603
+ });
604
+ const usage = data?.["usage"];
605
+ if (!Array.isArray(usage)) {
606
+ throw new requirement_1.RoomException("Invalid usage payload: expected 'usage' to be a list");
607
+ }
608
+ return usage.filter((item) => item && typeof item === "object");
609
+ }
610
+ async getSession(projectId, sessionId) {
611
+ return await this.request(`/accounts/projects/${projectId}/sessions/${sessionId}`, {
612
+ action: "fetch session",
613
+ });
614
+ }
615
+ async listActiveSessions(projectId) {
616
+ const data = await this.request(`/accounts/projects/${projectId}/sessions/active`, {
617
+ action: "list active sessions",
618
+ });
619
+ const sessions = Array.isArray(data?.sessions) ? data.sessions : [];
620
+ return sessions.map((item) => this.parseRoomSession(item));
621
+ }
622
+ async listRecentSessions(projectId) {
623
+ const data = await this.request(`/accounts/projects/${projectId}/sessions`, {
624
+ action: "list sessions",
625
+ });
626
+ const sessions = Array.isArray(data?.sessions) ? data.sessions : [];
627
+ return sessions.map((item) => this.parseRoomSession(item));
628
+ }
629
+ async listSessionEvents(projectId, sessionId) {
630
+ const data = await this.request(`/accounts/projects/${projectId}/sessions/${sessionId}/events`, {
631
+ action: "list session events",
632
+ });
633
+ const events = data?.["events"];
634
+ return Array.isArray(events) ? events : [];
635
+ }
636
+ async terminateSession(projectId, sessionId) {
637
+ await this.request(`/accounts/projects/${projectId}/sessions/${sessionId}/terminate`, {
638
+ method: "POST",
639
+ action: "terminate session",
640
+ responseType: "void",
641
+ });
642
+ }
643
+ async listSessionSpans(projectId, sessionId) {
644
+ const data = await this.request(`/accounts/projects/${projectId}/sessions/${sessionId}/spans`, {
645
+ action: "list session spans",
646
+ });
647
+ const spans = data?.["spans"];
648
+ return Array.isArray(spans) ? spans : [];
649
+ }
650
+ async listSessionMetrics(projectId, sessionId) {
651
+ const data = await this.request(`/accounts/projects/${projectId}/sessions/${sessionId}/metrics`, {
652
+ action: "list session metrics",
653
+ });
654
+ const metrics = data?.["metrics"];
655
+ return Array.isArray(metrics) ? metrics : [];
656
+ }
657
+ async createWebhook(projectId, params) {
658
+ const { name, url, events, description = "", action: webhookAction = "", payload = null } = params;
659
+ return await this.request(`/accounts/projects/${projectId}/webhooks`, {
660
+ method: "POST",
661
+ json: { name, description, url, events, action: webhookAction, payload },
662
+ action: "create webhook",
663
+ });
664
+ }
665
+ async updateWebhook(projectId, webhookId, params) {
666
+ const { name, url, events, description = "", action: webhookAction = null, payload = null } = params;
667
+ return await this.request(`/accounts/projects/${projectId}/webhooks/${webhookId}`, {
668
+ method: "PUT",
669
+ json: { name, description, url, events, action: webhookAction, payload },
670
+ action: "update webhook",
671
+ });
672
+ }
673
+ async listWebhooks(projectId) {
674
+ return await this.request(`/accounts/projects/${projectId}/webhooks`, {
675
+ action: "list webhooks",
676
+ });
677
+ }
678
+ async deleteWebhook(projectId, webhookId) {
679
+ await this.request(`/accounts/projects/${projectId}/webhooks/${webhookId}`, {
680
+ method: "DELETE",
681
+ action: "delete webhook",
682
+ responseType: "void",
683
+ });
684
+ }
685
+ async createMailbox(params) {
686
+ const { projectId, address, room, queue } = params;
687
+ await this.request(`/accounts/projects/${projectId}/mailboxes`, {
688
+ method: "POST",
689
+ json: { address, room, queue },
690
+ action: "create mailbox",
691
+ responseType: "void",
692
+ });
693
+ }
694
+ async updateMailbox(params) {
695
+ const { projectId, address, room, queue } = params;
696
+ await this.request(`/accounts/projects/${projectId}/mailboxes/${address}`, {
697
+ method: "PUT",
698
+ json: { room, queue },
699
+ action: "update mailbox",
700
+ responseType: "void",
701
+ });
702
+ }
703
+ async listMailboxes(projectId) {
704
+ const data = await this.request(`/accounts/projects/${projectId}/mailboxes`, {
705
+ action: "list mailboxes",
706
+ });
707
+ const mailboxes = Array.isArray(data?.mailboxes) ? data.mailboxes : [];
708
+ return mailboxes.map((item) => {
709
+ if (!item || typeof item !== "object") {
710
+ throw new requirement_1.RoomException("Invalid mailbox payload");
711
+ }
712
+ const { address, room, queue } = item;
713
+ if (typeof address !== "string" || typeof room !== "string" || typeof queue !== "string") {
714
+ throw new requirement_1.RoomException("Invalid mailbox payload: missing fields");
715
+ }
716
+ return { address, room, queue };
717
+ });
718
+ }
719
+ async deleteMailbox(projectId, address) {
720
+ await this.request(`/accounts/projects/${projectId}/mailboxes/${address}`, {
721
+ method: "DELETE",
722
+ action: "delete mailbox",
723
+ responseType: "void",
724
+ });
725
+ }
726
+ async createService(projectId, service) {
727
+ const data = await this.request(`/accounts/projects/${projectId}/services`, {
728
+ method: "POST",
729
+ json: serializeServiceSpec(service),
730
+ action: "create service",
731
+ });
732
+ if (!data || typeof data !== "object" || typeof data.id !== "string") {
733
+ throw new requirement_1.RoomException("Invalid create service response payload");
734
+ }
735
+ return data.id;
736
+ }
737
+ async createRoomService(projectId, roomName, service) {
738
+ const data = await this.request(`/accounts/projects/${projectId}/rooms/${roomName}/services`, {
739
+ method: "POST",
740
+ json: serializeServiceSpec(service),
741
+ action: "create room service",
742
+ });
743
+ if (!data || typeof data !== "object" || typeof data.id !== "string") {
744
+ throw new requirement_1.RoomException("Invalid create room service response payload");
745
+ }
746
+ return data.id;
747
+ }
748
+ async updateRoomService(projectId, roomName, serviceId, service) {
749
+ await this.request(`/accounts/projects/${projectId}/rooms/${roomName}/services/${serviceId}`, {
750
+ method: "PUT",
751
+ json: serializeServiceSpec(service),
752
+ action: "update room service",
753
+ responseType: "void",
754
+ });
755
+ }
756
+ async getRoomService(projectId, roomName, serviceId) {
757
+ const data = await this.request(`/accounts/projects/${projectId}/rooms/${roomName}/services/${serviceId}`, {
758
+ action: "fetch room service",
759
+ });
760
+ return data;
761
+ }
762
+ async listRoomServices(projectId, roomName) {
763
+ const data = await this.request(`/accounts/projects/${projectId}/rooms/${roomName}/services`, {
764
+ action: "list room services",
765
+ });
766
+ const services = Array.isArray(data?.services) ? data.services : [];
767
+ return services;
768
+ }
769
+ async deleteRoomService(projectId, roomName, serviceId) {
770
+ await this.request(`/accounts/projects/${projectId}/rooms/${roomName}/services/${serviceId}`, {
771
+ method: "DELETE",
772
+ action: "delete room service",
773
+ responseType: "void",
774
+ });
775
+ }
776
+ async updateService(projectId, serviceId, service) {
777
+ if (!service.id) {
778
+ throw new requirement_1.RoomException("Service id must be set to update a service");
779
+ }
780
+ await this.request(`/accounts/projects/${projectId}/services/${serviceId}`, {
781
+ method: "PUT",
782
+ json: serializeServiceSpec(service),
783
+ action: "update service",
784
+ responseType: "void",
785
+ });
786
+ }
787
+ async getService(projectId, serviceId) {
788
+ const data = await this.request(`/accounts/projects/${projectId}/services/${serviceId}`, {
789
+ action: "fetch service",
790
+ });
791
+ return data;
792
+ }
793
+ async listServices(projectId) {
794
+ const data = await this.request(`/accounts/projects/${projectId}/services`, {
795
+ action: "list services",
796
+ });
797
+ const services = Array.isArray(data?.services) ? data.services : [];
798
+ return services;
799
+ }
800
+ async deleteService(projectId, serviceId) {
801
+ await this.request(`/accounts/projects/${projectId}/services/${serviceId}`, {
802
+ method: "DELETE",
803
+ action: "delete service",
804
+ responseType: "void",
805
+ });
806
+ }
807
+ async createSecret(projectId, secret) {
808
+ await this.request(`/accounts/projects/${projectId}/secrets`, {
809
+ method: "POST",
810
+ json: this.toSecretPayload(secret),
811
+ action: "create secret",
812
+ responseType: "void",
813
+ });
814
+ }
815
+ async updateSecret(projectId, secret) {
816
+ if (!secret.id) {
817
+ throw new requirement_1.RoomException("Secret id is required to update a secret");
818
+ }
819
+ await this.request(`/accounts/projects/${projectId}/secrets/${secret.id}`, {
820
+ method: "PUT",
821
+ json: this.toSecretPayload(secret),
822
+ action: "update secret",
823
+ responseType: "void",
824
+ });
825
+ }
826
+ async deleteSecret(projectId, secretId) {
827
+ await this.request(`/accounts/projects/${projectId}/secrets/${secretId}`, {
828
+ method: "DELETE",
829
+ action: "delete secret",
830
+ responseType: "void",
831
+ });
832
+ }
833
+ async listSecrets(projectId) {
834
+ const data = await this.request(`/accounts/projects/${projectId}/secrets`, {
835
+ action: "list secrets",
836
+ });
837
+ const secrets = Array.isArray(data?.secrets) ? data.secrets : [];
838
+ return secrets.map((item) => this.parseSecret(item));
839
+ }
840
+ async createRoom(params) {
841
+ const { projectId, name, ifNotExists = false, metadata, permissions } = params;
842
+ const payload = {
843
+ name,
844
+ if_not_exists: Boolean(ifNotExists),
845
+ metadata,
846
+ };
847
+ if (permissions) {
848
+ const serialized = {};
849
+ for (const [key, value] of Object.entries(permissions)) {
850
+ serialized[key] = value instanceof participant_token_1.ApiScope ? value.toJSON() : value;
851
+ }
852
+ payload["permissions"] = serialized;
853
+ }
854
+ const data = await this.request(`/accounts/projects/${projectId}/rooms`, {
855
+ method: "POST",
856
+ json: payload,
857
+ action: "create room",
858
+ });
859
+ return this.parseRoom(data);
860
+ }
861
+ async getRoom(projectId, name) {
862
+ const data = await this.request(`/accounts/projects/${projectId}/rooms/${name}`, {
863
+ action: "fetch room",
864
+ });
865
+ return this.parseRoom(data);
866
+ }
867
+ async updateRoom(projectId, roomId, name) {
868
+ await this.request(`/accounts/projects/${projectId}/rooms/${roomId}`, {
869
+ method: "PUT",
870
+ json: { name },
871
+ action: "update room",
872
+ responseType: "void",
873
+ });
874
+ }
875
+ async deleteRoom(projectId, roomId) {
876
+ await this.request(`/accounts/projects/${projectId}/rooms/${roomId}`, {
877
+ method: "DELETE",
878
+ action: "delete room",
879
+ responseType: "void",
880
+ });
881
+ }
882
+ async connectRoom(projectId, room) {
883
+ const data = await this.request(`/accounts/projects/${projectId}/rooms/${room}/connect`, {
884
+ method: "POST",
885
+ json: {},
886
+ action: "connect room",
887
+ });
888
+ return this.parseRoomConnectionInfo(data);
889
+ }
890
+ async createRoomGrant(params) {
891
+ const { projectId, roomId, userId, permissions } = params;
892
+ await this.request(`/accounts/projects/${projectId}/room-grants`, {
893
+ method: "POST",
894
+ json: {
895
+ room_id: roomId,
896
+ user_id: userId,
897
+ permissions: permissions.toJSON(),
898
+ },
899
+ action: "create room grant",
900
+ responseType: "void",
901
+ });
902
+ }
903
+ async createRoomGrantByEmail(params) {
904
+ const { projectId, roomId, email, permissions } = params;
905
+ await this.request(`/accounts/projects/${projectId}/room-grants`, {
906
+ method: "POST",
907
+ json: {
908
+ room_id: roomId,
909
+ email,
910
+ permissions: permissions.toJSON(),
911
+ },
912
+ action: "create room grant",
913
+ responseType: "void",
914
+ });
915
+ }
916
+ async updateRoomGrant(params) {
917
+ const { projectId, roomId, userId, permissions, grantId } = params;
918
+ const gid = grantId ?? "unused";
919
+ await this.request(`/accounts/projects/${projectId}/room-grants/${gid}`, {
920
+ method: "PUT",
921
+ json: {
922
+ room_id: roomId,
923
+ user_id: userId,
924
+ permissions: permissions.toJSON(),
925
+ },
926
+ action: "update room grant",
927
+ responseType: "void",
928
+ });
929
+ }
930
+ async deleteRoomGrant(projectId, roomId, userId) {
931
+ const room = this.encodePathComponent(roomId);
932
+ const user = this.encodePathComponent(userId);
933
+ await this.request(`/accounts/projects/${projectId}/room-grants/${room}/${user}`, {
934
+ method: "DELETE",
935
+ action: "delete room grant",
936
+ responseType: "void",
937
+ });
938
+ }
939
+ async getRoomGrant(projectId, roomId, userId) {
940
+ const room = this.encodePathComponent(roomId);
941
+ const user = this.encodePathComponent(userId);
942
+ const data = await this.request(`/accounts/projects/${projectId}/room-grants/${room}/${user}`, {
943
+ action: "fetch room grant",
944
+ });
945
+ return this.parseProjectRoomGrant(data);
946
+ }
947
+ async listRooms(projectId, options = {}) {
948
+ const { limit = 50, offset = 0, orderBy = "room_name" } = options;
949
+ const data = await this.request(`/accounts/projects/${projectId}/rooms`, {
950
+ query: { limit, offset, order_by: orderBy },
951
+ action: "list rooms",
952
+ });
953
+ const rooms = Array.isArray(data?.rooms) ? data.rooms : [];
954
+ return rooms.map((item) => this.parseRoom(item));
955
+ }
956
+ async listRoomGrants(projectId, options = {}) {
957
+ const { limit = 50, offset = 0, orderBy = "room_name" } = options;
958
+ const data = await this.request(`/accounts/projects/${projectId}/room-grants`, {
959
+ query: { limit, offset, order_by: orderBy },
960
+ action: "list room grants",
961
+ });
962
+ const grants = Array.isArray(data?.room_grants) ? data.room_grants : [];
963
+ return grants.map((item) => this.parseProjectRoomGrant(item));
964
+ }
965
+ async listRoomGrantsByUser(projectId, userId, options = {}) {
966
+ const { limit = 50, offset = 0 } = options;
967
+ const encodedUser = this.encodePathComponent(userId);
968
+ const data = await this.request(`/accounts/projects/${projectId}/room-grants/by-user/${encodedUser}`, {
969
+ query: { limit, offset },
970
+ action: "list room grants by user",
971
+ });
972
+ const grants = Array.isArray(data?.room_grants) ? data.room_grants : [];
973
+ return grants.map((item) => this.parseProjectRoomGrant(item));
974
+ }
975
+ async listRoomGrantsByRoom(projectId, roomId, options = {}) {
976
+ const { limit = 50, offset = 0 } = options;
977
+ const encodedRoom = this.encodePathComponent(roomId);
978
+ const data = await this.request(`/accounts/projects/${projectId}/room-grants/by-room/${encodedRoom}`, {
979
+ query: { limit, offset },
980
+ action: "list room grants by room",
981
+ });
982
+ const grants = Array.isArray(data?.room_grants) ? data.room_grants : [];
983
+ return grants.map((item) => this.parseProjectRoomGrant(item));
984
+ }
985
+ async listUniqueRoomsWithGrants(projectId, options = {}) {
986
+ const { limit = 50, offset = 0 } = options;
987
+ const data = await this.request(`/accounts/projects/${projectId}/room-grants/by-room`, {
988
+ query: { limit, offset },
989
+ action: "list unique rooms with grants",
990
+ });
991
+ const rooms = Array.isArray(data?.rooms) ? data.rooms : [];
992
+ return rooms.map((item) => this.parseProjectRoomGrantCount(item));
993
+ }
994
+ async listUniqueUsersWithGrants(projectId, options = {}) {
995
+ const { limit = 50, offset = 0 } = options;
996
+ const data = await this.request(`/accounts/projects/${projectId}/room-grants/by-user`, {
997
+ query: { limit, offset },
998
+ action: "list unique users with grants",
999
+ });
1000
+ const users = Array.isArray(data?.users) ? data.users : [];
1001
+ return users.map((item) => this.parseProjectUserGrantCount(item));
1002
+ }
1003
+ async createOAuthClient(projectId, params) {
1004
+ const { grantTypes, responseTypes, redirectUris, scope, metadata = {} } = params;
1005
+ const data = await this.request(`/accounts/projects/${projectId}/oauth/clients`, {
1006
+ method: "POST",
1007
+ json: { grant_types: grantTypes, response_types: responseTypes, redirect_uris: redirectUris, scope, metadata },
1008
+ action: "create oauth client",
1009
+ });
1010
+ return this.parseOAuthClient(data);
1011
+ }
1012
+ async updateOAuthClient(projectId, clientId, params) {
1013
+ const body = {};
1014
+ if (params.grantTypes !== undefined)
1015
+ body["grant_types"] = params.grantTypes;
1016
+ if (params.responseTypes !== undefined)
1017
+ body["response_types"] = params.responseTypes;
1018
+ if (params.redirectUris !== undefined)
1019
+ body["redirect_uris"] = params.redirectUris;
1020
+ if (params.scope !== undefined)
1021
+ body["scope"] = params.scope;
1022
+ if (params.metadata !== undefined)
1023
+ body["metadata"] = params.metadata;
1024
+ return await this.request(`/accounts/projects/${projectId}/oauth/clients/${clientId}`, {
1025
+ method: "PUT",
1026
+ json: body,
1027
+ action: "update oauth client",
1028
+ });
1029
+ }
1030
+ async listOAuthClients(projectId) {
1031
+ const data = await this.request(`/accounts/projects/${projectId}/oauth/clients`, {
1032
+ action: "list oauth clients",
1033
+ });
1034
+ const clients = Array.isArray(data?.clients) ? data.clients : [];
1035
+ return clients.map((item) => this.parseOAuthClient(item));
1036
+ }
1037
+ async getOAuthClient(projectId, clientId) {
1038
+ const data = await this.request(`/accounts/projects/${projectId}/oauth/clients/${clientId}`, {
1039
+ action: "fetch oauth client",
1040
+ });
1041
+ return this.parseOAuthClient(data);
1042
+ }
1043
+ async deleteOAuthClient(projectId, clientId) {
1044
+ await this.request(`/accounts/projects/${projectId}/oauth/clients/${clientId}`, {
1045
+ method: "DELETE",
1046
+ action: "delete oauth client",
1047
+ responseType: "void",
1048
+ });
1049
+ }
1050
+ }
1051
+ exports.Meshagent = Meshagent;