@vex-chat/libvex 1.0.2 → 2.0.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.
Files changed (151) hide show
  1. package/README.md +103 -41
  2. package/dist/Client.d.ts +449 -554
  3. package/dist/Client.d.ts.map +1 -0
  4. package/dist/Client.js +1542 -1484
  5. package/dist/Client.js.map +1 -1
  6. package/dist/Storage.d.ts +111 -0
  7. package/dist/Storage.d.ts.map +1 -0
  8. package/dist/Storage.js +2 -0
  9. package/dist/Storage.js.map +1 -0
  10. package/dist/__tests__/harness/memory-storage.d.ts +29 -27
  11. package/dist/__tests__/harness/memory-storage.d.ts.map +1 -0
  12. package/dist/__tests__/harness/memory-storage.js +120 -109
  13. package/dist/__tests__/harness/memory-storage.js.map +1 -1
  14. package/dist/codec.d.ts +44 -0
  15. package/dist/codec.d.ts.map +1 -0
  16. package/dist/codec.js +51 -0
  17. package/dist/codec.js.map +1 -0
  18. package/dist/codecs.d.ts +201 -0
  19. package/dist/codecs.d.ts.map +1 -0
  20. package/dist/codecs.js +67 -0
  21. package/dist/codecs.js.map +1 -0
  22. package/dist/index.d.ts +7 -5
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +1 -0
  25. package/dist/index.js.map +1 -1
  26. package/dist/keystore/memory.d.ts +5 -4
  27. package/dist/keystore/memory.d.ts.map +1 -0
  28. package/dist/keystore/memory.js +9 -7
  29. package/dist/keystore/memory.js.map +1 -1
  30. package/dist/keystore/node.d.ts +6 -5
  31. package/dist/keystore/node.d.ts.map +1 -0
  32. package/dist/keystore/node.js +38 -19
  33. package/dist/keystore/node.js.map +1 -1
  34. package/dist/preset/common.d.ts +9 -0
  35. package/dist/preset/common.d.ts.map +1 -0
  36. package/dist/preset/common.js +2 -0
  37. package/dist/preset/common.js.map +1 -0
  38. package/dist/preset/node.d.ts +3 -5
  39. package/dist/preset/node.d.ts.map +1 -0
  40. package/dist/preset/node.js +5 -7
  41. package/dist/preset/node.js.map +1 -1
  42. package/dist/preset/test.d.ts +4 -4
  43. package/dist/preset/test.d.ts.map +1 -0
  44. package/dist/preset/test.js +8 -10
  45. package/dist/preset/test.js.map +1 -1
  46. package/dist/storage/node.d.ts +4 -3
  47. package/dist/storage/node.d.ts.map +1 -0
  48. package/dist/storage/node.js +4 -4
  49. package/dist/storage/node.js.map +1 -1
  50. package/dist/storage/schema.d.ts +55 -57
  51. package/dist/storage/schema.d.ts.map +1 -0
  52. package/dist/storage/sqlite.d.ts +33 -28
  53. package/dist/storage/sqlite.d.ts.map +1 -0
  54. package/dist/storage/sqlite.js +330 -290
  55. package/dist/storage/sqlite.js.map +1 -1
  56. package/dist/transport/types.d.ts +23 -16
  57. package/dist/transport/types.d.ts.map +1 -0
  58. package/dist/transport/websocket.d.ts +26 -0
  59. package/dist/transport/websocket.d.ts.map +1 -0
  60. package/dist/transport/websocket.js +83 -0
  61. package/dist/transport/websocket.js.map +1 -0
  62. package/dist/types/crypto.d.ts +35 -0
  63. package/dist/types/crypto.d.ts.map +1 -0
  64. package/dist/types/crypto.js +9 -0
  65. package/dist/types/crypto.js.map +1 -0
  66. package/dist/types/identity.d.ts +17 -0
  67. package/dist/types/identity.d.ts.map +1 -0
  68. package/dist/types/identity.js +6 -0
  69. package/dist/types/identity.js.map +1 -0
  70. package/dist/types/index.d.ts +3 -0
  71. package/dist/types/index.d.ts.map +1 -0
  72. package/dist/types/index.js +2 -0
  73. package/dist/types/index.js.map +1 -0
  74. package/dist/utils/capitalize.d.ts +1 -0
  75. package/dist/utils/capitalize.d.ts.map +1 -0
  76. package/dist/utils/createLogger.d.ts +1 -0
  77. package/dist/utils/createLogger.d.ts.map +1 -0
  78. package/dist/utils/createLogger.js +4 -11
  79. package/dist/utils/createLogger.js.map +1 -1
  80. package/dist/utils/formatBytes.d.ts +1 -0
  81. package/dist/utils/formatBytes.d.ts.map +1 -0
  82. package/dist/utils/formatBytes.js +3 -1
  83. package/dist/utils/formatBytes.js.map +1 -1
  84. package/dist/utils/sqlSessionToCrypto.d.ts +4 -2
  85. package/dist/utils/sqlSessionToCrypto.d.ts.map +1 -0
  86. package/dist/utils/sqlSessionToCrypto.js +5 -5
  87. package/dist/utils/sqlSessionToCrypto.js.map +1 -1
  88. package/dist/utils/uint8uuid.d.ts +1 -4
  89. package/dist/utils/uint8uuid.d.ts.map +1 -0
  90. package/dist/utils/uint8uuid.js +1 -7
  91. package/dist/utils/uint8uuid.js.map +1 -1
  92. package/package.json +58 -87
  93. package/src/Client.ts +3304 -0
  94. package/{dist/IStorage.d.ts → src/Storage.ts} +70 -62
  95. package/src/__tests__/codec.test.ts +251 -0
  96. package/src/__tests__/ghost.png +0 -0
  97. package/src/__tests__/harness/fixtures.ts +22 -0
  98. package/src/__tests__/harness/memory-storage.ts +254 -0
  99. package/src/__tests__/harness/platform-transports.ts +17 -0
  100. package/src/__tests__/harness/poison-node-imports.ts +108 -0
  101. package/src/__tests__/harness/shared-suite.ts +446 -0
  102. package/src/__tests__/platform-browser.test.ts +19 -0
  103. package/src/__tests__/platform-node.test.ts +10 -0
  104. package/src/__tests__/triggered.png +0 -0
  105. package/src/codec.ts +68 -0
  106. package/src/codecs.ts +101 -0
  107. package/src/index.ts +33 -0
  108. package/src/keystore/memory.ts +30 -0
  109. package/src/keystore/node.ts +91 -0
  110. package/src/preset/common.ts +13 -0
  111. package/src/preset/node.ts +34 -0
  112. package/src/preset/test.ts +37 -0
  113. package/src/storage/node.ts +33 -0
  114. package/src/storage/schema.ts +94 -0
  115. package/src/storage/sqlite.ts +676 -0
  116. package/src/transport/types.ts +29 -0
  117. package/src/transport/websocket.ts +106 -0
  118. package/src/types/crypto.ts +39 -0
  119. package/src/types/identity.ts +18 -0
  120. package/src/types/index.ts +9 -0
  121. package/src/utils/capitalize.ts +6 -0
  122. package/src/utils/createLogger.ts +37 -0
  123. package/src/utils/formatBytes.ts +15 -0
  124. package/src/utils/sqlSessionToCrypto.ts +16 -0
  125. package/src/utils/uint8uuid.ts +7 -0
  126. package/dist/IStorage.js +0 -2
  127. package/dist/IStorage.js.map +0 -1
  128. package/dist/keystore/types.d.ts +0 -4
  129. package/dist/keystore/types.js +0 -2
  130. package/dist/keystore/types.js.map +0 -1
  131. package/dist/preset/expo.d.ts +0 -2
  132. package/dist/preset/expo.js +0 -37
  133. package/dist/preset/expo.js.map +0 -1
  134. package/dist/preset/tauri.d.ts +0 -2
  135. package/dist/preset/tauri.js +0 -35
  136. package/dist/preset/tauri.js.map +0 -1
  137. package/dist/preset/types.d.ts +0 -13
  138. package/dist/preset/types.js +0 -2
  139. package/dist/preset/types.js.map +0 -1
  140. package/dist/storage/expo.d.ts +0 -3
  141. package/dist/storage/expo.js +0 -18
  142. package/dist/storage/expo.js.map +0 -1
  143. package/dist/storage/tauri.d.ts +0 -3
  144. package/dist/storage/tauri.js +0 -21
  145. package/dist/storage/tauri.js.map +0 -1
  146. package/dist/transport/browser.d.ts +0 -17
  147. package/dist/transport/browser.js +0 -56
  148. package/dist/transport/browser.js.map +0 -1
  149. package/dist/utils/constants.d.ts +0 -8
  150. package/dist/utils/constants.js +0 -9
  151. package/dist/utils/constants.js.map +0 -1
