react-native-notify-kit 9.6.0 → 10.0.0
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 +87 -5
- package/RNNotifeeCore.podspec +2 -0
- package/android/src/main/java/app/notifee/core/NotificationManager.java +98 -0
- package/android/src/test/java/app/notifee/core/GetDisplayedNotificationsDataTest.java +242 -0
- package/cli/bin/react-native-notify-kit +2 -0
- package/cli/dist/cli.bundle.js +20834 -0
- package/cli/dist/cli.d.ts +2 -0
- package/cli/dist/cli.js +87 -0
- package/cli/dist/cli.js.map +1 -0
- package/cli/dist/commands/initNse.d.ts +12 -0
- package/cli/dist/commands/initNse.js +212 -0
- package/cli/dist/commands/initNse.js.map +1 -0
- package/cli/dist/lib/detectProject.d.ts +15 -0
- package/cli/dist/lib/detectProject.js +156 -0
- package/cli/dist/lib/detectProject.js.map +1 -0
- package/cli/dist/lib/logger.d.ts +4 -0
- package/cli/dist/lib/logger.js +24 -0
- package/cli/dist/lib/logger.js.map +1 -0
- package/cli/dist/lib/patchPodfile.d.ts +12 -0
- package/cli/dist/lib/patchPodfile.js +143 -0
- package/cli/dist/lib/patchPodfile.js.map +1 -0
- package/cli/dist/lib/patchXcodeProject.d.ts +25 -0
- package/cli/dist/lib/patchXcodeProject.js +239 -0
- package/cli/dist/lib/patchXcodeProject.js.map +1 -0
- package/cli/dist/lib/writeTemplates.d.ts +11 -0
- package/cli/dist/lib/writeTemplates.js +82 -0
- package/cli/dist/lib/writeTemplates.js.map +1 -0
- package/cli/dist/templates/Info.plist.tmpl +29 -0
- package/cli/dist/templates/NotificationService.swift.tmpl +32 -0
- package/cli/dist/templates/NotifyKitNSE.entitlements.tmpl +6 -0
- package/cli/dist/templates/templates/Info.plist.tmpl +29 -0
- package/cli/dist/templates/templates/NotificationService.swift.tmpl +73 -0
- package/cli/dist/templates/templates/NotifyKitNSE.entitlements.tmpl +6 -0
- package/dist/NotifeeApiModule.d.ts +17 -0
- package/dist/NotifeeApiModule.js +66 -1
- package/dist/NotifeeApiModule.js.map +1 -1
- package/dist/fcm/index.d.ts +4 -0
- package/dist/fcm/index.js +3 -0
- package/dist/fcm/index.js.map +1 -0
- package/dist/fcm/parseFcmPayload.d.ts +16 -0
- package/dist/fcm/parseFcmPayload.js +37 -0
- package/dist/fcm/parseFcmPayload.js.map +1 -0
- package/dist/fcm/reconstructNotification.d.ts +8 -0
- package/dist/fcm/reconstructNotification.js +167 -0
- package/dist/fcm/reconstructNotification.js.map +1 -0
- package/dist/fcm/types.d.ts +51 -0
- package/dist/fcm/types.js +6 -0
- package/dist/fcm/types.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/types/Module.d.ts +21 -0
- package/dist/types/Notification.d.ts +35 -4
- package/dist/types/Notification.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/jest-mock.js +1 -0
- package/package.json +38 -3
- package/server/README.md +129 -0
- package/server/dist/android.d.ts +8 -0
- package/server/dist/android.d.ts.map +1 -0
- package/server/dist/android.js +20 -0
- package/server/dist/android.js.map +1 -0
- package/server/dist/buildPayload.d.ts +3 -0
- package/server/dist/buildPayload.d.ts.map +1 -0
- package/server/dist/buildPayload.js +82 -0
- package/server/dist/buildPayload.js.map +1 -0
- package/server/dist/index.d.ts +6 -0
- package/server/dist/index.d.ts.map +1 -0
- package/server/dist/index.js +12 -0
- package/server/dist/index.js.map +1 -0
- package/server/dist/ios.d.ts +11 -0
- package/server/dist/ios.d.ts.map +1 -0
- package/server/dist/ios.js +61 -0
- package/server/dist/ios.js.map +1 -0
- package/server/dist/serialize.d.ts +11 -0
- package/server/dist/serialize.d.ts.map +1 -0
- package/server/dist/serialize.js +32 -0
- package/server/dist/serialize.js.map +1 -0
- package/server/dist/types.d.ts +2 -0
- package/server/dist/types.d.ts.map +1 -0
- package/server/dist/types.js +3 -0
- package/server/dist/types.js.map +1 -0
- package/server/dist/validation.d.ts +3 -0
- package/server/dist/validation.d.ts.map +1 -0
- package/server/dist/validation.js +101 -0
- package/server/dist/validation.js.map +1 -0
- package/server/package.json +5 -0
- package/server/src/android.ts +27 -0
- package/server/src/buildPayload.ts +91 -0
- package/server/src/index.ts +12 -0
- package/server/src/ios.ts +88 -0
- package/server/src/serialize.ts +39 -0
- package/server/src/types.ts +24 -0
- package/server/src/validation.ts +134 -0
- package/server/tsconfig.json +25 -0
- package/src/NotifeeApiModule.ts +80 -1
- package/src/fcm/index.ts +4 -0
- package/src/fcm/parseFcmPayload.ts +56 -0
- package/src/fcm/reconstructNotification.ts +201 -0
- package/src/fcm/types.ts +57 -0
- package/src/index.ts +2 -0
- package/src/internal/fcmContract.d.ts +150 -0
- package/src/types/Module.ts +23 -0
- package/src/types/Notification.ts +35 -4
- package/src/version.ts +1 -1
package/dist/types/Module.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { AndroidChannel, AndroidChannelGroup, NativeAndroidChannel, NativeAndroi
|
|
|
4
4
|
import { IOSNotificationCategory, IOSNotificationConfig, IOSNotificationPermissions } from './NotificationIOS';
|
|
5
5
|
import { PowerManagerInfo } from './PowerManagerInfo';
|
|
6
6
|
import { DisplayedNotification, NotificationSettings, TriggerNotification } from '..';
|
|
7
|
+
import type { FcmConfig, FcmRemoteMessage } from '../fcm/types';
|
|
7
8
|
export interface Module {
|
|
8
9
|
/**
|
|
9
10
|
* API used to cancel all notifications.
|
|
@@ -604,6 +605,26 @@ export interface Module {
|
|
|
604
605
|
* @platform android
|
|
605
606
|
*/
|
|
606
607
|
hideNotificationDrawer(): void;
|
|
608
|
+
/**
|
|
609
|
+
* Processes an FCM remote message produced by the NotifyKit server SDK and
|
|
610
|
+
* displays a Notifee notification according to the embedded `notifee_options`.
|
|
611
|
+
*
|
|
612
|
+
* Safe to call from both `setBackgroundMessageHandler` and `onMessage`.
|
|
613
|
+
*
|
|
614
|
+
* @returns The displayed notification ID, or `null` if the call was an
|
|
615
|
+
* intentional no-op (iOS background, `fallbackBehavior: 'ignore'`,
|
|
616
|
+
* `suppressForegroundBanner`).
|
|
617
|
+
*/
|
|
618
|
+
handleFcmMessage(remoteMessage: FcmRemoteMessage): Promise<string | null>;
|
|
619
|
+
/**
|
|
620
|
+
* Configures defaults for {@link handleFcmMessage}. Call once at app startup,
|
|
621
|
+
* typically in `index.js` before `registerComponent`.
|
|
622
|
+
*
|
|
623
|
+
* Returns Promise for forward compatibility — a future version may persist
|
|
624
|
+
* config across cold starts, which would be async. Currently resolves
|
|
625
|
+
* synchronously.
|
|
626
|
+
*/
|
|
627
|
+
setFcmConfig(config: FcmConfig): Promise<void>;
|
|
607
628
|
}
|
|
608
629
|
/**
|
|
609
630
|
* Interface describing the static properties available on the default `react-native-notify-kit` export.
|
|
@@ -32,10 +32,41 @@ export interface Notification {
|
|
|
32
32
|
*/
|
|
33
33
|
body?: string | undefined;
|
|
34
34
|
/**
|
|
35
|
-
* Additional data to
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
35
|
+
* Additional data to associate with the notification.
|
|
36
|
+
*
|
|
37
|
+
* On Android, when populated by `getDisplayedNotifications()`, the `data`
|
|
38
|
+
* field reflects custom keys present in the underlying `Notification.extras`,
|
|
39
|
+
* with the following keys filtered out: prefixes `android.`, `google.`,
|
|
40
|
+
* `gcm.`, `fcm.` (with trailing dot — `fcmRegion` survives), and `notifee`
|
|
41
|
+
* (no trailing dot — library's reserved namespace, `notifeeFoo` is also
|
|
42
|
+
* filtered), plus exact keys `from`, `collapse_key`, `message_type`,
|
|
43
|
+
* `message_id`, `aps`, `fcm_options`.
|
|
44
|
+
*
|
|
45
|
+
* **Important FCM platform limitation on Android**: when the FCM Android SDK
|
|
46
|
+
* auto-displays a `notification`+`data` push while the app is in background
|
|
47
|
+
* or killed, custom `data` fields are placed only on the tap-action
|
|
48
|
+
* `PendingIntent` and never on `Notification.extras`. This is FCM's design
|
|
49
|
+
* (see `CommonNotificationBuilder.createContentIntent` in the firebase-android-sdk
|
|
50
|
+
* source) and cannot be worked around from any library — the PendingIntent's
|
|
51
|
+
* extras are sealed by Android's security model. Tracked in
|
|
52
|
+
* firebase-android-sdk#2639 (open since 2021).
|
|
53
|
+
*
|
|
54
|
+
* The `data` field DOES surface custom keys for: notifications created via
|
|
55
|
+
* `notifee.displayNotification({ data })`, FCM data-only messages handled
|
|
56
|
+
* in `onMessageReceived` followed by an explicit `displayNotification()`,
|
|
57
|
+
* custom `FirebaseMessagingService.handleIntent` overrides that inject
|
|
58
|
+
* extras before display, and notifications posted by other libraries that
|
|
59
|
+
* call `NotificationCompat.Builder.addExtras(bundle)`.
|
|
60
|
+
*
|
|
61
|
+
* Recommended pattern for full control over FCM push notifications on Android:
|
|
62
|
+
* send FCM data-only messages (no `notification` field server-side), handle
|
|
63
|
+
* them in `onMessageReceived`, and render the notification via
|
|
64
|
+
* `notifee.displayNotification()`.
|
|
65
|
+
*
|
|
66
|
+
* Note: the `fcm` filter diverges from iOS, which uses a broader bare-`fcm*`
|
|
67
|
+
* prefix filter (deliberately, to catch `fcm_options`). On Android, only
|
|
68
|
+
* `fcm.` (with dot) and the exact key `fcm_options` are filtered — custom
|
|
69
|
+
* keys like `fcmRegion` are preserved on Android but filtered on iOS.
|
|
39
70
|
*/
|
|
40
71
|
data?: {
|
|
41
72
|
[key: string]: string | object | number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Notification.js","sourceRoot":"","sources":["../../src/types/Notification.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"Notification.js","sourceRoot":"","sources":["../../src/types/Notification.ts"],"names":[],"mappings":"AAAA;;GAEG;AA4UH;;;;;GAKG;AACH,MAAM,CAAN,IAAY,SA2EX;AA3ED,WAAY,SAAS;IACnB;;;;;OAKG;IACH,gDAAY,CAAA;IAEZ;;;;;;;OAOG;IACH,mDAAa,CAAA;IAEb;;;;;;OAMG;IACH,2CAAS,CAAA;IAET;;OAEG;IACH,yDAAgB,CAAA;IAEhB;;;;;;OAMG;IACH,mDAAa,CAAA;IAEb;;;;;OAKG;IACH,uDAAe,CAAA;IAEf;;;;OAIG;IACH,+DAAmB,CAAA;IAEnB;;;;OAIG;IACH,2EAAyB,CAAA;IAEzB;;OAEG;IACH,yFAAgC,CAAA;IAEhC;;;;OAIG;IACH,iEAAoB,CAAA;AACtB,CAAC,EA3EW,SAAS,KAAT,SAAS,QA2EpB;AA+ED;;;;;;GAMG;AACH,MAAM,CAAN,IAAY,mBA0BX;AA1BD,WAAY,mBAAmB;IAC7B;;;;;;;OAOG;IACH,kFAAmB,CAAA;IAEnB;;OAEG;IACH,iEAAU,CAAA;IAEV;;OAEG;IACH,yEAAc,CAAA;IAEd;;;OAGG;IACH,2EAAe,CAAA;AACjB,CAAC,EA1BW,mBAAmB,KAAnB,mBAAmB,QA0B9B"}
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "
|
|
1
|
+
export declare const version = "10.0.0";
|
package/dist/version.js
CHANGED
package/dist/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,MAAM,CAAC,MAAM,OAAO,GAAG,
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAC"}
|
package/jest-mock.js
CHANGED
package/package.json
CHANGED
|
@@ -1,16 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-notify-kit",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.0.0",
|
|
4
4
|
"author": "Marco Crupi",
|
|
5
5
|
"description": "Maintained Notifee-compatible fork for React Native — advanced local notifications for Android & iOS.",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": "./cli/bin/react-native-notify-kit",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./server": {
|
|
15
|
+
"types": "./server/dist/index.d.ts",
|
|
16
|
+
"default": "./server/dist/index.js"
|
|
17
|
+
},
|
|
18
|
+
"./jest-mock": "./jest-mock.js",
|
|
19
|
+
"./react-native.config.js": "./react-native.config.js",
|
|
20
|
+
"./package.json": "./package.json",
|
|
21
|
+
"./src/internal/*": null,
|
|
22
|
+
"./src/*": "./src/*",
|
|
23
|
+
"./dist/*": "./dist/*"
|
|
24
|
+
},
|
|
8
25
|
"scripts": {
|
|
9
26
|
"validate:all:ts": "tsc --project ./",
|
|
10
27
|
"build": "genversion --es6 --semi src/version.ts && tsc",
|
|
11
|
-
"build:
|
|
28
|
+
"build:server": "tsc -p server/tsconfig.json",
|
|
29
|
+
"build:clean": "rimraf android/build && rimraf ios/build && rimraf dist && rimraf server/dist",
|
|
12
30
|
"build:watch": "tsc --watch",
|
|
31
|
+
"test:server": "jest --config jest.config.server.js",
|
|
13
32
|
"prepare": "yarn run build",
|
|
33
|
+
"prepack": "bash ../../scripts/prepack-cli.sh",
|
|
34
|
+
"postpack": "rm -rf cli",
|
|
14
35
|
"prepublishOnly": "cd ../.. && yarn run build:core",
|
|
15
36
|
"format:android": "google-java-format --replace -i $(find . -type f -name \"*.java\" ! -path \"*/node_modules/*\" ! -path \"*/generated/*\")",
|
|
16
37
|
"format:android:check": "google-java-format --set-exit-if-changed --replace -i $(find . -type f -name \"*.java\" ! -path \"*/node_modules/*\" ! -path \"*/generated/*\")",
|
|
@@ -31,6 +52,12 @@
|
|
|
31
52
|
"ts-jest": "^29.2.5",
|
|
32
53
|
"typescript": "^5.9.3"
|
|
33
54
|
},
|
|
55
|
+
"optionalDependencies": {
|
|
56
|
+
"chalk": "^4.1.0",
|
|
57
|
+
"commander": "^12.0.0",
|
|
58
|
+
"plist": "^3.1.0",
|
|
59
|
+
"xcode": "^3.0.1"
|
|
60
|
+
},
|
|
34
61
|
"peerDependencies": {
|
|
35
62
|
"react-native": ">=0.73.0"
|
|
36
63
|
},
|
|
@@ -79,6 +106,14 @@
|
|
|
79
106
|
"/*.podspec",
|
|
80
107
|
"/jest-mock.js",
|
|
81
108
|
"/react-native.config.js",
|
|
82
|
-
"tsconfig.json"
|
|
109
|
+
"tsconfig.json",
|
|
110
|
+
"/server/dist",
|
|
111
|
+
"/server/src",
|
|
112
|
+
"!/server/src/__tests__",
|
|
113
|
+
"/server/README.md",
|
|
114
|
+
"/server/tsconfig.json",
|
|
115
|
+
"/server/package.json",
|
|
116
|
+
"/cli/dist",
|
|
117
|
+
"/cli/bin"
|
|
83
118
|
]
|
|
84
119
|
}
|
package/server/README.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# react-native-notify-kit/server
|
|
2
|
+
|
|
3
|
+
Server-side FCM HTTP v1 payload builder for [`react-native-notify-kit`](../README.md). Runs in Node.js 22+ (backends, Firebase Cloud Functions). **Zero runtime dependencies.**
|
|
4
|
+
|
|
5
|
+
Use it to construct payloads that the client-side `handleFcmMessage` handler can consume — Android receives data-only messages routed through `setBackgroundMessageHandler`, iOS receives alert-style APNs payloads that a Notification Service Extension reads from the `notifee_options` key.
|
|
6
|
+
|
|
7
|
+
For the full end-to-end guide (client setup, iOS NSE scaffolding, migration, troubleshooting), see [`docs/fcm-mode.md`](../../../docs/fcm-mode.md).
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
Bundled with `react-native-notify-kit` — import from the `/server` subpath:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { buildNotifyKitPayload } from 'react-native-notify-kit/server';
|
|
15
|
+
import * as admin from 'firebase-admin';
|
|
16
|
+
|
|
17
|
+
const message = buildNotifyKitPayload({
|
|
18
|
+
token: '<device FCM token>',
|
|
19
|
+
notification: {
|
|
20
|
+
id: 'order-42',
|
|
21
|
+
title: 'Your order is on the way',
|
|
22
|
+
body: 'Tap to see live tracking',
|
|
23
|
+
data: { orderId: '42' },
|
|
24
|
+
android: {
|
|
25
|
+
channelId: 'orders',
|
|
26
|
+
smallIcon: 'ic_notification',
|
|
27
|
+
pressAction: { id: 'open-order' },
|
|
28
|
+
},
|
|
29
|
+
ios: {
|
|
30
|
+
sound: 'default',
|
|
31
|
+
interruptionLevel: 'timeSensitive',
|
|
32
|
+
attachments: [{ url: 'https://cdn.example.com/map.png' }],
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
options: {
|
|
36
|
+
androidPriority: 'high',
|
|
37
|
+
iosBadgeCount: 3,
|
|
38
|
+
ttl: 3600,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
await admin.messaging().send(message);
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## API
|
|
46
|
+
|
|
47
|
+
### `buildNotifyKitPayload(input: NotifyKitPayloadInput): NotifyKitPayloadOutput`
|
|
48
|
+
|
|
49
|
+
Main entry point. Validates the input, serializes the `notifee_options` blob, and returns a complete FCM HTTP v1 `Message` object with an `android` half (data-only) and an `apns` half (alert + `mutable-content: 1`). Routing field (`token` / `topic` / `condition`) is passed through from the input; exactly one must be provided.
|
|
50
|
+
|
|
51
|
+
The returned object also carries a **non-enumerable** `sizeBytes` field — accessible for your own diagnostics, invisible to `JSON.stringify` so it never leaks to FCM.
|
|
52
|
+
|
|
53
|
+
### `buildAndroidPayload(input, context): NotifyKitAndroidOutput`
|
|
54
|
+
|
|
55
|
+
Builds the Android half only: `{ priority, collapse_key?, ttl? }`. Use when composing a custom `Message` (rare).
|
|
56
|
+
|
|
57
|
+
### `buildIosApnsPayload(input, context): NotifyKitApnsOutput`
|
|
58
|
+
|
|
59
|
+
Builds the iOS APNs half only: `{ headers, payload }` with the `aps` object, `notifee_options` blob, and optional `notifee_data`. Use when composing a custom `Message`.
|
|
60
|
+
|
|
61
|
+
### `serializeNotifeeOptions(input): string`
|
|
62
|
+
|
|
63
|
+
Returns the JSON-serialized `notifee_options` blob: `{ _v: 1, title, body, android?, ios? }`. Use when you want the blob string directly (e.g., to send via a non-FCM transport while preserving the wire contract).
|
|
64
|
+
|
|
65
|
+
### Types
|
|
66
|
+
|
|
67
|
+
All types are re-exported from the server SDK:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
import type {
|
|
71
|
+
// Input
|
|
72
|
+
NotifyKitPayloadInput,
|
|
73
|
+
NotifyKitNotification,
|
|
74
|
+
NotifyKitOptions,
|
|
75
|
+
NotifyKitAndroidConfig,
|
|
76
|
+
NotifyKitIosConfig,
|
|
77
|
+
NotifyKitPressAction,
|
|
78
|
+
NotifyKitAndroidAction,
|
|
79
|
+
NotifyKitAndroidStyle,
|
|
80
|
+
NotifyKitIosAttachment,
|
|
81
|
+
NotifyKitIosInterruptionLevel,
|
|
82
|
+
|
|
83
|
+
// Output
|
|
84
|
+
NotifyKitPayloadOutput,
|
|
85
|
+
NotifyKitAndroidOutput,
|
|
86
|
+
NotifyKitApnsOutput,
|
|
87
|
+
NotifyKitApnsAps,
|
|
88
|
+
NotifyKitApnsHeaders,
|
|
89
|
+
NotifyKitApnsPayload,
|
|
90
|
+
ApnsInterruptionLevel,
|
|
91
|
+
|
|
92
|
+
// Blob
|
|
93
|
+
SerializedNotifeeOptions,
|
|
94
|
+
} from 'react-native-notify-kit/server';
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Full type definitions are in [`docs/fcm-mode.md#server-sdk-reference`](../../../docs/fcm-mode.md#server-sdk-reference).
|
|
98
|
+
|
|
99
|
+
## Behavior
|
|
100
|
+
|
|
101
|
+
- **Android** messages are delivered **data-only** — the FCM SDK never auto-displays them. The client handler owns rendering.
|
|
102
|
+
- **iOS** messages use APNs alert delivery with `mutable-content: 1`, so the Notification Service Extension always activates and reads `notifee_options`.
|
|
103
|
+
- All payloads carry a `_v: 1` version field in `notifee_options` for forward compatibility.
|
|
104
|
+
- Collapse key precedence: `options.collapseKey` > `notification.id` > omitted (no collapse).
|
|
105
|
+
- If the serialized payload approaches FCM's 4 KB limit, a `console.warn` is emitted (non-fatal). The exact byte count is also available via `output.sizeBytes` — non-enumerable, so it doesn't serialize into the FCM wire payload.
|
|
106
|
+
|
|
107
|
+
## Validation
|
|
108
|
+
|
|
109
|
+
All validation happens synchronously in `buildNotifyKitPayload`. Errors thrown as `Error` objects with the `[react-native-notify-kit/server]` prefix. The complete list of error messages lives in [`docs/fcm-mode.md#validation-rules`](../../../docs/fcm-mode.md#validation-rules); highlights:
|
|
110
|
+
|
|
111
|
+
- Exactly one of `token`, `topic`, `condition` required.
|
|
112
|
+
- `notification.title` and `notification.body` are required non-empty strings.
|
|
113
|
+
- `notification.data` values must be strings (use `JSON.stringify` for complex values).
|
|
114
|
+
- `notifee_options` and `notifee_data` are reserved and rejected in user `data`.
|
|
115
|
+
- `options.ttl` must be a **positive** integer in seconds (zero is rejected — omit to use FCM default).
|
|
116
|
+
- iOS attachments require `https://` URLs.
|
|
117
|
+
- `options.iosBadgeCount` must be a non-negative integer.
|
|
118
|
+
|
|
119
|
+
## Limitations
|
|
120
|
+
|
|
121
|
+
- **No deep runtime validation of `notification.android` / `notification.ios` sub-objects.** Nested fields (`channelId`, `smallIcon`, `color`, `pressAction`, `actions`, `style`, `sound`, `categoryId`, etc.) are structurally validated by TypeScript at compile time but not checked at runtime. JavaScript consumers bypassing TypeScript should validate inputs themselves. Deep runtime validation is planned.
|
|
122
|
+
- **Style types are limited to `BIG_TEXT` and `BIG_PICTURE`.** `MESSAGING`, `INBOX`, and `CALL` styles are available via the client `displayNotification` but not yet wired through the server SDK — their richer schemas (person avatars, reply actions) need forward-compatible versioning before the wire contract is frozen.
|
|
123
|
+
- **FCM 4 KB hard limit.** The serialized message is capped at 4 KB by FCM. The SDK warns at ~3500 bytes — reduce `data` keys or body length, or switch to a nudge-then-fetch pattern for large payloads.
|
|
124
|
+
|
|
125
|
+
## See also
|
|
126
|
+
|
|
127
|
+
- [Full FCM Mode guide](../../../docs/fcm-mode.md) — architecture, NSE setup, migration, troubleshooting.
|
|
128
|
+
- [Main README](../README.md) — Notifee's full client API surface.
|
|
129
|
+
- [CHANGELOG](../../../CHANGELOG.md) — release history.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { NotifyKitAndroidOutput, NotifyKitPayloadInput } from './types';
|
|
2
|
+
type BuildAndroidContext = {
|
|
3
|
+
collapseKey?: string;
|
|
4
|
+
ttlSeconds?: number;
|
|
5
|
+
};
|
|
6
|
+
export declare function buildAndroidPayload(input: NotifyKitPayloadInput, context: BuildAndroidContext): NotifyKitAndroidOutput;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=android.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"android.d.ts","sourceRoot":"","sources":["../src/android.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAoB,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAE/F,KAAK,mBAAmB,GAAG;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAMF,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,qBAAqB,EAC5B,OAAO,EAAE,mBAAmB,GAC3B,sBAAsB,CAYxB"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildAndroidPayload = buildAndroidPayload;
|
|
4
|
+
function toAndroidPriority(priority) {
|
|
5
|
+
return priority === 'normal' ? 'NORMAL' : 'HIGH';
|
|
6
|
+
}
|
|
7
|
+
function buildAndroidPayload(input, context) {
|
|
8
|
+
const options = input.options ?? {};
|
|
9
|
+
const output = {
|
|
10
|
+
priority: toAndroidPriority(options.androidPriority),
|
|
11
|
+
};
|
|
12
|
+
if (context.collapseKey !== undefined) {
|
|
13
|
+
output.collapse_key = context.collapseKey;
|
|
14
|
+
}
|
|
15
|
+
if (context.ttlSeconds !== undefined) {
|
|
16
|
+
output.ttl = `${context.ttlSeconds}s`;
|
|
17
|
+
}
|
|
18
|
+
return output;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=android.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"android.js","sourceRoot":"","sources":["../src/android.ts"],"names":[],"mappings":";;AAWA,kDAeC;AAnBD,SAAS,iBAAiB,CAAC,QAA6C;IACtE,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;AACnD,CAAC;AAED,SAAgB,mBAAmB,CACjC,KAA4B,EAC5B,OAA4B;IAE5B,MAAM,OAAO,GAAqB,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;IACtD,MAAM,MAAM,GAA2B;QACrC,QAAQ,EAAE,iBAAiB,CAAC,OAAO,CAAC,eAAe,CAAC;KACrD,CAAC;IACF,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACtC,MAAM,CAAC,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAC5C,CAAC;IACD,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,GAAG,GAAG,OAAO,CAAC,UAAU,GAAG,CAAC;IACxC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildPayload.d.ts","sourceRoot":"","sources":["../src/buildPayload.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAM7E,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,qBAAqB,GAAG,sBAAsB,CAiF1F"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildNotifyKitPayload = buildNotifyKitPayload;
|
|
4
|
+
const android_1 = require("./android");
|
|
5
|
+
const ios_1 = require("./ios");
|
|
6
|
+
const serialize_1 = require("./serialize");
|
|
7
|
+
const validation_1 = require("./validation");
|
|
8
|
+
const SIZE_WARN_THRESHOLD_BYTES = 3500;
|
|
9
|
+
const PREFIX = '[react-native-notify-kit/server]';
|
|
10
|
+
function buildNotifyKitPayload(input) {
|
|
11
|
+
(0, validation_1.validateInput)(input);
|
|
12
|
+
const { notification } = input;
|
|
13
|
+
const options = input.options ?? {};
|
|
14
|
+
const collapseKey = options.collapseKey ?? notification.id ?? undefined;
|
|
15
|
+
let expiration;
|
|
16
|
+
if (options.ttl !== undefined) {
|
|
17
|
+
expiration = String(Math.floor(Date.now() / 1000) + options.ttl);
|
|
18
|
+
}
|
|
19
|
+
const notifeeOptions = (0, serialize_1.serializeNotifeeOptions)({
|
|
20
|
+
title: notification.title,
|
|
21
|
+
body: notification.body,
|
|
22
|
+
...(notification.android !== undefined ? { android: notification.android } : {}),
|
|
23
|
+
...(notification.ios !== undefined ? { ios: notification.ios } : {}),
|
|
24
|
+
});
|
|
25
|
+
const notifeeData = (0, serialize_1.serializeData)(notification.data);
|
|
26
|
+
// Android path: top-level `data` carries `notification.data` keys verbatim
|
|
27
|
+
// plus `notifee_options`. `notifee_data` is intentionally NOT duplicated here —
|
|
28
|
+
// the client can read the original keys directly from `data`. iOS NSE still
|
|
29
|
+
// receives `notifee_data` inside `apns.payload` because APNs does not expose
|
|
30
|
+
// arbitrary top-level keys to the extension.
|
|
31
|
+
const data = {
|
|
32
|
+
...(notification.data ?? {}),
|
|
33
|
+
notifee_options: notifeeOptions,
|
|
34
|
+
};
|
|
35
|
+
const android = (0, android_1.buildAndroidPayload)(input, {
|
|
36
|
+
...(collapseKey !== undefined ? { collapseKey } : {}),
|
|
37
|
+
...(options.ttl !== undefined ? { ttlSeconds: options.ttl } : {}),
|
|
38
|
+
});
|
|
39
|
+
const apns = (0, ios_1.buildIosApnsPayload)(input, {
|
|
40
|
+
notifeeOptions,
|
|
41
|
+
...(notifeeData !== undefined ? { notifeeData } : {}),
|
|
42
|
+
...(collapseKey !== undefined ? { collapseKey } : {}),
|
|
43
|
+
...(expiration !== undefined ? { expiration } : {}),
|
|
44
|
+
});
|
|
45
|
+
// Build the FCM-bound payload first (without sizeBytes — that's metadata for
|
|
46
|
+
// the caller, not part of the wire format).
|
|
47
|
+
const fcmPayload = {
|
|
48
|
+
data,
|
|
49
|
+
android,
|
|
50
|
+
apns,
|
|
51
|
+
};
|
|
52
|
+
if (input.token !== undefined) {
|
|
53
|
+
fcmPayload.token = input.token;
|
|
54
|
+
}
|
|
55
|
+
else if (input.topic !== undefined) {
|
|
56
|
+
fcmPayload.topic = input.topic;
|
|
57
|
+
}
|
|
58
|
+
else if (input.condition !== undefined) {
|
|
59
|
+
fcmPayload.condition = input.condition;
|
|
60
|
+
}
|
|
61
|
+
// FCM's 4 KB limit is measured in UTF-8 bytes, not JS code units, so emoji
|
|
62
|
+
// and non-ASCII characters consume more than one byte each. Deviation from
|
|
63
|
+
// the spec's literal `JSON.stringify(output).length` to avoid underestimating
|
|
64
|
+
// payload size under such characters. sizeBytes measures the FCM-relevant
|
|
65
|
+
// fields only (excludes the sizeBytes field itself).
|
|
66
|
+
const sizeBytes = Buffer.byteLength(JSON.stringify(fcmPayload), 'utf8');
|
|
67
|
+
if (sizeBytes > SIZE_WARN_THRESHOLD_BYTES) {
|
|
68
|
+
console.warn(`${PREFIX} Payload size ${sizeBytes} bytes approaches FCM 4KB limit. Consider reducing notifee_options.`);
|
|
69
|
+
}
|
|
70
|
+
// Attach sizeBytes as non-enumerable so JSON.stringify and object spread
|
|
71
|
+
// never include it — consumers can safely pass the output directly to
|
|
72
|
+
// admin.messaging().send() without stripping metadata fields.
|
|
73
|
+
const output = { ...fcmPayload };
|
|
74
|
+
Object.defineProperty(output, 'sizeBytes', {
|
|
75
|
+
value: sizeBytes,
|
|
76
|
+
enumerable: false,
|
|
77
|
+
writable: false,
|
|
78
|
+
configurable: false,
|
|
79
|
+
});
|
|
80
|
+
return output;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=buildPayload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildPayload.js","sourceRoot":"","sources":["../src/buildPayload.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { buildNotifyKitPayload } from './buildPayload';
|
|
2
|
+
export { buildIosApnsPayload } from './ios';
|
|
3
|
+
export { buildAndroidPayload } from './android';
|
|
4
|
+
export { serializeNotifeeOptions } from './serialize';
|
|
5
|
+
export type { NotifyKitPayloadInput, NotifyKitPayloadOutput, NotifyKitNotification, NotifyKitOptions, NotifyKitAndroidConfig, NotifyKitIosConfig, } from './types';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,YAAY,EACV,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.serializeNotifeeOptions = exports.buildAndroidPayload = exports.buildIosApnsPayload = exports.buildNotifyKitPayload = void 0;
|
|
4
|
+
var buildPayload_1 = require("./buildPayload");
|
|
5
|
+
Object.defineProperty(exports, "buildNotifyKitPayload", { enumerable: true, get: function () { return buildPayload_1.buildNotifyKitPayload; } });
|
|
6
|
+
var ios_1 = require("./ios");
|
|
7
|
+
Object.defineProperty(exports, "buildIosApnsPayload", { enumerable: true, get: function () { return ios_1.buildIosApnsPayload; } });
|
|
8
|
+
var android_1 = require("./android");
|
|
9
|
+
Object.defineProperty(exports, "buildAndroidPayload", { enumerable: true, get: function () { return android_1.buildAndroidPayload; } });
|
|
10
|
+
var serialize_1 = require("./serialize");
|
|
11
|
+
Object.defineProperty(exports, "serializeNotifeeOptions", { enumerable: true, get: function () { return serialize_1.serializeNotifeeOptions; } });
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,+CAAuD;AAA9C,qHAAA,qBAAqB,OAAA;AAC9B,6BAA4C;AAAnC,0GAAA,mBAAmB,OAAA;AAC5B,qCAAgD;AAAvC,8GAAA,mBAAmB,OAAA;AAC5B,yCAAsD;AAA7C,oHAAA,uBAAuB,OAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ApnsInterruptionLevel, NotifyKitApnsOutput, NotifyKitIosInterruptionLevel, NotifyKitPayloadInput } from './types';
|
|
2
|
+
export declare function toApnsInterruptionLevel(level: NotifyKitIosInterruptionLevel): ApnsInterruptionLevel;
|
|
3
|
+
type BuildIosContext = {
|
|
4
|
+
notifeeOptions: string;
|
|
5
|
+
notifeeData?: string;
|
|
6
|
+
collapseKey?: string;
|
|
7
|
+
expiration?: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function buildIosApnsPayload(input: NotifyKitPayloadInput, context: BuildIosContext): NotifyKitApnsOutput;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=ios.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ios.d.ts","sourceRoot":"","sources":["../src/ios.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qBAAqB,EAGrB,mBAAmB,EACnB,6BAA6B,EAG7B,qBAAqB,EACtB,MAAM,SAAS,CAAC;AAWjB,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,6BAA6B,GACnC,qBAAqB,CAQvB;AAED,KAAK,eAAe,GAAG;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,qBAAqB,EAC5B,OAAO,EAAE,eAAe,GACvB,mBAAmB,CA6CrB"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toApnsInterruptionLevel = toApnsInterruptionLevel;
|
|
4
|
+
exports.buildIosApnsPayload = buildIosApnsPayload;
|
|
5
|
+
const INTERRUPTION_LEVEL_MAP = {
|
|
6
|
+
passive: 'passive',
|
|
7
|
+
active: 'active',
|
|
8
|
+
timeSensitive: 'time-sensitive',
|
|
9
|
+
critical: 'critical',
|
|
10
|
+
};
|
|
11
|
+
const PREFIX = '[react-native-notify-kit/server]';
|
|
12
|
+
function toApnsInterruptionLevel(level) {
|
|
13
|
+
const mapped = INTERRUPTION_LEVEL_MAP[level];
|
|
14
|
+
if (mapped === undefined) {
|
|
15
|
+
throw new Error(`${PREFIX} Validation: invalid interruptionLevel '${String(level)}'. Expected one of: passive, active, timeSensitive, critical`);
|
|
16
|
+
}
|
|
17
|
+
return mapped;
|
|
18
|
+
}
|
|
19
|
+
function buildIosApnsPayload(input, context) {
|
|
20
|
+
const notification = input.notification;
|
|
21
|
+
const options = input.options ?? {};
|
|
22
|
+
const ios = notification.ios;
|
|
23
|
+
const headers = {
|
|
24
|
+
'apns-push-type': 'alert',
|
|
25
|
+
'apns-priority': '10',
|
|
26
|
+
};
|
|
27
|
+
if (context.collapseKey !== undefined) {
|
|
28
|
+
headers['apns-collapse-id'] = context.collapseKey;
|
|
29
|
+
}
|
|
30
|
+
if (context.expiration !== undefined) {
|
|
31
|
+
headers['apns-expiration'] = context.expiration;
|
|
32
|
+
}
|
|
33
|
+
const aps = {
|
|
34
|
+
alert: { title: notification.title, body: notification.body },
|
|
35
|
+
'mutable-content': 1,
|
|
36
|
+
};
|
|
37
|
+
if (ios?.sound !== undefined) {
|
|
38
|
+
aps.sound = ios.sound;
|
|
39
|
+
}
|
|
40
|
+
if (ios?.categoryId !== undefined) {
|
|
41
|
+
aps.category = ios.categoryId;
|
|
42
|
+
}
|
|
43
|
+
if (ios?.threadId !== undefined) {
|
|
44
|
+
aps['thread-id'] = ios.threadId;
|
|
45
|
+
}
|
|
46
|
+
if (ios?.interruptionLevel !== undefined) {
|
|
47
|
+
aps['interruption-level'] = toApnsInterruptionLevel(ios.interruptionLevel);
|
|
48
|
+
}
|
|
49
|
+
if (options.iosBadgeCount !== undefined) {
|
|
50
|
+
aps.badge = options.iosBadgeCount;
|
|
51
|
+
}
|
|
52
|
+
const payload = {
|
|
53
|
+
aps,
|
|
54
|
+
notifee_options: context.notifeeOptions,
|
|
55
|
+
};
|
|
56
|
+
if (context.notifeeData !== undefined) {
|
|
57
|
+
payload.notifee_data = context.notifeeData;
|
|
58
|
+
}
|
|
59
|
+
return { headers, payload };
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=ios.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ios.js","sourceRoot":"","sources":["../src/ios.ts"],"names":[],"mappings":";;AAoBA,0DAUC;AASD,kDAgDC;AA5ED,MAAM,sBAAsB,GAAiE;IAC3F,OAAO,EAAE,SAAS;IAClB,MAAM,EAAE,QAAQ;IAChB,aAAa,EAAE,gBAAgB;IAC/B,QAAQ,EAAE,UAAU;CACrB,CAAC;AAEF,MAAM,MAAM,GAAG,kCAAkC,CAAC;AAElD,SAAgB,uBAAuB,CACrC,KAAoC;IAEpC,MAAM,MAAM,GAAG,sBAAsB,CAAC,KAAsC,CAAC,CAAC;IAC9E,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CACb,GAAG,MAAM,2CAA2C,MAAM,CAAC,KAAK,CAAC,8DAA8D,CAChI,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AASD,SAAgB,mBAAmB,CACjC,KAA4B,EAC5B,OAAwB;IAExB,MAAM,YAAY,GAA0B,KAAK,CAAC,YAAY,CAAC;IAC/D,MAAM,OAAO,GAAqB,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;IACtD,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC;IAE7B,MAAM,OAAO,GAAyB;QACpC,gBAAgB,EAAE,OAAO;QACzB,eAAe,EAAE,IAAI;KACtB,CAAC;IACF,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACtC,OAAO,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;IACpD,CAAC;IACD,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACrC,OAAO,CAAC,iBAAiB,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;IAClD,CAAC;IAED,MAAM,GAAG,GAAqB;QAC5B,KAAK,EAAE,EAAE,KAAK,EAAE,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE;QAC7D,iBAAiB,EAAE,CAAC;KACrB,CAAC;IACF,IAAI,GAAG,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;QAC7B,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;IACxB,CAAC;IACD,IAAI,GAAG,EAAE,UAAU,KAAK,SAAS,EAAE,CAAC;QAClC,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC;IAChC,CAAC;IACD,IAAI,GAAG,EAAE,QAAQ,KAAK,SAAS,EAAE,CAAC;QAChC,GAAG,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC;IAClC,CAAC;IACD,IAAI,GAAG,EAAE,iBAAiB,KAAK,SAAS,EAAE,CAAC;QACzC,GAAG,CAAC,oBAAoB,CAAC,GAAG,uBAAuB,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,OAAO,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;QACxC,GAAG,CAAC,KAAK,GAAG,OAAO,CAAC,aAAa,CAAC;IACpC,CAAC;IAED,MAAM,OAAO,GAAmC;QAC9C,GAAG;QACH,eAAe,EAAE,OAAO,CAAC,cAAc;KACxC,CAAC;IACF,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACtC,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAC7C,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { NotifyKitAndroidConfig, NotifyKitIosConfig } from './types';
|
|
2
|
+
type SerializeInput = {
|
|
3
|
+
title: string;
|
|
4
|
+
body: string;
|
|
5
|
+
android?: NotifyKitAndroidConfig;
|
|
6
|
+
ios?: NotifyKitIosConfig;
|
|
7
|
+
};
|
|
8
|
+
export declare function serializeNotifeeOptions(input: SerializeInput): string;
|
|
9
|
+
export declare function serializeData(data?: Record<string, string>): string | undefined;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=serialize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../src/serialize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAA4B,MAAM,SAAS,CAAC;AAEpG,KAAK,cAAc,GAAG;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC,GAAG,CAAC,EAAE,kBAAkB,CAAC;CAC1B,CAAC;AAIF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAgBrE;AAED,wBAAgB,aAAa,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,GAAG,SAAS,CAS/E"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.serializeNotifeeOptions = serializeNotifeeOptions;
|
|
4
|
+
exports.serializeData = serializeData;
|
|
5
|
+
const PREFIX = '[react-native-notify-kit/server]';
|
|
6
|
+
function serializeNotifeeOptions(input) {
|
|
7
|
+
const payload = { _v: 1, title: input.title, body: input.body };
|
|
8
|
+
if (input.android !== undefined) {
|
|
9
|
+
payload.android = input.android;
|
|
10
|
+
}
|
|
11
|
+
if (input.ios !== undefined) {
|
|
12
|
+
payload.ios = input.ios;
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
return JSON.stringify(payload);
|
|
16
|
+
}
|
|
17
|
+
catch (e) {
|
|
18
|
+
const detail = e instanceof Error ? `: ${e.message}` : `: ${String(e)}`;
|
|
19
|
+
throw new Error(`${PREFIX} Serialization: notifee_options contains circular references or non-serializable values. Check for circular object references in android/ios config${detail}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function serializeData(data) {
|
|
23
|
+
if (!data) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
const keys = Object.keys(data);
|
|
27
|
+
if (keys.length === 0) {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
return JSON.stringify(data);
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=serialize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialize.js","sourceRoot":"","sources":["../src/serialize.ts"],"names":[],"mappings":";;AAWA,0DAgBC;AAED,sCASC;AA7BD,MAAM,MAAM,GAAG,kCAAkC,CAAC;AAElD,SAAgB,uBAAuB,CAAC,KAAqB;IAC3D,MAAM,OAAO,GAA6B,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;IAC1F,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAChC,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAClC,CAAC;IACD,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;IAC1B,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QACxE,MAAM,IAAI,KAAK,CACb,GAAG,MAAM,sJAAsJ,MAAM,EAAE,CACxK,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAgB,aAAa,CAAC,IAA6B;IACzD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export type { NotifyKitPressAction, NotifyKitAndroidAction, NotifyKitAndroidStyle, NotifyKitAndroidConfig, NotifyKitIosAttachment, NotifyKitIosInterruptionLevel, NotifyKitIosConfig, NotifyKitNotification, NotifyKitOptions, NotifyKitPayloadInput, ApnsInterruptionLevel, NotifyKitAndroidOutput, NotifyKitApnsAps, NotifyKitApnsHeaders, NotifyKitApnsPayload, NotifyKitApnsOutput, NotifyKitPayloadOutput, SerializedNotifeeOptions, } from '../../src/internal/fcmContract';
|
|
2
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAIA,YAAY,EACV,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACtB,6BAA6B,EAC7B,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,gCAAgC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|