@entrig/capacitor 0.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.
@@ -0,0 +1,176 @@
1
+ package com.entrig.plugin.capacitor
2
+
3
+ import android.Manifest
4
+ import android.content.Intent
5
+ import android.os.Build
6
+ import android.util.Log
7
+ import com.getcapacitor.JSObject
8
+ import com.getcapacitor.PermissionState
9
+ import com.getcapacitor.Plugin
10
+ import com.getcapacitor.PluginCall
11
+ import com.getcapacitor.PluginMethod
12
+ import com.getcapacitor.annotation.CapacitorPlugin
13
+ import com.getcapacitor.annotation.Permission
14
+ import com.getcapacitor.annotation.PermissionCallback
15
+ import com.entrig.sdk.Entrig
16
+ import com.entrig.sdk.models.EntrigConfig
17
+ import com.entrig.sdk.models.NotificationEvent
18
+
19
+ @CapacitorPlugin(
20
+ name = "Entrig",
21
+ permissions = [
22
+ Permission(
23
+ alias = "notifications",
24
+ strings = [Manifest.permission.POST_NOTIFICATIONS]
25
+ )
26
+ ]
27
+ )
28
+ class EntrigPlugin : Plugin() {
29
+
30
+ companion object {
31
+ private const val TAG = "EntrigPlugin"
32
+ }
33
+
34
+ override fun load() {
35
+ // Set activity on SDK for foreground detection (lifecycle callbacks
36
+ // registered in initialize() won't fire for already-resumed activities)
37
+ bridge.activity?.let { Entrig.setActivity(it) }
38
+
39
+ // Handle initial intent (app launched from notification tap)
40
+ bridge.activity?.intent?.let { intent ->
41
+ Entrig.handleIntent(intent)
42
+ }
43
+
44
+ Entrig.setOnForegroundNotificationListener { notification ->
45
+ Log.d(TAG, "Foreground notification: ${notification.toMap()}")
46
+ notifyListeners("onForegroundNotification", notification.toJSObject(isForeground = true))
47
+ }
48
+
49
+ Entrig.setOnNotificationOpenedListener { notification ->
50
+ Log.d(TAG, "Notification opened: ${notification.toMap()}")
51
+ notifyListeners("onNotificationOpened", notification.toJSObject(isForeground = false))
52
+ }
53
+ }
54
+
55
+ @PluginMethod
56
+ fun init(call: PluginCall) {
57
+ val apiKey = call.getString("apiKey")
58
+ if (apiKey.isNullOrEmpty()) {
59
+ call.reject("API key is required and cannot be empty")
60
+ return
61
+ }
62
+
63
+ val showForegroundNotification = call.getBoolean("showForegroundNotification") ?: true
64
+ val config = EntrigConfig(
65
+ apiKey = apiKey,
66
+ handlePermission = false,
67
+ showForegroundNotification = showForegroundNotification
68
+ )
69
+
70
+ Entrig.initialize(context.applicationContext, config) { success, error ->
71
+ if (success) {
72
+ call.resolve()
73
+ } else {
74
+ call.reject(error ?: "Failed to initialize SDK")
75
+ }
76
+ }
77
+ }
78
+
79
+ @PluginMethod
80
+ fun register(call: PluginCall) {
81
+ val userId = call.getString("userId")
82
+ if (userId.isNullOrEmpty()) {
83
+ call.reject("userId is required")
84
+ return
85
+ }
86
+
87
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
88
+ getPermissionState("notifications") != PermissionState.GRANTED
89
+ ) {
90
+ requestPermissionForAlias("notifications", call, "onRegisterPermissionResult")
91
+ return
92
+ }
93
+
94
+ doRegister(call)
95
+ }
96
+
97
+ @PermissionCallback
98
+ private fun onRegisterPermissionResult(call: PluginCall) {
99
+ doRegister(call)
100
+ }
101
+
102
+ private fun doRegister(call: PluginCall) {
103
+ val userId = call.getString("userId")!!
104
+ Entrig.register(userId, activity, "capacitor") { success, error ->
105
+ if (success) {
106
+ call.resolve()
107
+ } else {
108
+ call.reject(error ?: "Registration failed")
109
+ }
110
+ }
111
+ }
112
+
113
+ @PluginMethod
114
+ fun requestPermission(call: PluginCall) {
115
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
116
+ getPermissionState("notifications") != PermissionState.GRANTED
117
+ ) {
118
+ requestPermissionForAlias("notifications", call, "onRequestPermissionResult")
119
+ return
120
+ }
121
+
122
+ val ret = JSObject()
123
+ ret.put("granted", true)
124
+ call.resolve(ret)
125
+ }
126
+
127
+ @PermissionCallback
128
+ private fun onRequestPermissionResult(call: PluginCall) {
129
+ val granted = getPermissionState("notifications") == PermissionState.GRANTED
130
+ val ret = JSObject()
131
+ ret.put("granted", granted)
132
+ call.resolve(ret)
133
+ }
134
+
135
+ @PluginMethod
136
+ fun unregister(call: PluginCall) {
137
+ Entrig.unregister { success, error ->
138
+ if (success) {
139
+ call.resolve()
140
+ } else {
141
+ call.reject(error ?: "Unregistration failed")
142
+ }
143
+ }
144
+ }
145
+
146
+ @PluginMethod
147
+ fun getInitialNotification(call: PluginCall) {
148
+ val initialNotification = Entrig.getInitialNotification()
149
+ if (initialNotification != null) {
150
+ call.resolve(initialNotification.toJSObject())
151
+ } else {
152
+ call.resolve(JSObject())
153
+ }
154
+ }
155
+
156
+ override fun handleOnNewIntent(intent: Intent) {
157
+ super.handleOnNewIntent(intent)
158
+ Entrig.handleIntent(intent)
159
+ }
160
+
161
+ private fun NotificationEvent.toJSObject(isForeground: Boolean = false): JSObject {
162
+ val obj = JSObject()
163
+ obj.put("title", title)
164
+ obj.put("body", body)
165
+ obj.put("type", type)
166
+ obj.put("deliveryId", deliveryId)
167
+
168
+ val dataObj = JSObject()
169
+ data?.forEach { (key, value) ->
170
+ dataObj.put(key, value)
171
+ }
172
+ obj.put("data", dataObj)
173
+ obj.put("isForeground", isForeground)
174
+ return obj
175
+ }
176
+ }
File without changes
package/bin/setup.js ADDED
@@ -0,0 +1,291 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+
6
+ const args = process.argv.slice(2);
7
+
8
+ if (args.length < 2 || args[0] !== "setup" || args[1] !== "ios") {
9
+ console.log("Usage: npx @entrig/capacitor setup ios");
10
+ process.exit(1);
11
+ }
12
+
13
+ console.log("🔧 Entrig Capacitor iOS Setup\n");
14
+
15
+ // Capacitor iOS project structure: ios/App/App/
16
+ const iosDir = path.join(process.cwd(), "ios");
17
+ if (!fs.existsSync(iosDir)) {
18
+ console.log("❌ Error: ios/ directory not found");
19
+ console.log(" Make sure you run this from your Capacitor project root.");
20
+ console.log(' Run "npx cap add ios" first if you haven\'t.');
21
+ process.exit(1);
22
+ }
23
+
24
+ const appDir = path.join(iosDir, "App", "App");
25
+ if (!fs.existsSync(appDir)) {
26
+ console.log("❌ Error: ios/App/App/ directory not found");
27
+ console.log(" This doesn't look like a standard Capacitor project.");
28
+ process.exit(1);
29
+ }
30
+
31
+ console.log("✅ Found Capacitor iOS project\n");
32
+
33
+ updateAppDelegate(appDir);
34
+ updateEntitlements(appDir);
35
+ updateInfoPlist(appDir);
36
+
37
+ console.log("\n🎉 Setup complete! Rebuild your iOS app to apply changes.\n");
38
+
39
+ // ─── AppDelegate ────────────────────────────────────────────────────────
40
+
41
+ function updateAppDelegate(appDir) {
42
+ const appDelegatePath = path.join(appDir, "AppDelegate.swift");
43
+
44
+ if (!fs.existsSync(appDelegatePath)) {
45
+ console.log("❌ Error: AppDelegate.swift not found");
46
+ process.exit(1);
47
+ }
48
+
49
+ console.log(
50
+ `📝 Checking ${path.relative(process.cwd(), appDelegatePath)}...`,
51
+ );
52
+
53
+ let content = fs.readFileSync(appDelegatePath, "utf8");
54
+
55
+ // Already configured?
56
+ if (content.includes("capacitorDidRegisterForRemoteNotifications")) {
57
+ console.log("✅ Entrig is already configured in AppDelegate.swift");
58
+ return;
59
+ }
60
+
61
+ // Check if delegate methods already exist
62
+ const hasTokenMethod = content.includes(
63
+ "didRegisterForRemoteNotificationsWithDeviceToken",
64
+ );
65
+ const hasFailMethod = content.includes(
66
+ "didFailToRegisterForRemoteNotificationsWithError",
67
+ );
68
+
69
+ if (hasTokenMethod || hasFailMethod) {
70
+ console.log(
71
+ "⚠️ Existing push notification delegate methods detected.",
72
+ );
73
+ console.log(" Please ensure they post Capacitor notifications:\n");
74
+ if (hasTokenMethod) {
75
+ console.log(" In didRegisterForRemoteNotificationsWithDeviceToken:");
76
+ console.log(
77
+ " NotificationCenter.default.post(name: .capacitorDidRegisterForRemoteNotifications, object: deviceToken)\n",
78
+ );
79
+ }
80
+ if (hasFailMethod) {
81
+ console.log(" In didFailToRegisterForRemoteNotificationsWithError:");
82
+ console.log(
83
+ " NotificationCenter.default.post(name: .capacitorDidFailToRegisterForRemoteNotifications, object: error)\n",
84
+ );
85
+ }
86
+ return;
87
+ }
88
+
89
+ // Backup
90
+ const backupPath = appDelegatePath + ".backup";
91
+ fs.copyFileSync(appDelegatePath, backupPath);
92
+ console.log(`💾 Backup created: ${path.relative(process.cwd(), backupPath)}`);
93
+
94
+ // Add delegate methods before the last closing brace
95
+ const methodsToAdd = `
96
+ // MARK: - Push Notification Token Handling
97
+
98
+ func application(_ application: UIApplication,
99
+ didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
100
+ NotificationCenter.default.post(name: .capacitorDidRegisterForRemoteNotifications, object: deviceToken)
101
+ }
102
+
103
+ func application(_ application: UIApplication,
104
+ didFailToRegisterForRemoteNotificationsWithError error: Error) {
105
+ NotificationCenter.default.post(name: .capacitorDidFailToRegisterForRemoteNotifications, object: error)
106
+ }
107
+ `;
108
+
109
+ const lastBraceIndex = content.lastIndexOf("}");
110
+ if (lastBraceIndex !== -1) {
111
+ content =
112
+ content.slice(0, lastBraceIndex) +
113
+ methodsToAdd +
114
+ content.slice(lastBraceIndex);
115
+ }
116
+
117
+ fs.writeFileSync(appDelegatePath, content);
118
+
119
+ console.log("✅ Configured AppDelegate.swift:");
120
+ console.log(" • Added didRegisterForRemoteNotifications method");
121
+ console.log(" • Added didFailToRegisterForRemoteNotifications method");
122
+ }
123
+
124
+ // ─── Entitlements ───────────────────────────────────────────────────────
125
+
126
+ function updateEntitlements(appDir) {
127
+ // Capacitor entitlements: ios/App/App/App.entitlements or *.entitlements
128
+ let entitlementsPath = null;
129
+ let entitlementsFileName = null;
130
+
131
+ const files = fs.readdirSync(appDir);
132
+ for (const f of files) {
133
+ if (f.endsWith(".entitlements")) {
134
+ entitlementsPath = path.join(appDir, f);
135
+ entitlementsFileName = f;
136
+ break;
137
+ }
138
+ }
139
+
140
+ if (!entitlementsPath) {
141
+ // Create default entitlements
142
+ entitlementsFileName = "App.entitlements";
143
+ entitlementsPath = path.join(appDir, entitlementsFileName);
144
+ const defaultEntitlements = `<?xml version="1.0" encoding="UTF-8"?>
145
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
146
+ <plist version="1.0">
147
+ <dict>
148
+ \t<key>aps-environment</key>
149
+ \t<string>development</string>
150
+ </dict>
151
+ </plist>`;
152
+
153
+ fs.writeFileSync(entitlementsPath, defaultEntitlements);
154
+ console.log(
155
+ `\n📝 Created: ${path.relative(process.cwd(), entitlementsPath)}`,
156
+ );
157
+ console.log("✅ Added aps-environment to entitlements");
158
+ } else {
159
+ console.log(
160
+ `\n📝 Checking ${path.relative(process.cwd(), entitlementsPath)}...`,
161
+ );
162
+
163
+ let content = fs.readFileSync(entitlementsPath, "utf8");
164
+
165
+ if (content.includes("aps-environment")) {
166
+ console.log("✅ aps-environment already configured");
167
+ } else {
168
+ // Backup
169
+ const backupPath = entitlementsPath + ".backup";
170
+ fs.copyFileSync(entitlementsPath, backupPath);
171
+ console.log(`💾 Backup created: ${path.relative(process.cwd(), backupPath)}`);
172
+
173
+ const apsEntry = `\t<key>aps-environment</key>\n\t<string>development</string>\n`;
174
+
175
+ if (content.includes("<dict/>")) {
176
+ content = content.replace("<dict/>", `<dict>\n${apsEntry}</dict>`);
177
+ } else {
178
+ const insertPoint = content.lastIndexOf("</dict>");
179
+ if (insertPoint === -1) {
180
+ console.log("❌ Error: Could not parse entitlements file");
181
+ return;
182
+ }
183
+ content = content.slice(0, insertPoint) + apsEntry + content.slice(insertPoint);
184
+ }
185
+
186
+ fs.writeFileSync(entitlementsPath, content);
187
+ console.log("✅ Added aps-environment to entitlements");
188
+ }
189
+ }
190
+
191
+ // Link entitlements in project.pbxproj
192
+ linkEntitlementsInXcodeProject(appDir, entitlementsFileName);
193
+ }
194
+
195
+ function linkEntitlementsInXcodeProject(appDir, entitlementsFileName) {
196
+ const pbxprojPath = path.join(appDir, "..", "App.xcodeproj", "project.pbxproj");
197
+
198
+ if (!fs.existsSync(pbxprojPath)) {
199
+ console.log("⚠️ Warning: project.pbxproj not found, skipping entitlements linking");
200
+ console.log(" Please manually enable Push Notifications in Xcode:");
201
+ console.log(" Target > Signing & Capabilities > + Capability > Push Notifications");
202
+ return;
203
+ }
204
+
205
+ let content = fs.readFileSync(pbxprojPath, "utf8");
206
+
207
+ if (content.includes("CODE_SIGN_ENTITLEMENTS")) {
208
+ console.log("✅ CODE_SIGN_ENTITLEMENTS already set in Xcode project");
209
+ return;
210
+ }
211
+
212
+ // Insert CODE_SIGN_ENTITLEMENTS after INFOPLIST_FILE = App/Info.plist;
213
+ // This is specific to app target build settings (Debug & Release)
214
+ const entitlementsValue = `App/${entitlementsFileName}`;
215
+ const anchor = "INFOPLIST_FILE = App/Info.plist;";
216
+
217
+ if (!content.includes(anchor)) {
218
+ console.log("⚠️ Could not find INFOPLIST_FILE in project.pbxproj");
219
+ console.log(" Please manually enable Push Notifications in Xcode:");
220
+ console.log(" Target > Signing & Capabilities > + Capability > Push Notifications");
221
+ return;
222
+ }
223
+
224
+ content = content.replace(
225
+ new RegExp(anchor.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"),
226
+ `${anchor}\n\t\t\t\tCODE_SIGN_ENTITLEMENTS = "${entitlementsValue}";`,
227
+ );
228
+
229
+ fs.writeFileSync(pbxprojPath, content);
230
+ console.log("✅ Linked entitlements in Xcode project");
231
+ }
232
+
233
+ // ─── Info.plist ─────────────────────────────────────────────────────────
234
+
235
+ function updateInfoPlist(appDir) {
236
+ const infoPlistPath = path.join(appDir, "Info.plist");
237
+
238
+ if (!fs.existsSync(infoPlistPath)) {
239
+ console.log(
240
+ `\n⚠️ Warning: ${path.relative(process.cwd(), infoPlistPath)} not found`,
241
+ );
242
+ return;
243
+ }
244
+
245
+ console.log(
246
+ `\n📝 Checking ${path.relative(process.cwd(), infoPlistPath)}...`,
247
+ );
248
+
249
+ let content = fs.readFileSync(infoPlistPath, "utf8");
250
+
251
+ if (
252
+ content.includes("UIBackgroundModes") &&
253
+ content.includes("remote-notification")
254
+ ) {
255
+ console.log("✅ UIBackgroundModes already configured");
256
+ return;
257
+ }
258
+
259
+ // Backup
260
+ const backupPath = infoPlistPath + ".backup";
261
+ fs.copyFileSync(infoPlistPath, backupPath);
262
+ console.log(`💾 Backup created: ${path.relative(process.cwd(), backupPath)}`);
263
+
264
+ if (content.includes("UIBackgroundModes")) {
265
+ // Add remote-notification to existing array
266
+ const arrayMatch = content.match(
267
+ /<key>UIBackgroundModes<\/key>\s*<array>/,
268
+ );
269
+ if (arrayMatch) {
270
+ const insertPoint = arrayMatch.index + arrayMatch[0].length;
271
+ const newEntry = "\n\t\t<string>remote-notification</string>";
272
+ content =
273
+ content.slice(0, insertPoint) + newEntry + content.slice(insertPoint);
274
+ }
275
+ } else {
276
+ // Add UIBackgroundModes before closing </dict>
277
+ const plistEnd = content.lastIndexOf("</plist>");
278
+ const dictEnd = content.lastIndexOf("</dict>", plistEnd);
279
+
280
+ if (dictEnd === -1) {
281
+ console.log("❌ Error: Could not parse Info.plist");
282
+ return;
283
+ }
284
+
285
+ const bgModes = `\t<key>UIBackgroundModes</key>\n\t<array>\n\t\t<string>remote-notification</string>\n\t</array>\n`;
286
+ content = content.slice(0, dictEnd) + bgModes + content.slice(dictEnd);
287
+ }
288
+
289
+ fs.writeFileSync(infoPlistPath, content);
290
+ console.log("✅ Added remote-notification to UIBackgroundModes");
291
+ }
package/dist/docs.json ADDED
@@ -0,0 +1,240 @@
1
+ {
2
+ "api": {
3
+ "name": "EntrigPlugin",
4
+ "slug": "entrigplugin",
5
+ "docs": "",
6
+ "tags": [],
7
+ "methods": [
8
+ {
9
+ "name": "init",
10
+ "signature": "(config: EntrigConfig) => Promise<void>",
11
+ "parameters": [
12
+ {
13
+ "name": "config",
14
+ "docs": "",
15
+ "type": "EntrigConfig"
16
+ }
17
+ ],
18
+ "returns": "Promise<void>",
19
+ "tags": [],
20
+ "docs": "",
21
+ "complexTypes": [
22
+ "EntrigConfig"
23
+ ],
24
+ "slug": "init"
25
+ },
26
+ {
27
+ "name": "register",
28
+ "signature": "(options: { userId: string; }) => Promise<void>",
29
+ "parameters": [
30
+ {
31
+ "name": "options",
32
+ "docs": "",
33
+ "type": "{ userId: string; }"
34
+ }
35
+ ],
36
+ "returns": "Promise<void>",
37
+ "tags": [],
38
+ "docs": "",
39
+ "complexTypes": [],
40
+ "slug": "register"
41
+ },
42
+ {
43
+ "name": "requestPermission",
44
+ "signature": "() => Promise<{ granted: boolean; }>",
45
+ "parameters": [],
46
+ "returns": "Promise<{ granted: boolean; }>",
47
+ "tags": [],
48
+ "docs": "",
49
+ "complexTypes": [],
50
+ "slug": "requestpermission"
51
+ },
52
+ {
53
+ "name": "unregister",
54
+ "signature": "() => Promise<void>",
55
+ "parameters": [],
56
+ "returns": "Promise<void>",
57
+ "tags": [],
58
+ "docs": "",
59
+ "complexTypes": [],
60
+ "slug": "unregister"
61
+ },
62
+ {
63
+ "name": "getInitialNotification",
64
+ "signature": "() => Promise<NotificationEvent | null>",
65
+ "parameters": [],
66
+ "returns": "Promise<NotificationEvent | null>",
67
+ "tags": [],
68
+ "docs": "",
69
+ "complexTypes": [
70
+ "NotificationEvent"
71
+ ],
72
+ "slug": "getinitialnotification"
73
+ },
74
+ {
75
+ "name": "addListener",
76
+ "signature": "(eventName: 'onForegroundNotification', listenerFunc: (event: NotificationEvent) => void) => Promise<PluginListenerHandle>",
77
+ "parameters": [
78
+ {
79
+ "name": "eventName",
80
+ "docs": "",
81
+ "type": "'onForegroundNotification'"
82
+ },
83
+ {
84
+ "name": "listenerFunc",
85
+ "docs": "",
86
+ "type": "(event: NotificationEvent) => void"
87
+ }
88
+ ],
89
+ "returns": "Promise<PluginListenerHandle>",
90
+ "tags": [],
91
+ "docs": "",
92
+ "complexTypes": [
93
+ "PluginListenerHandle",
94
+ "NotificationEvent"
95
+ ],
96
+ "slug": "addlisteneronforegroundnotification-"
97
+ },
98
+ {
99
+ "name": "addListener",
100
+ "signature": "(eventName: 'onNotificationOpened', listenerFunc: (event: NotificationEvent) => void) => Promise<PluginListenerHandle>",
101
+ "parameters": [
102
+ {
103
+ "name": "eventName",
104
+ "docs": "",
105
+ "type": "'onNotificationOpened'"
106
+ },
107
+ {
108
+ "name": "listenerFunc",
109
+ "docs": "",
110
+ "type": "(event: NotificationEvent) => void"
111
+ }
112
+ ],
113
+ "returns": "Promise<PluginListenerHandle>",
114
+ "tags": [],
115
+ "docs": "",
116
+ "complexTypes": [
117
+ "PluginListenerHandle",
118
+ "NotificationEvent"
119
+ ],
120
+ "slug": "addlisteneronnotificationopened-"
121
+ },
122
+ {
123
+ "name": "removeAllListeners",
124
+ "signature": "() => Promise<void>",
125
+ "parameters": [],
126
+ "returns": "Promise<void>",
127
+ "tags": [],
128
+ "docs": "",
129
+ "complexTypes": [],
130
+ "slug": "removealllisteners"
131
+ }
132
+ ],
133
+ "properties": []
134
+ },
135
+ "interfaces": [
136
+ {
137
+ "name": "EntrigConfig",
138
+ "slug": "entrigconfig",
139
+ "docs": "",
140
+ "tags": [],
141
+ "methods": [],
142
+ "properties": [
143
+ {
144
+ "name": "apiKey",
145
+ "tags": [],
146
+ "docs": "",
147
+ "complexTypes": [],
148
+ "type": "string"
149
+ },
150
+ {
151
+ "name": "handlePermission",
152
+ "tags": [],
153
+ "docs": "",
154
+ "complexTypes": [],
155
+ "type": "boolean | undefined"
156
+ },
157
+ {
158
+ "name": "showForegroundNotification",
159
+ "tags": [],
160
+ "docs": "",
161
+ "complexTypes": [],
162
+ "type": "boolean | undefined"
163
+ }
164
+ ]
165
+ },
166
+ {
167
+ "name": "NotificationEvent",
168
+ "slug": "notificationevent",
169
+ "docs": "",
170
+ "tags": [],
171
+ "methods": [],
172
+ "properties": [
173
+ {
174
+ "name": "title",
175
+ "tags": [],
176
+ "docs": "",
177
+ "complexTypes": [],
178
+ "type": "string"
179
+ },
180
+ {
181
+ "name": "body",
182
+ "tags": [],
183
+ "docs": "",
184
+ "complexTypes": [],
185
+ "type": "string"
186
+ },
187
+ {
188
+ "name": "data",
189
+ "tags": [],
190
+ "docs": "",
191
+ "complexTypes": [
192
+ "Record"
193
+ ],
194
+ "type": "Record<string, any>"
195
+ },
196
+ {
197
+ "name": "isForeground",
198
+ "tags": [],
199
+ "docs": "",
200
+ "complexTypes": [],
201
+ "type": "boolean"
202
+ }
203
+ ]
204
+ },
205
+ {
206
+ "name": "PluginListenerHandle",
207
+ "slug": "pluginlistenerhandle",
208
+ "docs": "",
209
+ "tags": [],
210
+ "methods": [],
211
+ "properties": [
212
+ {
213
+ "name": "remove",
214
+ "tags": [],
215
+ "docs": "",
216
+ "complexTypes": [],
217
+ "type": "() => Promise<void>"
218
+ }
219
+ ]
220
+ }
221
+ ],
222
+ "enums": [],
223
+ "typeAliases": [
224
+ {
225
+ "name": "Record",
226
+ "slug": "record",
227
+ "docs": "Construct a type with a set of properties K of type T",
228
+ "types": [
229
+ {
230
+ "text": "{\r\n [P in K]: T;\r\n}",
231
+ "complexTypes": [
232
+ "K",
233
+ "T"
234
+ ]
235
+ }
236
+ ]
237
+ }
238
+ ],
239
+ "pluginConfigs": []
240
+ }