package/dist/codecs.js ADDED
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Pre-built codec instances for every HTTP response type.
3
+ *
4
+ * Usage: import { UserCodec } from "./codecs.js";
5
+ * const data = decodeAxios(UserCodec, res.data);
6
+ *
7
+ * decode() returns typed data without runtime validation (SDK trusts server).
8
+ * For trust boundary validation, use codec.decodeSafe() directly.
9
+ */
10
+ import { ActionTokenSchema, ChannelSchema, DeviceSchema, EmojiSchema, FileSQLSchema, InviteSchema, KeyBundleSchema, PermissionSchema, ServerSchema, UserSchema, } from "@vex-chat/types";
11
+ import { z } from "zod/v4";
12
+ import { createCodec } from "./codec.js";
13
+ // ── Named schema codecs ─────────────────────────────────────────────────────
14
+ export const UserCodec = createCodec(UserSchema);
15
+ export const DeviceCodec = createCodec(DeviceSchema);
16
+ export const ServerCodec = createCodec(ServerSchema);
17
+ export const ChannelCodec = createCodec(ChannelSchema);
18
+ export const PermissionCodec = createCodec(PermissionSchema);
19
+ export const InviteCodec = createCodec(InviteSchema);
20
+ export const EmojiCodec = createCodec(EmojiSchema);
21
+ export const FileSQLCodec = createCodec(FileSQLSchema);
22
+ export const ActionTokenCodec = createCodec(ActionTokenSchema);
23
+ export const KeyBundleCodec = createCodec(KeyBundleSchema);
24
+ // ── Array codecs ────────────────────────────────────────────────────────────
25
+ export const UserArrayCodec = createCodec(z.array(UserSchema));
26
+ export const DeviceArrayCodec = createCodec(z.array(DeviceSchema));
27
+ export const ServerArrayCodec = createCodec(z.array(ServerSchema));
28
+ export const ChannelArrayCodec = createCodec(z.array(ChannelSchema));
29
+ export const PermissionArrayCodec = createCodec(z.array(PermissionSchema));
30
+ export const InviteArrayCodec = createCodec(z.array(InviteSchema));
31
+ export const EmojiArrayCodec = createCodec(z.array(EmojiSchema));
32
+ // ── Inline ad-hoc response codecs ───────────────────────────────────────────
33
+ export const ConnectResponseCodec = createCodec(z.object({ deviceToken: z.string() }));
34
+ export const AuthResponseCodec = createCodec(z.object({
35
+ token: z.string(),
36
+ user: UserSchema,
37
+ }));
38
+ export const DeviceChallengeCodec = createCodec(z.object({
39
+ challenge: z.string(),
40
+ challengeID: z.string(),
41
+ }));
42
+ export const WhoamiCodec = createCodec(z.object({
43
+ exp: z.number(),
44
+ token: z.string(),
45
+ user: UserSchema,
46
+ }));
47
+ export const OtkCountCodec = createCodec(z.object({ count: z.number() }));
48
+ // ── Helper: decode axios response buffer ────────────────────────────────────
49
+ /**
50
+ * Decode an axios arraybuffer response with a typed codec.
51
+ * Uses decodeSafe (Zod-validated) so schema mismatches surface immediately.
52
+ */
53
+ export function decodeAxios(codec,
54
+ /**
55
+ * Accepts `unknown` because axios types its `responseType: 'arraybuffer'`
56
+ * responses as `any`. At runtime this is always an `ArrayBuffer`.
57
+ */
58
+ data) {
59
+ if (data instanceof Uint8Array) {
60
+ return codec.decodeSafe(data);
61
+ }
62
+ if (data instanceof ArrayBuffer) {
63
+ return codec.decodeSafe(new Uint8Array(data));
64
+ }
65
+ throw new Error("Expected Uint8Array or ArrayBuffer from axios response");
66
+ }
67
+ //# sourceMappingURL=codecs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codecs.js","sourceRoot":"","sources":["../src/codecs.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  export { Client } from "./Client.js";
2
- export type { IChannels, IChannel, IClientOptions, IDevices, IEmojis, IDevice, IFile, IFiles, IFileProgress, IFileRes, IInvites, IKeys, IMe, IMessage, IMessages, IModeration, IPermission, IPermissions, IServers, IServer, ISessions, ISession, IUser, IUsers, } from "./Client.js";
3
- export type { IStorage } from "./IStorage.js";
4
- export type { KeyStore, StoredCredentials, IInvite } from "@vex-chat/types";
5
- export type { IClientAdapters, ILogger, IWebSocketCtor, IWebSocketLike, } from "./transport/types.js";
6
- export type { PlatformPreset } from "./preset/types.js";
2
+ export type { Channel, Channels, ClientOptions, Device, Devices, Emojis, FileProgress, FileRes, Files, Invites, Keys, Me, Message, Messages, Moderation, Permission, Permissions, Server, Servers, Session, Sessions, User, Users, VexFile, } from "./Client.js";
3
+ export { createCodec, msgpack } from "./codec.js";
4
+ export type { Storage } from "./Storage.js";
5
+ export type { Logger } from "./transport/types.js";
6
+ export type { KeyStore, StoredCredentials } from "./types/index.js";
7
+ export type { Invite } from "@vex-chat/types";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EACR,OAAO,EACP,QAAQ,EACR,aAAa,EACb,MAAM,EACN,OAAO,EACP,MAAM,EACN,YAAY,EACZ,OAAO,EACP,KAAK,EACL,OAAO,EACP,IAAI,EACJ,EAAE,EACF,OAAO,EACP,QAAQ,EACR,UAAU,EACV,UAAU,EACV,WAAW,EACX,MAAM,EACN,OAAO,EACP,OAAO,EACP,QAAQ,EACR,IAAI,EACJ,KAAK,EACL,OAAO,GACV,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAClD,YAAY,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,YAAY,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnD,YAAY,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEpE,YAAY,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  export { Client } from "./Client.js";
2
+ export { createCodec, msgpack } from "./codec.js";
2
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AA2BrC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC"}
@@ -2,10 +2,11 @@
2
2
  * In-memory KeyStore for testing and ephemeral sessions.
