simplex-chat 6.5.0-beta.4.4 → 6.5.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.
@@ -74,7 +74,7 @@ Defined in: [src/api.ts:6](../src/api.ts#L6)
74
74
 
75
75
  ### stack?
76
76
 
77
- > `optional` **stack**: `string`
77
+ > `optional` **stack?**: `string`
78
78
 
79
79
  Defined in: [node\_modules/typescript/lib/lib.es5.d.ts:1078](../node_modules/typescript/lib/lib.es5.d.ts#L1078)
80
80
 
@@ -14,7 +14,7 @@ Bot address settings.
14
14
 
15
15
  ### autoAccept?
16
16
 
17
- > `optional` **autoAccept**: `boolean`
17
+ > `optional` **autoAccept?**: `boolean`
18
18
 
19
19
  Defined in: [src/api.ts:28](../src/api.ts#L28)
20
20
 
@@ -30,7 +30,7 @@ true
30
30
 
31
31
  ### businessAddress?
32
32
 
33
- > `optional` **businessAddress**: `boolean`
33
+ > `optional` **businessAddress?**: `boolean`
34
34
 
35
35
  Defined in: [src/api.ts:41](../src/api.ts#L41)
36
36
 
@@ -47,7 +47,7 @@ false
47
47
 
48
48
  ### welcomeMessage?
49
49
 
50
- > `optional` **welcomeMessage**: `string` \| `MsgContent`
50
+ > `optional` **welcomeMessage?**: `string` \| `MsgContent`
51
51
 
52
52
  Defined in: [src/api.ts:34](../src/api.ts#L34)
53
53
 
@@ -0,0 +1,64 @@
1
+ [**simplex-chat**](README.md)
2
+
3
+ ***
4
+
5
+ [simplex-chat](README.md) / [api](Namespace.api.md) / DbConfig
6
+
7
+ # Type Alias: DbConfig
8
+
9
+ > **DbConfig** = \{ `encryptionKey?`: `string`; `filePrefix`: `string`; `type`: `"sqlite"`; \} \| \{ `connectionString`: `string`; `schemaPrefix?`: `string`; `type`: `"postgres"`; \}
10
+
11
+ Defined in: [src/api.ts:65](../src/api.ts#L65)
12
+
13
+ Database configuration. The native library is built against exactly one
14
+ backend (see `simplex_backend` / `SIMPLEX_BACKEND` at install time); this
15
+ type makes the caller state which one they are targeting so field names
16
+ can't lie about their meaning.
17
+
18
+ ## Union Members
19
+
20
+ ### Type Literal
21
+
22
+ \{ `encryptionKey?`: `string`; `filePrefix`: `string`; `type`: `"sqlite"`; \}
23
+
24
+ #### encryptionKey?
25
+
26
+ > `optional` **encryptionKey?**: `string`
27
+
28
+ Optional SQLCipher encryption key. Empty/omitted = unencrypted.
29
+
30
+ #### filePrefix
31
+
32
+ > **filePrefix**: `string`
33
+
34
+ File prefix — two schema files are named `<prefix>_chat.db` and `<prefix>_agent.db`.
35
+
36
+ #### type
37
+
38
+ > **type**: `"sqlite"`
39
+
40
+ SQLite backend (default).
41
+
42
+ ***
43
+
44
+ ### Type Literal
45
+
46
+ \{ `connectionString`: `string`; `schemaPrefix?`: `string`; `type`: `"postgres"`; \}
47
+
48
+ #### connectionString
49
+
50
+ > **connectionString**: `string`
51
+
52
+ PostgreSQL connection string (e.g. `postgres://user:pass@host/db`).
53
+
54
+ #### schemaPrefix?
55
+
56
+ > `optional` **schemaPrefix?**: `string`
57
+
58
+ Schema prefix used to namespace tables. Defaults to `"simplex_v1"` when omitted.
59
+
60
+ #### type
61
+
62
+ > **type**: `"postgres"`
63
+
64
+ PostgreSQL backend (Linux x86_64 only, libpq5 required).
@@ -4,7 +4,7 @@
4
4
 
5
5
  [simplex-chat](README.md) / [api](Namespace.api.md) / EventSubscriberFunc
6
6
 
7
- # Type Alias: EventSubscriberFunc()\<K\>
7
+ # Type Alias: EventSubscriberFunc\<K\>
8
8
 
9
9
  > **EventSubscriberFunc**\<`K`\> = (`event`) => `void` \| `Promise`\<`void`\>
10
10
 
@@ -20,7 +20,7 @@ Defined in: [src/api.ts:50](../src/api.ts#L50)
20
20
 
21
21
  ### event
22
22
 
23
- `ChatEvent` & \{ `type`: `K`; \}
23
+ `ChatEvent` & `object`
24
24
 
25
25
  ## Returns
26
26
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  > **run**(`__namedParameters`): `Promise`\<\[[`ChatApi`](api.Class.ChatApi.md), `User`, `UserContactLink` \| `undefined`\]\>
10
10
 
11
- Defined in: [src/bot.ts:49](../src/bot.ts#L49)
11
+ Defined in: [src/bot.ts:47](../src/bot.ts#L47)
12
12
 
13
13
  ## Parameters
14
14
 
@@ -6,43 +6,43 @@
6
6
 
7
7
  # Interface: BotConfig
8
8
 
9
- Defined in: [src/bot.ts:37](../src/bot.ts#L37)
9
+ Defined in: [src/bot.ts:35](../src/bot.ts#L35)
10
10
 
11
11
  ## Properties
12
12
 
13
13
  ### dbOpts
14
14
 
15
- > **dbOpts**: [`BotDbOpts`](bot.Interface.BotDbOpts.md)
15
+ > **dbOpts**: [`BotDbOpts`](bot.TypeAlias.BotDbOpts.md)
16
16
 
17
- Defined in: [src/bot.ts:39](../src/bot.ts#L39)
17
+ Defined in: [src/bot.ts:37](../src/bot.ts#L37)
18
18
 
19
19
  ***
20
20
 
21
21
  ### events?
22
22
 
23
- > `optional` **events**: [`EventSubscribers`](api.TypeAlias.EventSubscribers.md)
23
+ > `optional` **events?**: [`EventSubscribers`](api.TypeAlias.EventSubscribers.md)
24
24
 
25
- Defined in: [src/bot.ts:46](../src/bot.ts#L46)
25
+ Defined in: [src/bot.ts:44](../src/bot.ts#L44)
26
26
 
27
27
  ***
28
28
 
29
29
  ### onCommands?
30
30
 
31
- > `optional` **onCommands**: \{\[`key`: `string`\]: (`chatItem`, `command`) => `void` \| `Promise`\<`void`\> \| `undefined`; \}
31
+ > `optional` **onCommands?**: `object`
32
32
 
33
- Defined in: [src/bot.ts:43](../src/bot.ts#L43)
33
+ Defined in: [src/bot.ts:41](../src/bot.ts#L41)
34
34
 
35
35
  #### Index Signature
36
36
 
37
- \[`key`: `string`\]: (`chatItem`, `command`) => `void` \| `Promise`\<`void`\> \| `undefined`
37
+ \[`key`: `string`\]: ((`chatItem`, `command`) => `void` \| `Promise`\<`void`\>) \| `undefined`
38
38
 
39
39
  ***
40
40
 
41
- ### onMessage()?
41
+ ### onMessage?
42
42
 
43
- > `optional` **onMessage**: (`chatItem`, `content`) => `void` \| `Promise`\<`void`\>
43
+ > `optional` **onMessage?**: (`chatItem`, `content`) => `void` \| `Promise`\<`void`\>
44
44
 
45
- Defined in: [src/bot.ts:41](../src/bot.ts#L41)
45
+ Defined in: [src/bot.ts:39](../src/bot.ts#L39)
46
46
 
47
47
  #### Parameters
48
48
 
@@ -64,7 +64,7 @@ Defined in: [src/bot.ts:41](../src/bot.ts#L41)
64
64
 
65
65
  > **options**: [`BotOptions`](bot.Interface.BotOptions.md)
66
66
 
67
- Defined in: [src/bot.ts:40](../src/bot.ts#L40)
67
+ Defined in: [src/bot.ts:38](../src/bot.ts#L38)
68
68
 
69
69
  ***
70
70
 
@@ -72,4 +72,4 @@ Defined in: [src/bot.ts:40](../src/bot.ts#L40)
72
72
 
73
73
  > **profile**: `Profile`
74
74
 
75
- Defined in: [src/bot.ts:38](../src/bot.ts#L38)
75
+ Defined in: [src/bot.ts:36](../src/bot.ts#L36)
@@ -6,76 +6,76 @@
6
6
 
7
7
  # Interface: BotOptions
8
8
 
9
- Defined in: [src/bot.ts:13](../src/bot.ts#L13)
9
+ Defined in: [src/bot.ts:11](../src/bot.ts#L11)
10
10
 
11
11
  ## Properties
12
12
 
13
13
  ### addressSettings?
14
14
 
15
- > `optional` **addressSettings**: [`BotAddressSettings`](api.Interface.BotAddressSettings.md)
15
+ > `optional` **addressSettings?**: [`BotAddressSettings`](api.Interface.BotAddressSettings.md)
16
16
 
17
- Defined in: [src/bot.ts:17](../src/bot.ts#L17)
17
+ Defined in: [src/bot.ts:15](../src/bot.ts#L15)
18
18
 
19
19
  ***
20
20
 
21
21
  ### allowFiles?
22
22
 
23
- > `optional` **allowFiles**: `boolean`
23
+ > `optional` **allowFiles?**: `boolean`
24
24
 
25
- Defined in: [src/bot.ts:18](../src/bot.ts#L18)
25
+ Defined in: [src/bot.ts:16](../src/bot.ts#L16)
26
26
 
27
27
  ***
28
28
 
29
29
  ### commands?
30
30
 
31
- > `optional` **commands**: `ChatBotCommand`[]
31
+ > `optional` **commands?**: `ChatBotCommand`[]
32
32
 
33
- Defined in: [src/bot.ts:19](../src/bot.ts#L19)
33
+ Defined in: [src/bot.ts:17](../src/bot.ts#L17)
34
34
 
35
35
  ***
36
36
 
37
37
  ### createAddress?
38
38
 
39
- > `optional` **createAddress**: `boolean`
39
+ > `optional` **createAddress?**: `boolean`
40
40
 
41
- Defined in: [src/bot.ts:14](../src/bot.ts#L14)
41
+ Defined in: [src/bot.ts:12](../src/bot.ts#L12)
42
42
 
43
43
  ***
44
44
 
45
45
  ### logContacts?
46
46
 
47
- > `optional` **logContacts**: `boolean`
47
+ > `optional` **logContacts?**: `boolean`
48
48
 
49
- Defined in: [src/bot.ts:21](../src/bot.ts#L21)
49
+ Defined in: [src/bot.ts:19](../src/bot.ts#L19)
50
50
 
51
51
  ***
52
52
 
53
53
  ### logNetwork?
54
54
 
55
- > `optional` **logNetwork**: `boolean`
55
+ > `optional` **logNetwork?**: `boolean`
56
56
 
57
- Defined in: [src/bot.ts:22](../src/bot.ts#L22)
57
+ Defined in: [src/bot.ts:20](../src/bot.ts#L20)
58
58
 
59
59
  ***
60
60
 
61
61
  ### updateAddress?
62
62
 
63
- > `optional` **updateAddress**: `boolean`
63
+ > `optional` **updateAddress?**: `boolean`
64
64
 
65
- Defined in: [src/bot.ts:15](../src/bot.ts#L15)
65
+ Defined in: [src/bot.ts:13](../src/bot.ts#L13)
66
66
 
67
67
  ***
68
68
 
69
69
  ### updateProfile?
70
70
 
71
- > `optional` **updateProfile**: `boolean`
71
+ > `optional` **updateProfile?**: `boolean`
72
72
 
73
- Defined in: [src/bot.ts:16](../src/bot.ts#L16)
73
+ Defined in: [src/bot.ts:14](../src/bot.ts#L14)
74
74
 
75
75
  ***
76
76
 
77
77
  ### useBotProfile?
78
78
 
79
- > `optional` **useBotProfile**: `boolean`
79
+ > `optional` **useBotProfile?**: `boolean`
80
80
 
81
- Defined in: [src/bot.ts:20](../src/bot.ts#L20)
81
+ Defined in: [src/bot.ts:18](../src/bot.ts#L18)
@@ -0,0 +1,17 @@
1
+ [**simplex-chat**](README.md)
2
+
3
+ ***
4
+
5
+ [simplex-chat](README.md) / [bot](Namespace.bot.md) / BotDbOpts
6
+
7
+ # Type Alias: BotDbOpts
8
+
9
+ > **BotDbOpts** = [`DbConfig`](api.TypeAlias.DbConfig.md) & `object`
10
+
11
+ Defined in: [src/bot.ts:7](../src/bot.ts#L7)
12
+
13
+ ## Type Declaration
14
+
15
+ ### confirmMigrations?
16
+
17
+ > `optional` **confirmMigrations?**: [`MigrationConfirmation`](core.Enumeration.MigrationConfirmation.md)
@@ -16,7 +16,7 @@ Defined in: [src/core.ts:92](../src/core.ts#L92)
16
16
 
17
17
  ### Constructor
18
18
 
19
- > **new ChatAPIError**(`message`, `chatError`): `ChatAPIError`
19
+ > **new ChatAPIError**(`message`, `chatError?`): `ChatAPIError`
20
20
 
21
21
  Defined in: [src/core.ts:93](../src/core.ts#L93)
22
22
 
@@ -26,9 +26,9 @@ Defined in: [src/core.ts:93](../src/core.ts#L93)
26
26
 
27
27
  `string`
28
28
 
29
- ##### chatError
29
+ ##### chatError?
30
30
 
31
- `ChatError` | `undefined`
31
+ `ChatError` \| `undefined`
32
32
 
33
33
  #### Returns
34
34
 
@@ -74,7 +74,7 @@ Defined in: [node\_modules/typescript/lib/lib.es5.d.ts:1076](../node_modules/typ
74
74
 
75
75
  ### stack?
76
76
 
77
- > `optional` **stack**: `string`
77
+ > `optional` **stack?**: `string`
78
78
 
79
79
  Defined in: [node\_modules/typescript/lib/lib.es5.d.ts:1078](../node_modules/typescript/lib/lib.es5.d.ts#L1078)
80
80
 
@@ -74,7 +74,7 @@ Defined in: [node\_modules/typescript/lib/lib.es5.d.ts:1076](../node_modules/typ
74
74
 
75
75
  ### stack?
76
76
 
77
- > `optional` **stack**: `string`
77
+ > `optional` **stack?**: `string`
78
78
 
79
79
  Defined in: [node\_modules/typescript/lib/lib.es5.d.ts:1078](../node_modules/typescript/lib/lib.es5.d.ts#L1078)
80
80
 
@@ -18,7 +18,7 @@ Defined in: [src/core.ts:87](../src/core.ts#L87)
18
18
 
19
19
  ### error?
20
20
 
21
- > `optional` **error**: `ChatError`
21
+ > `optional` **error?**: `ChatError`
22
22
 
23
23
  Defined in: [src/core.ts:89](../src/core.ts#L89)
24
24
 
@@ -26,6 +26,6 @@ Defined in: [src/core.ts:89](../src/core.ts#L89)
26
26
 
27
27
  ### result?
28
28
 
29
- > `optional` **result**: `R`
29
+ > `optional` **result?**: `R`
30
30
 
31
31
  Defined in: [src/core.ts:88](../src/core.ts#L88)
@@ -2,7 +2,7 @@
2
2
  const {bot} = await import("../dist/index.js")
3
3
  const [chat, _user, _address] = await bot.run({
4
4
  profile: {displayName: "Squaring bot example", fullName: ""},
5
- dbOpts: {dbFilePrefix: "./squaring_bot", dbKey: ""},
5
+ dbOpts: {type: "sqlite", filePrefix: "./squaring_bot"},
6
6
  options: {
7
7
  addressSettings: {welcomeMessage: "Send a number, I will square it."},
8
8
  },
@@ -5,7 +5,7 @@ import {bot, util} from "../dist"
5
5
  const welcomeMessage = "Hello! I am a simple squaring bot.\n\nIf you send me a number, I will calculate its square."
6
6
  const [chat, _user, _address] = await bot.run({
7
7
  profile: {displayName: "Squaring bot example", fullName: ""},
8
- dbOpts: {dbFilePrefix: "./squaring_bot", dbKey: ""},
8
+ dbOpts: {type: "sqlite", filePrefix: "./squaring_bot"},
9
9
  options: {
10
10
  addressSettings: {autoAccept: true, welcomeMessage, businessAddress: false},
11
11
  commands: [ // commands to show in client UI
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "simplex-chat",
3
- "version": "6.5.0-beta.4.4",
3
+ "version": "6.5.1",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [
@@ -24,7 +24,7 @@
24
24
  "docs": "typedoc"
25
25
  },
26
26
  "dependencies": {
27
- "@simplex-chat/types": "^0.3.0",
27
+ "@simplex-chat/types": "^0.6.0",
28
28
  "extract-zip": "^2.0.1",
29
29
  "fast-deep-equal": "^3.1.3",
30
30
  "node-addon-api": "^8.5.0"
package/src/api.ts CHANGED
@@ -56,6 +56,41 @@ interface EventSubscriber<K extends CEvt.Tag> {
56
56
  once: boolean
57
57
  }
58
58
 
59
+ /**
60
+ * Database configuration. The native library is built against exactly one
61
+ * backend (see `simplex_backend` / `SIMPLEX_BACKEND` at install time); this
62
+ * type makes the caller state which one they are targeting so field names
63
+ * can't lie about their meaning.
64
+ */
65
+ export type DbConfig =
66
+ | {
67
+ /** SQLite backend (default). */
68
+ type: "sqlite"
69
+ /** File prefix — two schema files are named `<prefix>_chat.db` and `<prefix>_agent.db`. */
70
+ filePrefix: string
71
+ /** Optional SQLCipher encryption key. Empty/omitted = unencrypted. */
72
+ encryptionKey?: string
73
+ }
74
+ | {
75
+ /** PostgreSQL backend (Linux x86_64 only, libpq5 required). */
76
+ type: "postgres"
77
+ /** Schema prefix used to namespace tables. Defaults to `"simplex_v1"` when omitted. */
78
+ schemaPrefix?: string
79
+ /** PostgreSQL connection string (e.g. `postgres://user:pass@host/db`). */
80
+ connectionString: string
81
+ }
82
+
83
+ function dbConfigToMigrateArgs(db: DbConfig): [string, string] {
84
+ switch (db.type) {
85
+ case "sqlite":
86
+ return [db.filePrefix, db.encryptionKey ?? ""]
87
+ case "postgres":
88
+ return [db.schemaPrefix ?? "", db.connectionString]
89
+ default:
90
+ throw new Error(`Invalid DbConfig: ${JSON.stringify(db satisfies never)}`)
91
+ }
92
+ }
93
+
59
94
  /**
60
95
  * Main API class for interacting with the chat core library.
61
96
  */
@@ -64,21 +99,20 @@ export class ChatApi {
64
99
  private eventsLoop: Promise<void> | undefined = undefined
65
100
  private subscribers: {[K in CEvt.Tag]?: EventSubscriber<K>[]} = {}
66
101
  private receivers: EventSubscriberFunc<CEvt.Tag>[] = []
67
-
102
+
68
103
  private constructor(protected ctrl_: bigint | undefined) {}
69
104
 
70
105
  /**
71
106
  * Initializes the ChatApi.
72
- * @param {string} dbFilePrefix - File prefix for the database files.
73
- * @param {string} [dbKey=""] - Database encryption key.
107
+ * @param {DbConfig} db - Database configuration (sqlite or postgres).
74
108
  * @param {core.MigrationConfirmation} [confirm=core.MigrationConfirmation.YesUp] - Migration confirmation mode.
75
109
  */
76
110
  static async init(
77
- dbFilePrefix: string,
78
- dbKey: string = "",
111
+ db: DbConfig,
79
112
  confirm = core.MigrationConfirmation.YesUp
80
113
  ): Promise<ChatApi> {
81
- const ctrl = await core.chatMigrateInit(dbFilePrefix, dbKey, confirm)
114
+ const [path, key] = dbConfigToMigrateArgs(db)
115
+ const ctrl = await core.chatMigrateInit(path, key, confirm)
82
116
  return new ChatApi(ctrl)
83
117
  }
84
118
 
@@ -654,7 +688,7 @@ export class ChatApi {
654
688
  * Network usage: interactive.
655
689
  */
656
690
  async apiConnectPlan(userId: number, connectionLink: string): Promise<[T.ConnectionPlan, T.CreatedConnLink]> {
657
- const r = await this.sendChatCmd(CC.APIConnectPlan.cmdString({userId, connectionLink}))
691
+ const r = await this.sendChatCmd(CC.APIConnectPlan.cmdString({userId, connectionLink, resolveKnown: false}))
658
692
  if (r.type === "connectionPlan") return [r.connectionPlan, r.connLink]
659
693
  throw new ChatCommandError("error getting connect plan", r)
660
694
  }
@@ -730,6 +764,25 @@ export class ChatApi {
730
764
  throw new ChatCommandError("error listing groups", r)
731
765
  }
732
766
 
767
+ /**
768
+ * Get chat previews (paginated).
769
+ * Network usage: no.
770
+ *
771
+ * Prefer this over apiListContacts / apiListGroups for any scan: those
772
+ * methods load every record into memory in a single response and will fail
773
+ * on large databases.
774
+ */
775
+ async apiGetChats(
776
+ userId: number,
777
+ pagination: T.PaginationByTime,
778
+ query: T.ChatListQuery = {type: "filters", favorite: false, unread: false},
779
+ pendingConnections = false,
780
+ ): Promise<T.AChat[]> {
781
+ const r = await this.sendChatCmd(CC.APIGetChats.cmdString({userId, pendingConnections, pagination, query}))
782
+ if (r.type === "apiChats") return r.chats
783
+ throw new ChatCommandError("error getting chats", r)
784
+ }
785
+
733
786
  /**
734
787
  * Delete chat.
735
788
  * Network usage: background.
@@ -747,6 +800,47 @@ export class ChatApi {
747
800
  throw new ChatCommandError("error deleting chat", r)
748
801
  }
749
802
 
803
+ /**
804
+ * Set group custom data.
805
+ * Network usage: no.
806
+ */
807
+ async apiSetGroupCustomData(groupId: number, customData?: object): Promise<void> {
808
+ const r = await this.sendChatCmd(CC.APISetGroupCustomData.cmdString({groupId, customData}))
809
+ if (r.type === "cmdOk") return
810
+ throw new ChatCommandError("error setting group custom data", r)
811
+ }
812
+
813
+ /**
814
+ * Set contact custom data.
815
+ * Network usage: no.
816
+ */
817
+ async apiSetContactCustomData(contactId: number, customData?: object): Promise<void> {
818
+ const r = await this.sendChatCmd(CC.APISetContactCustomData.cmdString({contactId, customData}))
819
+ if (r.type === "cmdOk") return
820
+ throw new ChatCommandError("error setting contact custom data", r)
821
+ }
822
+
823
+ /**
824
+ * Set auto-accept member contacts.
825
+ * Network usage: no.
826
+ */
827
+ async apiSetAutoAcceptMemberContacts(userId: number, onOff: boolean): Promise<void> {
828
+ const r = await this.sendChatCmd(CC.APISetUserAutoAcceptMemberContacts.cmdString({userId, onOff}))
829
+ if (r.type === "cmdOk") return
830
+ throw new ChatCommandError("error setting auto-accept member contacts", r)
831
+ }
832
+
833
+ /**
834
+ * Get chat items.
835
+ * Network usage: no.
836
+ */
837
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
838
+ async apiGetChat(chatType: T.ChatType, chatId: number, count: number): Promise<any> {
839
+ const r: any = await this.sendChatCmd(`/_get chat ${T.ChatType.cmdString(chatType)}${chatId} count=${count}`)
840
+ if (r.type === "apiChat") return r.chat
841
+ throw new ChatCommandError("error getting chat", r)
842
+ }
843
+
750
844
  /**
751
845
  * Get active user profile
752
846
  * Network usage: no.
@@ -772,7 +866,7 @@ export class ChatApi {
772
866
  * Network usage: no.
773
867
  */
774
868
  async apiCreateActiveUser(profile?: T.Profile): Promise<T.User> {
775
- const r = await this.sendChatCmd(CC.CreateActiveUser.cmdString({newUser: {profile, pastTimestamp: false}}))
869
+ const r = await this.sendChatCmd(CC.CreateActiveUser.cmdString({newUser: {profile, pastTimestamp: false, userChatRelay: false}}))
776
870
  if (r.type === "activeUser") return r.user
777
871
  throw new ChatCommandError("unexpected response", r)
778
872
  }
@@ -831,4 +925,34 @@ export class ChatApi {
831
925
  const r = await this.sendChatCmd(CC.APISetContactPrefs.cmdString({contactId, preferences}))
832
926
  if (r.type !== "contactPrefsUpdated") throw new ChatCommandError("error setting contact prefs", r)
833
927
  }
928
+
929
+ /**
930
+ * Create a direct message contact with a group member.
931
+ * Returns the created contact.
932
+ * Network usage: interactive.
933
+ */
934
+ async apiCreateMemberContact(groupId: number, groupMemberId: number): Promise<T.Contact> {
935
+ const r: any = await this.sendChatCmd(`/_create member contact #${groupId} ${groupMemberId}`)
936
+ if (r.type === "newMemberContact") return r.contact
937
+ throw new ChatCommandError("error creating member contact", r)
938
+ }
939
+
940
+ /**
941
+ * Send a direct message invitation to a group member contact.
942
+ * The contact must have been created with {@link apiCreateMemberContact}.
943
+ * Network usage: interactive.
944
+ */
945
+ async apiSendMemberContactInvitation(contactId: number, message?: T.MsgContent | string): Promise<T.Contact> {
946
+ let cmd = `/_invite member contact @${contactId}`
947
+ if (message !== undefined) {
948
+ if (typeof message === "string") {
949
+ cmd += ` text ${message}`
950
+ } else {
951
+ cmd += ` json ${JSON.stringify(message)}`
952
+ }
953
+ }
954
+ const r: any = await this.sendChatCmd(cmd)
955
+ if (r.type === "newMemberContactSentInv") return r.contact
956
+ throw new ChatCommandError("error sending member contact invitation", r)
957
+ }
834
958
  }
package/src/bot.ts CHANGED
@@ -4,9 +4,7 @@ import * as core from "./core"
4
4
  import * as util from "./util"
5
5
  import equal = require("fast-deep-equal")
6
6
 
7
- export interface BotDbOpts {
8
- dbFilePrefix: string // two schema files will be named <prefix>_chat.db and <prefix>_agent.db
9
- dbKey?: string
7
+ export type BotDbOpts = api.DbConfig & {
10
8
  confirmMigrations?: core.MigrationConfirmation
11
9
  }
12
10
 
@@ -47,7 +45,7 @@ export interface BotConfig {
47
45
  }
48
46
 
49
47
  export async function run({profile, dbOpts, options = defaultOpts, onMessage, onCommands = {}, events = {}}: BotConfig): Promise<[api.ChatApi, T.User, T.UserContactLink | undefined]> {
50
- const bot = await api.ChatApi.init(dbOpts.dbFilePrefix, dbOpts.dbKey || "", dbOpts.confirmMigrations || core.MigrationConfirmation.YesUp)
48
+ const bot = await api.ChatApi.init(dbOpts, dbOpts.confirmMigrations || core.MigrationConfirmation.YesUp)
51
49
  const opts = fullOptions(options)
52
50
  if (onMessage) subscribeMessages(bot, onMessage)
53
51
  if (Object.keys(onCommands).length > 0) subscribeCommands(bot, onCommands)