@shadowob/sdk 1.1.1 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +745 -92
- package/dist/index.d.cts +1536 -116
- package/dist/index.d.ts +1536 -116
- package/dist/index.js +745 -92
- 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,6 +135,45 @@ 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
178
|
async listAgents() {
|
|
78
179
|
return this.request("/api/agents");
|
|
@@ -110,21 +211,62 @@ var ShadowClient = class {
|
|
|
110
211
|
body: JSON.stringify({})
|
|
111
212
|
});
|
|
112
213
|
}
|
|
214
|
+
async reportAgentUsageSnapshot(agentId, snapshot) {
|
|
215
|
+
return this.request(`/api/agents/${agentId}/usage-snapshot`, {
|
|
216
|
+
method: "POST",
|
|
217
|
+
body: JSON.stringify(snapshot)
|
|
218
|
+
});
|
|
219
|
+
}
|
|
113
220
|
async getAgentConfig(agentId) {
|
|
114
221
|
return this.request(`/api/agents/${agentId}/config`);
|
|
115
222
|
}
|
|
223
|
+
async updateAgentSlashCommands(agentId, commands) {
|
|
224
|
+
return this.request(`/api/agents/${agentId}/slash-commands`, {
|
|
225
|
+
method: "PUT",
|
|
226
|
+
body: JSON.stringify({ commands })
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
async getAgentSlashCommands(agentId) {
|
|
230
|
+
return this.request(`/api/agents/${agentId}/slash-commands`);
|
|
231
|
+
}
|
|
232
|
+
async listChannelSlashCommands(channelId) {
|
|
233
|
+
return this.request(
|
|
234
|
+
`/api/channels/${channelId}/slash-commands`
|
|
235
|
+
);
|
|
236
|
+
}
|
|
116
237
|
// ── Agent Policies ────────────────────────────────────────────────────
|
|
117
238
|
async listPolicies(agentId, serverId) {
|
|
118
|
-
|
|
239
|
+
const policies = await this.request(`/api/agents/${agentId}/policies`);
|
|
240
|
+
if (!serverId) return policies;
|
|
241
|
+
return policies.filter((policy) => policy.serverId === serverId);
|
|
119
242
|
}
|
|
120
243
|
async upsertPolicy(agentId, serverId, data) {
|
|
121
|
-
|
|
244
|
+
const policy = {
|
|
245
|
+
serverId,
|
|
246
|
+
...data.channelId !== void 0 ? { channelId: data.channelId } : {},
|
|
247
|
+
...data.mentionOnly !== void 0 ? { mentionOnly: data.mentionOnly } : {},
|
|
248
|
+
...data.reply !== void 0 ? { reply: data.reply } : {},
|
|
249
|
+
...data.config !== void 0 ? { config: data.config } : {}
|
|
250
|
+
};
|
|
251
|
+
const results = await this.request(`/api/agents/${agentId}/policies`, {
|
|
122
252
|
method: "PUT",
|
|
123
|
-
body: JSON.stringify(
|
|
253
|
+
body: JSON.stringify({ policies: [policy] })
|
|
124
254
|
});
|
|
255
|
+
const [result] = results;
|
|
256
|
+
if (!result) {
|
|
257
|
+
throw new Error(`Shadow API PUT /api/agents/${agentId}/policies returned no policy result`);
|
|
258
|
+
}
|
|
259
|
+
return result;
|
|
125
260
|
}
|
|
126
261
|
async deletePolicy(agentId, serverId, channelId) {
|
|
127
|
-
|
|
262
|
+
const policies = await this.listPolicies(agentId, serverId);
|
|
263
|
+
const policy = policies.find((entry) => entry.channelId === channelId);
|
|
264
|
+
if (!policy?.id) {
|
|
265
|
+
throw new Error(
|
|
266
|
+
`Shadow policy not found for agent ${agentId} in server ${serverId} channel ${channelId}`
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
return this.request(`/api/agents/${agentId}/policies/${policy.id}`, {
|
|
128
270
|
method: "DELETE"
|
|
129
271
|
});
|
|
130
272
|
}
|
|
@@ -147,6 +289,9 @@ var ShadowClient = class {
|
|
|
147
289
|
async getServer(serverIdOrSlug) {
|
|
148
290
|
return this.request(`/api/servers/${serverIdOrSlug}`);
|
|
149
291
|
}
|
|
292
|
+
async getServerAccess(serverIdOrSlug) {
|
|
293
|
+
return this.request(`/api/servers/${serverIdOrSlug}/access`);
|
|
294
|
+
}
|
|
150
295
|
async updateServer(serverIdOrSlug, data) {
|
|
151
296
|
return this.request(`/api/servers/${serverIdOrSlug}`, {
|
|
152
297
|
method: "PATCH",
|
|
@@ -165,6 +310,20 @@ var ShadowClient = class {
|
|
|
165
310
|
body: JSON.stringify(inviteCode ? { inviteCode } : {})
|
|
166
311
|
});
|
|
167
312
|
}
|
|
313
|
+
async requestServerAccess(serverIdOrSlug) {
|
|
314
|
+
return this.request(
|
|
315
|
+
`/api/servers/${serverIdOrSlug}/join-requests`,
|
|
316
|
+
{
|
|
317
|
+
method: "POST"
|
|
318
|
+
}
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
async reviewServerJoinRequest(requestId, status) {
|
|
322
|
+
return this.request(`/api/servers/join-requests/${requestId}`, {
|
|
323
|
+
method: "PATCH",
|
|
324
|
+
body: JSON.stringify({ status })
|
|
325
|
+
});
|
|
326
|
+
}
|
|
168
327
|
async leaveServer(serverId) {
|
|
169
328
|
return this.request(`/api/servers/${serverId}/leave`, { method: "POST" });
|
|
170
329
|
}
|
|
@@ -181,7 +340,7 @@ var ShadowClient = class {
|
|
|
181
340
|
return this.request(`/api/servers/${serverId}/members/${userId}`, { method: "DELETE" });
|
|
182
341
|
}
|
|
183
342
|
async regenerateInviteCode(serverId) {
|
|
184
|
-
return this.request(`/api/servers/${serverId}/invite`, { method: "POST" });
|
|
343
|
+
return this.request(`/api/servers/${serverId}/invite/regenerate`, { method: "POST" });
|
|
185
344
|
}
|
|
186
345
|
async addAgentsToServer(serverId, agentIds) {
|
|
187
346
|
return this.request(`/api/servers/${serverId}/agents`, {
|
|
@@ -206,6 +365,9 @@ var ShadowClient = class {
|
|
|
206
365
|
const ch = await this.request(`/api/channels/${channelId}`);
|
|
207
366
|
return { ...ch, description: ch.topic };
|
|
208
367
|
}
|
|
368
|
+
async getChannelAccess(channelId) {
|
|
369
|
+
return this.request(`/api/channels/${channelId}/access`);
|
|
370
|
+
}
|
|
209
371
|
async getChannelMembers(channelId) {
|
|
210
372
|
return this.request(`/api/channels/${channelId}/members`);
|
|
211
373
|
}
|
|
@@ -222,8 +384,8 @@ var ShadowClient = class {
|
|
|
222
384
|
return this.request(`/api/channels/${channelId}`, { method: "DELETE" });
|
|
223
385
|
}
|
|
224
386
|
async reorderChannels(serverId, channelIds) {
|
|
225
|
-
return this.request(`/api/servers/${serverId}/channels/
|
|
226
|
-
method: "
|
|
387
|
+
return this.request(`/api/servers/${serverId}/channels/positions`, {
|
|
388
|
+
method: "PATCH",
|
|
227
389
|
body: JSON.stringify({ channelIds })
|
|
228
390
|
});
|
|
229
391
|
}
|
|
@@ -233,18 +395,32 @@ var ShadowClient = class {
|
|
|
233
395
|
body: JSON.stringify({ userId })
|
|
234
396
|
});
|
|
235
397
|
}
|
|
398
|
+
async requestChannelAccess(channelId) {
|
|
399
|
+
return this.request(
|
|
400
|
+
`/api/channels/${channelId}/join-requests`,
|
|
401
|
+
{
|
|
402
|
+
method: "POST"
|
|
403
|
+
}
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
async reviewChannelJoinRequest(requestId, status) {
|
|
407
|
+
return this.request(`/api/channel-join-requests/${requestId}`, {
|
|
408
|
+
method: "PATCH",
|
|
409
|
+
body: JSON.stringify({ status })
|
|
410
|
+
});
|
|
411
|
+
}
|
|
236
412
|
async removeChannelMember(channelId, userId) {
|
|
237
413
|
return this.request(`/api/channels/${channelId}/members/${userId}`, { method: "DELETE" });
|
|
238
414
|
}
|
|
239
415
|
// ── Channel Buddy Policy ─────────────────────────────────────────────
|
|
240
|
-
async setBuddyPolicy(channelId, data) {
|
|
241
|
-
return this.request(`/api/channels/${channelId}/
|
|
416
|
+
async setBuddyPolicy(channelId, agentId, data) {
|
|
417
|
+
return this.request(`/api/channels/${channelId}/agents/${agentId}/policy`, {
|
|
242
418
|
method: "PUT",
|
|
243
419
|
body: JSON.stringify(data)
|
|
244
420
|
});
|
|
245
421
|
}
|
|
246
|
-
async getBuddyPolicy(channelId) {
|
|
247
|
-
return this.request(`/api/channels/${channelId}/
|
|
422
|
+
async getBuddyPolicy(channelId, agentId) {
|
|
423
|
+
return this.request(`/api/channels/${channelId}/agents/${agentId}/policy`);
|
|
248
424
|
}
|
|
249
425
|
// ── Messages ──────────────────────────────────────────────────────────
|
|
250
426
|
async sendMessage(channelId, content, opts) {
|
|
@@ -254,10 +430,27 @@ var ShadowClient = class {
|
|
|
254
430
|
content,
|
|
255
431
|
...opts?.threadId ? { threadId: opts.threadId } : {},
|
|
256
432
|
...opts?.replyToId ? { replyToId: opts.replyToId } : {},
|
|
257
|
-
...opts?.
|
|
433
|
+
...opts?.mentions ? { mentions: opts.mentions } : {},
|
|
434
|
+
...opts?.metadata ? { metadata: opts.metadata } : {},
|
|
435
|
+
...opts?.attachments ? { attachments: opts.attachments } : {}
|
|
258
436
|
})
|
|
259
437
|
});
|
|
260
438
|
}
|
|
439
|
+
async suggestMentions(input) {
|
|
440
|
+
const params = new URLSearchParams({
|
|
441
|
+
channelId: input.channelId,
|
|
442
|
+
trigger: input.trigger
|
|
443
|
+
});
|
|
444
|
+
if (input.query) params.set("q", input.query);
|
|
445
|
+
if (input.limit) params.set("limit", String(input.limit));
|
|
446
|
+
return this.request(`/api/mentions/suggest?${params}`);
|
|
447
|
+
}
|
|
448
|
+
async resolveMentions(input) {
|
|
449
|
+
return this.request("/api/mentions/resolve", {
|
|
450
|
+
method: "POST",
|
|
451
|
+
body: JSON.stringify(input)
|
|
452
|
+
});
|
|
453
|
+
}
|
|
261
454
|
async getMessages(channelId, limit = 50, cursor) {
|
|
262
455
|
const params = new URLSearchParams({ limit: String(limit) });
|
|
263
456
|
if (cursor) params.set("cursor", cursor);
|
|
@@ -268,6 +461,20 @@ var ShadowClient = class {
|
|
|
268
461
|
async getMessage(messageId) {
|
|
269
462
|
return this.request(`/api/messages/${messageId}`);
|
|
270
463
|
}
|
|
464
|
+
async submitInteractiveAction(messageId, input) {
|
|
465
|
+
return this.request(`/api/messages/${messageId}/interactive`, {
|
|
466
|
+
method: "POST",
|
|
467
|
+
body: JSON.stringify(input)
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
async getInteractiveState(messageId, blockId) {
|
|
471
|
+
const params = new URLSearchParams();
|
|
472
|
+
if (blockId) params.set("blockId", blockId);
|
|
473
|
+
const query = params.toString();
|
|
474
|
+
return this.request(
|
|
475
|
+
`/api/messages/${messageId}/interactive-state${query ? `?${query}` : ""}`
|
|
476
|
+
);
|
|
477
|
+
}
|
|
271
478
|
async editMessage(messageId, content) {
|
|
272
479
|
return this.request(`/api/messages/${messageId}`, {
|
|
273
480
|
method: "PATCH",
|
|
@@ -281,16 +488,10 @@ var ShadowClient = class {
|
|
|
281
488
|
}
|
|
282
489
|
// ── Pins ──────────────────────────────────────────────────────────────
|
|
283
490
|
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" });
|
|
491
|
+
return this.request(`/api/channels/${channelId}/pins/${messageId}`, { method: "PUT" });
|
|
288
492
|
}
|
|
289
493
|
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" });
|
|
494
|
+
return this.request(`/api/channels/${channelId}/pins/${messageId}`, { method: "DELETE" });
|
|
294
495
|
}
|
|
295
496
|
async getPinnedMessages(channelId) {
|
|
296
497
|
return this.request(`/api/channels/${channelId}/pins`);
|
|
@@ -337,36 +538,26 @@ var ShadowClient = class {
|
|
|
337
538
|
if (cursor) params.set("cursor", cursor);
|
|
338
539
|
return this.request(`/api/threads/${threadId}/messages?${params}`);
|
|
339
540
|
}
|
|
340
|
-
async sendToThread(threadId, content) {
|
|
541
|
+
async sendToThread(threadId, content, options) {
|
|
341
542
|
return this.request(`/api/threads/${threadId}/messages`, {
|
|
342
543
|
method: "POST",
|
|
343
|
-
body: JSON.stringify({
|
|
544
|
+
body: JSON.stringify({
|
|
545
|
+
content,
|
|
546
|
+
...options?.replyToId ? { replyToId: options.replyToId } : {},
|
|
547
|
+
...options?.mentions ? { mentions: options.mentions } : {},
|
|
548
|
+
...options?.metadata ? { metadata: options.metadata } : {}
|
|
549
|
+
})
|
|
344
550
|
});
|
|
345
551
|
}
|
|
346
|
-
// ──
|
|
347
|
-
async
|
|
348
|
-
return this.request("/api/dm
|
|
552
|
+
// ── Direct channels ──────────────────────────────────────────────────
|
|
553
|
+
async createDirectChannel(userId) {
|
|
554
|
+
return this.request("/api/channels/dm", {
|
|
349
555
|
method: "POST",
|
|
350
556
|
body: JSON.stringify({ userId })
|
|
351
557
|
});
|
|
352
558
|
}
|
|
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
|
-
});
|
|
559
|
+
async listDirectChannels() {
|
|
560
|
+
return this.request("/api/channels/dm");
|
|
370
561
|
}
|
|
371
562
|
// ── Notifications ─────────────────────────────────────────────────────
|
|
372
563
|
async listNotifications(limit = 50, offset = 0) {
|
|
@@ -417,8 +608,10 @@ var ShadowClient = class {
|
|
|
417
608
|
const formData = new FormData();
|
|
418
609
|
const blob = file instanceof Blob ? file : new Blob([file], { type: contentType });
|
|
419
610
|
formData.append("file", blob, filename);
|
|
420
|
-
if (messageId) {
|
|
611
|
+
if (typeof messageId === "string") {
|
|
421
612
|
formData.append("messageId", messageId);
|
|
613
|
+
} else if (messageId) {
|
|
614
|
+
if (messageId.messageId) formData.append("messageId", messageId.messageId);
|
|
422
615
|
}
|
|
423
616
|
const url = `${this.baseUrl}/api/media/upload`;
|
|
424
617
|
const res = await fetch(url, {
|
|
@@ -434,6 +627,12 @@ var ShadowClient = class {
|
|
|
434
627
|
}
|
|
435
628
|
return res.json();
|
|
436
629
|
}
|
|
630
|
+
async resolveAttachmentMediaUrl(attachmentId, options) {
|
|
631
|
+
const disposition = options?.disposition ?? "inline";
|
|
632
|
+
return this.request(
|
|
633
|
+
`/api/attachments/${attachmentId}/media-url?disposition=${disposition}`
|
|
634
|
+
);
|
|
635
|
+
}
|
|
437
636
|
/**
|
|
438
637
|
* Download a file from a URL and upload it to the Shadow media service.
|
|
439
638
|
* Supports local filesystem paths, file:// URLs, tilde paths, and HTTP(S) URLs.
|
|
@@ -449,6 +648,15 @@ var ShadowClient = class {
|
|
|
449
648
|
if (normalizedUrl.startsWith("~")) {
|
|
450
649
|
normalizedUrl = normalizedUrl.replace(/^~/, homedir());
|
|
451
650
|
}
|
|
651
|
+
if (this.isShadowPrivateMediaUrl(normalizedUrl)) {
|
|
652
|
+
const downloaded = await this.downloadFile(normalizedUrl);
|
|
653
|
+
return this.uploadMedia(
|
|
654
|
+
downloaded.buffer,
|
|
655
|
+
downloaded.filename,
|
|
656
|
+
downloaded.contentType,
|
|
657
|
+
messageId
|
|
658
|
+
);
|
|
659
|
+
}
|
|
452
660
|
if (!normalizedUrl.startsWith("/") && !normalizedUrl.startsWith("http://") && !normalizedUrl.startsWith("https://") && !normalizedUrl.startsWith("//")) {
|
|
453
661
|
const { existsSync } = await import("fs");
|
|
454
662
|
const { resolve } = await import("path");
|
|
@@ -523,7 +731,7 @@ var ShadowClient = class {
|
|
|
523
731
|
const buffer = await res.arrayBuffer();
|
|
524
732
|
const contentType = res.headers.get("content-type") ?? "application/octet-stream";
|
|
525
733
|
const urlPath = new URL(fullUrl).pathname;
|
|
526
|
-
const filename = decodeURIComponent(urlPath.split("/").pop() ?? "file");
|
|
734
|
+
const filename = contentDispositionFilename(res.headers.get("content-disposition")) ?? decodeURIComponent(urlPath.split("/").pop() ?? "file");
|
|
527
735
|
return { buffer, contentType, filename };
|
|
528
736
|
}
|
|
529
737
|
// ── Workspace ─────────────────────────────────────────────────────────
|
|
@@ -651,6 +859,21 @@ var ShadowClient = class {
|
|
|
651
859
|
async unlinkOAuthAccount(accountId) {
|
|
652
860
|
return this.request(`/api/auth/oauth/accounts/${accountId}`, { method: "DELETE" });
|
|
653
861
|
}
|
|
862
|
+
async changePassword(data) {
|
|
863
|
+
return this.request("/api/auth/password", {
|
|
864
|
+
method: "PUT",
|
|
865
|
+
body: JSON.stringify(data)
|
|
866
|
+
});
|
|
867
|
+
}
|
|
868
|
+
async getDashboard() {
|
|
869
|
+
return this.request("/api/auth/dashboard");
|
|
870
|
+
}
|
|
871
|
+
async loginWithGoogleIdToken(idToken) {
|
|
872
|
+
return this.request("/api/auth/google/id-token", {
|
|
873
|
+
method: "POST",
|
|
874
|
+
body: JSON.stringify({ idToken })
|
|
875
|
+
});
|
|
876
|
+
}
|
|
654
877
|
// ── Friendships ───────────────────────────────────────────────────────
|
|
655
878
|
async sendFriendRequest(username) {
|
|
656
879
|
return this.request("/api/friends/request", {
|
|
@@ -695,6 +918,27 @@ var ShadowClient = class {
|
|
|
695
918
|
body: JSON.stringify(data)
|
|
696
919
|
});
|
|
697
920
|
}
|
|
921
|
+
async getNotificationChannelPreferences() {
|
|
922
|
+
return this.request("/api/notifications/channel-preferences");
|
|
923
|
+
}
|
|
924
|
+
async updateNotificationChannelPreference(data) {
|
|
925
|
+
return this.request("/api/notifications/channel-preferences", {
|
|
926
|
+
method: "PATCH",
|
|
927
|
+
body: JSON.stringify(data)
|
|
928
|
+
});
|
|
929
|
+
}
|
|
930
|
+
async registerPushToken(data) {
|
|
931
|
+
return this.request("/api/notifications/push-tokens", {
|
|
932
|
+
method: "POST",
|
|
933
|
+
body: JSON.stringify(data)
|
|
934
|
+
});
|
|
935
|
+
}
|
|
936
|
+
async registerWebPushSubscription(data) {
|
|
937
|
+
return this.request("/api/notifications/web-push-subscriptions", {
|
|
938
|
+
method: "POST",
|
|
939
|
+
body: JSON.stringify(data)
|
|
940
|
+
});
|
|
941
|
+
}
|
|
698
942
|
// ── OAuth Apps ────────────────────────────────────────────────────────
|
|
699
943
|
async createOAuthApp(data) {
|
|
700
944
|
return this.request("/api/oauth/apps", {
|
|
@@ -815,6 +1059,133 @@ var ShadowClient = class {
|
|
|
815
1059
|
async getShop(serverId) {
|
|
816
1060
|
return this.request(`/api/servers/${serverId}/shop`);
|
|
817
1061
|
}
|
|
1062
|
+
async getMyShop() {
|
|
1063
|
+
return this.request("/api/me/shop");
|
|
1064
|
+
}
|
|
1065
|
+
async upsertMyShop(data) {
|
|
1066
|
+
return this.request("/api/me/shop", {
|
|
1067
|
+
method: "POST",
|
|
1068
|
+
body: JSON.stringify(data)
|
|
1069
|
+
});
|
|
1070
|
+
}
|
|
1071
|
+
async getUserShop(userId) {
|
|
1072
|
+
return this.request(`/api/users/${userId}/shop`);
|
|
1073
|
+
}
|
|
1074
|
+
async getManagedUserShop(userId) {
|
|
1075
|
+
return this.request(`/api/users/${userId}/shop/manage`);
|
|
1076
|
+
}
|
|
1077
|
+
async upsertManagedUserShop(userId, data) {
|
|
1078
|
+
return this.request(`/api/users/${userId}/shop/manage`, {
|
|
1079
|
+
method: "POST",
|
|
1080
|
+
body: JSON.stringify(data)
|
|
1081
|
+
});
|
|
1082
|
+
}
|
|
1083
|
+
async getShopById(shopId) {
|
|
1084
|
+
return this.request(`/api/shops/${shopId}`);
|
|
1085
|
+
}
|
|
1086
|
+
async listShopProducts(shopId, params) {
|
|
1087
|
+
const qs = new URLSearchParams();
|
|
1088
|
+
if (params?.keyword) qs.set("keyword", params.keyword);
|
|
1089
|
+
if (params?.limit) qs.set("limit", String(params.limit));
|
|
1090
|
+
if (params?.offset) qs.set("offset", String(params.offset));
|
|
1091
|
+
return this.request(`/api/shops/${shopId}/products?${qs}`);
|
|
1092
|
+
}
|
|
1093
|
+
async getScopeNeutralProduct(productId) {
|
|
1094
|
+
return this.request(`/api/products/${productId}`);
|
|
1095
|
+
}
|
|
1096
|
+
async getShopProduct(shopId, productId) {
|
|
1097
|
+
return this.request(`/api/shops/${shopId}/products/${productId}`);
|
|
1098
|
+
}
|
|
1099
|
+
async createShopProduct(shopId, data) {
|
|
1100
|
+
return this.request(`/api/shops/${shopId}/products`, {
|
|
1101
|
+
method: "POST",
|
|
1102
|
+
body: JSON.stringify(data)
|
|
1103
|
+
});
|
|
1104
|
+
}
|
|
1105
|
+
async updateShopProduct(shopId, productId, data) {
|
|
1106
|
+
return this.request(`/api/shops/${shopId}/products/${productId}`, {
|
|
1107
|
+
method: "PUT",
|
|
1108
|
+
body: JSON.stringify(data)
|
|
1109
|
+
});
|
|
1110
|
+
}
|
|
1111
|
+
async deleteShopProduct(shopId, productId) {
|
|
1112
|
+
return this.request(`/api/shops/${shopId}/products/${productId}`, { method: "DELETE" });
|
|
1113
|
+
}
|
|
1114
|
+
async purchaseShopProduct(shopId, productId, data) {
|
|
1115
|
+
return this.request(`/api/shops/${shopId}/products/${productId}/purchase`, {
|
|
1116
|
+
method: "POST",
|
|
1117
|
+
body: JSON.stringify(data)
|
|
1118
|
+
});
|
|
1119
|
+
}
|
|
1120
|
+
async purchaseCommerceOffer(offerId, data) {
|
|
1121
|
+
return this.request(`/api/commerce/offers/${offerId}/purchase`, {
|
|
1122
|
+
method: "POST",
|
|
1123
|
+
body: JSON.stringify(data)
|
|
1124
|
+
});
|
|
1125
|
+
}
|
|
1126
|
+
async getCommerceOfferCheckoutPreview(offerId, params) {
|
|
1127
|
+
const qs = new URLSearchParams();
|
|
1128
|
+
if (params?.skuId) qs.set("skuId", params.skuId);
|
|
1129
|
+
if (params?.viewerUserId) qs.set("viewerUserId", params.viewerUserId);
|
|
1130
|
+
const suffix = qs.toString() ? `?${qs}` : "";
|
|
1131
|
+
return this.request(`/api/commerce/offers/${offerId}/checkout-preview${suffix}`);
|
|
1132
|
+
}
|
|
1133
|
+
async createCommerceOffer(shopId, data) {
|
|
1134
|
+
return this.request(`/api/shops/${shopId}/offers`, {
|
|
1135
|
+
method: "POST",
|
|
1136
|
+
body: JSON.stringify(data)
|
|
1137
|
+
});
|
|
1138
|
+
}
|
|
1139
|
+
async listCommerceOffers(shopId, params) {
|
|
1140
|
+
const qs = new URLSearchParams();
|
|
1141
|
+
if (params?.keyword) qs.set("keyword", params.keyword);
|
|
1142
|
+
if (params?.limit) qs.set("limit", String(params.limit));
|
|
1143
|
+
return this.request(`/api/shops/${shopId}/offers?${qs}`);
|
|
1144
|
+
}
|
|
1145
|
+
async createCommerceDeliverable(shopId, offerId, data) {
|
|
1146
|
+
return this.request(`/api/shops/${shopId}/offers/${offerId}/deliverables`, {
|
|
1147
|
+
method: "POST",
|
|
1148
|
+
body: JSON.stringify(data)
|
|
1149
|
+
});
|
|
1150
|
+
}
|
|
1151
|
+
async listShopAssetDefinitions(shopId) {
|
|
1152
|
+
return this.request(`/api/shops/${shopId}/assets`);
|
|
1153
|
+
}
|
|
1154
|
+
async createShopAssetDefinition(shopId, data) {
|
|
1155
|
+
return this.request(`/api/shops/${shopId}/assets`, {
|
|
1156
|
+
method: "POST",
|
|
1157
|
+
body: JSON.stringify(data)
|
|
1158
|
+
});
|
|
1159
|
+
}
|
|
1160
|
+
async updateShopAssetDefinition(shopId, assetDefinitionId, data) {
|
|
1161
|
+
return this.request(`/api/shops/${shopId}/assets/${assetDefinitionId}`, {
|
|
1162
|
+
method: "PATCH",
|
|
1163
|
+
body: JSON.stringify(data)
|
|
1164
|
+
});
|
|
1165
|
+
}
|
|
1166
|
+
async purchaseMessageCommerceCard(messageId, cardId, data) {
|
|
1167
|
+
return this.request(`/api/messages/${messageId}/commerce-cards/${cardId}/purchase`, {
|
|
1168
|
+
method: "POST",
|
|
1169
|
+
body: JSON.stringify(data)
|
|
1170
|
+
});
|
|
1171
|
+
}
|
|
1172
|
+
async listCommerceProductCards(params) {
|
|
1173
|
+
const qs = new URLSearchParams();
|
|
1174
|
+
qs.set("target", params.target);
|
|
1175
|
+
qs.set("channelId", params.channelId);
|
|
1176
|
+
if (params.keyword) qs.set("keyword", params.keyword);
|
|
1177
|
+
if (params.limit) qs.set("limit", String(params.limit));
|
|
1178
|
+
return this.request(`/api/commerce/product-picker?${qs}`);
|
|
1179
|
+
}
|
|
1180
|
+
async openPaidFile(fileId) {
|
|
1181
|
+
return this.request(`/api/paid-files/${fileId}/open`, { method: "POST" });
|
|
1182
|
+
}
|
|
1183
|
+
async listShopEntitlements(shopId, params) {
|
|
1184
|
+
const qs = new URLSearchParams();
|
|
1185
|
+
if (params?.limit) qs.set("limit", String(params.limit));
|
|
1186
|
+
if (params?.offset) qs.set("offset", String(params.offset));
|
|
1187
|
+
return this.request(`/api/shops/${shopId}/entitlements?${qs}`);
|
|
1188
|
+
}
|
|
818
1189
|
async updateShop(serverId, data) {
|
|
819
1190
|
return this.request(`/api/servers/${serverId}/shop`, {
|
|
820
1191
|
method: "PUT",
|
|
@@ -889,7 +1260,7 @@ var ShadowClient = class {
|
|
|
889
1260
|
async createOrder(serverId, data) {
|
|
890
1261
|
return this.request(`/api/servers/${serverId}/shop/orders`, {
|
|
891
1262
|
method: "POST",
|
|
892
|
-
body: JSON.stringify(data
|
|
1263
|
+
body: JSON.stringify(data)
|
|
893
1264
|
});
|
|
894
1265
|
}
|
|
895
1266
|
async listOrders(serverId) {
|
|
@@ -930,18 +1301,232 @@ var ShadowClient = class {
|
|
|
930
1301
|
async getWallet() {
|
|
931
1302
|
return this.request("/api/wallet");
|
|
932
1303
|
}
|
|
933
|
-
async topUpWallet(
|
|
934
|
-
|
|
1304
|
+
async topUpWallet(_amount) {
|
|
1305
|
+
throw new Error(
|
|
1306
|
+
"Public wallet top-up is disabled. Use a verified payment flow, refund, settlement, or admin grant."
|
|
1307
|
+
);
|
|
1308
|
+
}
|
|
1309
|
+
async getWalletTransactions(params) {
|
|
1310
|
+
const qs = new URLSearchParams();
|
|
1311
|
+
if (params?.audience) qs.set("audience", params.audience);
|
|
1312
|
+
if (params?.direction) qs.set("direction", params.direction);
|
|
1313
|
+
if (params?.limit != null) qs.set("limit", String(params.limit));
|
|
1314
|
+
if (params?.offset != null) qs.set("offset", String(params.offset));
|
|
1315
|
+
const suffix = qs.toString() ? `?${qs}` : "";
|
|
1316
|
+
return this.request(`/api/wallet/transactions${suffix}`);
|
|
1317
|
+
}
|
|
1318
|
+
// ── Community Economy ────────────────────────────────────────────────
|
|
1319
|
+
async listCommunityAssets() {
|
|
1320
|
+
return this.request("/api/economy/assets");
|
|
1321
|
+
}
|
|
1322
|
+
async getCommunityAsset(grantId) {
|
|
1323
|
+
return this.request(`/api/economy/assets/${grantId}`);
|
|
1324
|
+
}
|
|
1325
|
+
async consumeCommunityAsset(grantId, data) {
|
|
1326
|
+
return this.request(`/api/economy/assets/${grantId}/consume`, {
|
|
1327
|
+
method: "POST",
|
|
1328
|
+
body: JSON.stringify(data)
|
|
1329
|
+
});
|
|
1330
|
+
}
|
|
1331
|
+
async lockCommunityAsset(grantId, data) {
|
|
1332
|
+
return this.request(`/api/economy/assets/${grantId}/lock`, {
|
|
1333
|
+
method: "POST",
|
|
1334
|
+
body: JSON.stringify(data)
|
|
1335
|
+
});
|
|
1336
|
+
}
|
|
1337
|
+
async unlockCommunityAsset(grantId, data) {
|
|
1338
|
+
return this.request(`/api/economy/assets/${grantId}/unlock`, {
|
|
1339
|
+
method: "POST",
|
|
1340
|
+
body: JSON.stringify(data)
|
|
1341
|
+
});
|
|
1342
|
+
}
|
|
1343
|
+
async revokeCommunityAsset(grantId, data) {
|
|
1344
|
+
return this.request(`/api/economy/assets/${grantId}/revoke`, {
|
|
1345
|
+
method: "POST",
|
|
1346
|
+
body: JSON.stringify(data)
|
|
1347
|
+
});
|
|
1348
|
+
}
|
|
1349
|
+
async sendTip(data) {
|
|
1350
|
+
return this.request("/api/economy/tips", {
|
|
1351
|
+
method: "POST",
|
|
1352
|
+
body: JSON.stringify(data)
|
|
1353
|
+
});
|
|
1354
|
+
}
|
|
1355
|
+
async listTips() {
|
|
1356
|
+
return this.request("/api/economy/tips");
|
|
1357
|
+
}
|
|
1358
|
+
async sendGift(data) {
|
|
1359
|
+
return this.request("/api/economy/gifts", {
|
|
1360
|
+
method: "POST",
|
|
1361
|
+
body: JSON.stringify(data)
|
|
1362
|
+
});
|
|
1363
|
+
}
|
|
1364
|
+
async listGifts() {
|
|
1365
|
+
return this.request("/api/economy/gifts");
|
|
1366
|
+
}
|
|
1367
|
+
async listSettlements(params) {
|
|
1368
|
+
const qs = new URLSearchParams();
|
|
1369
|
+
if (params?.limit != null) qs.set("limit", String(params.limit));
|
|
1370
|
+
if (params?.offset != null) qs.set("offset", String(params.offset));
|
|
1371
|
+
const suffix = qs.toString() ? `?${qs}` : "";
|
|
1372
|
+
return this.request(`/api/economy/settlements${suffix}`);
|
|
1373
|
+
}
|
|
1374
|
+
async settleAvailableSettlements() {
|
|
1375
|
+
return this.request("/api/economy/settlements/settle", { method: "POST" });
|
|
1376
|
+
}
|
|
1377
|
+
// ── Cloud SaaS DIY Generation ───────────────────────────────────────
|
|
1378
|
+
async createDiyCloudRun(data) {
|
|
1379
|
+
return this.request("/api/cloud-saas/diy/runs", {
|
|
1380
|
+
method: "POST",
|
|
1381
|
+
body: JSON.stringify(data)
|
|
1382
|
+
});
|
|
1383
|
+
}
|
|
1384
|
+
async getDiyCloudRun(runId) {
|
|
1385
|
+
return this.request(`/api/cloud-saas/diy/runs/${encodeURIComponent(runId)}`);
|
|
1386
|
+
}
|
|
1387
|
+
async createDiyCloudFeedbackRun(runId, data) {
|
|
1388
|
+
return this.request(`/api/cloud-saas/diy/runs/${encodeURIComponent(runId)}/feedback`, {
|
|
1389
|
+
method: "POST",
|
|
1390
|
+
body: JSON.stringify(data)
|
|
1391
|
+
});
|
|
1392
|
+
}
|
|
1393
|
+
async streamDiyCloudRun(runId, options = {}) {
|
|
1394
|
+
const qs = new URLSearchParams();
|
|
1395
|
+
if (options.afterSeq != null) qs.set("afterSeq", String(options.afterSeq));
|
|
1396
|
+
const suffix = qs.toString() ? `?${qs}` : "";
|
|
1397
|
+
return this.requestRaw(
|
|
1398
|
+
`/api/cloud-saas/diy/runs/${encodeURIComponent(runId)}/stream${suffix}`,
|
|
1399
|
+
{
|
|
1400
|
+
headers: { Accept: "text/event-stream" }
|
|
1401
|
+
}
|
|
1402
|
+
);
|
|
1403
|
+
}
|
|
1404
|
+
async cancelDiyCloudRun(runId) {
|
|
1405
|
+
return this.request(`/api/cloud-saas/diy/runs/${encodeURIComponent(runId)}/cancel`, {
|
|
1406
|
+
method: "POST"
|
|
1407
|
+
});
|
|
1408
|
+
}
|
|
1409
|
+
// ── Cloud SaaS Deployment Runtime ──────────────────────────────────
|
|
1410
|
+
async getCloudDeploymentManifest(deploymentId) {
|
|
1411
|
+
return this.request(`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/manifest`);
|
|
1412
|
+
}
|
|
1413
|
+
async syncCloudDeploymentTemplate(deploymentId, data = {}) {
|
|
1414
|
+
return this.request(
|
|
1415
|
+
`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/template`,
|
|
1416
|
+
{
|
|
1417
|
+
method: "POST",
|
|
1418
|
+
body: JSON.stringify(data)
|
|
1419
|
+
}
|
|
1420
|
+
);
|
|
1421
|
+
}
|
|
1422
|
+
async redeployCloudDeployment(deploymentId, data = {}) {
|
|
1423
|
+
return this.request(
|
|
1424
|
+
`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/redeploy`,
|
|
1425
|
+
{
|
|
1426
|
+
method: "POST",
|
|
1427
|
+
body: JSON.stringify(data)
|
|
1428
|
+
}
|
|
1429
|
+
);
|
|
1430
|
+
}
|
|
1431
|
+
async pauseCloudDeployment(deploymentId, data = {}) {
|
|
1432
|
+
return this.request(`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/pause`, {
|
|
1433
|
+
method: "POST",
|
|
1434
|
+
body: JSON.stringify(data)
|
|
1435
|
+
});
|
|
1436
|
+
}
|
|
1437
|
+
async resumeCloudDeployment(deploymentId, data = {}) {
|
|
1438
|
+
return this.request(`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/resume`, {
|
|
1439
|
+
method: "POST",
|
|
1440
|
+
body: JSON.stringify(data)
|
|
1441
|
+
});
|
|
1442
|
+
}
|
|
1443
|
+
async listCloudDeploymentBackups(deploymentId, params = {}) {
|
|
1444
|
+
const qs = new URLSearchParams();
|
|
1445
|
+
if (params.agentId) qs.set("agentId", params.agentId);
|
|
1446
|
+
const suffix = qs.toString() ? `?${qs}` : "";
|
|
1447
|
+
return this.request(
|
|
1448
|
+
`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/backups${suffix}`
|
|
1449
|
+
);
|
|
1450
|
+
}
|
|
1451
|
+
async createCloudDeploymentBackup(deploymentId, data = {}) {
|
|
1452
|
+
return this.request(`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/backups`, {
|
|
935
1453
|
method: "POST",
|
|
936
|
-
body: JSON.stringify(
|
|
1454
|
+
body: JSON.stringify(data)
|
|
1455
|
+
});
|
|
1456
|
+
}
|
|
1457
|
+
async restoreCloudDeploymentBackup(deploymentId, data = {}) {
|
|
1458
|
+
return this.request(`/api/cloud-saas/deployments/${encodeURIComponent(deploymentId)}/restore`, {
|
|
1459
|
+
method: "POST",
|
|
1460
|
+
body: JSON.stringify(data)
|
|
937
1461
|
});
|
|
938
1462
|
}
|
|
939
|
-
|
|
940
|
-
|
|
1463
|
+
// ── Cloud SaaS Provider Gateway ─────────────────────────────────────
|
|
1464
|
+
async listCloudProviderCatalogs() {
|
|
1465
|
+
return this.request("/api/cloud-saas/provider-catalogs");
|
|
1466
|
+
}
|
|
1467
|
+
async listCloudProviderProfiles() {
|
|
1468
|
+
return this.request("/api/cloud-saas/provider-profiles");
|
|
1469
|
+
}
|
|
1470
|
+
async upsertCloudProviderProfile(data) {
|
|
1471
|
+
return this.request("/api/cloud-saas/provider-profiles", {
|
|
1472
|
+
method: "PUT",
|
|
1473
|
+
body: JSON.stringify(data)
|
|
1474
|
+
});
|
|
1475
|
+
}
|
|
1476
|
+
async testCloudProviderProfile(profileId) {
|
|
1477
|
+
return this.request(`/api/cloud-saas/provider-profiles/${encodeURIComponent(profileId)}/test`, {
|
|
1478
|
+
method: "POST"
|
|
1479
|
+
});
|
|
1480
|
+
}
|
|
1481
|
+
async refreshCloudProviderProfileModels(profileId) {
|
|
1482
|
+
return this.request(
|
|
1483
|
+
`/api/cloud-saas/provider-profiles/${encodeURIComponent(profileId)}/models/refresh`,
|
|
1484
|
+
{ method: "POST" }
|
|
1485
|
+
);
|
|
1486
|
+
}
|
|
1487
|
+
async deleteCloudProviderProfile(profileId) {
|
|
1488
|
+
return this.request(`/api/cloud-saas/provider-profiles/${encodeURIComponent(profileId)}`, {
|
|
1489
|
+
method: "DELETE"
|
|
1490
|
+
});
|
|
1491
|
+
}
|
|
1492
|
+
// ── Recharge (Stripe) ───────────────────────────────────────────────
|
|
1493
|
+
async getRechargeConfig() {
|
|
1494
|
+
return this.request("/api/v1/recharge/config");
|
|
1495
|
+
}
|
|
1496
|
+
async createRechargeIntent(params) {
|
|
1497
|
+
return this.request("/api/v1/recharge/create-intent", {
|
|
1498
|
+
method: "POST",
|
|
1499
|
+
body: JSON.stringify(params)
|
|
1500
|
+
});
|
|
1501
|
+
}
|
|
1502
|
+
async getRechargeHistory(params) {
|
|
1503
|
+
const qs = new URLSearchParams();
|
|
1504
|
+
if (params?.limit) qs.set("limit", String(params.limit));
|
|
1505
|
+
if (params?.offset) qs.set("offset", String(params.offset));
|
|
1506
|
+
const query = qs.toString();
|
|
1507
|
+
return this.request(`/api/v1/recharge/history${query ? `?${query}` : ""}`);
|
|
1508
|
+
}
|
|
1509
|
+
async confirmRechargePayment(paymentIntentId) {
|
|
1510
|
+
return this.request("/api/v1/recharge/confirm", {
|
|
1511
|
+
method: "POST",
|
|
1512
|
+
body: JSON.stringify({ paymentIntentId })
|
|
1513
|
+
});
|
|
941
1514
|
}
|
|
942
1515
|
async getEntitlements(serverId) {
|
|
943
1516
|
return this.request(`/api/servers/${serverId}/shop/entitlements`);
|
|
944
1517
|
}
|
|
1518
|
+
async getAllEntitlements() {
|
|
1519
|
+
return this.request("/api/entitlements");
|
|
1520
|
+
}
|
|
1521
|
+
async verifyEntitlement(entitlementId) {
|
|
1522
|
+
return this.request(`/api/entitlements/${entitlementId}/verify`);
|
|
1523
|
+
}
|
|
1524
|
+
async cancelEntitlement(entitlementId, reason) {
|
|
1525
|
+
return this.request(`/api/entitlements/${entitlementId}/cancel`, {
|
|
1526
|
+
method: "POST",
|
|
1527
|
+
body: JSON.stringify({ reason })
|
|
1528
|
+
});
|
|
1529
|
+
}
|
|
945
1530
|
// ── Task Center ───────────────────────────────────────────────────────
|
|
946
1531
|
async getTaskCenter() {
|
|
947
1532
|
return this.request("/api/tasks");
|
|
@@ -955,41 +1540,126 @@ var ShadowClient = class {
|
|
|
955
1540
|
async getRewardHistory() {
|
|
956
1541
|
return this.request("/api/tasks/rewards");
|
|
957
1542
|
}
|
|
958
|
-
// ──
|
|
959
|
-
async
|
|
1543
|
+
// ── API Tokens ────────────────────────────────────────────────────────
|
|
1544
|
+
async createApiToken(data) {
|
|
1545
|
+
return this.request("/api/tokens", {
|
|
1546
|
+
method: "POST",
|
|
1547
|
+
body: JSON.stringify(data)
|
|
1548
|
+
});
|
|
1549
|
+
}
|
|
1550
|
+
async listApiTokens() {
|
|
1551
|
+
return this.request("/api/tokens");
|
|
1552
|
+
}
|
|
1553
|
+
async deleteApiToken(tokenId) {
|
|
1554
|
+
return this.request(`/api/tokens/${tokenId}`, { method: "DELETE" });
|
|
1555
|
+
}
|
|
1556
|
+
// ── Discover ──────────────────────────────────────────────────────────
|
|
1557
|
+
async discoverFeed(params) {
|
|
960
1558
|
const qs = new URLSearchParams();
|
|
961
|
-
if (params?.
|
|
1559
|
+
if (params?.type) qs.set("type", params.type);
|
|
962
1560
|
if (params?.limit) qs.set("limit", String(params.limit));
|
|
963
1561
|
if (params?.offset) qs.set("offset", String(params.offset));
|
|
964
|
-
return this.request(`/api/
|
|
1562
|
+
return this.request(`/api/discover/feed?${qs}`);
|
|
965
1563
|
}
|
|
966
|
-
async
|
|
967
|
-
|
|
1564
|
+
async discoverSearch(params) {
|
|
1565
|
+
const qs = new URLSearchParams({ q: params.q });
|
|
1566
|
+
if (params?.type) qs.set("type", params.type);
|
|
1567
|
+
if (params?.limit) qs.set("limit", String(params.limit));
|
|
1568
|
+
return this.request(`/api/discover/search?${qs}`);
|
|
968
1569
|
}
|
|
969
|
-
|
|
970
|
-
|
|
1570
|
+
// ── Voice Enhance ─────────────────────────────────────────────────────
|
|
1571
|
+
async enhanceVoice(data) {
|
|
1572
|
+
return this.request("/api/voice/enhance", {
|
|
1573
|
+
method: "POST",
|
|
1574
|
+
body: JSON.stringify(data)
|
|
1575
|
+
});
|
|
971
1576
|
}
|
|
972
|
-
async
|
|
973
|
-
|
|
1577
|
+
async enhanceVoiceQuery(params) {
|
|
1578
|
+
const qs = new URLSearchParams({ transcript: params.transcript });
|
|
1579
|
+
if (params.language) qs.set("language", params.language);
|
|
1580
|
+
if (params.enableSelfCorrection !== void 0)
|
|
1581
|
+
qs.set("enableSelfCorrection", String(params.enableSelfCorrection));
|
|
1582
|
+
if (params.enableListFormatting !== void 0)
|
|
1583
|
+
qs.set("enableListFormatting", String(params.enableListFormatting));
|
|
1584
|
+
if (params.enableFillerRemoval !== void 0)
|
|
1585
|
+
qs.set("enableFillerRemoval", String(params.enableFillerRemoval));
|
|
1586
|
+
if (params.enableToneAdjustment !== void 0)
|
|
1587
|
+
qs.set("enableToneAdjustment", String(params.enableToneAdjustment));
|
|
1588
|
+
if (params.targetTone) qs.set("targetTone", params.targetTone);
|
|
1589
|
+
return this.request(`/api/voice/enhance?${qs}`);
|
|
1590
|
+
}
|
|
1591
|
+
async getVoiceConfig() {
|
|
1592
|
+
return this.request("/api/voice/config");
|
|
1593
|
+
}
|
|
1594
|
+
async updateVoiceConfig(data) {
|
|
1595
|
+
return this.request("/api/voice/config", {
|
|
974
1596
|
method: "POST",
|
|
975
1597
|
body: JSON.stringify(data)
|
|
976
1598
|
});
|
|
977
1599
|
}
|
|
978
|
-
async
|
|
979
|
-
return this.request(
|
|
980
|
-
|
|
1600
|
+
async voiceHealthCheck() {
|
|
1601
|
+
return this.request("/api/voice/health");
|
|
1602
|
+
}
|
|
1603
|
+
// ── Profile Comments ──────────────────────────────────────────────────
|
|
1604
|
+
async getProfileComments(profileUserId, params) {
|
|
1605
|
+
const qs = new URLSearchParams();
|
|
1606
|
+
if (params?.limit) qs.set("limit", String(params.limit));
|
|
1607
|
+
if (params?.offset) qs.set("offset", String(params.offset));
|
|
1608
|
+
return this.request(`/api/profile-comments/${profileUserId}?${qs}`);
|
|
1609
|
+
}
|
|
1610
|
+
async getProfileCommentStats(profileUserId) {
|
|
1611
|
+
return this.request(`/api/profile-comments/${profileUserId}/stats`);
|
|
1612
|
+
}
|
|
1613
|
+
async getCommentReplies(parentId, params) {
|
|
1614
|
+
const qs = new URLSearchParams();
|
|
1615
|
+
if (params?.limit) qs.set("limit", String(params.limit));
|
|
1616
|
+
if (params?.offset) qs.set("offset", String(params.offset));
|
|
1617
|
+
return this.request(`/api/profile-comments/replies/${parentId}?${qs}`);
|
|
1618
|
+
}
|
|
1619
|
+
async createProfileComment(data) {
|
|
1620
|
+
return this.request("/api/profile-comments", {
|
|
1621
|
+
method: "POST",
|
|
981
1622
|
body: JSON.stringify(data)
|
|
982
1623
|
});
|
|
983
1624
|
}
|
|
984
|
-
async
|
|
985
|
-
return this.request(`/api/
|
|
1625
|
+
async deleteProfileComment(commentId) {
|
|
1626
|
+
return this.request(`/api/profile-comments/${commentId}`, { method: "DELETE" });
|
|
986
1627
|
}
|
|
987
|
-
async
|
|
988
|
-
return this.request(`/api/
|
|
1628
|
+
async addProfileCommentReaction(commentId, emoji) {
|
|
1629
|
+
return this.request(`/api/profile-comments/${commentId}/reactions`, {
|
|
1630
|
+
method: "POST",
|
|
1631
|
+
body: JSON.stringify({ emoji })
|
|
1632
|
+
});
|
|
1633
|
+
}
|
|
1634
|
+
async removeProfileCommentReaction(commentId, emoji) {
|
|
1635
|
+
return this.request(`/api/profile-comments/${commentId}/reactions`, {
|
|
1636
|
+
method: "DELETE",
|
|
1637
|
+
body: JSON.stringify({ emoji })
|
|
1638
|
+
});
|
|
1639
|
+
}
|
|
1640
|
+
// ── Agent Dashboard ───────────────────────────────────────────────────
|
|
1641
|
+
async getAgentDashboard(agentId) {
|
|
1642
|
+
return this.request(`/api/agents/${agentId}/dashboard`);
|
|
1643
|
+
}
|
|
1644
|
+
async addAgentDashboardEvent(agentId, data) {
|
|
1645
|
+
return this.request(`/api/agents/${agentId}/dashboard/events`, {
|
|
989
1646
|
method: "POST",
|
|
990
1647
|
body: JSON.stringify(data)
|
|
991
1648
|
});
|
|
992
1649
|
}
|
|
1650
|
+
// ── Channel Archive ───────────────────────────────────────────────────
|
|
1651
|
+
async archiveChannel(channelId, reason) {
|
|
1652
|
+
return this.request(`/api/channels/${channelId}/archive`, {
|
|
1653
|
+
method: "POST",
|
|
1654
|
+
body: JSON.stringify(reason ? { reason } : {})
|
|
1655
|
+
});
|
|
1656
|
+
}
|
|
1657
|
+
async unarchiveChannel(channelId) {
|
|
1658
|
+
return this.request(`/api/channels/${channelId}/unarchive`, { method: "POST" });
|
|
1659
|
+
}
|
|
1660
|
+
async getArchivedChannels(serverId) {
|
|
1661
|
+
return this.request(`/api/servers/${serverId}/channels/archived`);
|
|
1662
|
+
}
|
|
993
1663
|
};
|
|
994
1664
|
|
|
995
1665
|
// src/constants.ts
|
|
@@ -1111,9 +1781,9 @@ var ShadowSocket = class {
|
|
|
1111
1781
|
sendMessage(data) {
|
|
1112
1782
|
this.socket.emit("message:send", data);
|
|
1113
1783
|
}
|
|
1114
|
-
/** Send a typing indicator */
|
|
1115
|
-
sendTyping(channelId) {
|
|
1116
|
-
this.socket.emit("message:typing", { channelId });
|
|
1784
|
+
/** Send or clear a typing indicator */
|
|
1785
|
+
sendTyping(channelId, typing = true) {
|
|
1786
|
+
this.socket.emit("message:typing", { channelId, typing });
|
|
1117
1787
|
}
|
|
1118
1788
|
/** Update user presence status */
|
|
1119
1789
|
updatePresence(status) {
|
|
@@ -1123,23 +1793,6 @@ var ShadowSocket = class {
|
|
|
1123
1793
|
updateActivity(channelId, activity) {
|
|
1124
1794
|
this.socket.emit("presence:activity", { channelId, activity });
|
|
1125
1795
|
}
|
|
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
1796
|
};
|
|
1144
1797
|
export {
|
|
1145
1798
|
CLIENT_EVENTS,
|