3
3
  * No persistence — credentials are lost when the process exits.
4
4
  */
5
- import type { KeyStore, StoredCredentials } from "@vex-chat/types";
5
+ import type { KeyStore, StoredCredentials } from "../types/index.js";
6
6
  export declare class MemoryKeyStore implements KeyStore {
7
- private store;
8
- load(username?: string): Promise<StoredCredentials | null>;
9
- save(creds: StoredCredentials): Promise<void>;
7
+ private readonly store;
10
8
  clear(username: string): Promise<void>;
9
+ load(username?: string): Promise<null | StoredCredentials>;
10
+ save(creds: StoredCredentials): Promise<void>;
11
11
  }
12
+ //# sourceMappingURL=memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/keystore/memory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAErE,qBAAa,cAAe,YAAW,QAAQ;IAC3C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAwC;IAE9D,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKtC,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAW1D,IAAI,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;CAIhD"}
@@ -1,18 +1,20 @@
1
1
  export class MemoryKeyStore {
2
2
  store = new Map();
3
- async load(username) {
3
+ clear(username) {
4
+ this.store.delete(username);
5
+ return Promise.resolve();
6
+ }
7
+ load(username) {
4
8
  if (username) {
5
- return this.store.get(username) ?? null;
9
+ return Promise.resolve(this.store.get(username) ?? null);
6
10
  }
7
11
  // Return the most recently saved credentials
8
12
  const entries = [...this.store.values()];
9
- return entries.length > 0 ? entries[entries.length - 1] : null;
13
+ return Promise.resolve(entries.length > 0 ? (entries[entries.length - 1] ?? null) : null);
10
14
  }
11
- async save(creds) {
15
+ save(creds) {
12
16
  this.store.set(creds.username, creds);
13
- }
14
- async clear(username) {
15
- this.store.delete(username);
17
+ return Promise.resolve();
16
18
  }
17
19
  }
18
20
  //# sourceMappingURL=memory.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/keystore/memory.ts"],"names":[],"mappings":"AAMA,MAAM,OAAO,cAAc;IACf,KAAK,GAAG,IAAI,GAAG,EAA6B,CAAC;IAErD,KAAK,CAAC,IAAI,CAAC,QAAiB;QACxB,IAAI,QAAQ,EAAE,CAAC;YACX,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC;QAC5C,CAAC;QACD,6CAA6C;QAC7C,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QACzC,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAwB;QAC/B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,QAAgB;QACxB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;CACJ"}
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/keystore/memory.ts"],"names":[],"mappings":"AAMA,MAAM,OAAO,cAAc;IACN,KAAK,GAAG,IAAI,GAAG,EAA6B,CAAC;IAE9D,KAAK,CAAC,QAAgB;QAClB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC5B,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;IAED,IAAI,CAAC,QAAiB;QAClB,IAAI,QAAQ,EAAE,CAAC;YACX,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,CAAC;QAC7D,CAAC;QACD,6CAA6C;QAC7C,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QACzC,OAAO,OAAO,CAAC,OAAO,CAClB,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CACpE,CAAC;IACN,CAAC;IAED,IAAI,CAAC,KAAwB;QACzB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACtC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;CACJ"}
@@ -1,10 +1,11 @@
1
- import type { KeyStore, StoredCredentials } from "@vex-chat/types";
1
+ import type { KeyStore, StoredCredentials } from "../types/index.js";
2
2
  export declare class NodeKeyStore implements KeyStore {
3
- private dir;
3
+ private readonly dir;
4
4
  constructor(dir?: string);
5
- private filePath;
6
- load(username?: string): Promise<StoredCredentials | null>;
7
- save(creds: StoredCredentials): Promise<void>;
8
5
  clear(username: string): Promise<void>;
6
+ load(username?: string): Promise<null | StoredCredentials>;
7
+ save(creds: StoredCredentials): Promise<void>;
8
+ private filePath;
9
9
  private readFile;
10
10
  }
11
+ //# sourceMappingURL=node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/keystore/node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAarE,qBAAa,YAAa,YAAW,QAAQ;IACzC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;gBAEjB,GAAG,GAAE,MAAY;IAI7B,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAStC,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAyB1D,IAAI,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAO7C,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,QAAQ;CAanB"}
@@ -1,3 +1,5 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
1
3
  /**
2
4
  * File-backed KeyStore for Node.js (CLI tools, bots, integration tests).
3
5
  *
@@ -5,19 +7,23 @@
5
7
  * Node-only — imports node:fs.
6
8
  */
7
9
  import { XUtils } from "@vex-chat/crypto";
8
- import * as fs from "node:fs";
9
- import * as path from "node:path";
10
10
  export class NodeKeyStore {
11
11
  dir;
12
12
  constructor(dir = ".") {
13
13
  this.dir = dir;
14
14
  }
15
- filePath(username) {
16
- return path.join(this.dir, `${username}.vex`);
15
+ clear(username) {
16
+ try {
17
+ fs.unlinkSync(this.filePath(username));
18
+ }
19
+ catch {
20
+ // File may not exist
21
+ }
22
+ return Promise.resolve();
17
23
  }
18
- async load(username) {
24
+ load(username) {
19
25
  if (username) {
20
- return this.readFile(this.filePath(username));
26
+ return Promise.resolve(this.readFile(this.filePath(username)));
21
27
  }
22
28
  // Find most recent .vex file in the directory
23
29
  try {
@@ -25,40 +31,53 @@ export class NodeKeyStore {
25
31
  .readdirSync(this.dir)
26
32
  .filter((f) => f.endsWith(".vex"))
27
33
  .map((f) => ({
28
- name: f,
29
34
  mtime: fs.statSync(path.join(this.dir, f)).mtimeMs,
35
+ name: f,
30
36
  }))
31
37
  .sort((a, b) => b.mtime - a.mtime);
32
38
  if (files.length === 0)
33
- return null;
34
- return this.readFile(path.join(this.dir, files[0].name));
39
+ return Promise.resolve(null);
40
+ const newest = files[0];
41
+ if (!newest)
42
+ return Promise.resolve(null);
43
+ return Promise.resolve(this.readFile(path.join(this.dir, newest.name)));
35
44
  }
36
45
  catch {
37
- return null;
46
+ return Promise.resolve(null);
38
47
  }
39
48
  }
40
- async save(creds) {
49
+ save(creds) {
41
50
  const data = JSON.stringify(creds);
42
51
  const encrypted = XUtils.encryptKeyData("", data);
43
52
  fs.writeFileSync(this.filePath(creds.username), encrypted);
53
+ return Promise.resolve();
44
54
  }
45
- async clear(username) {
46
- try {
47
- fs.unlinkSync(this.filePath(username));
48
- }
49
- catch {
50
- // File may not exist
51
- }
55
+ filePath(username) {
56
+ return path.join(this.dir, `${username}.vex`);
52
57
  }
53
58
  readFile(filePath) {
54
59
  try {
55
60
  const data = fs.readFileSync(filePath);
56
61
  const decrypted = XUtils.decryptKeyData(new Uint8Array(data), "");
57
- return JSON.parse(decrypted);
62
+ const parsed = JSON.parse(decrypted);
63
+ if (isStoredCredentials(parsed)) {
64
+ return parsed;
65
+ }
66
+ return null;
58
67
  }
59
68
  catch {
60
69
  return null;
61
70
  }
62
71
  }
63
72
  }
73
+ function isStoredCredentials(value) {
74
+ if (typeof value !== "object" || value === null)
75
+ return false;
76
+ return ("username" in value &&
77
+ typeof value.username === "string" &&
78
+ "deviceID" in value &&
79
+ typeof value.deviceID === "string" &&
80
+ "deviceKey" in value &&
81
+ typeof value.deviceKey === "string");
82
+ }
64
83
  //# sourceMappingURL=node.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/keystore/node.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAGlC,MAAM,OAAO,YAAY;IACb,GAAG,CAAS;IAEpB,YAAY,MAAc,GAAG;QACzB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACnB,CAAC;IAEO,QAAQ,CAAC,QAAgB;QAC7B,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,MAAM,CAAC,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,QAAiB;QACxB,IAAI,QAAQ,EAAE,CAAC;YACX,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;QAClD,CAAC;QACD,8CAA8C;QAC9C,IAAI,CAAC;YACD,MAAM,KAAK,GAAG,EAAE;iBACX,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;iBACrB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;iBACjC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACT,IAAI,EAAE,CAAC;gBACP,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO;aACrD,CAAC,CAAC;iBACF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;YACvC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAC;YACpC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9D,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAwB;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,SAAS,GAAG,MAAM,CAAC,cAAc,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAClD,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC,CAAC;IAC/D,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,QAAgB;QACxB,IAAI,CAAC;YACD,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC3C,CAAC;QAAC,MAAM,CAAC;YACL,qBAAqB;QACzB,CAAC;IACL,CAAC;IAEO,QAAQ,CAAC,QAAgB;QAC7B,IAAI,CAAC;YACD,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;YACvC,MAAM,SAAS,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;YAClE,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAsB,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;CACJ"}
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/keystore/node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { Storage } from "../Storage.js";
2
+ import type { Logger } from "../transport/types.js";
3
+ /** Internal preset interface used by nodePreset and testPreset. */
4
+ export interface PlatformPreset {
5
+ createStorage(dbName: string, privateKey: string, logger: Logger): Promise<Storage>;
6
+ deviceName: string;
7
+ logger: Logger;
8
+ }
9
+ //# sourceMappingURL=common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/preset/common.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAEpD,mEAAmE;AACnE,MAAM,WAAW,cAAc;IAC3B,aAAa,CACT,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,CAAC,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAClB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=common.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/preset/common.ts"],"names":[],"mappings":""}
@@ -1,12 +1,10 @@
1
1
  /**
2
2
  * Platform preset for Node.js (CLI tools, bots, tests).
3
3
  *
4
- * - WebSocket: ws (loaded dynamically)
4
+ * - WebSocket: native global (Node 22+)
5
5
  * - Storage: Kysely + better-sqlite3
6
6
  * - Logger: winston (loaded dynamically)
7
- *
8
- * Async because ws and winston are lazy-loaded to keep them out of
9
- * browser bundles that import from the main entrypoint.
10
7
  */
11
- import type { PlatformPreset } from "./types.js";
8
+ import type { PlatformPreset } from "./common.js";
12
9
  export declare function nodePreset(logLevel?: string): Promise<PlatformPreset>;
10
+ //# sourceMappingURL=node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/preset/node.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,wBAAsB,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAsB3E"}
@@ -1,16 +1,14 @@
1
1
  export async function nodePreset(logLevel) {
2
- const { default: WebSocket } = await import("ws");
3
2
  const { createLogger } = await import("../utils/createLogger.js");
4
3
  const logger = createLogger("libvex", logLevel);
5
4
  return {
6
- adapters: {
7
- logger,
8
- WebSocket: WebSocket,
9
- },
10
- async createStorage(dbName, privateKey, _logger) {
5
+ async createStorage(dbName, privateKey, storageLogger) {
11
6
  const { createNodeStorage } = await import("../storage/node.js");
12
- return createNodeStorage(dbName, privateKey, _logger ?? logger);
7
+ const storage = createNodeStorage(dbName, privateKey, storageLogger);
8
+ return storage;
13
9
  },
10
+ deviceName: process.platform,
11
+ logger,
14
12
  };
15
13
  }
16
14
  //# sourceMappingURL=node.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/preset/node.ts"],"names":[],"mappings":"AAaA,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAiB;IAC9C,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;IAClD,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAC;IAClE,MAAM,MAAM,GAAY,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAEzD,OAAO;QACH,QAAQ,EAAE;YACN,MAAM;YACN,SAAS,EAAE,SAAgB;SAC9B;QACD,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO;YAC3C,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;YACjE,OAAO,iBAAiB,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,IAAI,MAAM,CAAC,CAAC;QACpE,CAAC;KACJ,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/preset/node.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAiB;IAC9C,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAC;IAClE,MAAM,MAAM,GAAW,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAExD,OAAO;QACH,KAAK,CAAC,aAAa,CACf,MAAM,EACN,UAAU,EACV,aAAa;YAEb,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;YAEjE,MAAM,OAAO,GAAY,iBAAiB,CACtC,MAAM,EACN,UAAU,EACV,aAAa,CAChB,CAAC;YACF,OAAO,OAAO,CAAC;QACnB,CAAC;QACD,UAAU,EAAE,OAAO,CAAC,QAAQ;QAC5B,MAAM;KACT,CAAC;AACN,CAAC"}
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * Platform preset for tests — no I/O, no platform dependencies.
3
3
  *
4
- * - WebSocket: must be injected by the test (platform-specific)
4
+ * - WebSocket: native global (Node 22+)
5
5
  * - Storage: in-memory (no persistence)
6
6
  * - Logger: console
7
7
  */
8
- import type { PlatformPreset } from "./types.js";
9
- import type { IWebSocketCtor } from "../transport/types.js";
10
- export declare function testPreset(WebSocket: IWebSocketCtor): PlatformPreset;
8
+ import type { PlatformPreset } from "./common.js";
9
+ export declare function testPreset(): PlatformPreset;
10
+ //# sourceMappingURL=test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../src/preset/test.ts"],"names":[],"mappings":"AACA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAelD,wBAAgB,UAAU,IAAI,cAAc,CAa3C"}
@@ -1,28 +1,26 @@
1
1
  const logger = {
2
+ debug() { },
3
+ error(m) {
4
+ console.error(`[test] ${m}`);
5
+ },
2
6
  info(m) {
3
7
  console.log(`[test] ${m}`);
4
8
  },
5
9
  warn(m) {
6
10
  console.warn(`[test] ${m}`);
7
11
  },
8
- error(m) {
9
- console.error(`[test] ${m}`);
10
- },
11
- debug() { },
12
12
  };
13
- export function testPreset(WebSocket) {
13
+ export function testPreset() {
14
14
  return {
15
- adapters: {
16
- logger,
17
- WebSocket,
18
- },
19
- async createStorage(dbName, privateKey, _logger) {
15
+ async createStorage(_dbName, privateKey, _logger) {
20
16
  // Lazy import to avoid pulling eventemitter3 into the type graph
21
17
  const { MemoryStorage } = await import("../__tests__/harness/memory-storage.js");
22
18
  const storage = new MemoryStorage(privateKey);
23
19
  await storage.init();
24
20
  return storage;
25
21
  },
22
+ deviceName: "test",
23
+ logger,
26
24
  };
27
25
  }
28
26
  //# sourceMappingURL=test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/preset/test.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,GAAY;IACpB,IAAI,CAAC,CAAS;QACV,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC/B,CAAC;IACD,IAAI,CAAC,CAAS;QACV,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAChC,CAAC;IACD,KAAK,CAAC,CAAS;QACX,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IACjC,CAAC;IACD,KAAK,KAAI,CAAC;CACb,CAAC;AAEF,MAAM,UAAU,UAAU,CAAC,SAAyB;IAChD,OAAO;QACH,QAAQ,EAAE;YACN,MAAM;YACN,SAAS;SACZ;QACD,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO;YAC3C,iEAAiE;YACjE,MAAM,EAAE,aAAa,EAAE,GACnB,MAAM,MAAM,CAAC,wCAAwC,CAAC,CAAC;YAC3D,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC,UAAU,CAAC,CAAC;YAC9C,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;YACrB,OAAO,OAAO,CAAC;QACnB,CAAC;KACJ,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/preset/test.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,GAAW;IACnB,KAAK,KAAI,CAAC;IACV,KAAK,CAAC,CAAS;QACX,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IACjC,CAAC;IACD,IAAI,CAAC,CAAS;QACV,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC/B,CAAC;IACD,IAAI,CAAC,CAAS;QACV,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAChC,CAAC;CACJ,CAAC;AAEF,MAAM,UAAU,UAAU;IACtB,OAAO;QACH,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO;YAC5C,iEAAiE;YACjE,MAAM,EAAE,aAAa,EAAE,GACnB,MAAM,MAAM,CAAC,wCAAwC,CAAC,CAAC;YAC3D,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC,UAAU,CAAC,CAAC;YAC9C,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;YACrB,OAAO,OAAO,CAAC;QACnB,CAAC;QACD,UAAU,EAAE,MAAM;QAClB,MAAM;KACT,CAAC;AACN,CAAC"}
@@ -1,3 +1,4 @@
1
- import type { IStorage } from "../IStorage.js";
2
- import type { ILogger } from "../transport/types.js";
3
- export declare function createNodeStorage(dbPath: string, SK: string, logger?: ILogger): IStorage;
1
+ import type { Storage } from "../Storage.js";
2
+ import type { Logger } from "../transport/types.js";
3
+ export declare function createNodeStorage(dbPath: string, SK: string, logger?: Logger): Storage;
4
+ //# sourceMappingURL=node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/storage/node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAYpD,wBAAgB,iBAAiB,CAC7B,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,EACV,MAAM,CAAC,EAAE,MAAM,GAChB,OAAO,CAeT"}
@@ -1,9 +1,9 @@
1
+ import BetterSqlite3 from "better-sqlite3";
1
2
  /**
2
3
  * Node.js storage factory — creates SqliteStorage with better-sqlite3 dialect.
3
4
  * Node-only — imports better-sqlite3 which is a native addon.
4
5
  */
5
6
  import { Kysely, SqliteDialect } from "kysely";
6
- import BetterSqlite3 from "better-sqlite3";
7
7
  import { SqliteStorage } from "./sqlite.js";
8
8
  export function createNodeStorage(dbPath, SK, logger) {
9
9
  const db = new Kysely({
@@ -12,13 +12,13 @@ export function createNodeStorage(dbPath, SK, logger) {
12
12
  }),
13
13
  });
14
14
  const log = logger ?? {
15
+ debug() { },
16
+ error() { },
15
17
  info() { },
16
18
  warn() { },
17
- error() { },
18
- debug() { },
19
19
  };
20
20
  const storage = new SqliteStorage(db, SK, log);
21
- storage.init();
21
+ void storage.init();
22
22
  return storage;
23
23
  }
24
24
  //# sourceMappingURL=node.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/storage/node.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC/C,OAAO,aAAa,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAI5C,MAAM,UAAU,iBAAiB,CAC7B,MAAc,EACd,EAAU,EACV,MAAgB;IAEhB,MAAM,EAAE,GAAG,IAAI,MAAM,CAAiB;QAClC,OAAO,EAAE,IAAI,aAAa,CAAC;YACvB,QAAQ,EAAE,IAAI,aAAa,CAAC,MAAM,CAAC;SACtC,CAAC;KACL,CAAC,CAAC;IACH,MAAM,GAAG,GAAY,MAAM,IAAI;QAC3B,IAAI,KAAI,CAAC;QACT,IAAI,KAAI,CAAC;QACT,KAAK,KAAI,CAAC;QACV,KAAK,KAAI,CAAC;KACb,CAAC;IACF,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;IAC/C,OAAO,CAAC,IAAI,EAAE,CAAC;IACf,OAAO,OAAO,CAAC;AACnB,CAAC"}
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/storage/node.ts"],"names":[],"mappings":"AAIA,OAAO,aAAa,MAAM,gBAAgB,CAAC;AAC3C;;;GAGG;AACH,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,UAAU,iBAAiB,CAC7B,MAAc,EACd,EAAU,EACV,MAAe;IAEf,MAAM,EAAE,GAAG,IAAI,MAAM,CAAiB;QAClC,OAAO,EAAE,IAAI,aAAa,CAAC;YACvB,QAAQ,EAAE,IAAI,aAAa,CAAC,MAAM,CAAC;SACtC,CAAC;KACL,CAAC,CAAC;IACH,MAAM,GAAG,GAAW,MAAM,IAAI;QAC1B,KAAK,KAAI,CAAC;QACV,KAAK,KAAI,CAAC;QACV,IAAI,KAAI,CAAC;QACT,IAAI,KAAI,CAAC;KACZ,CAAC;IACF,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;IAC/C,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC;IACpB,OAAO,OAAO,CAAC;AACnB,CAAC"}
@@ -1,79 +1,77 @@
1
1
  /**
2
2
  * Kysely typed table interfaces for the client-side SQLite database.
3
- *
4
- * These mirror the schema previously created by knex / raw SQL in the
5
- * three platform-specific storage implementations (Node, Tauri, Expo).
6
3
  */
7
- import type { Generated, Insertable, Selectable, Updateable } from "kysely";
8
- interface MessagesTable {
9
- nonce: string;
10
- sender: string;
11
- recipient: string;
12
- group: string | null;
13
- mailID: string;
14
- message: string;
15
- direction: string;
16
- timestamp: string;
17
- decrypted: number;
18
- forward: number;
19
- authorID: string;
20
- readerID: string;
4
+ import type { ColumnType, Generated, Insertable, Selectable, Updateable } from "kysely";
5
+ export interface ClientDatabase {
6
+ devices: DevicesTable;
7
+ messages: MessagesTable;
8
+ oneTimeKeys: OneTimeKeysTable;
9
+ preKeys: PreKeysTable;
10
+ sessions: SessionsTable;
21
11
  }
12
+ export type DeviceRow = Selectable<DevicesTable>;
13
+ export type DeviceUpdate = Updateable<DevicesTable>;
14
+ export type MessageRow = Selectable<MessagesTable>;
15
+ export type MessageUpdate = Updateable<MessagesTable>;
16
+ export type NewDevice = Insertable<DevicesTable>;
17
+ export type NewMessage = Insertable<MessagesTable>;
18
+ export type NewOneTimeKey = Insertable<OneTimeKeysTable>;
19
+ export type NewPreKey = Insertable<PreKeysTable>;
20
+ export type NewSession = Insertable<SessionsTable>;
21
+ export type OneTimeKeyRow = Selectable<OneTimeKeysTable>;
22
+ export type PreKeyRow = Selectable<PreKeysTable>;
23
+ export type SessionRow = Selectable<SessionsTable>;
24
+ export type SessionUpdate = Updateable<SessionsTable>;
22
25
  interface DevicesTable {
26
+ deleted: number;
23
27
  deviceID: string;
28
+ lastLogin: string;
29
+ name: string;
24
30
  owner: string;
25
31
  signKey: string;
26
- name: string;
27
- lastLogin: string;
28
- deleted: number;
29
32
  }
30
- interface SessionsTable {
31
- sessionID: string;
32
- userID: string;
33
- deviceID: string;
34
- SK: string;
35
- publicKey: string;
36
- fingerprint: string;
37
- mode: string;
38
- lastUsed: string;
39
- verified: number;
33
+ interface MessagesTable {
34
+ authorID: string;
35
+ decrypted: number;
36
+ direction: string;
37
+ forward: number;
38
+ group: null | string;
39
+ mailID: string;
40
+ message: string;
41
+ nonce: string;
42
+ readerID: string;
43
+ recipient: string;
44
+ sender: string;
45
+ timestamp: string;
40
46
  }
41
- interface PreKeysTable {
47
+ interface OneTimeKeysTable {
48
+ deviceID: ColumnType<string, string | undefined, string>;
42
49
  index: Generated<number>;
43
- keyID: string;
44
- userID: string;
45
- deviceID: string;
50
+ keyID: ColumnType<string, string | undefined, string>;
46
51
  privateKey: string;
47
52
  publicKey: string;
48
53
  signature: string;
54
+ userID: ColumnType<string, string | undefined, string>;
49
55
  }
50
- interface OneTimeKeysTable {
56
+ interface PreKeysTable {
57
+ deviceID: ColumnType<string, string | undefined, string>;
51
58
  index: Generated<number>;
52
- keyID: string;
53
- userID: string;
54
- deviceID: string;
59
+ keyID: ColumnType<string, string | undefined, string>;
55
60
  privateKey: string;
56
61
  publicKey: string;
57
62
  signature: string;
63
+ userID: ColumnType<string, string | undefined, string>;
58
64
  }
59
- export interface ClientDatabase {
60
- messages: MessagesTable;
61
- devices: DevicesTable;
62
- sessions: SessionsTable;
63
- preKeys: PreKeysTable;
64
- oneTimeKeys: OneTimeKeysTable;
65
+ interface SessionsTable {
66
+ deviceID: string;
67
+ fingerprint: string;
68
+ lastUsed: string;
69
+ mode: string;
70
+ publicKey: string;
71
+ sessionID: string;
72
+ SK: string;
73
+ userID: string;
74
+ verified: number;
65
75
  }
66
- export type MessageRow = Selectable<MessagesTable>;
67
- export type NewMessage = Insertable<MessagesTable>;
68
- export type MessageUpdate = Updateable<MessagesTable>;
69
- export type DeviceRow = Selectable<DevicesTable>;
70
- export type NewDevice = Insertable<DevicesTable>;
71
- export type DeviceUpdate = Updateable<DevicesTable>;
72
- export type SessionRow = Selectable<SessionsTable>;
73
- export type NewSession = Insertable<SessionsTable>;
74
- export type SessionUpdate = Updateable<SessionsTable>;
75
- export type PreKeyRow = Selectable<PreKeysTable>;
76
- export type NewPreKey = Insertable<PreKeysTable>;
77
- export type OneTimeKeyRow = Selectable<OneTimeKeysTable>;
78
- export type NewOneTimeKey = Insertable<OneTimeKeysTable>;
79
76
  export {};
77
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/storage/schema.ts"],"names":[],"mappings":"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"}