@shadowob/sdk 0.2.1 → 0.2.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/LICENSE +661 -0
- package/package.json +2 -2
- package/src/client.ts +619 -17
- package/src/index.ts +17 -0
- package/src/socket.ts +23 -1
- package/src/types.ts +186 -0
package/src/client.ts
CHANGED
|
@@ -1,14 +1,31 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
ShadowApp,
|
|
3
|
+
ShadowCartItem,
|
|
4
|
+
ShadowCategory,
|
|
2
5
|
ShadowChannel,
|
|
6
|
+
ShadowContract,
|
|
3
7
|
ShadowDmChannel,
|
|
8
|
+
ShadowFriendship,
|
|
4
9
|
ShadowInviteCode,
|
|
10
|
+
ShadowListing,
|
|
5
11
|
ShadowMember,
|
|
6
12
|
ShadowMessage,
|
|
7
13
|
ShadowNotification,
|
|
14
|
+
ShadowNotificationPreferences,
|
|
15
|
+
ShadowOAuthApp,
|
|
16
|
+
ShadowOAuthConsent,
|
|
17
|
+
ShadowOAuthToken,
|
|
18
|
+
ShadowOrder,
|
|
19
|
+
ShadowProduct,
|
|
8
20
|
ShadowRemoteConfig,
|
|
21
|
+
ShadowReview,
|
|
9
22
|
ShadowServer,
|
|
23
|
+
ShadowShop,
|
|
24
|
+
ShadowTask,
|
|
10
25
|
ShadowThread,
|
|
26
|
+
ShadowTransaction,
|
|
11
27
|
ShadowUser,
|
|
28
|
+
ShadowWallet,
|
|
12
29
|
} from './types'
|
|
13
30
|
|
|
14
31
|
/**
|
|
@@ -328,14 +345,18 @@ export class ShadowClient {
|
|
|
328
345
|
serverId: string,
|
|
329
346
|
data: { name: string; type?: string; description?: string },
|
|
330
347
|
): Promise<ShadowChannel> {
|
|
331
|
-
|
|
348
|
+
const { description, ...rest } = data
|
|
349
|
+
const body = { ...rest, ...(description !== undefined ? { topic: description } : {}) }
|
|
350
|
+
const ch = await this.request<Record<string, unknown>>(`/api/servers/${serverId}/channels`, {
|
|
332
351
|
method: 'POST',
|
|
333
|
-
body: JSON.stringify(
|
|
352
|
+
body: JSON.stringify(body),
|
|
334
353
|
})
|
|
354
|
+
return { ...ch, description: ch.topic } as unknown as ShadowChannel
|
|
335
355
|
}
|
|
336
356
|
|
|
337
357
|
async getChannel(channelId: string): Promise<ShadowChannel> {
|
|
338
|
-
|
|
358
|
+
const ch = await this.request<Record<string, unknown>>(`/api/channels/${channelId}`)
|
|
359
|
+
return { ...ch, description: ch.topic } as unknown as ShadowChannel
|
|
339
360
|
}
|
|
340
361
|
|
|
341
362
|
async getChannelMembers(channelId: string): Promise<ShadowMember[]> {
|
|
@@ -346,10 +367,13 @@ export class ShadowClient {
|
|
|
346
367
|
channelId: string,
|
|
347
368
|
data: { name?: string; description?: string | null },
|
|
348
369
|
): Promise<ShadowChannel> {
|
|
349
|
-
|
|
370
|
+
const { description, ...rest } = data
|
|
371
|
+
const body = { ...rest, ...(description !== undefined ? { topic: description } : {}) }
|
|
372
|
+
const ch = await this.request<Record<string, unknown>>(`/api/channels/${channelId}`, {
|
|
350
373
|
method: 'PATCH',
|
|
351
|
-
body: JSON.stringify(
|
|
374
|
+
body: JSON.stringify(body),
|
|
352
375
|
})
|
|
376
|
+
return { ...ch, description: ch.topic } as unknown as ShadowChannel
|
|
353
377
|
}
|
|
354
378
|
|
|
355
379
|
async deleteChannel(channelId: string): Promise<{ success: boolean }> {
|
|
@@ -440,11 +464,17 @@ export class ShadowClient {
|
|
|
440
464
|
|
|
441
465
|
// ── Pins ──────────────────────────────────────────────────────────────
|
|
442
466
|
|
|
443
|
-
async pinMessage(messageId: string): Promise<{ success: boolean }> {
|
|
467
|
+
async pinMessage(messageId: string, channelId?: string): Promise<{ success: boolean }> {
|
|
468
|
+
if (channelId) {
|
|
469
|
+
return this.request(`/api/channels/${channelId}/pins/${messageId}`, { method: 'PUT' })
|
|
470
|
+
}
|
|
444
471
|
return this.request(`/api/messages/${messageId}/pin`, { method: 'POST' })
|
|
445
472
|
}
|
|
446
473
|
|
|
447
|
-
async unpinMessage(messageId: string): Promise<{ success: boolean }> {
|
|
474
|
+
async unpinMessage(messageId: string, channelId?: string): Promise<{ success: boolean }> {
|
|
475
|
+
if (channelId) {
|
|
476
|
+
return this.request(`/api/channels/${channelId}/pins/${messageId}`, { method: 'DELETE' })
|
|
477
|
+
}
|
|
448
478
|
return this.request(`/api/messages/${messageId}/pin`, { method: 'DELETE' })
|
|
449
479
|
}
|
|
450
480
|
|
|
@@ -537,10 +567,14 @@ export class ShadowClient {
|
|
|
537
567
|
return this.request(`/api/dm/channels/${channelId}/messages?${params}`)
|
|
538
568
|
}
|
|
539
569
|
|
|
540
|
-
async sendDmMessage(
|
|
570
|
+
async sendDmMessage(
|
|
571
|
+
channelId: string,
|
|
572
|
+
content: string,
|
|
573
|
+
options?: { replyToId?: string },
|
|
574
|
+
): Promise<ShadowMessage> {
|
|
541
575
|
return this.request(`/api/dm/channels/${channelId}/messages`, {
|
|
542
576
|
method: 'POST',
|
|
543
|
-
body: JSON.stringify({ content }),
|
|
577
|
+
body: JSON.stringify({ content, replyToId: options?.replyToId }),
|
|
544
578
|
})
|
|
545
579
|
}
|
|
546
580
|
|
|
@@ -556,7 +590,7 @@ export class ShadowClient {
|
|
|
556
590
|
}
|
|
557
591
|
|
|
558
592
|
async markAllNotificationsRead(): Promise<{ success: boolean }> {
|
|
559
|
-
return this.request('/api/notifications/read-all', { method: '
|
|
593
|
+
return this.request('/api/notifications/read-all', { method: 'POST' })
|
|
560
594
|
}
|
|
561
595
|
|
|
562
596
|
async getUnreadCount(): Promise<{ count: number }> {
|
|
@@ -573,34 +607,40 @@ export class ShadowClient {
|
|
|
573
607
|
limit?: number
|
|
574
608
|
offset?: number
|
|
575
609
|
}): Promise<{ messages: ShadowMessage[]; total: number }> {
|
|
576
|
-
const params = new URLSearchParams({
|
|
610
|
+
const params = new URLSearchParams({ query: query.q })
|
|
577
611
|
if (query.serverId) params.set('serverId', query.serverId)
|
|
578
612
|
if (query.channelId) params.set('channelId', query.channelId)
|
|
579
|
-
if (query.authorId) params.set('
|
|
613
|
+
if (query.authorId) params.set('from', query.authorId)
|
|
580
614
|
if (query.limit) params.set('limit', String(query.limit))
|
|
581
615
|
if (query.offset) params.set('offset', String(query.offset))
|
|
582
|
-
|
|
616
|
+
const result = await this.request<
|
|
617
|
+
ShadowMessage[] | { messages: ShadowMessage[]; total: number }
|
|
618
|
+
>(`/api/search/messages?${params}`)
|
|
619
|
+
if (Array.isArray(result)) {
|
|
620
|
+
return { messages: result, total: result.length }
|
|
621
|
+
}
|
|
622
|
+
return result
|
|
583
623
|
}
|
|
584
624
|
|
|
585
625
|
// ── Invites ───────────────────────────────────────────────────────────
|
|
586
626
|
|
|
587
627
|
async listInvites(): Promise<ShadowInviteCode[]> {
|
|
588
|
-
return this.request('/api/
|
|
628
|
+
return this.request('/api/invite-codes')
|
|
589
629
|
}
|
|
590
630
|
|
|
591
631
|
async createInvites(count: number, note?: string): Promise<ShadowInviteCode[]> {
|
|
592
|
-
return this.request('/api/
|
|
632
|
+
return this.request('/api/invite-codes', {
|
|
593
633
|
method: 'POST',
|
|
594
634
|
body: JSON.stringify({ count, ...(note ? { note } : {}) }),
|
|
595
635
|
})
|
|
596
636
|
}
|
|
597
637
|
|
|
598
638
|
async deactivateInvite(inviteId: string): Promise<ShadowInviteCode> {
|
|
599
|
-
return this.request(`/api/
|
|
639
|
+
return this.request(`/api/invite-codes/${inviteId}/deactivate`, { method: 'PATCH' })
|
|
600
640
|
}
|
|
601
641
|
|
|
602
642
|
async deleteInvite(inviteId: string): Promise<{ success: boolean }> {
|
|
603
|
-
return this.request(`/api/
|
|
643
|
+
return this.request(`/api/invite-codes/${inviteId}`, { method: 'DELETE' })
|
|
604
644
|
}
|
|
605
645
|
|
|
606
646
|
// ── Media ─────────────────────────────────────────────────────────────
|
|
@@ -965,4 +1005,566 @@ export class ShadowClient {
|
|
|
965
1005
|
)
|
|
966
1006
|
return res.arrayBuffer()
|
|
967
1007
|
}
|
|
1008
|
+
|
|
1009
|
+
// ── Auth (extended) ───────────────────────────────────────────────────
|
|
1010
|
+
|
|
1011
|
+
async getUserProfile(userId: string): Promise<ShadowUser> {
|
|
1012
|
+
return this.request(`/api/auth/users/${userId}`)
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
async listOAuthAccounts(): Promise<
|
|
1016
|
+
{ id: string; provider: string; providerAccountId: string }[]
|
|
1017
|
+
> {
|
|
1018
|
+
return this.request('/api/auth/oauth/accounts')
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
async unlinkOAuthAccount(accountId: string): Promise<{ success: boolean }> {
|
|
1022
|
+
return this.request(`/api/auth/oauth/accounts/${accountId}`, { method: 'DELETE' })
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
// ── Friendships ───────────────────────────────────────────────────────
|
|
1026
|
+
|
|
1027
|
+
async sendFriendRequest(username: string): Promise<ShadowFriendship> {
|
|
1028
|
+
return this.request('/api/friends/request', {
|
|
1029
|
+
method: 'POST',
|
|
1030
|
+
body: JSON.stringify({ username }),
|
|
1031
|
+
})
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
async acceptFriendRequest(requestId: string): Promise<ShadowFriendship> {
|
|
1035
|
+
return this.request(`/api/friends/${requestId}/accept`, { method: 'POST' })
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
async rejectFriendRequest(requestId: string): Promise<ShadowFriendship> {
|
|
1039
|
+
return this.request(`/api/friends/${requestId}/reject`, { method: 'POST' })
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
async removeFriend(friendshipId: string): Promise<{ success: boolean }> {
|
|
1043
|
+
return this.request(`/api/friends/${friendshipId}`, { method: 'DELETE' })
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
async listFriends(): Promise<ShadowFriendship[]> {
|
|
1047
|
+
return this.request('/api/friends')
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
async listPendingFriendRequests(): Promise<ShadowFriendship[]> {
|
|
1051
|
+
return this.request('/api/friends/pending')
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
async listSentFriendRequests(): Promise<ShadowFriendship[]> {
|
|
1055
|
+
return this.request('/api/friends/sent')
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
// ── Notifications (extended) ──────────────────────────────────────────
|
|
1059
|
+
|
|
1060
|
+
async markScopeRead(scope: {
|
|
1061
|
+
serverId?: string
|
|
1062
|
+
channelId?: string
|
|
1063
|
+
}): Promise<{ success: boolean }> {
|
|
1064
|
+
return this.request('/api/notifications/read-scope', {
|
|
1065
|
+
method: 'POST',
|
|
1066
|
+
body: JSON.stringify(scope),
|
|
1067
|
+
})
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
async getScopedUnread(): Promise<Record<string, number>> {
|
|
1071
|
+
return this.request('/api/notifications/scoped-unread')
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
async getNotificationPreferences(): Promise<ShadowNotificationPreferences> {
|
|
1075
|
+
return this.request('/api/notifications/preferences')
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
async updateNotificationPreferences(
|
|
1079
|
+
data: Partial<ShadowNotificationPreferences>,
|
|
1080
|
+
): Promise<ShadowNotificationPreferences> {
|
|
1081
|
+
return this.request('/api/notifications/preferences', {
|
|
1082
|
+
method: 'PATCH',
|
|
1083
|
+
body: JSON.stringify(data),
|
|
1084
|
+
})
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
// ── OAuth Apps ────────────────────────────────────────────────────────
|
|
1088
|
+
|
|
1089
|
+
async createOAuthApp(data: {
|
|
1090
|
+
name: string
|
|
1091
|
+
redirectUris: string[]
|
|
1092
|
+
scopes?: string[]
|
|
1093
|
+
}): Promise<ShadowOAuthApp> {
|
|
1094
|
+
return this.request('/api/oauth/apps', {
|
|
1095
|
+
method: 'POST',
|
|
1096
|
+
body: JSON.stringify(data),
|
|
1097
|
+
})
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
async listOAuthApps(): Promise<ShadowOAuthApp[]> {
|
|
1101
|
+
return this.request('/api/oauth/apps')
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
async updateOAuthApp(
|
|
1105
|
+
appId: string,
|
|
1106
|
+
data: { name?: string; redirectUris?: string[]; scopes?: string[] },
|
|
1107
|
+
): Promise<ShadowOAuthApp> {
|
|
1108
|
+
return this.request(`/api/oauth/apps/${appId}`, {
|
|
1109
|
+
method: 'PATCH',
|
|
1110
|
+
body: JSON.stringify(data),
|
|
1111
|
+
})
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
async deleteOAuthApp(appId: string): Promise<{ success: boolean }> {
|
|
1115
|
+
return this.request(`/api/oauth/apps/${appId}`, { method: 'DELETE' })
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
async resetOAuthAppSecret(appId: string): Promise<{ clientSecret: string }> {
|
|
1119
|
+
return this.request(`/api/oauth/apps/${appId}/reset-secret`, { method: 'POST' })
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
async getOAuthAuthorization(params: {
|
|
1123
|
+
client_id: string
|
|
1124
|
+
redirect_uri: string
|
|
1125
|
+
scope?: string
|
|
1126
|
+
state?: string
|
|
1127
|
+
}): Promise<{ app: ShadowOAuthApp }> {
|
|
1128
|
+
const qs = new URLSearchParams(params)
|
|
1129
|
+
return this.request(`/api/oauth/authorize?${qs}`)
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
async approveOAuthAuthorization(data: {
|
|
1133
|
+
client_id: string
|
|
1134
|
+
redirect_uri: string
|
|
1135
|
+
scope?: string
|
|
1136
|
+
state?: string
|
|
1137
|
+
}): Promise<{ redirectUrl: string }> {
|
|
1138
|
+
return this.request('/api/oauth/authorize', {
|
|
1139
|
+
method: 'POST',
|
|
1140
|
+
body: JSON.stringify(data),
|
|
1141
|
+
})
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
async exchangeOAuthToken(data: {
|
|
1145
|
+
grant_type: 'authorization_code' | 'refresh_token'
|
|
1146
|
+
code?: string
|
|
1147
|
+
refresh_token?: string
|
|
1148
|
+
client_id: string
|
|
1149
|
+
client_secret: string
|
|
1150
|
+
redirect_uri?: string
|
|
1151
|
+
}): Promise<ShadowOAuthToken> {
|
|
1152
|
+
return this.request('/api/oauth/token', {
|
|
1153
|
+
method: 'POST',
|
|
1154
|
+
body: JSON.stringify(data),
|
|
1155
|
+
})
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
async listOAuthConsents(): Promise<ShadowOAuthConsent[]> {
|
|
1159
|
+
return this.request('/api/oauth/consents')
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
async revokeOAuthConsent(appId: string): Promise<{ success: boolean }> {
|
|
1163
|
+
return this.request('/api/oauth/revoke', {
|
|
1164
|
+
method: 'POST',
|
|
1165
|
+
body: JSON.stringify({ appId }),
|
|
1166
|
+
})
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
// ── Marketplace / Rentals ─────────────────────────────────────────────
|
|
1170
|
+
|
|
1171
|
+
async browseListings(params?: {
|
|
1172
|
+
search?: string
|
|
1173
|
+
tags?: string[]
|
|
1174
|
+
minPrice?: number
|
|
1175
|
+
maxPrice?: number
|
|
1176
|
+
limit?: number
|
|
1177
|
+
offset?: number
|
|
1178
|
+
}): Promise<{ listings: ShadowListing[]; total: number }> {
|
|
1179
|
+
const qs = new URLSearchParams()
|
|
1180
|
+
if (params?.search) qs.set('search', params.search)
|
|
1181
|
+
if (params?.tags) for (const t of params.tags) qs.append('tags', t)
|
|
1182
|
+
if (params?.minPrice != null) qs.set('minPrice', String(params.minPrice))
|
|
1183
|
+
if (params?.maxPrice != null) qs.set('maxPrice', String(params.maxPrice))
|
|
1184
|
+
if (params?.limit) qs.set('limit', String(params.limit))
|
|
1185
|
+
if (params?.offset) qs.set('offset', String(params.offset))
|
|
1186
|
+
return this.request(`/api/marketplace/listings?${qs}`)
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
async getListing(listingId: string): Promise<ShadowListing> {
|
|
1190
|
+
return this.request(`/api/marketplace/listings/${listingId}`)
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
async estimateRentalCost(
|
|
1194
|
+
listingId: string,
|
|
1195
|
+
hours: number,
|
|
1196
|
+
): Promise<{ totalCost: number; currency: string }> {
|
|
1197
|
+
const qs = new URLSearchParams({ hours: String(hours) })
|
|
1198
|
+
return this.request(`/api/marketplace/listings/${listingId}/estimate?${qs}`)
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
async listMyListings(): Promise<ShadowListing[]> {
|
|
1202
|
+
return this.request('/api/marketplace/my-listings')
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
async createListing(data: {
|
|
1206
|
+
agentId: string
|
|
1207
|
+
title: string
|
|
1208
|
+
description: string
|
|
1209
|
+
pricePerHour: number
|
|
1210
|
+
currency?: string
|
|
1211
|
+
tags?: string[]
|
|
1212
|
+
}): Promise<ShadowListing> {
|
|
1213
|
+
return this.request('/api/marketplace/listings', {
|
|
1214
|
+
method: 'POST',
|
|
1215
|
+
body: JSON.stringify(data),
|
|
1216
|
+
})
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
async updateListing(
|
|
1220
|
+
listingId: string,
|
|
1221
|
+
data: Partial<{ title: string; description: string; pricePerHour: number; tags: string[] }>,
|
|
1222
|
+
): Promise<ShadowListing> {
|
|
1223
|
+
return this.request(`/api/marketplace/listings/${listingId}`, {
|
|
1224
|
+
method: 'PUT',
|
|
1225
|
+
body: JSON.stringify(data),
|
|
1226
|
+
})
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
async toggleListing(listingId: string): Promise<ShadowListing> {
|
|
1230
|
+
return this.request(`/api/marketplace/listings/${listingId}/toggle`, { method: 'PUT' })
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
async deleteListing(listingId: string): Promise<{ success: boolean }> {
|
|
1234
|
+
return this.request(`/api/marketplace/listings/${listingId}`, { method: 'DELETE' })
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
async signContract(data: { listingId: string; hours: number }): Promise<ShadowContract> {
|
|
1238
|
+
return this.request('/api/marketplace/contracts', {
|
|
1239
|
+
method: 'POST',
|
|
1240
|
+
body: JSON.stringify(data),
|
|
1241
|
+
})
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
async listContracts(params?: {
|
|
1245
|
+
role?: 'tenant' | 'owner'
|
|
1246
|
+
status?: string
|
|
1247
|
+
}): Promise<ShadowContract[]> {
|
|
1248
|
+
const qs = new URLSearchParams()
|
|
1249
|
+
if (params?.role) qs.set('role', params.role)
|
|
1250
|
+
if (params?.status) qs.set('status', params.status)
|
|
1251
|
+
return this.request(`/api/marketplace/contracts?${qs}`)
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
async getContract(contractId: string): Promise<ShadowContract> {
|
|
1255
|
+
return this.request(`/api/marketplace/contracts/${contractId}`)
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
async terminateContract(contractId: string): Promise<ShadowContract> {
|
|
1259
|
+
return this.request(`/api/marketplace/contracts/${contractId}/terminate`, { method: 'POST' })
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
async recordUsageSession(
|
|
1263
|
+
contractId: string,
|
|
1264
|
+
data: { durationMinutes: number; description?: string },
|
|
1265
|
+
): Promise<{ success: boolean }> {
|
|
1266
|
+
return this.request(`/api/marketplace/contracts/${contractId}/usage`, {
|
|
1267
|
+
method: 'POST',
|
|
1268
|
+
body: JSON.stringify(data),
|
|
1269
|
+
})
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
async reportViolation(
|
|
1273
|
+
contractId: string,
|
|
1274
|
+
data: { reason: string },
|
|
1275
|
+
): Promise<{ success: boolean }> {
|
|
1276
|
+
return this.request(`/api/marketplace/contracts/${contractId}/violate`, {
|
|
1277
|
+
method: 'POST',
|
|
1278
|
+
body: JSON.stringify(data),
|
|
1279
|
+
})
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
// ── Shop ──────────────────────────────────────────────────────────────
|
|
1283
|
+
|
|
1284
|
+
async getShop(serverId: string): Promise<ShadowShop> {
|
|
1285
|
+
return this.request(`/api/servers/${serverId}/shop`)
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
async updateShop(
|
|
1289
|
+
serverId: string,
|
|
1290
|
+
data: Partial<{ name: string; description: string | null; isEnabled: boolean }>,
|
|
1291
|
+
): Promise<ShadowShop> {
|
|
1292
|
+
return this.request(`/api/servers/${serverId}/shop`, {
|
|
1293
|
+
method: 'PUT',
|
|
1294
|
+
body: JSON.stringify(data),
|
|
1295
|
+
})
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
async listCategories(serverId: string): Promise<ShadowCategory[]> {
|
|
1299
|
+
return this.request(`/api/servers/${serverId}/shop/categories`)
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
async createCategory(
|
|
1303
|
+
serverId: string,
|
|
1304
|
+
data: { name: string; description?: string },
|
|
1305
|
+
): Promise<ShadowCategory> {
|
|
1306
|
+
return this.request(`/api/servers/${serverId}/shop/categories`, {
|
|
1307
|
+
method: 'POST',
|
|
1308
|
+
body: JSON.stringify(data),
|
|
1309
|
+
})
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
async updateCategory(
|
|
1313
|
+
serverId: string,
|
|
1314
|
+
categoryId: string,
|
|
1315
|
+
data: Partial<{ name: string; description: string | null; position: number }>,
|
|
1316
|
+
): Promise<ShadowCategory> {
|
|
1317
|
+
return this.request(`/api/servers/${serverId}/shop/categories/${categoryId}`, {
|
|
1318
|
+
method: 'PUT',
|
|
1319
|
+
body: JSON.stringify(data),
|
|
1320
|
+
})
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
async deleteCategory(serverId: string, categoryId: string): Promise<{ success: boolean }> {
|
|
1324
|
+
return this.request(`/api/servers/${serverId}/shop/categories/${categoryId}`, {
|
|
1325
|
+
method: 'DELETE',
|
|
1326
|
+
})
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
async listProducts(
|
|
1330
|
+
serverId: string,
|
|
1331
|
+
params?: {
|
|
1332
|
+
status?: string
|
|
1333
|
+
categoryId?: string
|
|
1334
|
+
keyword?: string
|
|
1335
|
+
limit?: number
|
|
1336
|
+
offset?: number
|
|
1337
|
+
},
|
|
1338
|
+
): Promise<{ products: ShadowProduct[]; total: number }> {
|
|
1339
|
+
const qs = new URLSearchParams()
|
|
1340
|
+
if (params?.status) qs.set('status', params.status)
|
|
1341
|
+
if (params?.categoryId) qs.set('categoryId', params.categoryId)
|
|
1342
|
+
if (params?.keyword) qs.set('keyword', params.keyword)
|
|
1343
|
+
if (params?.limit) qs.set('limit', String(params.limit))
|
|
1344
|
+
if (params?.offset) qs.set('offset', String(params.offset))
|
|
1345
|
+
return this.request(`/api/servers/${serverId}/shop/products?${qs}`)
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
async getProduct(serverId: string, productId: string): Promise<ShadowProduct> {
|
|
1349
|
+
return this.request(`/api/servers/${serverId}/shop/products/${productId}`)
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1352
|
+
async createProduct(
|
|
1353
|
+
serverId: string,
|
|
1354
|
+
data: {
|
|
1355
|
+
name: string
|
|
1356
|
+
description?: string
|
|
1357
|
+
price: number
|
|
1358
|
+
currency?: string
|
|
1359
|
+
stock: number
|
|
1360
|
+
categoryId?: string
|
|
1361
|
+
images?: string[]
|
|
1362
|
+
},
|
|
1363
|
+
): Promise<ShadowProduct> {
|
|
1364
|
+
return this.request(`/api/servers/${serverId}/shop/products`, {
|
|
1365
|
+
method: 'POST',
|
|
1366
|
+
body: JSON.stringify(data),
|
|
1367
|
+
})
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
async updateProduct(
|
|
1371
|
+
serverId: string,
|
|
1372
|
+
productId: string,
|
|
1373
|
+
data: Partial<{
|
|
1374
|
+
name: string
|
|
1375
|
+
description: string | null
|
|
1376
|
+
price: number
|
|
1377
|
+
stock: number
|
|
1378
|
+
status: string
|
|
1379
|
+
categoryId: string | null
|
|
1380
|
+
images: string[]
|
|
1381
|
+
}>,
|
|
1382
|
+
): Promise<ShadowProduct> {
|
|
1383
|
+
return this.request(`/api/servers/${serverId}/shop/products/${productId}`, {
|
|
1384
|
+
method: 'PUT',
|
|
1385
|
+
body: JSON.stringify(data),
|
|
1386
|
+
})
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
async deleteProduct(serverId: string, productId: string): Promise<{ success: boolean }> {
|
|
1390
|
+
return this.request(`/api/servers/${serverId}/shop/products/${productId}`, { method: 'DELETE' })
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
async getCart(serverId: string): Promise<ShadowCartItem[]> {
|
|
1394
|
+
return this.request(`/api/servers/${serverId}/shop/cart`)
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
async addToCart(
|
|
1398
|
+
serverId: string,
|
|
1399
|
+
data: { productId: string; quantity: number },
|
|
1400
|
+
): Promise<ShadowCartItem> {
|
|
1401
|
+
return this.request(`/api/servers/${serverId}/shop/cart`, {
|
|
1402
|
+
method: 'POST',
|
|
1403
|
+
body: JSON.stringify(data),
|
|
1404
|
+
})
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
async updateCartItem(
|
|
1408
|
+
serverId: string,
|
|
1409
|
+
itemId: string,
|
|
1410
|
+
quantity: number,
|
|
1411
|
+
): Promise<ShadowCartItem> {
|
|
1412
|
+
return this.request(`/api/servers/${serverId}/shop/cart/${itemId}`, {
|
|
1413
|
+
method: 'PUT',
|
|
1414
|
+
body: JSON.stringify({ quantity }),
|
|
1415
|
+
})
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
async removeCartItem(serverId: string, itemId: string): Promise<{ success: boolean }> {
|
|
1419
|
+
return this.request(`/api/servers/${serverId}/shop/cart/${itemId}`, { method: 'DELETE' })
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
async createOrder(
|
|
1423
|
+
serverId: string,
|
|
1424
|
+
data?: { items?: { productId: string; quantity: number }[] },
|
|
1425
|
+
): Promise<ShadowOrder> {
|
|
1426
|
+
return this.request(`/api/servers/${serverId}/shop/orders`, {
|
|
1427
|
+
method: 'POST',
|
|
1428
|
+
body: JSON.stringify(data ?? {}),
|
|
1429
|
+
})
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1432
|
+
async listOrders(serverId: string): Promise<ShadowOrder[]> {
|
|
1433
|
+
return this.request(`/api/servers/${serverId}/shop/orders`)
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1436
|
+
async listShopOrders(serverId: string): Promise<ShadowOrder[]> {
|
|
1437
|
+
return this.request(`/api/servers/${serverId}/shop/orders/manage`)
|
|
1438
|
+
}
|
|
1439
|
+
|
|
1440
|
+
async getOrder(serverId: string, orderId: string): Promise<ShadowOrder> {
|
|
1441
|
+
return this.request(`/api/servers/${serverId}/shop/orders/${orderId}`)
|
|
1442
|
+
}
|
|
1443
|
+
|
|
1444
|
+
async updateOrderStatus(serverId: string, orderId: string, status: string): Promise<ShadowOrder> {
|
|
1445
|
+
return this.request(`/api/servers/${serverId}/shop/orders/${orderId}/status`, {
|
|
1446
|
+
method: 'PUT',
|
|
1447
|
+
body: JSON.stringify({ status }),
|
|
1448
|
+
})
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
async cancelOrder(serverId: string, orderId: string): Promise<ShadowOrder> {
|
|
1452
|
+
return this.request(`/api/servers/${serverId}/shop/orders/${orderId}/cancel`, {
|
|
1453
|
+
method: 'POST',
|
|
1454
|
+
})
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
async getProductReviews(serverId: string, productId: string): Promise<ShadowReview[]> {
|
|
1458
|
+
return this.request(`/api/servers/${serverId}/shop/products/${productId}/reviews`)
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1461
|
+
async createReview(
|
|
1462
|
+
serverId: string,
|
|
1463
|
+
orderId: string,
|
|
1464
|
+
data: { productId: string; rating: number; content: string },
|
|
1465
|
+
): Promise<ShadowReview> {
|
|
1466
|
+
return this.request(`/api/servers/${serverId}/shop/orders/${orderId}/review`, {
|
|
1467
|
+
method: 'POST',
|
|
1468
|
+
body: JSON.stringify(data),
|
|
1469
|
+
})
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1472
|
+
async replyToReview(serverId: string, reviewId: string, reply: string): Promise<ShadowReview> {
|
|
1473
|
+
return this.request(`/api/servers/${serverId}/shop/reviews/${reviewId}/reply`, {
|
|
1474
|
+
method: 'PUT',
|
|
1475
|
+
body: JSON.stringify({ reply }),
|
|
1476
|
+
})
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
async getWallet(): Promise<ShadowWallet> {
|
|
1480
|
+
return this.request('/api/wallet')
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
async topUpWallet(amount: number): Promise<ShadowWallet> {
|
|
1484
|
+
return this.request('/api/wallet/topup', {
|
|
1485
|
+
method: 'POST',
|
|
1486
|
+
body: JSON.stringify({ amount }),
|
|
1487
|
+
})
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
async getWalletTransactions(): Promise<ShadowTransaction[]> {
|
|
1491
|
+
return this.request('/api/wallet/transactions')
|
|
1492
|
+
}
|
|
1493
|
+
|
|
1494
|
+
async getEntitlements(serverId: string): Promise<Record<string, unknown>[]> {
|
|
1495
|
+
return this.request(`/api/servers/${serverId}/shop/entitlements`)
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1498
|
+
// ── Task Center ───────────────────────────────────────────────────────
|
|
1499
|
+
|
|
1500
|
+
async getTaskCenter(): Promise<{ tasks: ShadowTask[] }> {
|
|
1501
|
+
return this.request('/api/tasks')
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
async claimTask(taskKey: string): Promise<{ success: boolean; reward: number }> {
|
|
1505
|
+
return this.request(`/api/tasks/${taskKey}/claim`, { method: 'POST' })
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
async getReferralSummary(): Promise<{ count: number; rewards: number }> {
|
|
1509
|
+
return this.request('/api/tasks/referral-summary')
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
async getRewardHistory(): Promise<{
|
|
1513
|
+
rewards: { amount: number; reason: string; createdAt: string }[]
|
|
1514
|
+
}> {
|
|
1515
|
+
return this.request('/api/tasks/rewards')
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1518
|
+
// ── Server Apps ───────────────────────────────────────────────────────
|
|
1519
|
+
|
|
1520
|
+
async listApps(
|
|
1521
|
+
serverId: string,
|
|
1522
|
+
params?: { status?: string; limit?: number; offset?: number },
|
|
1523
|
+
): Promise<{ apps: ShadowApp[]; total: number }> {
|
|
1524
|
+
const qs = new URLSearchParams()
|
|
1525
|
+
if (params?.status) qs.set('status', params.status)
|
|
1526
|
+
if (params?.limit) qs.set('limit', String(params.limit))
|
|
1527
|
+
if (params?.offset) qs.set('offset', String(params.offset))
|
|
1528
|
+
return this.request(`/api/servers/${serverId}/apps?${qs}`)
|
|
1529
|
+
}
|
|
1530
|
+
|
|
1531
|
+
async getHomepageApp(serverId: string): Promise<ShadowApp | null> {
|
|
1532
|
+
return this.request(`/api/servers/${serverId}/apps/homepage`)
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
async getApp(serverId: string, appId: string): Promise<ShadowApp> {
|
|
1536
|
+
return this.request(`/api/servers/${serverId}/apps/${appId}`)
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1539
|
+
async createApp(
|
|
1540
|
+
serverId: string,
|
|
1541
|
+
data: { name: string; slug: string; type: string; url?: string },
|
|
1542
|
+
): Promise<ShadowApp> {
|
|
1543
|
+
return this.request(`/api/servers/${serverId}/apps`, {
|
|
1544
|
+
method: 'POST',
|
|
1545
|
+
body: JSON.stringify(data),
|
|
1546
|
+
})
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
async updateApp(
|
|
1550
|
+
serverId: string,
|
|
1551
|
+
appId: string,
|
|
1552
|
+
data: Partial<{ name: string; slug: string; type: string; url: string; status: string }>,
|
|
1553
|
+
): Promise<ShadowApp> {
|
|
1554
|
+
return this.request(`/api/servers/${serverId}/apps/${appId}`, {
|
|
1555
|
+
method: 'PATCH',
|
|
1556
|
+
body: JSON.stringify(data),
|
|
1557
|
+
})
|
|
1558
|
+
}
|
|
1559
|
+
|
|
1560
|
+
async deleteApp(serverId: string, appId: string): Promise<{ success: boolean }> {
|
|
1561
|
+
return this.request(`/api/servers/${serverId}/apps/${appId}`, { method: 'DELETE' })
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1564
|
+
async publishApp(serverId: string, data: { name: string; slug: string }): Promise<ShadowApp> {
|
|
1565
|
+
return this.request(`/api/servers/${serverId}/apps/publish`, {
|
|
1566
|
+
method: 'POST',
|
|
1567
|
+
body: JSON.stringify(data),
|
|
1568
|
+
})
|
|
1569
|
+
}
|
|
968
1570
|
}
|