appsonair-react-native-apppush 0.0.1-alpha
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/LICENSE +21 -0
- package/README.md +540 -0
- package/android/build.gradle +177 -0
- package/android/gradle.properties +15 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/AndroidManifestNew.xml +2 -0
- package/android/src/main/java/com/appsonairreactnativeapppush/AppsonairReactNativeApppushModuleImpl.kt +767 -0
- package/android/src/main/java/com/appsonairreactnativeapppush/AppsonairReactNativeApppushPackage.kt +43 -0
- package/android/src/newarch/java/com/appsonairreactnativeapppush/AppsonairReactNativeApppushModule.kt +199 -0
- package/android/src/oldarch/java/com/appsonairreactnativeapppush/AppsonairReactNativeApppushModule.kt +249 -0
- package/appsonair-react-native-apppush.podspec +77 -0
- package/ios/AppsonairReactNativeApppush-Bridging-Header.h +12 -0
- package/ios/AppsonairReactNativeApppush.h +28 -0
- package/ios/AppsonairReactNativeApppush.mm +494 -0
- package/ios/AppsonairReactNativeApppushImpl.swift +594 -0
- package/lib/commonjs/NativeAppsonairApppush.js +48 -0
- package/lib/commonjs/NativeAppsonairApppush.js.map +1 -0
- package/lib/commonjs/index.js +686 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/types.js +2 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/module/NativeAppsonairApppush.js +47 -0
- package/lib/module/NativeAppsonairApppush.js.map +1 -0
- package/lib/module/index.js +612 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/src/NativeAppsonairApppush.d.ts +134 -0
- package/lib/typescript/commonjs/src/NativeAppsonairApppush.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/index.d.ts +392 -0
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/types.d.ts +221 -0
- package/lib/typescript/commonjs/src/types.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/src/NativeAppsonairApppush.d.ts +134 -0
- package/lib/typescript/module/src/NativeAppsonairApppush.d.ts.map +1 -0
- package/lib/typescript/module/src/index.d.ts +392 -0
- package/lib/typescript/module/src/index.d.ts.map +1 -0
- package/lib/typescript/module/src/types.d.ts +221 -0
- package/lib/typescript/module/src/types.d.ts.map +1 -0
- package/package.json +119 -0
- package/react-native.config.js +14 -0
- package/src/NativeAppsonairApppush.ts +188 -0
- package/src/index.tsx +745 -0
- package/src/types.ts +284 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-platform types for the AppsOnAir Push SDK.
|
|
3
|
+
*
|
|
4
|
+
* Where the two native SDKs disagree, this file defines the single shape the
|
|
5
|
+
* wrapper exposes and the native bridges normalise to. Every such decision
|
|
6
|
+
* traces to a row in `appsonair-push-notification-android/CROSS_PLATFORM_PARITY.md`;
|
|
7
|
+
* the row id is cited so the reason survives.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// MARK: - Configuration
|
|
11
|
+
|
|
12
|
+
export interface PushConfig {
|
|
13
|
+
/** Print SDK logs to the console. Keep `false` in production. */
|
|
14
|
+
debug?: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* There is deliberately no `appGroupId` option.
|
|
19
|
+
*
|
|
20
|
+
* The parity audit's A1 row proposes one, but the native iOS initializer is
|
|
21
|
+
* `initialize(debug:swizzle:)` — it takes no App Group argument. iOS resolves the
|
|
22
|
+
* group itself, from an `AppsOnAirAppGroup` string in the app's Info.plist, else
|
|
23
|
+
* the convention `group.<bundle-id>.appsonair`. Accepting the value here would be
|
|
24
|
+
* a knob that silently does nothing, so it is configured where it is actually
|
|
25
|
+
* read. See the README's iOS setup section.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
// MARK: - Notification payload
|
|
29
|
+
|
|
30
|
+
/** An action button attached to the notification payload. */
|
|
31
|
+
export interface NotificationActionButton {
|
|
32
|
+
id: string;
|
|
33
|
+
title: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** A media attachment, or one entry synthesised from `imageUrl`. */
|
|
37
|
+
export interface NotificationAttachment {
|
|
38
|
+
id: string | null;
|
|
39
|
+
url: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* A received or tapped notification.
|
|
44
|
+
*
|
|
45
|
+
* Parity C1: iOS emits 14 fields, Android 6. This is the union — fields the
|
|
46
|
+
* running platform cannot source resolve to `null` (or `[]`), never `undefined`.
|
|
47
|
+
* The per-field platform notes below are the authoritative support matrix.
|
|
48
|
+
*/
|
|
49
|
+
export interface PushNotification {
|
|
50
|
+
/** Payload `notification_id`. */
|
|
51
|
+
id: string | null;
|
|
52
|
+
/** Payload `campaign_id`. **iOS only** — `null` on Android. */
|
|
53
|
+
campaignId: string | null;
|
|
54
|
+
/** Payload `template_id`. **iOS only** — `null` on Android. */
|
|
55
|
+
templateId: string | null;
|
|
56
|
+
/** Payload `sent_at`, ISO-8601 exactly as received. **iOS only.** */
|
|
57
|
+
sentAt: string | null;
|
|
58
|
+
|
|
59
|
+
title: string | null;
|
|
60
|
+
/** Second line above the body. **iOS only** — Android has no subtitle concept. */
|
|
61
|
+
subtitle: string | null;
|
|
62
|
+
body: string | null;
|
|
63
|
+
|
|
64
|
+
/** Payload `url` — deep link opened on tap. */
|
|
65
|
+
launchUrl: string | null;
|
|
66
|
+
/** Payload `image_url`. On iOS this loses to `attachments` when both are present. */
|
|
67
|
+
imageUrl: string | null;
|
|
68
|
+
/** Payload `attachments`. **iOS only** — always `[]` on Android. */
|
|
69
|
+
attachments: NotificationAttachment[];
|
|
70
|
+
/** Payload `actions`. Supported on both platforms. */
|
|
71
|
+
actionButtons: NotificationActionButton[];
|
|
72
|
+
/** Payload `badge_increment`. **iOS only** — `null` on Android. */
|
|
73
|
+
badgeIncrement: number | null;
|
|
74
|
+
/** Payload `collapse_id` (iOS) / `collapse_key` (Android). */
|
|
75
|
+
collapseId: string | null;
|
|
76
|
+
/** Sound file name in `res/raw`, no extension. **Android only** — `null` on iOS. */
|
|
77
|
+
sound: string | null;
|
|
78
|
+
/** Notification channel id. **Android only** — `null` on iOS. */
|
|
79
|
+
channelId: string | null;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Flattened string map of the payload's custom keys.
|
|
83
|
+
*
|
|
84
|
+
* Parity C1: Android's native `data` map is already `Map<String, String>`;
|
|
85
|
+
* the iOS bridge flattens `userInfo` to match, so this field has the same
|
|
86
|
+
* meaning on both platforms.
|
|
87
|
+
*/
|
|
88
|
+
data: Record<string, string>;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The complete unmodified payload. Shapes differ per platform (APNs `userInfo`
|
|
92
|
+
* vs the FCM data bundle) — reach for `data` first, and use this only for keys
|
|
93
|
+
* that survive neither flattening nor the typed fields above.
|
|
94
|
+
*/
|
|
95
|
+
rawPayload: Record<string, unknown>;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// MARK: - Events
|
|
99
|
+
|
|
100
|
+
export interface TokenUpdatedEvent {
|
|
101
|
+
/** APNs hex token on iOS, FCM registration token on Android. */
|
|
102
|
+
token: string;
|
|
103
|
+
/**
|
|
104
|
+
* Parity B1/C8: which APNs endpoint the backend must use.
|
|
105
|
+
* **iOS only** — always `null` on Android, where FCM routes for you.
|
|
106
|
+
*/
|
|
107
|
+
environment: 'sandbox' | 'production' | null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface NotificationOpenedEvent {
|
|
111
|
+
notification: PushNotification;
|
|
112
|
+
/** `null` when the notification body was tapped; set for an action-button tap. */
|
|
113
|
+
actionId: string | null;
|
|
114
|
+
/** The payload's launch URL, if any. */
|
|
115
|
+
url: string | null;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface NotificationReceivedEvent {
|
|
119
|
+
notification: PushNotification;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Fired while the app is in the foreground, before the notification is displayed.
|
|
124
|
+
*
|
|
125
|
+
* Parity B4/F7: `preventDefault()` is exposed, presentation options are not —
|
|
126
|
+
* iOS lets the OS present, Android builds the notification itself, so any
|
|
127
|
+
* option set would mean different things on each platform.
|
|
128
|
+
*/
|
|
129
|
+
export interface NotificationWillDisplayEvent {
|
|
130
|
+
notification: PushNotification;
|
|
131
|
+
/**
|
|
132
|
+
* Suppress the system notification. Must be called synchronously in the handler.
|
|
133
|
+
*
|
|
134
|
+
* **Honoured on Android only.** The Android SDK calls its foreground listeners
|
|
135
|
+
* on FCM's background thread, so the bridge can park there while JS decides.
|
|
136
|
+
* iOS's `handleWillPresent(notification:)` returns its presentation options
|
|
137
|
+
* synchronously with no completion handler to hold open, so by the time a JS
|
|
138
|
+
* handler runs the notification has already been presented. On iOS this event
|
|
139
|
+
* is informational and calling `preventDefault()` does nothing.
|
|
140
|
+
*/
|
|
141
|
+
preventDefault: () => void;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export interface PermissionChangedEvent {
|
|
145
|
+
granted: boolean;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export interface PushSubscriptionState {
|
|
149
|
+
id: string | null;
|
|
150
|
+
token: string | null;
|
|
151
|
+
optedIn: boolean;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export interface PushSubscriptionChangedEvent {
|
|
155
|
+
previous: PushSubscriptionState;
|
|
156
|
+
current: PushSubscriptionState;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export interface UserState {
|
|
160
|
+
/** The external id linked via `login()`. `null` while anonymous. */
|
|
161
|
+
externalId: string | null;
|
|
162
|
+
/** The AppsOnAir-assigned device id. */
|
|
163
|
+
appsOnAirId: string;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export interface UserStateChangedEvent {
|
|
167
|
+
current: UserState;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* A data-only push that is delivered without being displayed.
|
|
172
|
+
*
|
|
173
|
+
* Parity F5 — supported on both platforms, but the two are triggered
|
|
174
|
+
* differently and your backend has to send for both:
|
|
175
|
+
*
|
|
176
|
+
* - **iOS** uses the APNs transport flag, `content-available: 1`.
|
|
177
|
+
* - **Android** has no transport-level equivalent in FCM, so the SDK keys off a
|
|
178
|
+
* `silent: "true"` entry in the data payload. A data push *without* that key
|
|
179
|
+
* renders as a visible notification and fires no listener here.
|
|
180
|
+
*
|
|
181
|
+
* On iOS the OS completion handler is invoked as soon as the event is emitted,
|
|
182
|
+
* so a handler cannot extend the background execution window.
|
|
183
|
+
*/
|
|
184
|
+
export interface SilentNotificationEvent {
|
|
185
|
+
data: Record<string, string>;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** Firebase Installation ID. Parity B2: **Android only.** */
|
|
189
|
+
export interface InstallationIdEvent {
|
|
190
|
+
id: string;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Parity C5: the union of both platforms' error codes in one casing.
|
|
195
|
+
* `tokenRegistrationFailed` is the shared name for iOS `apnsRegistrationFailed`
|
|
196
|
+
* and Android `TOKEN_FETCH_FAILED`.
|
|
197
|
+
*
|
|
198
|
+
* Native `PushError.cause` is dropped — a `Throwable` does not cross the bridge.
|
|
199
|
+
*/
|
|
200
|
+
export type PushErrorCode =
|
|
201
|
+
| 'notInitialized'
|
|
202
|
+
| 'permissionDenied'
|
|
203
|
+
/** **Android only.** No `google-services.json`, or the plugin was not applied. */
|
|
204
|
+
| 'firebaseNotConfigured'
|
|
205
|
+
| 'tokenRegistrationFailed'
|
|
206
|
+
| 'installationIdFetchFailed'
|
|
207
|
+
| 'unknown';
|
|
208
|
+
|
|
209
|
+
export interface PushErrorEvent {
|
|
210
|
+
code: PushErrorCode;
|
|
211
|
+
message: string;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// MARK: - Enums
|
|
215
|
+
|
|
216
|
+
/** Parity C6: one casing for both platforms; the bridge maps to the native enum. */
|
|
217
|
+
export type LogLevel =
|
|
218
|
+
| 'none'
|
|
219
|
+
| 'fatal'
|
|
220
|
+
| 'error'
|
|
221
|
+
| 'warn'
|
|
222
|
+
| 'info'
|
|
223
|
+
| 'debug'
|
|
224
|
+
| 'verbose';
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Parity C7: iOS reports all five states. Android has no granular type and
|
|
228
|
+
* reports only `authorized` or `denied` — it can never return `notDetermined`,
|
|
229
|
+
* so do not branch on that value for a cross-platform pre-prompt.
|
|
230
|
+
*/
|
|
231
|
+
export type PermissionStatus =
|
|
232
|
+
| 'notDetermined'
|
|
233
|
+
| 'denied'
|
|
234
|
+
| 'authorized'
|
|
235
|
+
| 'provisional'
|
|
236
|
+
| 'ephemeral';
|
|
237
|
+
|
|
238
|
+
export interface RequestPermissionOptions {
|
|
239
|
+
/**
|
|
240
|
+
* When permission was already permanently denied, send the user to the OS
|
|
241
|
+
* settings screen instead of failing silently. Defaults to `false`.
|
|
242
|
+
*/
|
|
243
|
+
fallbackToSettings?: boolean;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// MARK: - Android notification channels
|
|
247
|
+
|
|
248
|
+
/** Mirrors `NotificationManager.IMPORTANCE_*`. */
|
|
249
|
+
export type NotificationChannelImportance =
|
|
250
|
+
| 'none'
|
|
251
|
+
| 'min'
|
|
252
|
+
| 'low'
|
|
253
|
+
| 'default'
|
|
254
|
+
| 'high'
|
|
255
|
+
| 'max';
|
|
256
|
+
|
|
257
|
+
/** Parity F4: **Android only.** A no-op on iOS, which has no channel concept. */
|
|
258
|
+
export interface NotificationChannelConfig {
|
|
259
|
+
id: string;
|
|
260
|
+
name: string;
|
|
261
|
+
importance?: NotificationChannelImportance;
|
|
262
|
+
description?: string;
|
|
263
|
+
/** Sound file name in `res/raw`, without extension. */
|
|
264
|
+
sound?: string;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// MARK: - Background sync
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Parity H1: the two native APIs share no method name, parameter, or unit —
|
|
271
|
+
* iOS takes seconds via BGTaskScheduler, Android minutes via WorkManager. This
|
|
272
|
+
* is the single shape; each bridge converts.
|
|
273
|
+
*/
|
|
274
|
+
export interface BackgroundSyncOptions {
|
|
275
|
+
/** Defaults to 60. iOS converts to seconds and treats it as a *minimum* delay. */
|
|
276
|
+
intervalMinutes?: number;
|
|
277
|
+
/** Android WorkManager constraint. Ignored on iOS. Defaults to `true`. */
|
|
278
|
+
requireNetwork?: boolean;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/** Returned by every `on*` subscribe helper. Call `remove()` to unsubscribe. */
|
|
282
|
+
export interface Subscription {
|
|
283
|
+
remove: () => void;
|
|
284
|
+
}
|