@shadowob/sdk 1.1.1 → 1.1.3-dev.261
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/dist/index.cjs +773 -94
- package/dist/index.d.cts +1579 -119
- package/dist/index.d.ts +1579 -119
- package/dist/index.js +773 -94
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -1,10 +1,46 @@
|
|
|
1
1
|
// src/client.ts
|
|
2
|
+
function sanitizeErrorBody(body) {
|
|
3
|
+
if (!body) return "(empty response)";
|
|
4
|
+
if (!/<[^>]+>/.test(body)) return body.slice(0, 500);
|
|
5
|
+
const titleMatch = /<title>([^<]+)<\/title>/i.exec(body);
|
|
6
|
+
if (titleMatch?.[1]) return titleMatch[1].trim();
|
|
7
|
+
const text = body.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
|
|
8
|
+
return text.slice(0, 200) || "(HTML error page)";
|
|
9
|
+
}
|
|
10
|
+
function contentDispositionFilename(header) {
|
|
11
|
+
if (!header) return null;
|
|
12
|
+
const utf8Match = /filename\*=UTF-8''([^;]+)/i.exec(header);
|
|
13
|
+
if (utf8Match?.[1]) {
|
|
14
|
+
try {
|
|
15
|
+
return decodeURIComponent(utf8Match[1].trim());
|
|
16
|
+
} catch {
|
|
17
|
+
return utf8Match[1].trim();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const quotedMatch = /filename="([^"]+)"/i.exec(header);
|
|
21
|
+
if (quotedMatch?.[1]) return quotedMatch[1];
|
|
22
|
+
const bareMatch = /filename=([^;]+)/i.exec(header);
|
|
23
|
+
return bareMatch?.[1]?.trim() ?? null;
|
|
24
|
+
}
|
|
2
25
|
var ShadowClient = class {
|
|
3
26
|
constructor(baseUrl, token) {
|
|
4
27
|
this.token = token;
|
|
5
28
|
this.baseUrl = baseUrl.replace(/\/api\/?$/, "");
|
|
6
29
|
}
|
|
7
30
|
baseUrl;
|
|
31
|
+
isShadowPrivateMediaUrl(value) {
|
|
32
|
+
if (value.startsWith("/shadow/uploads/") || value.startsWith("/api/media/signed/")) {
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
if (!/^https?:\/\//.test(value)) return false;
|
|
36
|
+
try {
|
|
37
|
+
const url = new URL(value);
|
|
38
|
+
const base = new URL(this.baseUrl);
|
|
39
|
+
return url.origin === base.origin && (url.pathname.startsWith("/shadow/uploads/") || url.pathname.startsWith("/api/media/signed/"));
|
|
40
|
+
} catch {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
8
44
|
async request(path, init) {
|
|
9
45
|
const url = `${this.baseUrl}${path}`;
|
|
10
46
|
const controller = new AbortController();
|
|
@@ -21,11 +57,19 @@ var ShadowClient = class {
|
|
|
21
57
|
});
|
|
22
58
|
if (!res.ok) {
|
|
23
59
|
const body = await res.text().catch(() => "");
|
|
60
|
+
const message = sanitizeErrorBody(body);
|
|
24
61
|
throw new Error(
|
|
25
|
-
`Shadow API ${init?.method ?? "GET"} ${path} failed (${res.status}): ${
|
|
62
|
+
`Shadow API ${init?.method ?? "GET"} ${path} failed (${res.status}): ${message}`
|
|
26
63
|
);
|
|
27
64
|
}
|
|
28
|
-
|
|
65
|
+
const payload = await res.json();
|
|
66
|
+
if (payload && typeof payload === "object" && !Array.isArray(payload) && "ok" in payload && !("success" in payload)) {
|
|
67
|
+
return {
|
|
68
|
+
...payload,
|
|
69
|
+
success: Boolean(payload.ok)
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
return payload;
|
|
29
73
|
} finally {
|
|
30
74
|
clearTimeout(timeout);
|
|
31
75
|
}
|
|
@@ -41,7 +85,10 @@ var ShadowClient = class {
|
|
|
41
85
|
});
|
|
42
86
|
if (!res.ok) {
|
|
43
87
|
const body = await res.text().catch(() => "");
|
|
44
|
-
|
|
88
|
+
const message = sanitizeErrorBody(body);
|
|
89
|
+
throw new Error(
|
|
90
|
+
`Shadow API ${init?.method ?? "GET"} ${path} failed (${res.status}): ${message}`
|
|
91
|
+
);
|
|
45
92
|
}
|
|
46
93
|
return res;
|
|
47
94
|
}
|
|
@@ -58,8 +105,23 @@ var ShadowClient = class {
|
|
|
58
105
|
body: JSON.stringify(data)
|
|
59
106
|
});
|
|
60
107
|
}
|
|
61
|
-
async
|
|
62
|
-
return this.request("/api/auth/
|
|
108
|
+
async startEmailLogin(data) {
|
|
109
|
+
return this.request("/api/auth/email/start", {
|
|
110
|
+
method: "POST",
|
|
111
|
+
body: JSON.stringify(data)
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
async verifyEmailLogin(data) {
|
|
115
|
+
return this.request("/api/auth/email/verify", {
|
|
116
|
+
method: "POST",
|
|
117
|
+
body: JSON.stringify(data)
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
async refreshToken(refreshToken) {
|
|
121
|
+
return this.request("/api/auth/refresh", {
|
|
122
|
+
method: "POST",
|
|
123
|
+
body: JSON.stringify({ refreshToken })
|
|
124
|
+
});
|
|
63
125
|
}
|
|
64
126
|
async getMe() {
|
|
65
127
|
return this.request("/api/auth/me");
|
|
@@ -73,9 +135,51 @@ var ShadowClient = class {
|
|
|
73
135
|
async disconnect() {
|
|
74
136
|
return this.request("/api/auth/disconnect", { method: "POST" });
|
|
75
137
|
}
|
|
138
|
+
async getMembership() {
|
|
139
|
+
return this.request("/api/membership/me");
|
|
140
|
+
}
|
|
141
|
+
async redeemInviteCode(code) {
|
|
142
|
+
return this.request("/api/membership/redeem-invite", {
|
|
143
|
+
method: "POST",
|
|
144
|
+
body: JSON.stringify({ code })
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
async launchPlay(data) {
|
|
148
|
+
return this.request("/api/play/launch", {
|
|
149
|
+
method: "POST",
|
|
150
|
+
body: JSON.stringify(data)
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
async getPlayCatalog() {
|
|
154
|
+
const response = await this.request("/api/play/catalog");
|
|
155
|
+
return response.plays;
|
|
156
|
+
}
|
|
157
|
+
// ── Official Model Proxy ──────────────────────────────────────────────
|
|
158
|
+
async listOfficialModelProxyModels() {
|
|
159
|
+
return this.request("/api/ai/v1/models");
|
|
160
|
+
}
|
|
161
|
+
async getOfficialModelProxyBilling() {
|
|
162
|
+
return this.request("/api/ai/v1/billing");
|
|
163
|
+
}
|
|
164
|
+
async createOfficialChatCompletion(data) {
|
|
165
|
+
return this.request("/api/ai/v1/chat/completions", {
|
|
166
|
+
method: "POST",
|
|
167
|
+
body: JSON.stringify(data)
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
async createOfficialChatCompletionStream(data) {
|
|
171
|
+
return this.requestRaw("/api/ai/v1/chat/completions", {
|
|
172
|
+
method: "POST",
|
|
173
|
+
headers: { "Content-Type": "application/json" },
|
|
174
|
+
body: JSON.stringify({ ...data, stream: true })
|
|
175
|
+
});
|
|
176
|
+
}
|
|
76
177
|
// ── Agents ────────────────────────────────────────────────────────────
|
|
77
|
-
async listAgents() {
|
|
78
|
-
|
|
178
|
+
async listAgents(options) {
|
|
179
|
+
const params = new URLSearchParams();
|
|
180
|
+
if (options?.includeRentals) params.set("includeRentals", "true");
|
|
181
|
+
const query = params.toString();
|
|
182
|
+
return this.request(`/api/agents${query ? `?${query}` : ""}`);
|
|
79
183
|
}
|
|
80
184
|
async createAgent(data) {
|
|
81
185
|
return this.request("/api/agents", {
|
|
@@ -110,21 +214,62 @@ var ShadowClient = class {
|
|
|
110
214
|
body: JSON.stringify({})
|
|
111
215
|
});
|
|
112
216
|
}
|
|
217
|
+
async reportAgentUsageSnapshot(agentId, snapshot) {
|
|
218
|
+
return this.request(`/api/agents/${agentId}/usage-snapshot`, {
|
|
219
|
+
method: "POST",
|
|
220
|
+
body: JSON.stringify(snapshot)
|
|
221
|
+
});
|
|
222
|
+
}
|
|
113
223
|
async getAgentConfig(agentId) {
|
|
114
224
|
return this.request(`/api/agents/${agentId}/config`);
|
|
115
225
|
}
|
|
226
|
+
async updateAgentSlashCommands(agentId, commands) {
|
|
227
|
+
return this.request(`/api/agents/${agentId}/slash-commands`, {
|
|
228
|
+
method: "PUT",
|
|
229
|
+
body: JSON.stringify({ commands })
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
async getAgentSlashCommands(agentId) {
|
|
233
|
+
return this.request(`/api/agents/${agentId}/slash-commands`);
|
|
234
|
+
}
|
|
235
|
+
async listChannelSlashCommands(channelId) {
|
|
236
|
+
return this.request(
|
|
237
|
+
`/api/channels/${channelId}/slash-commands`
|
|
238
|
+
);
|
|
239
|
+
}
|
|
116
240
|
// ── Agent Policies ────────────────────────────────────────────────────
|
|
117
241
|
async listPolicies(agentId, serverId) {
|
|
118
|
-
|
|
242
|
+
const policies = await this.request(`/api/agents/${agentId}/policies`);
|
|
243
|
+
if (!serverId) return policies;
|
|
244
|
+
return policies.filter((policy) => policy.serverId === serverId);
|
|
119
245
|
}
|
|
120
246
|
async upsertPolicy(agentId, serverId, data) {
|
|
121
|
-
|
|
247
|
+
const policy = {
|
|
248
|
+
serverId,
|
|
249
|
+
...data.channelId !== void 0 ? { channelId: data.channelId } : {},
|
|
250
|
+
...data.mentionOnly !== void 0 ? { mentionOnly: data.mentionOnly } : {},
|
|
251
|
+
...data.reply !== void 0 ? { reply: data.reply } : {},
|
|
252
|
+
...data.config !== void 0 ? { config: data.config } : {}
|
|
253
|
+
};
|
|
254
|
+
const results = await this.request(`/api/agents/${agentId}/policies`, {
|
|
122
255
|
method: "PUT",
|
|
123
|
-
body: JSON.stringify(
|
|
256
|
+
body: JSON.stringify({ policies: [policy] })
|
|
124
257
|
});
|
|
258
|
+
const [result] = results;
|
|
259
|
+
if (!result) {
|
|
260
|
+
throw new Error(`Shadow API PUT /api/agents/${agentId}/policies returned no policy result`);
|
|
261
|
+
}
|
|
262
|
+
return result;
|
|
125
263
|
}
|
|
126
264
|
async deletePolicy(agentId, serverId, channelId) {
|
|
127
|
-
|
|
265
|
+
const policies = await this.listPolicies(agentId, serverId);
|
|
266
|
+
const policy = policies.find((entry) => entry.channelId === channelId);
|
|
267
|
+
if (!policy?.id) {
|
|
268
|
+
throw new Error(
|
|
269
|
+
`Shadow policy not found for agent ${agentId} in server ${serverId} channel ${channelId}`
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
return this.request(`/api/agents/${agentId}/policies/${policy.id}`, {
|
|
128
273
|
method: "DELETE"
|
|
129
274
|
});
|
|
130
275
|
}
|
|
@@ -147,6 +292,9 @@ var ShadowClient = class {
|
|
|
147
292
|
async getServer(serverIdOrSlug) {
|
|
148
293
|
return this.request(`/api/servers/${serverIdOrSlug}`);
|
|
149
294
|
}
|
|
295
|
+
async getServerAccess(serverIdOrSlug) {
|
|
296
|
+
return this.request(`/api/servers/${serverIdOrSlug}/access`);
|
|
297
|
+
}
|
|
150
298
|
async updateServer(serverIdOrSlug, data) {
|
|
151
299
|
return this.request(`/api/servers/${serverIdOrSlug}`, {
|
|
152
300
|
method: "PATCH",
|
|
@@ -165,6 +313,20 @@ var ShadowClient = class {
|
|
|
165
313
|
body: JSON.stringify(inviteCode ? { inviteCode } : {})
|
|
166
314
|
});
|
|
167
315
|
}
|
|
316
|
+
async requestServerAccess(serverIdOrSlug) {
|
|
317
|
+
return this.request(
|
|
318
|
+
`/api/servers/${serverIdOrSlug}/join-requests`,
|
|
319
|
+
{
|
|
320
|
+
method: "POST"
|
|
321
|
+
}
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
async reviewServerJoinRequest(requestId, status) {
|
|
325
|
+
return this.request(`/api/servers/join-requests/${requestId}`, {
|
|
326
|
+
method: "PATCH",
|
|
327
|
+
body: JSON.stringify({ status })
|
|
328
|
+
});
|
|
329
|
+
}
|
|
168
330
|
async leaveServer(serverId) {
|
|
169
331
|
return this.request(`/api/servers/${serverId}/leave`, { method: "POST" });
|
|
170
332
|
}
|
|
@@ -181,7 +343,7 @@ var ShadowClient = class {
|
|
|
181
343
|
return this.request(`/api/servers/${serverId}/members/${userId}`, { method: "DELETE" });
|
|
182
344
|
}
|
|
183
345
|
async regenerateInviteCode(serverId) {
|
|
184
|
-
return this.request(`/api/servers/${serverId}/invite`, { method: "POST" });
|
|
346
|
+
return this.request(`/api/servers/${serverId}/invite/regenerate`, { method: "POST" });
|
|
185
347
|
}
|
|
186
348
|
async addAgentsToServer(serverId, agentIds) {
|
|
187
349
|
return this.request(`/api/servers/${serverId}/agents`, {
|
|
@@ -206,6 +368,9 @@ var ShadowClient = class {
|
|
|
206
368
|
const ch = await this.request(`/api/channels/${channelId}`);
|
|
207
369
|
return { ...ch, description: ch.topic };
|
|
208
370
|
}
|
|
371
|
+
async getChannelAccess(channelId) {
|
|
372
|
+
return this.request(`/api/channels/${channelId}/access`);
|
|
373
|
+
}
|
|
209
374
|
async getChannelMembers(channelId) {
|
|
210
375
|
return this.request(`/api/channels/${channelId}/members`);
|
|
211
376
|
}
|
|
@@ -222,8 +387,8 @@ var ShadowClient = class {
|
|
|
222
387
|
return this.request(`/api/channels/${channelId}`, { method: "DELETE" });
|
|
223
388
|
}
|
|
224
389
|
async reorderChannels(serverId, channelIds) {
|
|
225
|
-
return this.request(`/api/servers/${serverId}/channels/
|
|
226
|
-
method: "
|
|
390
|
+
return this.request(`/api/servers/${serverId}/channels/positions`, {
|
|
391
|
+
method: "PATCH",
|
|
227
392
|
body: JSON.stringify({ channelIds })
|
|
228
393
|
});
|
|
229
394
|
}
|
|
@@ -233,18 +398,32 @@ var ShadowClient = class {
|
|
|
233
398
|
body: JSON.stringify({ userId })
|
|
234
399
|
});
|
|
235
400
|
}
|
|
401
|
+
async requestChannelAccess(channelId) {
|
|
402
|
+
return this.request(
|
|
403
|
+
`/api/channels/${channelId}/join-requests`,
|
|
404
|
+
{
|
|
405
|
+
method: "POST"
|
|
406
|
+
}
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
async reviewChannelJoinRequest(requestId, status) {
|
|
410
|
+
return this.request(`/api/channel-join-requests/${requestId}`, {
|
|
411
|
+
method: "PATCH",
|
|
412
|
+
body: JSON.stringify({ status })
|
|
413
|
+
});
|
|
414
|
+
}
|
|
236
415
|
async removeChannelMember(channelId, userId) {
|
|
237
416
|
return this.request(`/api/channels/${channelId}/members/${userId}`, { method: "DELETE" });
|
|
238
417
|
}
|
|
239
418
|
// ── Channel Buddy Policy ─────────────────────────────────────────────
|
|
240
|
-
async setBuddyPolicy(channelId, data) {
|
|
241
|
-
return this.request(`/api/channels/${channelId}/
|
|
419
|
+
async setBuddyPolicy(channelId, agentId, data) {
|
|
420
|
+
return this.request(`/api/channels/${channelId}/agents/${agentId}/policy`, {
|
|
242
421
|
method: "PUT",
|
|
243
422
|
body: JSON.stringify(data)
|
|
244
423
|
});
|
|
245
424
|
}
|
|
246
|
-
async getBuddyPolicy(channelId) {
|
|
247
|
-
return this.request(`/api/channels/${channelId}/
|
|
425
|
+
async getBuddyPolicy(channelId, agentId) {
|
|
426
|
+
return this.request(`/api/channels/${channelId}/agents/${agentId}/policy`);
|
|
248
427
|
}
|
|
249
428
|
// ── Messages ──────────────────────────────────────────────────────────
|
|
250
429
|
async sendMessage(channelId, content, opts) {
|
|
@@ -254,10 +433,27 @@ var ShadowClient = class {
|
|
|
254
433
|
content,
|
|
255
434
|
...opts?.threadId ? { threadId: opts.threadId } : {},
|
|
256
435
|
...opts?.replyToId ? { replyToId: opts.replyToId } : {},
|
|
257
|
-
...opts?.
|
|
436
|
+
...opts?.mentions ? { mentions: opts.mentions } : {},
|
|
437
|
+
...opts?.metadata ? { metadata: opts.metadata } : {},
|
|
438
|
+
...opts?.attachments ? { attachments: opts.attachments } : {}
|
|
258
439
|
})
|
|
259
440
|
});
|
|
260
441
|
}
|
|
442
|
+
async suggestMentions(input) {
|
|
443
|
+
const params = new URLSearchParams({
|
|
444
|
+
channelId: input.channelId,
|
|
445
|
+
trigger: input.trigger
|
|
446
|
+
});
|
|
447
|
+
if (input.query) params.set("q", input.query);
|
|
448
|
+
if (input.limit) params.set("limit", String(input.limit));
|
|
449
|
+
return this.request(`/api/mentions/suggest?${params}`);
|
|
450
|
+
}
|
|
451
|
+
async resolveMentions(input) {
|
|
452
|
+
return this.request("/api/mentions/resolve", {
|
|
453
|
+
method: "POST",
|
|
454
|
+
body: JSON.stringify(input)
|
|
455
|
+
});
|
|
456
|
+
}
|
|
261
457
|
async getMessages(channelId, limit = 50, cursor) {
|
|
262
458
|
const params = new URLSearchParams({ limit: String(limit) });
|
|
263
459
|
if (cursor) params.set("cursor", cursor);
|
|
@@ -268,6 +464,20 @@ var ShadowClient = class {
|
|
|
268
464
|
async getMessage(messageId) {
|
|
269
465
|
return this.request(`/api/messages/${messageId}`);
|
|
270
466
|
}
|
|
467
|
+
async submitInteractiveAction(messageId, input) {
|
|
468
|
+
return this.request(`/api/messages/${messageId}/interactive`, {
|
|
469
|
+
method: "POST",
|
|
470
|
+
body: JSON.stringify(input)
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
async getInteractiveState(messageId, blockId) {
|
|
474
|
+
const params = new URLSearchParams();
|
|
475
|
+
if (blockId) params.set("blockId", blockId);
|
|
476
|
+
const query = params.toString();
|
|
477
|
+
return this.request(
|
|
478
|
+
`/api/messages/${messageId}/interactive-state${query ? `?${query}` : ""}`
|
|
479
|
+
);
|
|
480
|
+
}
|
|
271
481
|
async editMessage(messageId, content) {
|
|
272
482
|
return this.request(`/api/messages/${messageId}`, {
|
|
273
483
|
method: "PATCH",
|
|
@@ -281,16 +491,10 @@ var ShadowClient = class {
|
|
|
281
491
|
}
|
|
282
492
|
// ── Pins ──────────────────────────────────────────────────────────────
|
|
283
493
|
async pinMessage(messageId, channelId) {
|
|
284
|
-
|
|
285
|
-
return this.request(`/api/channels/${channelId}/pins/${messageId}`, { method: "PUT" });
|
|
286
|
-
}
|
|
287
|
-
return this.request(`/api/messages/${messageId}/pin`, { method: "POST" });
|
|
494
|
+
return this.request(`/api/channels/${channelId}/pins/${messageId}`, { method: "PUT" });
|
|
288
495
|
}
|
|
289
496
|
async unpinMessage(messageId, channelId) {
|
|
290
|
-
|
|
291
|
-
return this.request(`/api/channels/${channelId}/pins/${messageId}`, { method: "DELETE" });
|
|
292
|
-
}
|
|
293
|
-
return this.request(`/api/messages/${messageId}/pin`, { method: "DELETE" });
|
|
497
|
+
return this.request(`/api/channels/${channelId}/pins/${messageId}`, { method: "DELETE" });
|
|
294
498
|
}
|
|
295
499
|
async getPinnedMessages(channelId) {
|
|
296
500
|
return this.request(`/api/channels/${channelId}/pins`);
|
|
@@ -337,36 +541,26 @@ var ShadowClient = class {
|
|
|
337
541
|
if (cursor) params.set("cursor", cursor);
|
|
338
542
|
return this.request(`/api/threads/${threadId}/messages?${params}`);
|
|
339
543
|
}
|
|
340
|
-
async sendToThread(threadId, content) {
|
|
544
|
+
async sendToThread(threadId, content, options) {
|
|
341
545
|
return this.request(`/api/threads/${threadId}/messages`, {
|
|
342
546
|
method: "POST",
|
|
343
|
-
body: JSON.stringify({
|
|
547
|
+
body: JSON.stringify({
|
|
548
|
+
content,
|
|
549
|
+
...options?.replyToId ? { replyToId: options.replyToId } : {},
|
|
550
|
+
...options?.mentions ? { mentions: options.mentions } : {},
|
|
551
|
+
...options?.metadata ? { metadata: options.metadata } : {}
|
|
552
|
+
})
|
|
344
553
|
});
|
|
345
554
|
}
|
|
346
|
-
// ──
|
|
347
|
-
async
|
|
348
|
-
return this.request("/api/dm
|
|
555
|
+
// ── Direct channels ──────────────────────────────────────────────────
|
|
556
|
+
async createDirectChannel(userId) {
|
|
557
|
+
return this.request("/api/channels/dm", {
|
|
349
558
|
method: "POST",
|
|
350
559
|
body: JSON.stringify({ userId })
|
|
351
560
|
});
|
|
352
561
|
}
|
|
353
|
-
async
|
|
354
|
-
return this.request("/api/dm
|
|
355
|
-
}
|
|
356
|
-
async getDmMessages(channelId, limit = 50, cursor) {
|
|
357
|
-
const params = new URLSearchParams({ limit: String(limit) });
|
|
358
|
-
if (cursor) params.set("cursor", cursor);
|
|
359
|
-
return this.request(`/api/dm/channels/${channelId}/messages?${params}`);
|
|
360
|
-
}
|
|
361
|
-
async sendDmMessage(channelId, content, options) {
|
|
362
|
-
return this.request(`/api/dm/channels/${channelId}/messages`, {
|
|
363
|
-
method: "POST",
|
|
364
|
-
body: JSON.stringify({
|
|
365
|
-
content,
|
|
366
|
-
replyToId: options?.replyToId,
|
|
367
|
-
...options?.metadata ? { metadata: options.metadata } : {}
|
|
368
|
-
})
|
|
369
|
-
});
|
|
562
|
+
async listDirectChannels() {
|
|
563
|
+
return this.request("/api/channels/dm");
|
|
370
564
|
}
|
|
371
565
|
// ── Notifications ─────────────────────────────────────────────────────
|
|
372
566
|
async listNotifications(limit = 50, offset = 0) {
|
|
@@ -417,8 +611,10 @@ var ShadowClient = class {
|
|
|
417
611
|
const formData = new FormData();
|
|
418
612
|
const blob = file instanceof Blob ? file : new Blob([file], { type: contentType });
|
|
419
613
|
formData.append("file", blob, filename);
|
|
420
|
-
if (messageId) {
|
|
614
|
+
if (typeof messageId === "string") {
|
|
421
615
|
formData.append("messageId", messageId);
|
|
616
|
+
} else if (messageId) {
|
|
617
|
+
if (messageId.messageId) formData.append("messageId", messageId.messageId);
|
|
422
618
|
}
|
|
423
619
|
const url = `${this.baseUrl}/api/media/upload`;
|
|
424
620
|
const res = await fetch(url, {
|
|
@@ -434,6 +630,20 @@ var ShadowClient = class {
|
|
|
434
630
|
}
|
|
435
631
|
return res.json();
|
|
436
632
|
}
|
|
633
|
+
async resolveAttachmentMediaUrl(attachmentId, options) {
|
|
634
|
+
const disposition = options?.disposition ?? "inline";
|
|
635
|
+
return this.request(
|
|
636
|
+
`/api/attachments/${attachmentId}/media-url?disposition=${disposition}`
|
|
637
|
+
);
|
|
638
|
+
}
|
|
639
|
+
async resolveWorkspaceMediaUrl(serverId, fileId, options) {
|
|
640
|
+
const params = new URLSearchParams();
|
|
641
|
+
params.set("disposition", options?.disposition ?? "inline");
|
|
642
|
+
if (options?.contentRef) params.set("contentRef", options.contentRef);
|
|
643
|
+
return this.request(
|
|
644
|
+
`/api/servers/${serverId}/workspace/files/${fileId}/media-url?${params}`
|
|
645
|
+
);
|
|
646
|
+
}
|
|
437
647
|
/**
|
|
438
648
|
* Download a file from a URL and upload it to the Shadow media service.
|
|
439
649
|
* Supports local filesystem paths, file:// URLs, tilde paths, and HTTP(S) URLs.
|
|
@@ -449,6 +659,15 @@ var ShadowClient = class {
|
|
|
449
659
|
if (normalizedUrl.startsWith("~")) {
|
|
450
660
|
normalizedUrl = normalizedUrl.replace(/^~/, homedir());
|
|
451
661
|
}
|
|
662
|
+
if (this.isShadowPrivateMediaUrl(normalizedUrl)) {
|
|
663
|
+
const downloaded = await this.downloadFile(normalizedUrl);
|
|
664
|
+
return this.uploadMedia(
|
|
665
|
+
downloaded.buffer,
|
|
666
|
+
downloaded.filename,
|
|
667
|
+
downloaded.contentType,
|
|
668
|
+
messageId
|
|
669
|
+
);
|
|
670
|
+
}
|
|
452
671
|
if (!normalizedUrl.startsWith("/") && !normalizedUrl.startsWith("http://") && !normalizedUrl.startsWith("https://") && !normalizedUrl.startsWith("//")) {
|
|
453
672
|
const { existsSync } = await import("fs");
|
|
454
673
|
const { resolve } = await import("path");
|
|
@@ -523,7 +742,7 @@ var ShadowClient = class {
|
|
|
523
742
|
const buffer = await res.arrayBuffer();
|
|
524
743
|
const contentType = res.headers.get("content-type") ?? "application/octet-stream";
|
|
525
744
|
const urlPath = new URL(fullUrl).pathname;
|
|
526
|
-
const filename = decodeURIComponent(urlPath.split("/").pop() ?? "file");
|
|
745
|
+
const filename = contentDispositionFilename(res.headers.get("content-disposition")) ?? decodeURIComponent(urlPath.split("/").pop() ?? "file");
|
|
527
746
|
return { buffer, contentType, filename };
|
|
528
747
|
}
|
|
529
748
|
// ── Workspace ─────────────────────────────────────────────────────────
|
|
@@ -651,6 +870,21 @@ var ShadowClient = class {
|
|
|
651
870
|
async unlinkOAuthAccount(accountId) {
|
|
652
871
|
return this.request(`/api/auth/oauth/accounts/${accountId}`, { method: "DELETE" });
|
|
653
872
|
}
|
|
873
|
+
async changePassword(data) {
|
|
874
|
+
return this.request("/api/auth/password", {
|
|
875
|
+
method: "PUT",
|
|
876
|
+
body: JSON.stringify(data)
|
|
877
|
+
});
|
|
878
|
+
}
|
|
879
|
+
async getDashboard() {
|
|
880
|
+
return this.request("/api/auth/dashboard");
|
|
881
|
+
}
|
|
882
|
+
async loginWithGoogleIdToken(idToken) {
|
|
883
|
+
return this.request("/api/auth/google/id-token", {
|
|
884
|
+
method: "POST",
|
|
885
|
+
body: JSON.stringify({ idToken })
|
|
886
|
+
});
|
|
887
|
+
}
|
|
654
888
|
// ── Friendships ───────────────────────────────────────────────────────
|
|
655
889
|
async sendFriendRequest(username) {
|
|
656
890
|
return this.request("/api/friends/request", {
|
|
@@ -695,6 +929,27 @@ var ShadowClient = class {
|
|
|
695
929
|
body: JSON.stringify(data)
|
|
696
930
|
});
|
|
697
931
|
}
|
|
932
|
+
async getNotificationChannelPreferences() {
|
|
933
|
+
return this.request("/api/notifications/channel-preferences");
|
|
934
|
+
}
|
|
935
|
+
async updateNotificationChannelPreference(data) {
|
|
936
|
+
return this.request("/api/notifications/channel-preferences", {
|
|
937
|
+
method: "PATCH",
|
|
938
|
+
body: JSON.stringify(data)
|
|
939
|
+
});
|
|
940
|
+
}
|
|
941
|
+
async registerPushToken(data) {
|
|
942
|
+
return this.request("/api/notifications/push-tokens", {
|
|
943
|
+
method: "POST",
|
|
944
|
+
body: JSON.stringify(data)
|
|
945
|
+
});
|
|
946
|
+
}
|
|
947
|
+
async registerWebPushSubscription(data) {
|
|
948
|
+
return this.request("/api/notifications/web-push-subscriptions", {
|
|
949
|
+
method: "POST",
|
|
950
|
+
body: JSON.stringify(data)
|
|
951
|
+
});
|
|
952
|
+
}
|
|
698
953
|
// ── OAuth Apps ────────────────────────────────────────────────────────
|
|
699
954
|
async createOAuthApp(data) {
|
|
700
955
|
return this.request("/api/oauth/apps", {
|
|
@@ -742,6 +997,21 @@ var ShadowClient = class {
|
|
|
742
997
|
body: JSON.stringify({ appId })
|
|
743
998
|
});
|
|
744
999
|
}
|
|
1000
|
+
async sendOAuthChannelMessage(channelId, content, opts) {
|
|
1001
|
+
return this.request(`/api/oauth/channels/${channelId}/messages`, {
|
|
1002
|
+
method: "POST",
|
|
1003
|
+
body: JSON.stringify({
|
|
1004
|
+
content,
|
|
1005
|
+
...opts?.metadata ? { metadata: opts.metadata } : {}
|
|
1006
|
+
})
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1009
|
+
async sendOAuthBuddyMessage(buddyId, data) {
|
|
1010
|
+
return this.request(`/api/oauth/buddies/${buddyId}/messages`, {
|
|
1011
|
+
method: "POST",
|
|
1012
|
+
body: JSON.stringify(data)
|
|
1013
|
+
});
|
|
1014
|
+
}
|
|
745
1015
|
// ── Marketplace / Rentals ─────────────────────────────────────────────
|
|
746
1016
|
async browseListings(params) {
|
|
747
1017
|
const qs = new URLSearchParams();
|
|
@@ -815,6 +1085,133 @@ var ShadowClient = class {
|
|
|
815
1085
|
async getShop(serverId) {
|
|
816
1086
|
return this.request(`/api/servers/${serverId}/shop`);
|
|
817
1087
|
}
|
|
1088
|
+
async getMyShop() {
|
|
1089
|
+
return this.request("/api/me/shop");
|
|
1090
|
+
}
|
|
1091
|
+
async upsertMyShop(data) {
|
|
1092
|
+
return this.request("/api/me/shop", {
|
|
1093
|
+
method: "POST",
|
|
1094
|
+
body: JSON.stringify(data)
|
|
1095
|
+
});
|
|
1096
|
+
}
|
|
1097
|
+
async getUserShop(userId) {
|
|
1098
|
+
return this.request(`/api/users/${userId}/shop`);
|
|
1099
|
+
}
|
|
1100
|
+
async getManagedUserShop(userId) {
|
|
1101
|
+
return this.request(`/api/users/${userId}/shop/manage`);
|
|
1102
|
+
}
|
|
1103
|
+
async upsertManagedUserShop(userId, data) {
|
|
1104
|
+
return this.request(`/api/users/${userId}/shop/manage`, {
|
|
1105
|
+
method: "POST",
|
|
1106
|
+
body: JSON.stringify(data)
|
|
1107
|
+
});
|
|
1108
|
+
}
|
|
1109
|
+
async getShopById(shopId) {
|
|
1110
|
+
return this.request(`/api/shops/${shopId}`);
|
|
1111
|
+
}
|
|
1112
|
+
async listShopProducts(shopId, params) {
|
|
1113
|
+
const qs = new URLSearchParams();
|
|
1114
|
+
if (params?.keyword) qs.set("keyword", params.keyword);
|
|
1115
|
+
if (params?.limit) qs.set("limit", String(params.limit));
|
|
1116
|
+
if (params?.offset) qs.set("offset", String(params.offset));
|
|
1117
|
+
return this.request(`/api/shops/${shopId}/products?${qs}`);
|
|
1118
|
+
}
|
|
1119
|
+
async getScopeNeutralProduct(productId) {
|
|
1120
|
+
return this.request(`/api/products/${productId}`);
|
|
1121
|
+
}
|
|
1122
|
+
async getShopProduct(shopId, productId) {
|
|
1123
|
+
return this.request(`/api/shops/${shopId}/products/${productId}`);
|
|
1124
|
+
}
|
|
1125
|
+
async createShopProduct(shopId, data) {
|
|
1126
|
+
return this.request(`/api/shops/${shopId}/products`, {
|
|
1127
|
+
method: "POST",
|
|
1128
|
+
body: JSON.stringify(data)
|
|
1129
|
+
});
|
|
1130
|
+
}
|
|
1131
|
+
async updateShopProduct(shopId, productId, data) {
|
|
1132
|
+
return this.request(`/api/shops/${shopId}/products/${productId}`, {
|
|
1133
|
+
method: "PUT",
|
|
1134
|
+
body: JSON.stringify(data)
|
|
1135
|
+
});
|
|
1136
|
+
}
|
|
1137
|
+
async deleteShopProduct(shopId, productId) {
|
|
1138
|
+
return this.request(`/api/shops/${shopId}/products/${productId}`, { method: "DELETE" });
|
|
1139
|
+
}
|
|
1140
|
+
async purchaseShopProduct(shopId, productId, data) {
|
|
1141
|
+
return this.request(`/api/shops/${shopId}/products/${productId}/purchase`, {
|
|
1142
|
+
method: "POST",
|
|
1143
|
+
body: JSON.stringify(data)
|
|
1144
|
+
});
|
|
1145
|
+
}
|
|
1146
|
+
async purchaseCommerceOffer(offerId, data) {
|
|
1147
|
+
return this.request(`/api/commerce/offers/${offerId}/purchase`, {
|
|
1148
|
+
method: "POST",
|
|
1149
|
+
body: JSON.stringify(data)
|
|
1150
|
+
});
|
|
1151
|
+
}
|
|
1152
|
+
async getCommerceOfferCheckoutPreview(offerId, params) {
|
|
1153
|
+
const qs = new URLSearchParams();
|
|
1154
|
+
if (params?.skuId) qs.set("skuId", params.skuId);
|
|
1155
|
+
if (params?.viewerUserId) qs.set("viewerUserId", params.viewerUserId);
|
|
1156
|
+
const suffix = qs.toString() ? `?${qs}` : "";
|
|
1157
|
+
return this.request(`/api/commerce/offers/${offerId}/checkout-preview${suffix}`);
|
|
1158
|
+
}
|
|
1159
|
+
async createCommerceOffer(shopId, data) {
|
|
1160
|
+
return this.request(`/api/shops/${shopId}/offers`, {
|
|
1161
|
+
method: "POST",
|
|
1162
|
+
body: JSON.stringify(data)
|
|
1163
|
+
});
|
|
1164
|
+
}
|
|
1165
|
+
async listCommerceOffers(shopId, params) {
|
|
1166
|
+
const qs = new URLSearchParams();
|
|
1167
|
+
if (params?.keyword) qs.set("keyword", params.keyword);
|
|
1168
|
+
if (params?.limit) qs.set("limit", String(params.limit));
|
|
1169
|
+
return this.request(`/api/shops/${shopId}/offers?${qs}`);
|
|
1170
|
+
}
|
|
1171
|
+
async createCommerceDeliverable(shopId, offerId, data) {
|
|
1172
|
+
return this.request(`/api/shops/${shopId}/offers/${offerId}/deliverables`, {
|
|
1173
|
+
method: "POST",
|
|
1174
|
+
body: JSON.stringify(data)
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1177
|
+
async listShopAssetDefinitions(shopId) {
|
|
1178
|
+
return this.request(`/api/shops/${shopId}/assets`);
|
|
1179
|
+
}
|
|
1180
|
+
async createShopAssetDefinition(shopId, data) {
|
|
1181
|
+
return this.request(`/api/shops/${shopId}/assets`, {
|
|
1182
|
+
method: "POST",
|
|
1183
|
+
body: JSON.stringify(data)
|
|
1184
|
+
});
|
|
1185
|
+
}
|
|
1186
|
+
async updateShopAssetDefinition(shopId, assetDefinitionId, data) {
|
|
1187
|
+
return this.request(`/api/shops/${shopId}/assets/${assetDefinitionId}`, {
|
|
1188
|
+
method: "PATCH",
|
|
1189
|
+
body: JSON.stringify(data)
|
|
1190
|
+
});
|
|
1191
|
+
}
|
|
1192
|
+
async purchaseMessageCommerceCard(messageId, cardId, data) {
|
|
1193
|
+
return this.request(`/api/messages/${messageId}/commerce-cards/${cardId}/purchase`, {
|
|
1194
|
+
method: "POST",
|
|
1195
|
+
body: JSON.stringify(data)
|
|
1196
|
+
});
|
|
1197
|
+
}
|
|
1198
|
+
async listCommerceProductCards(params) {
|
|
1199
|
+
const qs = new URLSearchParams();
|
|
1200
|
+
qs.set("target", params.target);
|
|
1201
|
+
qs.set("channelId", params.channelId);
|
|
1202
|
+
if (params.keyword) qs.set("keyword", params.keyword);
|
|
1203
|
+
if (params.limit) qs.set("limit", String(params.limit));
|
|
1204
|
+
return this.request(`/api/commerce/product-picker?${qs}`);
|
|
1205
|
+
}
|
|
1206
|
+
async openPaidFile(fileId) {
|
|
1207
|
+
return this.request(`/api/paid-files/${fileId}/open`, { method: "POST" });
|
|
1208
|
+
}
|
|
1209
|
+
async listShopEntitlements(shopId, params) {
|
|
1210
|
+
const qs = new URLSearchParams();
|
|
1211
|
+
if (params?.limit) qs.set("limit", String(params.limit));
|
|
1212
|
+
if (params?.offset) qs.set("offset", String(params.offset));
|
|
1213
|
+
return this.request(`/api/shops/${shopId}/entitlements?${qs}`);
|
|
1214
|
+
}
|
|
818
1215
|
async updateShop(serverId, data) {
|
|
819
1216
|
return this.request(`/api/servers/${serverId}/shop`, {
|
|
820
1217
|
method: "PUT",
|
|
@@ -889,7 +1286,7 @@ var ShadowClient = class {
|
|
|
889
1286
|
async createOrder(serverId, data) {
|
|
890
1287
|
return this.request(`/api/servers/${serverId}/shop/orders`, {
|
|
891
1288
|
method: "POST",
|
|
892
|
-
body: JSON.stringify(data
|
|
1289
|
+
body: JSON.stringify(data)
|
|
893
1290
|
});
|
|
894
1291
|
}
|
|
895
1292
|
async listOrders(serverId) {
|
|
@@ -930,18 +1327,232 @@ var ShadowClient = class {
|
|
|
930
1327
|
async getWallet() {
|
|
931
1328
|
return this.request("/api/wallet");
|
|
932
1329
|
}
|
|
933
|
-
async topUpWallet(
|
|
934
|
-
|
|
1330
|
+
async topUpWallet(_amount) {
|
|
1331
|
+
throw new Error(
|
|
1332
|
+
"Public wallet top-up is disabled. Use a verified payment flow, refund, settlement, or admin grant."
|
|
1333
|
+
);
|
|
1334
|
+
}
|
|
1335
|
+
async getWalletTransactions(params) {
|
|
1336
|
+
const qs = new URLSearchParams();
|
|
1337
|
+
if (params?.audience) qs.set("audience", params.audience);
|
|
1338
|
+
if (params?.direction) qs.set("direction", params.direction);
|
|
1339
|
+
if (params?.limit != null) qs.set("limit", String(params.limit));
|
|
1340
|
+
if (params?.offset != null) qs.set("offset", String(params.offset));
|
|
1341
|
+
const suffix = qs.toString() ? `?${qs}` : "";
|
|
1342
|
+
return this.request(`/api/wallet/transactions${suffix}`);
|
|
1343
|
+
}
|
|
1344
|
+
// ── Community Economy ────────────────────────────────────────────────
|
|
1345
|
+
async listCommunityAssets() {
|
|
1346
|
+
return this.request("/api/economy/assets");
|
|
1347
|
+
}
|
|
1348
|
+
async getCommunityAsset(grantId) {
|
|
1349
|
+
return this.request(`/api/economy/assets/${grantId}`);
|
|
1350
|
+
}
|
|
1351
|
+
async consumeCommunityAsset(grantId, data) {
|
|
1352
|
+
return this.request(`/api/economy/assets/${grantId}/consume`, {
|
|
935
1353
|
method: "POST",
|
|
936
|
-
body: JSON.stringify(
|
|
1354
|
+
body: JSON.stringify(data)
|
|
937
1355
|
});
|
|
938
1356
|
}
|
|
939
|
-
async
|
|
940
|
-
return this.request(
|
|
1357
|
+
async lockCommunityAsset(grantId, data) {
|
|
1358
|
+
return this.request(`/api/economy/assets/${grantId}/lock`, {
|
|
1359
|
+
method: "POST",
|
|
1360
|
+
body: JSON.stringify(data)
|
|
1361
|
+
});
|
|
1362
|
+
}
|
|
1363
|
+
async unlockCommunityAsset(grantId, data) {
|
|
1364
|
+
return this.request(`/api/economy/assets/${grantId}/unlock`, {
|
|
1365
|
+
method: "POST",
|
|
1366
|
+
body: JSON.stringify(data)
|
|
1367
|
+
});
|
|
1368
|
+
}
|
|
1369
|
+
async revokeCommunityAsset(grantId, data) {
|
|
1370
|
+
return this.request(`/api/economy/assets/${grantId}/revoke`, {
|
|
1371
|
+
method: "POST",
|
|
1372
|
+
body: JSON.stringify(data)
|
|
1373
|
+
});
|
|
1374
|
+
}
|
|
1375
|
+
async sendTip(data) {
|
|
1376
|
+
return this.request("/api/economy/tips", {
|
|
1377
|
+
method: "POST",
|
|
1378
|
+
body: JSON.stringify(data)
|
|
1379
|
+
});
|
|
1380
|
+
}
|
|
1381
|
+
async listTips() {
|
|
1382
|
+
return this.request("/api/economy/tips");
|
|
1383
|
+
}
|
|
1384
|
+
async sendGift(data) {
|
|
1385
|
+
return this.request("/api/economy/gifts", {
|
|
1386
|
+
method: "POST",
|
|
1387
|
+
body: JSON.stringify(data)
|
|
1388
|
+
});
|
|
1389
|
+
}
|
|
1390
|
+
async listGifts() {
|
|
1391
|
+
return this.request("/api/economy/gifts");
|
|
1392
|
+
}
|
|
1393
|
+
async listSettlements(params) {
|
|
1394
|
+
const qs = new URLSearchParams();
|
|
1395
|
+
if (params?.limit != null) qs.set("limit", String(params.limit));
|
|
1396
|
+
if (params?.offset != null) qs.set("offset", String(params.offset));
|
|
1397
|
+
const suffix = qs.toString() ? `?${qs}` : "";
|
|
1398
|
+
return this.request(`/api/economy/settlements${suffix}`);
|
|
1399
|
+
}
|
|
1400
|
+
async settleAvailableSettlements() {
|
|
1401
|
+
return this.request("/api/economy/settlements/settle", { method: "POST" });
|
|
1402
|
+
}
|
|
1403
|
+
// ── Cloud SaaS DIY Generation ───────────────────────────────────────
|
|
1404
|
+
async createDiyCloudRun(data) {
|
|
1405
|
+
return this.request("/api/cloud-saas/diy/runs", {
|
|
1406
|
+
method: "POST",
|
|
1407
|
+
body: JSON.stringify(data)
|
|
1408
|
+
});
|
|
1409
|
+
}
|
|
1410
|
+
async getDiyCloudRun(runId) {
|
|
1411
|
+
return this.request(`/api/cloud-saas/diy/runs/${encodeURIComponent(runId)}`);
|
|
1412
|
+
}
|
|
1413
|
+
async createDiyCloudFeedbackRun(runId, data) {
|
|
1414
|
+
return this.request(`/api/cloud-saas/diy/runs/${encodeURIComponent(runId)}/feedback`, {
|
|
1415
|
+
method: "POST",
|
|
1416
|
+
body: JSON.stringify(data)
|
|
1417
|
+
});
|
|
1418
|
+
}
|
|
1419
|
+
async streamDiyCloudRun(runId, options = {}) {
|
|
1420
|
+
const qs = new URLSearchParams();
|
|
1421
|
+
if (options.afterSeq != null) qs.set("afterSeq", String(options.afterSeq));
|
|
1422
|
+
const suffix = qs.toString() ? `?${qs}` : "";
|
|
1423
|
+
return this.requestRaw(
|
|
1424
|
+
`/api/cloud-saas/diy/runs/${encodeURIComponent(runId)}/stream${suffix}`,
|
|
1425
|
+
{
|
|
1426
|
+
headers: { Accept: "text/event-stream" }
|
|
1427
|
+
}
|
|
1428
|
+
);
|
|
1429
|
+
}
|
|
1430
|
+
async cancelDiyCloudRun(runId) {
|
|
1431
|
+
return this.request(`/api/cloud-saas/diy/runs/${encodeURIComponent(runId)}/cancel`, {
|
|
1432
|
+
method: "POST"
|
|
1433
|
+
});
|
|
1434
|
+
}
|
|
1435
|
+
// ── Cloud SaaS Deployment Runtime ──────────────────────────────────
|
|
1436
|
+
async getCloudDeploymentManifest(deploymentId) {
|
|
1437
|
+
return this.request(`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/manifest`);
|
|
1438
|
+
}
|
|
1439
|
+
async syncCloudDeploymentTemplate(deploymentId, data = {}) {
|
|
1440
|
+
return this.request(
|
|
1441
|
+
`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/template`,
|
|
1442
|
+
{
|
|
1443
|
+
method: "POST",
|
|
1444
|
+
body: JSON.stringify(data)
|
|
1445
|
+
}
|
|
1446
|
+
);
|
|
1447
|
+
}
|
|
1448
|
+
async redeployCloudDeployment(deploymentId, data = {}) {
|
|
1449
|
+
return this.request(
|
|
1450
|
+
`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/redeploy`,
|
|
1451
|
+
{
|
|
1452
|
+
method: "POST",
|
|
1453
|
+
body: JSON.stringify(data)
|
|
1454
|
+
}
|
|
1455
|
+
);
|
|
1456
|
+
}
|
|
1457
|
+
async pauseCloudDeployment(deploymentId, data = {}) {
|
|
1458
|
+
return this.request(`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/pause`, {
|
|
1459
|
+
method: "POST",
|
|
1460
|
+
body: JSON.stringify(data)
|
|
1461
|
+
});
|
|
1462
|
+
}
|
|
1463
|
+
async resumeCloudDeployment(deploymentId, data = {}) {
|
|
1464
|
+
return this.request(`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/resume`, {
|
|
1465
|
+
method: "POST",
|
|
1466
|
+
body: JSON.stringify(data)
|
|
1467
|
+
});
|
|
1468
|
+
}
|
|
1469
|
+
async listCloudDeploymentBackups(deploymentId, params = {}) {
|
|
1470
|
+
const qs = new URLSearchParams();
|
|
1471
|
+
if (params.agentId) qs.set("agentId", params.agentId);
|
|
1472
|
+
const suffix = qs.toString() ? `?${qs}` : "";
|
|
1473
|
+
return this.request(
|
|
1474
|
+
`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/backups${suffix}`
|
|
1475
|
+
);
|
|
1476
|
+
}
|
|
1477
|
+
async createCloudDeploymentBackup(deploymentId, data = {}) {
|
|
1478
|
+
return this.request(`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/backups`, {
|
|
1479
|
+
method: "POST",
|
|
1480
|
+
body: JSON.stringify(data)
|
|
1481
|
+
});
|
|
1482
|
+
}
|
|
1483
|
+
async restoreCloudDeploymentBackup(deploymentId, data = {}) {
|
|
1484
|
+
return this.request(`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/restore`, {
|
|
1485
|
+
method: "POST",
|
|
1486
|
+
body: JSON.stringify(data)
|
|
1487
|
+
});
|
|
1488
|
+
}
|
|
1489
|
+
// ── Cloud SaaS Provider Gateway ─────────────────────────────────────
|
|
1490
|
+
async listCloudProviderCatalogs() {
|
|
1491
|
+
return this.request("/api/cloud-saas/provider-catalogs");
|
|
1492
|
+
}
|
|
1493
|
+
async listCloudProviderProfiles() {
|
|
1494
|
+
return this.request("/api/cloud-saas/provider-profiles");
|
|
1495
|
+
}
|
|
1496
|
+
async upsertCloudProviderProfile(data) {
|
|
1497
|
+
return this.request("/api/cloud-saas/provider-profiles", {
|
|
1498
|
+
method: "PUT",
|
|
1499
|
+
body: JSON.stringify(data)
|
|
1500
|
+
});
|
|
1501
|
+
}
|
|
1502
|
+
async testCloudProviderProfile(profileId) {
|
|
1503
|
+
return this.request(`/api/cloud-saas/provider-profiles/${encodeURIComponent(profileId)}/test`, {
|
|
1504
|
+
method: "POST"
|
|
1505
|
+
});
|
|
1506
|
+
}
|
|
1507
|
+
async refreshCloudProviderProfileModels(profileId) {
|
|
1508
|
+
return this.request(
|
|
1509
|
+
`/api/cloud-saas/provider-profiles/${encodeURIComponent(profileId)}/models/refresh`,
|
|
1510
|
+
{ method: "POST" }
|
|
1511
|
+
);
|
|
1512
|
+
}
|
|
1513
|
+
async deleteCloudProviderProfile(profileId) {
|
|
1514
|
+
return this.request(`/api/cloud-saas/provider-profiles/${encodeURIComponent(profileId)}`, {
|
|
1515
|
+
method: "DELETE"
|
|
1516
|
+
});
|
|
1517
|
+
}
|
|
1518
|
+
// ── Recharge (Stripe) ───────────────────────────────────────────────
|
|
1519
|
+
async getRechargeConfig() {
|
|
1520
|
+
return this.request("/api/v1/recharge/config");
|
|
1521
|
+
}
|
|
1522
|
+
async createRechargeIntent(params) {
|
|
1523
|
+
return this.request("/api/v1/recharge/create-intent", {
|
|
1524
|
+
method: "POST",
|
|
1525
|
+
body: JSON.stringify(params)
|
|
1526
|
+
});
|
|
1527
|
+
}
|
|
1528
|
+
async getRechargeHistory(params) {
|
|
1529
|
+
const qs = new URLSearchParams();
|
|
1530
|
+
if (params?.limit) qs.set("limit", String(params.limit));
|
|
1531
|
+
if (params?.offset) qs.set("offset", String(params.offset));
|
|
1532
|
+
const query = qs.toString();
|
|
1533
|
+
return this.request(`/api/v1/recharge/history${query ? `?${query}` : ""}`);
|
|
1534
|
+
}
|
|
1535
|
+
async confirmRechargePayment(paymentIntentId) {
|
|
1536
|
+
return this.request("/api/v1/recharge/confirm", {
|
|
1537
|
+
method: "POST",
|
|
1538
|
+
body: JSON.stringify({ paymentIntentId })
|
|
1539
|
+
});
|
|
941
1540
|
}
|
|
942
1541
|
async getEntitlements(serverId) {
|
|
943
1542
|
return this.request(`/api/servers/${serverId}/shop/entitlements`);
|
|
944
1543
|
}
|
|
1544
|
+
async getAllEntitlements() {
|
|
1545
|
+
return this.request("/api/entitlements");
|
|
1546
|
+
}
|
|
1547
|
+
async verifyEntitlement(entitlementId) {
|
|
1548
|
+
return this.request(`/api/entitlements/${entitlementId}/verify`);
|
|
1549
|
+
}
|
|
1550
|
+
async cancelEntitlement(entitlementId, reason) {
|
|
1551
|
+
return this.request(`/api/entitlements/${entitlementId}/cancel`, {
|
|
1552
|
+
method: "POST",
|
|
1553
|
+
body: JSON.stringify({ reason })
|
|
1554
|
+
});
|
|
1555
|
+
}
|
|
945
1556
|
// ── Task Center ───────────────────────────────────────────────────────
|
|
946
1557
|
async getTaskCenter() {
|
|
947
1558
|
return this.request("/api/tasks");
|
|
@@ -955,41 +1566,126 @@ var ShadowClient = class {
|
|
|
955
1566
|
async getRewardHistory() {
|
|
956
1567
|
return this.request("/api/tasks/rewards");
|
|
957
1568
|
}
|
|
958
|
-
// ──
|
|
959
|
-
async
|
|
1569
|
+
// ── API Tokens ────────────────────────────────────────────────────────
|
|
1570
|
+
async createApiToken(data) {
|
|
1571
|
+
return this.request("/api/tokens", {
|
|
1572
|
+
method: "POST",
|
|
1573
|
+
body: JSON.stringify(data)
|
|
1574
|
+
});
|
|
1575
|
+
}
|
|
1576
|
+
async listApiTokens() {
|
|
1577
|
+
return this.request("/api/tokens");
|
|
1578
|
+
}
|
|
1579
|
+
async deleteApiToken(tokenId) {
|
|
1580
|
+
return this.request(`/api/tokens/${tokenId}`, { method: "DELETE" });
|
|
1581
|
+
}
|
|
1582
|
+
// ── Discover ──────────────────────────────────────────────────────────
|
|
1583
|
+
async discoverFeed(params) {
|
|
960
1584
|
const qs = new URLSearchParams();
|
|
961
|
-
if (params?.
|
|
1585
|
+
if (params?.type) qs.set("type", params.type);
|
|
962
1586
|
if (params?.limit) qs.set("limit", String(params.limit));
|
|
963
1587
|
if (params?.offset) qs.set("offset", String(params.offset));
|
|
964
|
-
return this.request(`/api/
|
|
1588
|
+
return this.request(`/api/discover/feed?${qs}`);
|
|
965
1589
|
}
|
|
966
|
-
async
|
|
967
|
-
|
|
1590
|
+
async discoverSearch(params) {
|
|
1591
|
+
const qs = new URLSearchParams({ q: params.q });
|
|
1592
|
+
if (params?.type) qs.set("type", params.type);
|
|
1593
|
+
if (params?.limit) qs.set("limit", String(params.limit));
|
|
1594
|
+
return this.request(`/api/discover/search?${qs}`);
|
|
968
1595
|
}
|
|
969
|
-
|
|
970
|
-
|
|
1596
|
+
// ── Voice Enhance ─────────────────────────────────────────────────────
|
|
1597
|
+
async enhanceVoice(data) {
|
|
1598
|
+
return this.request("/api/voice/enhance", {
|
|
1599
|
+
method: "POST",
|
|
1600
|
+
body: JSON.stringify(data)
|
|
1601
|
+
});
|
|
971
1602
|
}
|
|
972
|
-
async
|
|
973
|
-
|
|
1603
|
+
async enhanceVoiceQuery(params) {
|
|
1604
|
+
const qs = new URLSearchParams({ transcript: params.transcript });
|
|
1605
|
+
if (params.language) qs.set("language", params.language);
|
|
1606
|
+
if (params.enableSelfCorrection !== void 0)
|
|
1607
|
+
qs.set("enableSelfCorrection", String(params.enableSelfCorrection));
|
|
1608
|
+
if (params.enableListFormatting !== void 0)
|
|
1609
|
+
qs.set("enableListFormatting", String(params.enableListFormatting));
|
|
1610
|
+
if (params.enableFillerRemoval !== void 0)
|
|
1611
|
+
qs.set("enableFillerRemoval", String(params.enableFillerRemoval));
|
|
1612
|
+
if (params.enableToneAdjustment !== void 0)
|
|
1613
|
+
qs.set("enableToneAdjustment", String(params.enableToneAdjustment));
|
|
1614
|
+
if (params.targetTone) qs.set("targetTone", params.targetTone);
|
|
1615
|
+
return this.request(`/api/voice/enhance?${qs}`);
|
|
1616
|
+
}
|
|
1617
|
+
async getVoiceConfig() {
|
|
1618
|
+
return this.request("/api/voice/config");
|
|
1619
|
+
}
|
|
1620
|
+
async updateVoiceConfig(data) {
|
|
1621
|
+
return this.request("/api/voice/config", {
|
|
974
1622
|
method: "POST",
|
|
975
1623
|
body: JSON.stringify(data)
|
|
976
1624
|
});
|
|
977
1625
|
}
|
|
978
|
-
async
|
|
979
|
-
return this.request(
|
|
980
|
-
|
|
1626
|
+
async voiceHealthCheck() {
|
|
1627
|
+
return this.request("/api/voice/health");
|
|
1628
|
+
}
|
|
1629
|
+
// ── Profile Comments ──────────────────────────────────────────────────
|
|
1630
|
+
async getProfileComments(profileUserId, params) {
|
|
1631
|
+
const qs = new URLSearchParams();
|
|
1632
|
+
if (params?.limit) qs.set("limit", String(params.limit));
|
|
1633
|
+
if (params?.offset) qs.set("offset", String(params.offset));
|
|
1634
|
+
return this.request(`/api/profile-comments/${profileUserId}?${qs}`);
|
|
1635
|
+
}
|
|
1636
|
+
async getProfileCommentStats(profileUserId) {
|
|
1637
|
+
return this.request(`/api/profile-comments/${profileUserId}/stats`);
|
|
1638
|
+
}
|
|
1639
|
+
async getCommentReplies(parentId, params) {
|
|
1640
|
+
const qs = new URLSearchParams();
|
|
1641
|
+
if (params?.limit) qs.set("limit", String(params.limit));
|
|
1642
|
+
if (params?.offset) qs.set("offset", String(params.offset));
|
|
1643
|
+
return this.request(`/api/profile-comments/replies/${parentId}?${qs}`);
|
|
1644
|
+
}
|
|
1645
|
+
async createProfileComment(data) {
|
|
1646
|
+
return this.request("/api/profile-comments", {
|
|
1647
|
+
method: "POST",
|
|
981
1648
|
body: JSON.stringify(data)
|
|
982
1649
|
});
|
|
983
1650
|
}
|
|
984
|
-
async
|
|
985
|
-
return this.request(`/api/
|
|
1651
|
+
async deleteProfileComment(commentId) {
|
|
1652
|
+
return this.request(`/api/profile-comments/${commentId}`, { method: "DELETE" });
|
|
1653
|
+
}
|
|
1654
|
+
async addProfileCommentReaction(commentId, emoji) {
|
|
1655
|
+
return this.request(`/api/profile-comments/${commentId}/reactions`, {
|
|
1656
|
+
method: "POST",
|
|
1657
|
+
body: JSON.stringify({ emoji })
|
|
1658
|
+
});
|
|
1659
|
+
}
|
|
1660
|
+
async removeProfileCommentReaction(commentId, emoji) {
|
|
1661
|
+
return this.request(`/api/profile-comments/${commentId}/reactions`, {
|
|
1662
|
+
method: "DELETE",
|
|
1663
|
+
body: JSON.stringify({ emoji })
|
|
1664
|
+
});
|
|
1665
|
+
}
|
|
1666
|
+
// ── Agent Dashboard ───────────────────────────────────────────────────
|
|
1667
|
+
async getAgentDashboard(agentId) {
|
|
1668
|
+
return this.request(`/api/agents/${agentId}/dashboard`);
|
|
986
1669
|
}
|
|
987
|
-
async
|
|
988
|
-
return this.request(`/api/
|
|
1670
|
+
async addAgentDashboardEvent(agentId, data) {
|
|
1671
|
+
return this.request(`/api/agents/${agentId}/dashboard/events`, {
|
|
989
1672
|
method: "POST",
|
|
990
1673
|
body: JSON.stringify(data)
|
|
991
1674
|
});
|
|
992
1675
|
}
|
|
1676
|
+
// ── Channel Archive ───────────────────────────────────────────────────
|
|
1677
|
+
async archiveChannel(channelId, reason) {
|
|
1678
|
+
return this.request(`/api/channels/${channelId}/archive`, {
|
|
1679
|
+
method: "POST",
|
|
1680
|
+
body: JSON.stringify(reason ? { reason } : {})
|
|
1681
|
+
});
|
|
1682
|
+
}
|
|
1683
|
+
async unarchiveChannel(channelId) {
|
|
1684
|
+
return this.request(`/api/channels/${channelId}/unarchive`, { method: "POST" });
|
|
1685
|
+
}
|
|
1686
|
+
async getArchivedChannels(serverId) {
|
|
1687
|
+
return this.request(`/api/servers/${serverId}/channels/archived`);
|
|
1688
|
+
}
|
|
993
1689
|
};
|
|
994
1690
|
|
|
995
1691
|
// src/constants.ts
|
|
@@ -1111,9 +1807,9 @@ var ShadowSocket = class {
|
|
|
1111
1807
|
sendMessage(data) {
|
|
1112
1808
|
this.socket.emit("message:send", data);
|
|
1113
1809
|
}
|
|
1114
|
-
/** Send a typing indicator */
|
|
1115
|
-
sendTyping(channelId) {
|
|
1116
|
-
this.socket.emit("message:typing", { channelId });
|
|
1810
|
+
/** Send or clear a typing indicator */
|
|
1811
|
+
sendTyping(channelId, typing = true) {
|
|
1812
|
+
this.socket.emit("message:typing", { channelId, typing });
|
|
1117
1813
|
}
|
|
1118
1814
|
/** Update user presence status */
|
|
1119
1815
|
updatePresence(status) {
|
|
@@ -1123,23 +1819,6 @@ var ShadowSocket = class {
|
|
|
1123
1819
|
updateActivity(channelId, activity) {
|
|
1124
1820
|
this.socket.emit("presence:activity", { channelId, activity });
|
|
1125
1821
|
}
|
|
1126
|
-
// ── DM actions ────────────────────────────────────────────────────────
|
|
1127
|
-
/** Join a DM channel room */
|
|
1128
|
-
joinDmChannel(dmChannelId) {
|
|
1129
|
-
this.socket.emit("dm:join", { dmChannelId });
|
|
1130
|
-
}
|
|
1131
|
-
/** Leave a DM channel room */
|
|
1132
|
-
leaveDmChannel(dmChannelId) {
|
|
1133
|
-
this.socket.emit("dm:leave", { dmChannelId });
|
|
1134
|
-
}
|
|
1135
|
-
/** Send a DM message via WebSocket */
|
|
1136
|
-
sendDmMessage(data) {
|
|
1137
|
-
this.socket.emit("dm:send", data);
|
|
1138
|
-
}
|
|
1139
|
-
/** Send a DM typing indicator */
|
|
1140
|
-
sendDmTyping(dmChannelId) {
|
|
1141
|
-
this.socket.emit("dm:typing", { dmChannelId });
|
|
1142
|
-
}
|
|
1143
1822
|
};
|
|
1144
1823
|
export {
|
|
1145
1824
|
CLIENT_EVENTS,
|