@noverachat/sdk-web 0.0.3 → 0.2.0
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/README.ko.md +8 -8
- package/README.md +8 -8
- package/dist/index.cjs +485 -258
- package/dist/index.d.cts +212 -169
- package/dist/index.d.ts +212 -169
- package/dist/index.js +485 -258
- package/package.json +1 -1
- package/src/client.ts +50 -157
- package/src/features/room.ts +274 -344
- package/src/generated/rest.ts +529 -0
- package/src/index.ts +4 -0
- package/src/types.ts +62 -177
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -14,6 +14,11 @@ import type {
|
|
|
14
14
|
MessageIdStr, RegisterDeviceParams, UnreadSummary, WsAnnouncementEvent,
|
|
15
15
|
WsInbound, WsPresence, WsRoomEvent,
|
|
16
16
|
} from "./types.js";
|
|
17
|
+
import {
|
|
18
|
+
parseAppPolicy, parseBlockOut, parseDeviceListResponse, parseDeviceOut,
|
|
19
|
+
parseFileOut, parseInviteAcceptResponse, parsePushPreferencesOut,
|
|
20
|
+
parseUnreadSummary,
|
|
21
|
+
} from "./generated/rest.js";
|
|
17
22
|
|
|
18
23
|
/** Client-level events (not tied to a single Room facade). `roomEvent` fires
|
|
19
24
|
* for membership / room-lifecycle changes on ANY room — including ones the
|
|
@@ -202,20 +207,8 @@ export class NoveraChat {
|
|
|
202
207
|
* read on the server) — fetch once on connect to decide which
|
|
203
208
|
* destructive buttons to expose. */
|
|
204
209
|
async appPolicy(): Promise<AppPolicy> {
|
|
205
|
-
const raw = await this.http.request<
|
|
206
|
-
|
|
207
|
-
allow_member_bulk_delete: boolean;
|
|
208
|
-
read_receipts_enabled: boolean;
|
|
209
|
-
typing_indicators_enabled: boolean;
|
|
210
|
-
allow_member_delete_any_message: boolean;
|
|
211
|
-
}>("GET", "/api/v1/app/policy");
|
|
212
|
-
return {
|
|
213
|
-
appId: raw.app_id,
|
|
214
|
-
allowMemberBulkDelete: raw.allow_member_bulk_delete,
|
|
215
|
-
readReceiptsEnabled: raw.read_receipts_enabled ?? true,
|
|
216
|
-
typingIndicatorsEnabled: raw.typing_indicators_enabled ?? true,
|
|
217
|
-
deleteAnyMessageEnabled: raw.allow_member_delete_any_message ?? false,
|
|
218
|
-
};
|
|
210
|
+
const raw = await this.http.request<unknown>("GET", "/api/v1/app/policy");
|
|
211
|
+
return parseAppPolicy(raw);
|
|
219
212
|
}
|
|
220
213
|
|
|
221
214
|
// ---- device tokens (push) ----
|
|
@@ -227,32 +220,21 @@ export class NoveraChat {
|
|
|
227
220
|
* safe. Returns the stored device record (token shown only as a prefix).
|
|
228
221
|
*/
|
|
229
222
|
async registerDevice(params: RegisterDeviceParams): Promise<DeviceInfo> {
|
|
230
|
-
const raw = await this.http.request<
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
}>("POST", "/api/v1/users/me/devices", {
|
|
240
|
-
device_id: params.deviceId,
|
|
241
|
-
token: params.token,
|
|
242
|
-
token_type: params.tokenType,
|
|
243
|
-
os: params.os ?? null,
|
|
244
|
-
app_version: params.appVersion ?? null,
|
|
245
|
-
});
|
|
246
|
-
return this._toDeviceInfo(raw);
|
|
223
|
+
const raw = await this.http.request<unknown>(
|
|
224
|
+
"POST", "/api/v1/users/me/devices", {
|
|
225
|
+
device_id: params.deviceId,
|
|
226
|
+
token: params.token,
|
|
227
|
+
token_type: params.tokenType,
|
|
228
|
+
os: params.os ?? null,
|
|
229
|
+
app_version: params.appVersion ?? null,
|
|
230
|
+
});
|
|
231
|
+
return parseDeviceOut(raw);
|
|
247
232
|
}
|
|
248
233
|
|
|
249
234
|
/** List the devices registered for the authenticated user. */
|
|
250
235
|
async listDevices(): Promise<DeviceInfo[]> {
|
|
251
|
-
const raw = await this.http.request<
|
|
252
|
-
|
|
253
|
-
total: number;
|
|
254
|
-
}>("GET", "/api/v1/users/me/devices");
|
|
255
|
-
return raw.items.map((d) => this._toDeviceInfo(d));
|
|
236
|
+
const raw = await this.http.request<unknown>("GET", "/api/v1/users/me/devices");
|
|
237
|
+
return parseDeviceListResponse(raw).items;
|
|
256
238
|
}
|
|
257
239
|
|
|
258
240
|
/**
|
|
@@ -288,10 +270,10 @@ export class NoveraChat {
|
|
|
288
270
|
* 2. **Global (this)** — overrides all rooms when off.
|
|
289
271
|
*/
|
|
290
272
|
async getPushPreferences(): Promise<{ pushEnabled: boolean }> {
|
|
291
|
-
const raw = await this.http.request<
|
|
273
|
+
const raw = await this.http.request<unknown>(
|
|
292
274
|
"GET", "/api/v1/users/me/push-preferences",
|
|
293
275
|
);
|
|
294
|
-
return
|
|
276
|
+
return parsePushPreferencesOut(raw);
|
|
295
277
|
}
|
|
296
278
|
|
|
297
279
|
/**
|
|
@@ -300,11 +282,11 @@ export class NoveraChat {
|
|
|
300
282
|
* `true` to restore normal delivery. Idempotent.
|
|
301
283
|
*/
|
|
302
284
|
async setPushEnabled(enabled: boolean): Promise<{ pushEnabled: boolean }> {
|
|
303
|
-
const raw = await this.http.request<
|
|
285
|
+
const raw = await this.http.request<unknown>(
|
|
304
286
|
"PATCH", "/api/v1/users/me/push-preferences",
|
|
305
287
|
{ push_enabled: enabled },
|
|
306
288
|
);
|
|
307
|
-
return
|
|
289
|
+
return parsePushPreferencesOut(raw);
|
|
308
290
|
}
|
|
309
291
|
|
|
310
292
|
// -------------------------------------------------------------------------
|
|
@@ -325,19 +307,11 @@ export class NoveraChat {
|
|
|
325
307
|
* @param reason Optional local note ≤500 chars.
|
|
326
308
|
*/
|
|
327
309
|
async blockUser(userId: string, reason?: string): Promise<Block> {
|
|
328
|
-
const raw = await this.http.request<
|
|
329
|
-
blocked_user_id: string;
|
|
330
|
-
reason: string | null;
|
|
331
|
-
created_at: string;
|
|
332
|
-
}>(
|
|
310
|
+
const raw = await this.http.request<unknown>(
|
|
333
311
|
"POST", `/api/v1/users/me/blocks/${encodeURIComponent(userId)}`,
|
|
334
312
|
{ reason: reason ?? null },
|
|
335
313
|
);
|
|
336
|
-
return
|
|
337
|
-
blockedUserId: raw.blocked_user_id,
|
|
338
|
-
reason: raw.reason,
|
|
339
|
-
createdAt: raw.created_at,
|
|
340
|
-
};
|
|
314
|
+
return parseBlockOut(raw);
|
|
341
315
|
}
|
|
342
316
|
|
|
343
317
|
/** Unblock a user. Idempotent — resolves either way. */
|
|
@@ -349,38 +323,8 @@ export class NoveraChat {
|
|
|
349
323
|
|
|
350
324
|
/** List every user the caller has blocked, newest first. */
|
|
351
325
|
async listBlocks(): Promise<Block[]> {
|
|
352
|
-
const raw = await this.http.request<
|
|
353
|
-
|
|
354
|
-
reason: string | null;
|
|
355
|
-
created_at: string;
|
|
356
|
-
}>>("GET", "/api/v1/users/me/blocks");
|
|
357
|
-
return raw.map((r) => ({
|
|
358
|
-
blockedUserId: r.blocked_user_id,
|
|
359
|
-
reason: r.reason,
|
|
360
|
-
createdAt: r.created_at,
|
|
361
|
-
}));
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
private _toDeviceInfo(raw: {
|
|
365
|
-
device_id: string;
|
|
366
|
-
token_type: DeviceInfo["tokenType"];
|
|
367
|
-
token_preview: string;
|
|
368
|
-
os: DeviceInfo["os"];
|
|
369
|
-
app_version: string | null;
|
|
370
|
-
push_enabled: boolean;
|
|
371
|
-
last_active_at: string | null;
|
|
372
|
-
created_at: string;
|
|
373
|
-
}): DeviceInfo {
|
|
374
|
-
return {
|
|
375
|
-
deviceId: raw.device_id,
|
|
376
|
-
tokenType: raw.token_type,
|
|
377
|
-
tokenPreview: raw.token_preview,
|
|
378
|
-
os: raw.os,
|
|
379
|
-
appVersion: raw.app_version,
|
|
380
|
-
pushEnabled: raw.push_enabled,
|
|
381
|
-
lastActiveAt: raw.last_active_at,
|
|
382
|
-
createdAt: raw.created_at,
|
|
383
|
-
};
|
|
326
|
+
const raw = await this.http.request<unknown[]>("GET", "/api/v1/users/me/blocks");
|
|
327
|
+
return raw.map((r) => parseBlockOut(r));
|
|
384
328
|
}
|
|
385
329
|
|
|
386
330
|
/**
|
|
@@ -441,76 +385,31 @@ export class NoveraChat {
|
|
|
441
385
|
* shipping date.
|
|
442
386
|
*/
|
|
443
387
|
async getFileMeta(fileId: MessageIdStr): Promise<FileMeta> {
|
|
444
|
-
//
|
|
445
|
-
//
|
|
446
|
-
//
|
|
447
|
-
//
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
mime: string;
|
|
453
|
-
size_bytes: number;
|
|
454
|
-
original_name: string | null;
|
|
455
|
-
width: number | null;
|
|
456
|
-
height: number | null;
|
|
457
|
-
duration_sec: number | null;
|
|
458
|
-
thumbnail_status: "pending" | "ready" | "failed" | "skipped";
|
|
459
|
-
forward_blocked?: boolean;
|
|
460
|
-
}>("GET", `/api/v1/files/${encodeURIComponent(fileId)}/meta`);
|
|
388
|
+
// Endpoint returns the generated ``FileOut`` shape (size_bytes /
|
|
389
|
+
// original_name / …). Parse it with the codegen'd converter, then
|
|
390
|
+
// fold down to the leaner inline ``FileMeta`` (= FileInline) the SDK
|
|
391
|
+
// exposes — the same fields WS chat_receive frames carry.
|
|
392
|
+
const raw = await this.http.request<unknown>(
|
|
393
|
+
"GET", `/api/v1/files/${encodeURIComponent(fileId)}/meta`,
|
|
394
|
+
);
|
|
395
|
+
const f = parseFileOut(raw);
|
|
461
396
|
return {
|
|
462
|
-
id:
|
|
463
|
-
kind:
|
|
464
|
-
mime:
|
|
465
|
-
size:
|
|
466
|
-
name:
|
|
467
|
-
width:
|
|
468
|
-
height:
|
|
469
|
-
durationSec:
|
|
470
|
-
thumbnailStatus:
|
|
471
|
-
forwardBlocked: Boolean(
|
|
397
|
+
id: f.id,
|
|
398
|
+
kind: f.kind,
|
|
399
|
+
mime: f.mime,
|
|
400
|
+
size: f.sizeBytes,
|
|
401
|
+
name: f.originalName ?? null,
|
|
402
|
+
width: f.width ?? null,
|
|
403
|
+
height: f.height ?? null,
|
|
404
|
+
durationSec: f.durationSec ?? null,
|
|
405
|
+
thumbnailStatus: f.thumbnailStatus,
|
|
406
|
+
forwardBlocked: Boolean(f.forwardBlocked),
|
|
472
407
|
};
|
|
473
408
|
}
|
|
474
409
|
|
|
475
410
|
async unreadSummary(): Promise<UnreadSummary> {
|
|
476
|
-
const raw = await this.http.request<
|
|
477
|
-
|
|
478
|
-
rooms: Array<{
|
|
479
|
-
room_id: string;
|
|
480
|
-
name: string | null;
|
|
481
|
-
room_type: string | null;
|
|
482
|
-
unread_count: number;
|
|
483
|
-
last_message_id: string | null;
|
|
484
|
-
last_message_preview: string | null;
|
|
485
|
-
last_read_message_id: string | null;
|
|
486
|
-
member_count: number;
|
|
487
|
-
members_preview: Array<{
|
|
488
|
-
user_id: string;
|
|
489
|
-
nickname: string | null;
|
|
490
|
-
profile_image_url: string | null;
|
|
491
|
-
is_online: boolean | null;
|
|
492
|
-
}>;
|
|
493
|
-
}>;
|
|
494
|
-
}>("GET", "/api/v1/users/me/unread");
|
|
495
|
-
return {
|
|
496
|
-
total: raw.total,
|
|
497
|
-
rooms: raw.rooms.map((r) => ({
|
|
498
|
-
roomId: r.room_id,
|
|
499
|
-
name: r.name,
|
|
500
|
-
roomType: r.room_type ?? null,
|
|
501
|
-
unreadCount: r.unread_count,
|
|
502
|
-
lastMessageId: r.last_message_id,
|
|
503
|
-
lastMessagePreview: r.last_message_preview ?? null,
|
|
504
|
-
lastReadMessageId: r.last_read_message_id,
|
|
505
|
-
memberCount: r.member_count ?? 0,
|
|
506
|
-
members: (r.members_preview ?? []).map((m) => ({
|
|
507
|
-
userId: m.user_id,
|
|
508
|
-
nickname: m.nickname ?? null,
|
|
509
|
-
profileImageUrl: m.profile_image_url ?? null,
|
|
510
|
-
isOnline: m.is_online ?? null,
|
|
511
|
-
})),
|
|
512
|
-
})),
|
|
513
|
-
};
|
|
411
|
+
const raw = await this.http.request<unknown>("GET", "/api/v1/users/me/unread");
|
|
412
|
+
return parseUnreadSummary(raw);
|
|
514
413
|
}
|
|
515
414
|
|
|
516
415
|
/**
|
|
@@ -529,16 +428,10 @@ export class NoveraChat {
|
|
|
529
428
|
* kicked from the target room.
|
|
530
429
|
*/
|
|
531
430
|
async acceptInvite(token: string): Promise<AcceptInviteResult> {
|
|
532
|
-
const raw = await this.http.request<
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
}>("POST", `/api/v1/invites/${encodeURIComponent(token)}/accept`);
|
|
537
|
-
return {
|
|
538
|
-
roomId: raw.room_id,
|
|
539
|
-
roomName: raw.room_name,
|
|
540
|
-
wasAlreadyMember: raw.was_already_member,
|
|
541
|
-
};
|
|
431
|
+
const raw = await this.http.request<unknown>(
|
|
432
|
+
"POST", `/api/v1/invites/${encodeURIComponent(token)}/accept`,
|
|
433
|
+
);
|
|
434
|
+
return parseInviteAcceptResponse(raw);
|
|
542
435
|
}
|
|
543
436
|
|
|
544
437
|
// ---- internal ----
|