@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.
- package/EntrigCapacitor.podspec +18 -0
- package/Package.swift +29 -0
- package/README.md +448 -0
- package/android/build.gradle +61 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/entrig/plugin/capacitor/EntrigPlugin.kt +176 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/bin/setup.js +291 -0
- package/dist/docs.json +240 -0
- package/dist/esm/definitions.d.ts +26 -0
- package/dist/esm/definitions.js +2 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +13 -0
- package/dist/esm/web.js +20 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +34 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +37 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Sources/EntrigPlugin/EntrigPlugin.swift +169 -0
- package/ios/Tests/EntrigPluginTests/EntrigTests.swift +15 -0
- package/package.json +84 -0
|
@@ -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
|
+
}
|