@vex-chat/libvex 1.0.0-rc.1 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/Client.d.ts CHANGED
@@ -2,30 +2,44 @@ import type { IChannel, IDevice, IEmoji, IFileResponse, IFileSQL, IInvite, IPerm
2
2
  import { AxiosError } from "axios";
3
3
  import { EventEmitter } from "events";
4
4
  import type { IStorage } from "./IStorage.js";
5
- interface ICensoredUser {
6
- lastSeen: number;
7
- userID: string;
8
- username: string;
9
- }
10
5
  /**
11
6
  * IMessage is a chat message.
12
7
  */
13
8
  export interface IMessage {
9
+ /** Hex-encoded nonce used for message encryption. */
14
10
  nonce: string;
11
+ /** Globally unique message identifier. */
15
12
  mailID: string;
13
+ /** Sender device ID. */
16
14
  sender: string;
15
+ /** Recipient device ID. */
17
16
  recipient: string;
17
+ /** Plaintext message content (or empty string when decryption failed). */
18
18
  message: string;
19
+ /** Whether this message was received or sent by the current client. */
19
20
  direction: "incoming" | "outgoing";
21
+ /** Time the message was created/received. */
20
22
  timestamp: Date;
23
+ /** Whether payload decryption succeeded. */
21
24
  decrypted: boolean;
25
+ /** Channel ID for group messages; `null` for direct messages. */
22
26
  group: string | null;
27
+ /** `true` when this message was forwarded to another owned device. */
23
28
  forward: boolean;
29
+ /** User ID of the original author. */
24
30
  authorID: string;
31
+ /** User ID of the intended reader. */
25
32
  readerID: string;
26
33
  }
27
34
  /**
28
35
  * IPermission is a permission to a resource.
36
+ *
37
+ * Common fields:
38
+ * - `permissionID`: unique permission row ID
39
+ * - `userID`: user receiving this grant
40
+ * - `resourceID`: target server/channel/etc.
41
+ * - `resourceType`: type string for the resource
42
+ * - `powerLevel`: authorization level
29
43
  */
30
44
  export type { IPermission } from "@vex-chat/types";
31
45
  /**
@@ -33,154 +47,298 @@ export type { IPermission } from "@vex-chat/types";
33
47
  * encoded as hex strings.
34
48
  */
35
49
  export interface IKeys {
50
+ /** Public Ed25519 key as hex. */
36
51
  public: string;
52
+ /** Secret Ed25519 key as hex. Store securely. */
37
53
  private: string;
38
54
  }
55
+ /**
56
+ * Device record associated with a user account.
57
+ *
58
+ * Common fields:
59
+ * - `deviceID`: unique device identifier
60
+ * - `owner`: owning user ID
61
+ * - `signKey`: signing public key
62
+ * - `name`: user-facing device name
63
+ * - `lastLogin`: last login timestamp string
64
+ * - `deleted`: soft-delete flag
65
+ */
39
66
  export type { IDevice } from "@vex-chat/types";
40
67
  /**
41
68
  * IUser is a single user on the vex platform.
69
+ *
70
+ * This is intentionally a censored user shape for client use, containing:
71
+ * - `userID`
72
+ * - `username`
73
+ * - `lastSeen`
42
74
  */
43
- export interface IUser extends ICensoredUser {
75
+ export interface IUser {
76
+ /** Last-seen timestamp (unix epoch milliseconds). */
77
+ lastSeen: number;
78
+ /** User identifier. */
79
+ userID: string;
80
+ /** Public username. */
81
+ username: string;
44
82
  }
45
83
  /**
46
84
  * ISession is an end to end encryption session with another peer.
85
+ *
86
+ * Key fields include:
87
+ * - `sessionID`
88
+ * - `userID`
89
+ * - `deviceID`
90
+ * - `mode` (`initiator` or `receiver`)
91
+ * - `publicKey` and `fingerprint`
92
+ * - `lastUsed`
93
+ * - `verified`
94
+ *
95
+ * @example
96
+ * ```ts
97
+ * const session: ISession = {
98
+ * sessionID: "f6e4fbd0-7222-4ba8-b799-c227faf5c8de",
99
+ * userID: "f34f5e37-616f-4d3a-a437-e7c27c31cb73",
100
+ * deviceID: "9b0f3f46-06ad-4bc4-8adf-4de10e13cb9c",
101
+ * mode: "initiator",
102
+ * SK: "7d9afde6683ecc2d1f55e34e1b95de9d4042dfd4e8cda7fdf3f0f7e02fef8f9a",
103
+ * publicKey: "d58f39dc4bcfe4e8ef022f34e8b6f4f6ddc9c4acee30c0d58f126aa5db3f61b0",
104
+ * fingerprint: "05294b9aa81d0fd0ca12a4b585f531d8ef1f53f8ea3d0200a0df3f9c44a7d8b1",
105
+ * lastUsed: new Date(),
106
+ * verified: false,
107
+ * };
108
+ * ```
47
109
  */
48
110
  export interface ISession extends ISessionSQL {
49
111
  }
50
112
  /**
51
113
  * IChannel is a chat channel on a server.
114
+ *
115
+ * Common fields:
116
+ * - `channelID`
117
+ * - `serverID`
118
+ * - `name`
52
119
  */
53
120
  export type { IChannel } from "@vex-chat/types";
54
121
  /**
55
122
  * IServer is a single chat server.
123
+ *
124
+ * Common fields:
125
+ * - `serverID`
126
+ * - `name`
127
+ * - `icon` (optional URL/data)
56
128
  */
57
129
  export type { IServer } from "@vex-chat/types";
58
130
  /**
59
- * Ifile is an uploaded encrypted file.
131
+ * IFile is an uploaded encrypted file.
132
+ *
133
+ * Common fields:
134
+ * - `fileID`: file identifier
135
+ * - `owner`: owner device/user ID
136
+ * - `nonce`: file encryption nonce (hex)
137
+ *
138
+ * @example
139
+ * ```ts
140
+ * const file: IFile = {
141
+ * fileID: "bb1c3fd1-4928-48ab-9d09-3ea0972fbd9d",
142
+ * owner: "9b0f3f46-06ad-4bc4-8adf-4de10e13cb9c",
143
+ * nonce: "aa6c8d42f3fdd032a1e9fced4be379582d26ce8f69822d64",
144
+ * };
145
+ * ```
60
146
  */
61
147
  export interface IFile extends IFileSQL {
62
148
  }
63
149
  /**
64
150
  * IFileRes is a server response to a file retrieval request.
151
+ *
152
+ * Structure:
153
+ * - `details`: metadata (`IFile`)
154
+ * - `data`: decrypted binary bytes
155
+ *
156
+ * @example
157
+ * ```ts
158
+ * const response: IFileRes = {
159
+ * details: {
160
+ * fileID: "bb1c3fd1-4928-48ab-9d09-3ea0972fbd9d",
161
+ * owner: "9b0f3f46-06ad-4bc4-8adf-4de10e13cb9c",
162
+ * nonce: "aa6c8d42f3fdd032a1e9fced4be379582d26ce8f69822d64",
163
+ * },
164
+ * data: Buffer.from("hello"),
165
+ * };
166
+ * ```
65
167
  */
66
168
  export interface IFileRes extends IFileResponse {
67
169
  }
68
170
  /**
69
171
  * @ignore
70
172
  */
71
- interface IMe {
72
- user: () => ICensoredUser;
173
+ export interface IMe {
174
+ /** Returns the currently authenticated user profile. */
175
+ user: () => IUser;
176
+ /** Returns metadata for the currently authenticated device. */
73
177
  device: () => IDevice;
178
+ /** Uploads and sets a new avatar image for the current user. */
74
179
  setAvatar: (avatar: Buffer) => Promise<void>;
75
180
  }
76
181
  /**
77
182
  * @ignore
78
183
  */
79
- interface IUsers {
184
+ export interface IUsers {
185
+ /**
186
+ * Looks up a user by user ID, username, or signing key.
187
+ */
80
188
  retrieve: (userID: string) => Promise<[IUser | null, AxiosError | null]>;
189
+ /** Returns users with whom the current device has active sessions. */
81
190
  familiars: () => Promise<IUser[]>;
82
191
  }
83
192
  /**
84
193
  * @ignore
85
194
  */
86
- interface IMessages {
195
+ export interface IMessages {
196
+ /** Sends an encrypted direct message to one user. */
87
197
  send: (userID: string, message: string) => Promise<void>;
198
+ /** Sends an encrypted message to all members of a channel. */
88
199
  group: (channelID: string, message: string) => Promise<void>;
200
+ /** Returns local direct-message history with one user. */
89
201
  retrieve: (userID: string) => Promise<IMessage[]>;
202
+ /** Returns local group-message history for one channel. */
90
203
  retrieveGroup: (channelID: string) => Promise<IMessage[]>;
204
+ /** Deletes local history for a user/channel, optionally older than a duration. */
91
205
  delete: (userOrChannelID: string, duration?: string) => Promise<void>;
206
+ /** Deletes all locally stored message history. */
92
207
  purge: () => Promise<void>;
93
208
  }
94
209
  /**
95
210
  * @ignore
96
211
  */
97
- interface IServers {
212
+ export interface IServers {
213
+ /** Lists servers available to the authenticated user. */
98
214
  retrieve: () => Promise<IServer[]>;
215
+ /** Gets one server by ID. */
99
216
  retrieveByID: (serverID: string) => Promise<IServer | null>;
217
+ /** Creates a server. */
100
218
  create: (name: string) => Promise<IServer>;
219
+ /** Deletes a server. */
101
220
  delete: (serverID: string) => Promise<void>;
221
+ /** Leaves a server by removing the user's permission entry. */
102
222
  leave: (serverID: string) => Promise<void>;
103
223
  }
104
224
  /**
105
225
  * @ignore
106
226
  */
107
- interface IModeration {
227
+ export interface IModeration {
228
+ /** Removes a user from a server by revoking their server permission(s). */
108
229
  kick: (userID: string, serverID: string) => Promise<void>;
230
+ /** Returns all permission entries for a server. */
109
231
  fetchPermissionList: (serverID: string) => Promise<IPermission[]>;
110
232
  }
111
233
  /**
112
234
  * @ignore
113
235
  */
114
- interface IPermissions {
236
+ export interface IPermissions {
237
+ /** Lists permissions granted to the authenticated user. */
115
238
  retrieve: () => Promise<IPermission[]>;
239
+ /** Deletes one permission grant. */
116
240
  delete: (permissionID: string) => Promise<void>;
117
241
  }
118
242
  /**
119
243
  * @ignore
120
244
  */
121
- interface IInvites {
245
+ export interface IInvites {
246
+ /** Redeems an invite and returns the created permission grant. */
122
247
  redeem: (inviteID: string) => Promise<IPermission>;
248
+ /** Creates an invite for a server and duration. */
123
249
  create: (serverID: string, duration: string) => Promise<IInvite>;
250
+ /** Lists active invites for a server. */
124
251
  retrieve: (serverID: string) => Promise<IInvite[]>;
125
252
  }
126
253
  /**
127
254
  * @ignore
128
255
  */
129
- interface IChannels {
256
+ export interface IChannels {
257
+ /** Lists channels in a server. */
130
258
  retrieve: (serverID: string) => Promise<IChannel[]>;
259
+ /** Gets one channel by ID. */
131
260
  retrieveByID: (channelID: string) => Promise<IChannel | null>;
261
+ /** Creates a channel in a server. */
132
262
  create: (name: string, serverID: string) => Promise<IChannel>;
263
+ /** Deletes a channel. */
133
264
  delete: (channelID: string) => Promise<void>;
265
+ /** Lists users currently visible in a channel. */
134
266
  userList: (channelID: string) => Promise<IUser[]>;
135
267
  }
136
268
  /**
137
269
  * @ignore
138
270
  */
139
- interface ISessions {
271
+ export interface ISessions {
272
+ /** Returns all locally known sessions. */
140
273
  retrieve: () => Promise<ISessionSQL[]>;
274
+ /** Builds a human-readable verification phrase from a session fingerprint. */
141
275
  verify: (session: ISessionSQL) => string;
276
+ /** Marks one session as verification-confirmed. */
142
277
  markVerified: (fingerprint: string) => Promise<void>;
143
278
  }
144
279
  /**
145
280
  * @ignore
146
281
  */
147
- interface IDevices {
282
+ export interface IDevices {
283
+ /** Fetches one device by ID. */
148
284
  retrieve: (deviceIdentifier: string) => Promise<IDevice | null>;
285
+ /** Registers the current key material as a new device. */
149
286
  register: () => Promise<IDevice | null>;
287
+ /** Deletes one of the account's devices (except the currently active one). */
150
288
  delete: (deviceID: string) => Promise<void>;
151
289
  }
152
290
  /**
153
291
  * @ignore
154
292
  */
155
- interface IFiles {
293
+ export interface IFiles {
294
+ /** Uploads and encrypts a file. */
156
295
  create: (file: Buffer) => Promise<[IFileSQL, string]>;
296
+ /** Downloads and decrypts a file using a file ID and key. */
157
297
  retrieve: (fileID: string, key: string) => Promise<IFileResponse | null>;
158
298
  }
159
299
  /**
160
300
  * @ignore
161
301
  */
162
- interface IEmojis {
302
+ export interface IEmojis {
303
+ /** Uploads a custom emoji to a server. */
163
304
  create: (emoji: Buffer, name: string, serverID: string) => Promise<IEmoji | null>;
305
+ /** Lists emojis available on a server. */
164
306
  retrieveList: (serverID: string) => Promise<IEmoji[]>;
307
+ /** Fetches one emoji's metadata by ID. */
165
308
  retrieve: (emojiID: string) => Promise<IEmoji | null>;
166
309
  }
310
+ /**
311
+ * Progress payload emitted by the `fileProgress` event.
312
+ */
167
313
  export interface IFileProgress {
314
+ /** Correlation token (file ID, nonce, or label depending on operation). */
168
315
  token: string;
316
+ /** Whether this progress event is for upload or download. */
169
317
  direction: "upload" | "download";
318
+ /** Integer percentage from `0` to `100`. */
170
319
  progress: number;
320
+ /** Bytes transferred so far. */
171
321
  loaded: number;
322
+ /** Total expected bytes when available, otherwise `0`. */
172
323
  total: number;
173
324
  }
174
325
  /**
175
326
  * IClientOptions are the options you can pass into the client.
176
327
  */
177
328
  export interface IClientOptions {
329
+ /** Logging level for client runtime logs. */
178
330
  logLevel?: "error" | "warn" | "info" | "http" | "verbose" | "debug" | "silly";
331
+ /** API host without protocol. Defaults to `api.vex.wtf`. */
179
332
  host?: string;
333
+ /** Folder path where the sqlite file is created. */
180
334
  dbFolder?: string;
335
+ /** Use sqlite in-memory mode (`:memory:`) instead of a file. */
181
336
  inMemoryDb?: boolean;
337
+ /** Logging level for storage/database logs. */
182
338
  dbLogLevel?: "error" | "warn" | "info" | "http" | "verbose" | "debug" | "silly";
339
+ /** Use `http/ws` instead of `https/wss`. Intended for local/dev environments. */
183
340
  unsafeHttp?: boolean;
341
+ /** Whether local message history should be persisted by default storage. */
184
342
  saveHistory?: boolean;
185
343
  }
186
344
  export declare interface Client {
@@ -213,6 +371,14 @@ export declare interface Client {
213
371
  * @event
214
372
  */
215
373
  on(event: "ready", callback: () => void): this;
374
+ /**
375
+ * Emitted before the first inbox fetch/decrypt cycle after connect.
376
+ *
377
+ * Use this to show temporary loading UI while historical messages are
378
+ * decrypted from server payloads.
379
+ *
380
+ * @event
381
+ */
216
382
  on(event: "decryptingMail", callback: () => void): this;
217
383
  /**
218
384
  * This is emitted when you are connected to the chat.
@@ -349,12 +515,32 @@ export declare interface Client {
349
515
  *
350
516
  * main();
351
517
  * ```
352
- *
353
- * @noInheritDoc
354
518
  */
355
519
  export declare class Client extends EventEmitter {
520
+ /**
521
+ * Loads a key file from disk.
522
+ *
523
+ * Pass-through utility from `@vex-chat/crypto`.
524
+ */
356
525
  static loadKeyFile: (path: string, password: string) => string;
526
+ /**
527
+ * Saves a key file to disk.
528
+ *
529
+ * Pass-through utility from `@vex-chat/crypto`.
530
+ */
357
531
  static saveKeyFile: (path: string, password: string, keyToSave: string, iterationOverride?: number) => void;
532
+ /**
533
+ * Creates and initializes a client in one step.
534
+ *
535
+ * @param privateKey Optional hex secret key. When omitted, a fresh key is generated.
536
+ * @param options Runtime options.
537
+ * @param storage Optional custom storage backend implementing `IStorage`.
538
+ *
539
+ * @example
540
+ * ```ts
541
+ * const client = await Client.create(privateKey, { host: "api.vex.wtf" });
542
+ * ```
543
+ */
358
544
  static create: (privateKey?: string, options?: IClientOptions, storage?: IStorage) => Promise<Client>;
359
545
  /**
360
546
  * Generates an ed25519 secret key as a hex string.
@@ -371,37 +557,75 @@ export declare class Client extends EventEmitter {
371
557
  private static getMnemonic;
372
558
  private static deserializeExtra;
373
559
  /**
374
- * The IUsers interface contains methods for dealing with users.
560
+ * User operations.
561
+ *
562
+ * @example
563
+ * ```ts
564
+ * const [user] = await client.users.retrieve("alice");
565
+ * const familiarUsers = await client.users.familiars();
566
+ * ```
375
567
  */
376
568
  users: IUsers;
569
+ /**
570
+ * Emoji operations.
571
+ *
572
+ * @example
573
+ * ```ts
574
+ * const emoji = await client.emoji.create(imageBuffer, "party", serverID);
575
+ * const list = await client.emoji.retrieveList(serverID);
576
+ * ```
577
+ */
377
578
  emoji: IEmojis;
579
+ /**
580
+ * Helpers for information/actions related to the currently authenticated account.
581
+ */
378
582
  me: IMe;
379
- devices: IDevices;
380
583
  /**
381
- * The IMessages interface contains methods for dealing with messages.
584
+ * Device management methods.
382
585
  */
586
+ devices: IDevices;
587
+ /** File upload/download methods. */
383
588
  files: IFiles;
384
589
  /**
385
- * The IPermissions object contains all methods for dealing with permissions.
590
+ * Permission-management methods for the current user.
386
591
  */
387
592
  permissions: IPermissions;
388
593
  /**
389
- * The IModeration object contains all methods for dealing with permissions.
594
+ * Server moderation helper methods.
390
595
  */
391
596
  moderation: IModeration;
392
597
  /**
393
- * The IInvites interface contains methods for dealing with invites.
598
+ * Invite-management methods.
394
599
  */
395
600
  invites: IInvites;
396
601
  /**
397
- * The IMessages interface contains methods for dealing with messages.
602
+ * Message operations (direct and group).
603
+ *
604
+ * @example
605
+ * ```ts
606
+ * await client.messages.send(userID, "Hello!");
607
+ * await client.messages.group(channelID, "Hello channel!");
608
+ * const dmHistory = await client.messages.retrieve(userID);
609
+ * ```
398
610
  */
399
611
  messages: IMessages;
400
612
  /**
401
- * The ISessions interface contains methods for dealing with encryption sessions.
613
+ * Encryption-session helpers.
402
614
  */
403
615
  sessions: ISessions;
616
+ /**
617
+ * Server operations.
618
+ *
619
+ * @example
620
+ * ```ts
621
+ * const servers = await client.servers.retrieve();
622
+ * const created = await client.servers.create("Team Space");
623
+ * ```
624
+ */
404
625
  servers: IServers;
626
+ /**
627
+ * Channel operations.
628
+ */
405
629
  channels: IChannels;
406
630
  /**
407
631
  * This is true if the client has ever been initialized. You can only initialize
@@ -438,6 +662,14 @@ export declare class Client extends EventEmitter {
438
662
  private forwarded;
439
663
  private prefixes;
440
664
  private constructor();
665
+ /**
666
+ * Returns the current HTTP API origin with protocol.
667
+ *
668
+ * @example
669
+ * ```ts
670
+ * console.log(client.getHost()); // "https://api.vex.wtf"
671
+ * ```
672
+ */
441
673
  getHost(): string;
442
674
  /**
443
675
  * Manually closes the client. Emits the closed event on successful shutdown.
@@ -447,16 +679,43 @@ export declare class Client extends EventEmitter {
447
679
  * Gets the hex string representations of the public and private keys.
448
680
  */
449
681
  getKeys(): IKeys;
682
+ /**
683
+ * Authenticates with username/password and stores the auth token/cookie.
684
+ *
685
+ * @param username Account username.
686
+ * @param password Account password.
687
+ * @returns `null` on success, or the thrown error object on failure.
688
+ *
689
+ * @example
690
+ * ```ts
691
+ * const err = await client.login("alice", "correct horse battery staple");
692
+ * if (err) console.error(err);
693
+ * ```
694
+ */
450
695
  login(username: string, password: string): Promise<Error | null>;
451
696
  /**
452
697
  * Returns the authorization cookie details. Throws if you don't have a
453
698
  * valid authorization cookie.
454
699
  */
700
+ /**
701
+ * Returns details about the currently authenticated session.
702
+ *
703
+ * @returns The authenticated user, token expiry, and active token.
704
+ *
705
+ * @example
706
+ * ```ts
707
+ * const auth = await client.whoami();
708
+ * console.log(auth.user.username, new Date(auth.exp));
709
+ * ```
710
+ */
455
711
  whoami(): Promise<{
456
- user: ICensoredUser;
712
+ user: IUser;
457
713
  exp: number;
458
714
  token: string;
459
715
  }>;
716
+ /**
717
+ * Logs out the current authenticated session from the server.
718
+ */
460
719
  logout(): Promise<void>;
461
720
  /**
462
721
  * Connects your device to the chat. You must have an valid authorization cookie.
@@ -471,7 +730,10 @@ export declare class Client extends EventEmitter {
471
730
  *
472
731
  * @example [user, err] = await client.register("MyUsername");
473
732
  */
474
- register(username: string, password: string): Promise<[ICensoredUser | null, Error | null]>;
733
+ register(username: string, password: string): Promise<[IUser | null, Error | null]>;
734
+ /**
735
+ * Returns a compact `<username><deviceID>` debug label.
736
+ */
475
737
  toString(): string;
476
738
  private redeemInvite;
477
739
  private retrieveInvites;