doopush-react-native-sdk 0.1.2
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/README.md +177 -0
- package/android/build.gradle +54 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/doopush/reactnative/DooPushReactNativeSDKModule.kt +146 -0
- package/app.plugin.js +1 -0
- package/build/DooPush.d.ts +40 -0
- package/build/DooPush.d.ts.map +1 -0
- package/build/DooPush.js +49 -0
- package/build/DooPush.js.map +1 -0
- package/build/DooPushModule.d.ts +7 -0
- package/build/DooPushModule.d.ts.map +1 -0
- package/build/DooPushModule.js +8 -0
- package/build/DooPushModule.js.map +1 -0
- package/build/events.d.ts +23 -0
- package/build/events.d.ts.map +1 -0
- package/build/events.js +11 -0
- package/build/events.js.map +1 -0
- package/build/index.d.ts +5 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +5 -0
- package/build/index.js.map +1 -0
- package/build/types.d.ts +46 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +2 -0
- package/build/types.js.map +1 -0
- package/expo-module.config.json +10 -0
- package/ios/DooPushAppDelegateSubscriber.swift +36 -0
- package/ios/DooPushReactNativeSDK.podspec +33 -0
- package/ios/DooPushReactNativeSDKModule.swift +134 -0
- package/package.json +48 -0
- package/plugin/build/android/withAndroid.d.ts +3 -0
- package/plugin/build/android/withAndroid.js +13 -0
- package/plugin/build/android/withAppBuildGradle.d.ts +3 -0
- package/plugin/build/android/withAppBuildGradle.js +43 -0
- package/plugin/build/android/withGoogleServices.d.ts +3 -0
- package/plugin/build/android/withGoogleServices.js +63 -0
- package/plugin/build/android/withRootBuildGradle.d.ts +7 -0
- package/plugin/build/android/withRootBuildGradle.js +25 -0
- package/plugin/build/index.d.ts +3 -0
- package/plugin/build/index.js +12 -0
- package/plugin/build/ios/withEntitlements.d.ts +6 -0
- package/plugin/build/ios/withEntitlements.js +14 -0
- package/plugin/build/ios/withIOS.d.ts +3 -0
- package/plugin/build/ios/withIOS.js +11 -0
- package/plugin/build/ios/withInfoPlist.d.ts +6 -0
- package/plugin/build/ios/withInfoPlist.js +19 -0
- package/plugin/build/schema.d.ts +78 -0
- package/plugin/build/schema.js +52 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import ExpoModulesCore
|
|
2
|
+
import DooPushSDK
|
|
3
|
+
import UIKit
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Forwards UIApplicationDelegate push-notification callbacks from the
|
|
7
|
+
* Expo-managed AppDelegate to DooPush iOS SDK.
|
|
8
|
+
*
|
|
9
|
+
* Without this, the APNs device token never reaches DooPushManager and
|
|
10
|
+
* `DooPush.register()` hangs forever after the user grants permission.
|
|
11
|
+
*/
|
|
12
|
+
public class DooPushAppDelegateSubscriber: ExpoAppDelegateSubscriber {
|
|
13
|
+
|
|
14
|
+
public func application(
|
|
15
|
+
_ application: UIApplication,
|
|
16
|
+
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
|
|
17
|
+
) {
|
|
18
|
+
DooPushManager.shared.didRegisterForRemoteNotifications(with: deviceToken)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public func application(
|
|
22
|
+
_ application: UIApplication,
|
|
23
|
+
didFailToRegisterForRemoteNotificationsWithError error: Error
|
|
24
|
+
) {
|
|
25
|
+
DooPushManager.shared.didFailToRegisterForRemoteNotifications(with: error)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public func application(
|
|
29
|
+
_ application: UIApplication,
|
|
30
|
+
didReceiveRemoteNotification userInfo: [AnyHashable: Any],
|
|
31
|
+
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
|
|
32
|
+
) {
|
|
33
|
+
_ = DooPushManager.shared.handleNotification(userInfo)
|
|
34
|
+
completionHandler(.newData)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, '..', 'package.json')))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = 'DooPushReactNativeSDK'
|
|
7
|
+
s.version = package['version']
|
|
8
|
+
s.summary = package['description']
|
|
9
|
+
s.description = package['description']
|
|
10
|
+
s.license = package['license']
|
|
11
|
+
s.author = 'DooPush'
|
|
12
|
+
s.homepage = package['repository']['url']
|
|
13
|
+
s.platforms = { :ios => '13.0' }
|
|
14
|
+
s.swift_version = '5.9'
|
|
15
|
+
s.source = { :git => package['repository']['url'], :tag => "v#{s.version}" }
|
|
16
|
+
s.static_framework = true
|
|
17
|
+
|
|
18
|
+
# Native SDK dependency.
|
|
19
|
+
# During v0.1.0 alpha development, use path-based to avoid waiting for SPM publish.
|
|
20
|
+
# Switch to `s.dependency 'DooPushSDK', '~> 1.1'` once published.
|
|
21
|
+
s.dependency 'DooPushSDK'
|
|
22
|
+
|
|
23
|
+
s.dependency 'ExpoModulesCore'
|
|
24
|
+
|
|
25
|
+
s.source_files = '**/*.{h,m,mm,swift,hpp,cpp}'
|
|
26
|
+
s.exclude_files = 'Tests/**/*'
|
|
27
|
+
|
|
28
|
+
# Pod target xcconfig to handle dependency resolution.
|
|
29
|
+
s.pod_target_xcconfig = {
|
|
30
|
+
'DEFINES_MODULE' => 'YES',
|
|
31
|
+
'SWIFT_COMPILATION_MODE' => 'wholemodule'
|
|
32
|
+
}
|
|
33
|
+
end
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import ExpoModulesCore
|
|
2
|
+
import DooPushSDK
|
|
3
|
+
import UserNotifications
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* DooPush React Native SDK — iOS bridge
|
|
7
|
+
* v0.1.0 alpha
|
|
8
|
+
*
|
|
9
|
+
* Mode: ACTIVE (default) — DooPush owns UNUserNotificationCenterDelegate via the
|
|
10
|
+
* delegate-forwarding mechanism added in DooPushSDK v1.1.0. Coexists with
|
|
11
|
+
* expo-notifications because both delegates forward to each other.
|
|
12
|
+
*/
|
|
13
|
+
public class DooPushReactNativeSDKModule: Module, DooPushDelegate {
|
|
14
|
+
|
|
15
|
+
public func definition() -> ModuleDefinition {
|
|
16
|
+
Name("DooPushReactNativeSDK")
|
|
17
|
+
|
|
18
|
+
Events("onRegister", "onRegisterError", "onMessage")
|
|
19
|
+
|
|
20
|
+
OnCreate {
|
|
21
|
+
// Wire DooPush's delegate to this module so we can forward events to JS.
|
|
22
|
+
DooPushManager.shared.delegate = self
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// ── configure ───────────────────────────────────────────────────
|
|
26
|
+
Function("configure") { (config: [String: Any]) in
|
|
27
|
+
guard let appId = config["appId"] as? String,
|
|
28
|
+
let apiKey = config["apiKey"] as? String else {
|
|
29
|
+
throw NSError(
|
|
30
|
+
domain: "DooPushReactNativeSDK",
|
|
31
|
+
code: -1,
|
|
32
|
+
userInfo: [NSLocalizedDescriptionKey: "configure requires appId + apiKey"]
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
let baseURL = (config["baseURL"] as? String) ?? ""
|
|
36
|
+
DooPushManager.shared.configure(appId: appId, apiKey: apiKey, baseURL: baseURL)
|
|
37
|
+
|
|
38
|
+
// Always enable automatic notification tracking for active mode (default).
|
|
39
|
+
DooPushManager.shared.enableAutomaticNotificationTracking()
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// ── register ────────────────────────────────────────────────────
|
|
43
|
+
AsyncFunction("register") { (promise: Promise) in
|
|
44
|
+
DooPushManager.shared.registerForPushNotifications { token, error in
|
|
45
|
+
if let error = error {
|
|
46
|
+
promise.reject("E_REGISTER", error.localizedDescription)
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
guard let token = token else {
|
|
50
|
+
promise.reject("E_REGISTER", "Unknown failure: no token returned")
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
let deviceId = DooPushManager.shared.getDeviceId() ?? ""
|
|
54
|
+
promise.resolve([
|
|
55
|
+
"token": token,
|
|
56
|
+
"deviceId": deviceId,
|
|
57
|
+
"vendor": "apns"
|
|
58
|
+
])
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ── registerWithToken ───────────────────────────────────────────
|
|
63
|
+
AsyncFunction("registerWithToken") { (token: String, vendor: String, promise: Promise) in
|
|
64
|
+
DooPushManager.shared.registerDevice(withToken: token, vendor: vendor) { deviceId, error in
|
|
65
|
+
if let error = error {
|
|
66
|
+
promise.reject("E_REGISTER", error.localizedDescription)
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
promise.resolve(["deviceId": deviceId ?? ""])
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ── token getters ───────────────────────────────────────────────
|
|
74
|
+
AsyncFunction("getDeviceToken") { () -> String? in
|
|
75
|
+
return DooPushManager.shared.getDeviceToken()
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
AsyncFunction("getDeviceId") { () -> String? in
|
|
79
|
+
return DooPushManager.shared.getDeviceId()
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// MARK: - DooPushDelegate
|
|
84
|
+
|
|
85
|
+
public func dooPush(_ manager: DooPushManager, didRegisterWithToken token: String) {
|
|
86
|
+
sendEvent("onRegister", [
|
|
87
|
+
"token": token,
|
|
88
|
+
"deviceId": manager.getDeviceId() ?? "",
|
|
89
|
+
"vendor": "apns"
|
|
90
|
+
])
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public func dooPush(_ manager: DooPushManager, didReceiveNotification userInfo: [AnyHashable: Any]) {
|
|
94
|
+
sendEvent("onMessage", normalizeMessage(userInfo))
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
public func dooPush(_ manager: DooPushManager, didFailWithError error: Error) {
|
|
98
|
+
sendEvent("onRegisterError", [
|
|
99
|
+
"code": "E_REGISTER",
|
|
100
|
+
"message": error.localizedDescription
|
|
101
|
+
])
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// MARK: - Helpers
|
|
105
|
+
|
|
106
|
+
/// Convert APNs userInfo into the JS-side DooPushMessage shape.
|
|
107
|
+
private func normalizeMessage(_ userInfo: [AnyHashable: Any]) -> [String: Any] {
|
|
108
|
+
var data: [String: String] = [:]
|
|
109
|
+
var title: String?
|
|
110
|
+
var body: String?
|
|
111
|
+
for (k, v) in userInfo {
|
|
112
|
+
guard let key = k as? String else { continue }
|
|
113
|
+
if key == "aps", let aps = v as? [String: Any], let alert = aps["alert"] as? [String: Any] {
|
|
114
|
+
title = alert["title"] as? String
|
|
115
|
+
body = alert["body"] as? String
|
|
116
|
+
continue
|
|
117
|
+
}
|
|
118
|
+
if let s = v as? String {
|
|
119
|
+
data[key] = s
|
|
120
|
+
} else {
|
|
121
|
+
data[key] = "\(v)"
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return [
|
|
125
|
+
"vendor": "apns",
|
|
126
|
+
"title": title as Any,
|
|
127
|
+
"body": body as Any,
|
|
128
|
+
"messageId": userInfo["apns-id"] as? String as Any,
|
|
129
|
+
"pushLogId": data["push_log_id"] as Any,
|
|
130
|
+
"dedupKey": data["dedup_key"] as Any,
|
|
131
|
+
"data": data
|
|
132
|
+
]
|
|
133
|
+
}
|
|
134
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "doopush-react-native-sdk",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "React Native SDK for DooPush push notification service. Built with Expo Modules API; works in Expo (managed/prebuild) and bare RN.",
|
|
5
|
+
"main": "build/index.js",
|
|
6
|
+
"types": "build/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"build",
|
|
9
|
+
"ios",
|
|
10
|
+
"android",
|
|
11
|
+
"plugin/build",
|
|
12
|
+
"expo-module.config.json",
|
|
13
|
+
"app.plugin.js",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"keywords": [
|
|
17
|
+
"react-native",
|
|
18
|
+
"expo",
|
|
19
|
+
"push-notifications",
|
|
20
|
+
"doopush",
|
|
21
|
+
"fcm",
|
|
22
|
+
"apns"
|
|
23
|
+
],
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "https://github.com/doopush/doopush-react-native-sdk"
|
|
27
|
+
},
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"expo": "*",
|
|
31
|
+
"react": "*",
|
|
32
|
+
"react-native": "*"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/react": "~18.2.45",
|
|
36
|
+
"expo-module-scripts": "^3.5.0",
|
|
37
|
+
"expo-modules-core": "~1.11.0",
|
|
38
|
+
"react": "18.2.0",
|
|
39
|
+
"react-native": "0.73.0",
|
|
40
|
+
"typescript": "^5.3.0"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "tsc && pnpm --filter ./plugin build",
|
|
44
|
+
"build:plugin": "tsc -p plugin/tsconfig.json",
|
|
45
|
+
"test": "pnpm --filter ./plugin test",
|
|
46
|
+
"clean": "rm -rf build plugin/build"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withAndroid = void 0;
|
|
4
|
+
const withRootBuildGradle_1 = require("./withRootBuildGradle");
|
|
5
|
+
const withAppBuildGradle_1 = require("./withAppBuildGradle");
|
|
6
|
+
const withGoogleServices_1 = require("./withGoogleServices");
|
|
7
|
+
const withAndroid = (config, validated) => {
|
|
8
|
+
config = (0, withRootBuildGradle_1.withDooPushRootBuildGradle)(config, validated);
|
|
9
|
+
config = (0, withAppBuildGradle_1.withDooPushAppBuildGradle)(config, validated);
|
|
10
|
+
config = (0, withGoogleServices_1.withDooPushGoogleServices)(config, validated);
|
|
11
|
+
return config;
|
|
12
|
+
};
|
|
13
|
+
exports.withAndroid = withAndroid;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withDooPushAppBuildGradle = void 0;
|
|
4
|
+
const config_plugins_1 = require("@expo/config-plugins");
|
|
5
|
+
const VENDOR_PLACEHOLDER_KEYS = [
|
|
6
|
+
'DOOPUSH_MI_APP_ID',
|
|
7
|
+
'DOOPUSH_MI_APP_KEY',
|
|
8
|
+
'DOOPUSH_OPPO_APP_KEY',
|
|
9
|
+
'DOOPUSH_OPPO_APP_SECRET',
|
|
10
|
+
'DOOPUSH_VIVO_APP_ID',
|
|
11
|
+
'DOOPUSH_VIVO_API_KEY',
|
|
12
|
+
'DOOPUSH_MEIZU_APP_ID',
|
|
13
|
+
'DOOPUSH_MEIZU_APP_KEY',
|
|
14
|
+
'DOOPUSH_HONOR_APP_ID',
|
|
15
|
+
'DOOPUSH_HONOR_DEVELOPER_ID',
|
|
16
|
+
];
|
|
17
|
+
const withDooPushAppBuildGradle = (config, validated) => {
|
|
18
|
+
return (0, config_plugins_1.withAppBuildGradle)(config, (cfg) => {
|
|
19
|
+
let contents = cfg.modResults.contents;
|
|
20
|
+
// 1. Apply google-services plugin if FCM enabled
|
|
21
|
+
if (validated.android.vendors.fcm) {
|
|
22
|
+
if (!contents.includes("apply plugin: 'com.google.gms.google-services'")) {
|
|
23
|
+
contents += `\napply plugin: 'com.google.gms.google-services'\n`;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// 2. Inject manifestPlaceholders block (defaultConfig).
|
|
27
|
+
// For v0.1 alpha, all OEM vendors get empty string placeholders.
|
|
28
|
+
const placeholders = VENDOR_PLACEHOLDER_KEYS
|
|
29
|
+
.map((k) => ` ${k}: ""`)
|
|
30
|
+
.join(',\n');
|
|
31
|
+
const placeholderBlock = `manifestPlaceholders = [\n${placeholders}\n ]`;
|
|
32
|
+
if (!contents.includes('manifestPlaceholders')) {
|
|
33
|
+
contents = contents.replace(/defaultConfig\s*{/, `defaultConfig {\n ${placeholderBlock}`);
|
|
34
|
+
}
|
|
35
|
+
// 3. Inject DooPush Android SDK dependency if not present
|
|
36
|
+
if (!contents.includes('com.github.doopush:doopush-android-sdk')) {
|
|
37
|
+
contents = contents.replace(/dependencies\s*{/, `dependencies {\n implementation 'com.github.doopush:doopush-android-sdk:1.1.+'`);
|
|
38
|
+
}
|
|
39
|
+
cfg.modResults.contents = contents;
|
|
40
|
+
return cfg;
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
exports.withDooPushAppBuildGradle = withDooPushAppBuildGradle;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.withDooPushGoogleServices = void 0;
|
|
37
|
+
const config_plugins_1 = require("@expo/config-plugins");
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const withDooPushGoogleServices = (config, validated) => {
|
|
41
|
+
if (!validated.android.vendors.fcm) {
|
|
42
|
+
return config; // No FCM vendor → no file to copy
|
|
43
|
+
}
|
|
44
|
+
const sourcePath = validated.android.vendors.fcm.googleServicesFile;
|
|
45
|
+
return (0, config_plugins_1.withDangerousMod)(config, [
|
|
46
|
+
'android',
|
|
47
|
+
async (cfg) => {
|
|
48
|
+
const projectRoot = cfg.modRequest.projectRoot;
|
|
49
|
+
const absSource = path.isAbsolute(sourcePath)
|
|
50
|
+
? sourcePath
|
|
51
|
+
: path.resolve(projectRoot, sourcePath);
|
|
52
|
+
if (!fs.existsSync(absSource)) {
|
|
53
|
+
throw new Error(`[doopush-react-native-sdk] google-services.json not found at: ${absSource}`);
|
|
54
|
+
}
|
|
55
|
+
const destDir = path.join(cfg.modRequest.platformProjectRoot, 'app');
|
|
56
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
57
|
+
const dest = path.join(destDir, 'google-services.json');
|
|
58
|
+
fs.copyFileSync(absSource, dest);
|
|
59
|
+
return cfg;
|
|
60
|
+
},
|
|
61
|
+
]);
|
|
62
|
+
};
|
|
63
|
+
exports.withDooPushGoogleServices = withDooPushGoogleServices;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ConfigPlugin } from '@expo/config-plugins';
|
|
2
|
+
import type { PluginConfig } from '../schema';
|
|
3
|
+
/**
|
|
4
|
+
* Adds Maven repositories (jitpack + mavenLocal during dev) to root build.gradle.
|
|
5
|
+
* Idempotent.
|
|
6
|
+
*/
|
|
7
|
+
export declare const withDooPushRootBuildGradle: ConfigPlugin<PluginConfig>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withDooPushRootBuildGradle = void 0;
|
|
4
|
+
const config_plugins_1 = require("@expo/config-plugins");
|
|
5
|
+
/**
|
|
6
|
+
* Adds Maven repositories (jitpack + mavenLocal during dev) to root build.gradle.
|
|
7
|
+
* Idempotent.
|
|
8
|
+
*/
|
|
9
|
+
const withDooPushRootBuildGradle = (config, _validated) => {
|
|
10
|
+
return (0, config_plugins_1.withProjectBuildGradle)(config, (cfg) => {
|
|
11
|
+
let contents = cfg.modResults.contents;
|
|
12
|
+
// Add JitPack repo if missing.
|
|
13
|
+
const jitpack = `maven { url 'https://jitpack.io' }`;
|
|
14
|
+
if (!contents.includes('jitpack.io')) {
|
|
15
|
+
contents = contents.replace(/allprojects\s*{\s*repositories\s*{/, `allprojects {\n repositories {\n ${jitpack}`);
|
|
16
|
+
}
|
|
17
|
+
// mavenLocal for development.
|
|
18
|
+
if (!contents.includes('mavenLocal()')) {
|
|
19
|
+
contents = contents.replace(/allprojects\s*{\s*repositories\s*{/, `allprojects {\n repositories {\n mavenLocal()`);
|
|
20
|
+
}
|
|
21
|
+
cfg.modResults.contents = contents;
|
|
22
|
+
return cfg;
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
exports.withDooPushRootBuildGradle = withDooPushRootBuildGradle;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const schema_1 = require("./schema");
|
|
4
|
+
const withIOS_1 = require("./ios/withIOS");
|
|
5
|
+
const withAndroid_1 = require("./android/withAndroid");
|
|
6
|
+
const withDooPush = (config, raw) => {
|
|
7
|
+
const validated = (0, schema_1.validatePluginConfig)(raw);
|
|
8
|
+
config = (0, withIOS_1.withIOS)(config, validated);
|
|
9
|
+
config = (0, withAndroid_1.withAndroid)(config, validated);
|
|
10
|
+
return config;
|
|
11
|
+
};
|
|
12
|
+
exports.default = withDooPush;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withDooPushEntitlements = void 0;
|
|
4
|
+
const config_plugins_1 = require("@expo/config-plugins");
|
|
5
|
+
/**
|
|
6
|
+
* Sets aps-environment entitlement based on plugin's ios.mode.
|
|
7
|
+
*/
|
|
8
|
+
const withDooPushEntitlements = (config, validated) => {
|
|
9
|
+
return (0, config_plugins_1.withEntitlementsPlist)(config, (cfg) => {
|
|
10
|
+
cfg.modResults['aps-environment'] = validated.ios.mode;
|
|
11
|
+
return cfg;
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
exports.withDooPushEntitlements = withDooPushEntitlements;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withIOS = void 0;
|
|
4
|
+
const withInfoPlist_1 = require("./withInfoPlist");
|
|
5
|
+
const withEntitlements_1 = require("./withEntitlements");
|
|
6
|
+
const withIOS = (config, validated) => {
|
|
7
|
+
config = (0, withInfoPlist_1.withDooPushInfoPlist)(config, validated);
|
|
8
|
+
config = (0, withEntitlements_1.withDooPushEntitlements)(config, validated);
|
|
9
|
+
return config;
|
|
10
|
+
};
|
|
11
|
+
exports.withIOS = withIOS;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withDooPushInfoPlist = void 0;
|
|
4
|
+
const config_plugins_1 = require("@expo/config-plugins");
|
|
5
|
+
/**
|
|
6
|
+
* Adds `remote-notification` to Info.plist UIBackgroundModes (idempotent).
|
|
7
|
+
*/
|
|
8
|
+
const withDooPushInfoPlist = (config, _validated) => {
|
|
9
|
+
return (0, config_plugins_1.withInfoPlist)(config, (cfg) => {
|
|
10
|
+
var _a;
|
|
11
|
+
const plist = cfg.modResults;
|
|
12
|
+
const existing = (_a = plist.UIBackgroundModes) !== null && _a !== void 0 ? _a : [];
|
|
13
|
+
if (!existing.includes('remote-notification')) {
|
|
14
|
+
plist.UIBackgroundModes = [...existing, 'remote-notification'];
|
|
15
|
+
}
|
|
16
|
+
return cfg;
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
exports.withDooPushInfoPlist = withDooPushInfoPlist;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/** Plugin input schema. Validated at prebuild time. */
|
|
3
|
+
export declare const PluginConfigSchema: z.ZodObject<{
|
|
4
|
+
appId: z.ZodString;
|
|
5
|
+
apiKey: z.ZodString;
|
|
6
|
+
baseURL: z.ZodOptional<z.ZodString>;
|
|
7
|
+
ios: z.ZodDefault<z.ZodObject<{
|
|
8
|
+
mode: z.ZodDefault<z.ZodEnum<["development", "production"]>>;
|
|
9
|
+
}, "strip", z.ZodTypeAny, {
|
|
10
|
+
mode: "development" | "production";
|
|
11
|
+
}, {
|
|
12
|
+
mode?: "development" | "production" | undefined;
|
|
13
|
+
}>>;
|
|
14
|
+
android: z.ZodDefault<z.ZodObject<{
|
|
15
|
+
vendors: z.ZodDefault<z.ZodObject<{
|
|
16
|
+
fcm: z.ZodOptional<z.ZodObject<{
|
|
17
|
+
googleServicesFile: z.ZodString;
|
|
18
|
+
}, "strip", z.ZodTypeAny, {
|
|
19
|
+
googleServicesFile: string;
|
|
20
|
+
}, {
|
|
21
|
+
googleServicesFile: string;
|
|
22
|
+
}>>;
|
|
23
|
+
}, "strip", z.ZodTypeAny, {
|
|
24
|
+
fcm?: {
|
|
25
|
+
googleServicesFile: string;
|
|
26
|
+
} | undefined;
|
|
27
|
+
}, {
|
|
28
|
+
fcm?: {
|
|
29
|
+
googleServicesFile: string;
|
|
30
|
+
} | undefined;
|
|
31
|
+
}>>;
|
|
32
|
+
}, "strip", z.ZodTypeAny, {
|
|
33
|
+
vendors: {
|
|
34
|
+
fcm?: {
|
|
35
|
+
googleServicesFile: string;
|
|
36
|
+
} | undefined;
|
|
37
|
+
};
|
|
38
|
+
}, {
|
|
39
|
+
vendors?: {
|
|
40
|
+
fcm?: {
|
|
41
|
+
googleServicesFile: string;
|
|
42
|
+
} | undefined;
|
|
43
|
+
} | undefined;
|
|
44
|
+
}>>;
|
|
45
|
+
}, "strip", z.ZodTypeAny, {
|
|
46
|
+
appId: string;
|
|
47
|
+
apiKey: string;
|
|
48
|
+
ios: {
|
|
49
|
+
mode: "development" | "production";
|
|
50
|
+
};
|
|
51
|
+
android: {
|
|
52
|
+
vendors: {
|
|
53
|
+
fcm?: {
|
|
54
|
+
googleServicesFile: string;
|
|
55
|
+
} | undefined;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
baseURL?: string | undefined;
|
|
59
|
+
}, {
|
|
60
|
+
appId: string;
|
|
61
|
+
apiKey: string;
|
|
62
|
+
baseURL?: string | undefined;
|
|
63
|
+
ios?: {
|
|
64
|
+
mode?: "development" | "production" | undefined;
|
|
65
|
+
} | undefined;
|
|
66
|
+
android?: {
|
|
67
|
+
vendors?: {
|
|
68
|
+
fcm?: {
|
|
69
|
+
googleServicesFile: string;
|
|
70
|
+
} | undefined;
|
|
71
|
+
} | undefined;
|
|
72
|
+
} | undefined;
|
|
73
|
+
}>;
|
|
74
|
+
export type PluginConfig = z.infer<typeof PluginConfigSchema>;
|
|
75
|
+
/**
|
|
76
|
+
* Parse and validate plugin config; throws a friendly error on invalid input.
|
|
77
|
+
*/
|
|
78
|
+
export declare function validatePluginConfig(input: unknown): PluginConfig;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PluginConfigSchema = void 0;
|
|
4
|
+
exports.validatePluginConfig = validatePluginConfig;
|
|
5
|
+
const zod_1 = require("zod");
|
|
6
|
+
/** Plugin input schema. Validated at prebuild time. */
|
|
7
|
+
exports.PluginConfigSchema = zod_1.z.object({
|
|
8
|
+
appId: zod_1.z
|
|
9
|
+
.string({ required_error: 'appId is required', invalid_type_error: 'appId is required' })
|
|
10
|
+
.min(1, 'appId is required'),
|
|
11
|
+
apiKey: zod_1.z
|
|
12
|
+
.string({ required_error: 'apiKey is required', invalid_type_error: 'apiKey is required' })
|
|
13
|
+
.min(1, 'apiKey is required'),
|
|
14
|
+
baseURL: zod_1.z.string().url().optional(),
|
|
15
|
+
ios: zod_1.z
|
|
16
|
+
.object({
|
|
17
|
+
mode: zod_1.z.enum(['development', 'production']).default('production'),
|
|
18
|
+
})
|
|
19
|
+
.default({}),
|
|
20
|
+
android: zod_1.z
|
|
21
|
+
.object({
|
|
22
|
+
vendors: zod_1.z
|
|
23
|
+
.object({
|
|
24
|
+
fcm: zod_1.z
|
|
25
|
+
.object({
|
|
26
|
+
googleServicesFile: zod_1.z
|
|
27
|
+
.string({
|
|
28
|
+
required_error: 'googleServicesFile is required when fcm vendor is enabled',
|
|
29
|
+
invalid_type_error: 'googleServicesFile is required when fcm vendor is enabled',
|
|
30
|
+
})
|
|
31
|
+
.min(1, 'googleServicesFile is required when fcm vendor is enabled'),
|
|
32
|
+
})
|
|
33
|
+
.optional(),
|
|
34
|
+
// v0.5.0 will add hms / honor / xiaomi / oppo / vivo / meizu here.
|
|
35
|
+
})
|
|
36
|
+
.default({}),
|
|
37
|
+
})
|
|
38
|
+
.default({}),
|
|
39
|
+
});
|
|
40
|
+
/**
|
|
41
|
+
* Parse and validate plugin config; throws a friendly error on invalid input.
|
|
42
|
+
*/
|
|
43
|
+
function validatePluginConfig(input) {
|
|
44
|
+
const result = exports.PluginConfigSchema.safeParse(input);
|
|
45
|
+
if (!result.success) {
|
|
46
|
+
const issues = result.error.issues
|
|
47
|
+
.map((i) => ` - ${i.path.join('.')}: ${i.message}`)
|
|
48
|
+
.join('\n');
|
|
49
|
+
throw new Error(`[doopush-react-native-sdk] config plugin received invalid input:\n${issues}`);
|
|
50
|
+
}
|
|
51
|
+
return result.data;
|
|
52
|
+
}
|