react-native-notify-kit 10.4.9 → 10.5.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 +3 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
- package/server/README.md +6 -4
- 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/src/android.ts +4 -4
- package/src/internal/fcmContract.d.ts +10 -8
- package/src/version.ts +1 -1
package/README.md
CHANGED
|
@@ -377,7 +377,7 @@ For bare React Native projects with non-standard iOS paths or heavily-customized
|
|
|
377
377
|
|
|
378
378
|
## Server SDK
|
|
379
379
|
|
|
380
|
-
`react-native-notify-kit` ships a **zero-dependency server SDK** under the `/server` subpath
|
|
380
|
+
`react-native-notify-kit` ships a **zero-dependency server SDK** under the `/server` subpath for building Firebase Admin-compatible FCM messages that the client `handleFcmMessage` handler consumes. Firebase Admin serializes each message to the FCM HTTP v1 request format. The SDK runs in Node.js 22+ and Firebase Cloud Functions.
|
|
381
381
|
|
|
382
382
|
```ts
|
|
383
383
|
import { buildNotifyKitPayload } from 'react-native-notify-kit/server';
|
|
@@ -399,6 +399,8 @@ const message = buildNotifyKitPayload({
|
|
|
399
399
|
await admin.messaging().send(message);
|
|
400
400
|
```
|
|
401
401
|
|
|
402
|
+
`options.ttl` is expressed in seconds. Pass the message directly to Firebase Admin without an adapter or a manual unit conversion.
|
|
403
|
+
|
|
402
404
|
Full reference: [docs/fcm-mode.mdx#server-sdk-reference](docs/fcm-mode.mdx#server-sdk-reference) (types, validation rules, payload shape, FCM 4 KB limit).
|
|
403
405
|
|
|
404
406
|
## CLI Tools
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "10.
|
|
1
|
+
export declare const version = "10.5.0";
|
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-notify-kit",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.5.0",
|
|
4
4
|
"author": "Marco Crupi",
|
|
5
5
|
"description": "Maintained Notifee-compatible React Native notifications library for Android, iOS, FCM Mode, rich notifications, foreground services, and Expo CNG development builds.",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"build:watch": "tsc --watch",
|
|
33
33
|
"test:server": "jest --config jest.config.server.js",
|
|
34
34
|
"prepare": "yarn run build",
|
|
35
|
-
"prepack": "cd ../.. && bash build_ios_core.sh && bash scripts/verify-ios-core-generation.sh && bash scripts/prepack-cli.sh",
|
|
35
|
+
"prepack": "yarn run build:server && cd ../.. && bash build_ios_core.sh && bash scripts/verify-ios-core-generation.sh && bash scripts/prepack-cli.sh",
|
|
36
36
|
"postpack": "rm -rf cli",
|
|
37
37
|
"prepublishOnly": "cd ../.. && yarn run build:core",
|
|
38
38
|
"format:android": "google-java-format --replace -i $(find . -type f -name \"*.java\" ! -path \"*/node_modules/*\" ! -path \"*/generated/*\")",
|
package/server/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# react-native-notify-kit/server
|
|
2
2
|
|
|
3
|
-
Server-side
|
|
3
|
+
Server-side Firebase Admin-compatible FCM message builder for [`react-native-notify-kit`](../README.md). Runs in Node.js 22+ (backends, Firebase Cloud Functions). **Zero runtime dependencies.**
|
|
4
4
|
|
|
5
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
6
|
|
|
@@ -42,21 +42,23 @@ const message = buildNotifyKitPayload({
|
|
|
42
42
|
await admin.messaging().send(message);
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
+
`options.ttl` is expressed in seconds. Pass the message directly to Firebase Admin without an adapter or a manual unit conversion.
|
|
46
|
+
|
|
45
47
|
## API
|
|
46
48
|
|
|
47
49
|
### `buildNotifyKitPayload(input: NotifyKitPayloadInput): NotifyKitPayloadOutput`
|
|
48
50
|
|
|
49
|
-
Main entry point. Validates the input, serializes the `notifee_options` blob, and returns a
|
|
51
|
+
Main entry point. Validates the input, serializes the `notifee_options` blob, and returns a Firebase Admin-compatible message with an `android` half (data-only) and an `apns` half (alert + `mutable-content: 1`). Firebase Admin serializes the message to the FCM HTTP v1 request format. Routing field (`token` / `topic` / `condition`) is passed through from the input; exactly one must be provided.
|
|
50
52
|
|
|
51
53
|
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
54
|
|
|
53
55
|
### `buildAndroidPayload(input, context): NotifyKitAndroidOutput`
|
|
54
56
|
|
|
55
|
-
Builds the Android half only: `{ priority,
|
|
57
|
+
Builds the Android half only: `{ priority: 'high' | 'normal', collapseKey?: string, ttl?: number }`. The public `options.ttl` input is expressed in seconds; the Firebase Admin-compatible `android.ttl` output is expressed in milliseconds. Use when composing a custom message (rare).
|
|
56
58
|
|
|
57
59
|
### `buildIosApnsPayload(input, context): NotifyKitApnsOutput`
|
|
58
60
|
|
|
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
|
|
61
|
+
Builds the iOS APNs half only: `{ headers, payload }` with the `aps` object, `notifee_options` blob, and optional `notifee_data`. When TTL is set, `apns-expiration` is an absolute UNIX epoch timestamp in seconds. Use when composing a custom message.
|
|
60
62
|
|
|
61
63
|
### `serializeNotifeeOptions(input): string`
|
|
62
64
|
|
|
@@ -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.collapseKey = context.collapseKey;
|
|
14
|
+
}
|
|
15
|
+
if (context.ttlSeconds !== undefined) {
|
|
16
|
+
output.ttl = context.ttlSeconds * 1000;
|
|
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,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAC3C,CAAC;IACD,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IACzC,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":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAarD,wBAAgB,aAAa,CAAC,KAAK,EAAE,qBAAqB,GAAG,IAAI,CAwHhE"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateInput = validateInput;
|
|
4
|
+
const PREFIX = '[react-native-notify-kit/server]';
|
|
5
|
+
const RESERVED_DATA_KEYS = ['notifee_options', 'notifee_data'];
|
|
6
|
+
function err(category, message) {
|
|
7
|
+
return new Error(`${PREFIX} ${category}: ${message}`);
|
|
8
|
+
}
|
|
9
|
+
function isNonEmptyString(value) {
|
|
10
|
+
return typeof value === 'string' && value.length > 0;
|
|
11
|
+
}
|
|
12
|
+
function validateInput(input) {
|
|
13
|
+
if (input === null || typeof input !== 'object') {
|
|
14
|
+
throw err('Validation', 'input must be an object');
|
|
15
|
+
}
|
|
16
|
+
const routingCount = (input.token !== undefined ? 1 : 0) +
|
|
17
|
+
(input.topic !== undefined ? 1 : 0) +
|
|
18
|
+
(input.condition !== undefined ? 1 : 0);
|
|
19
|
+
if (routingCount !== 1) {
|
|
20
|
+
throw err('Routing', `exactly one of 'token', 'topic', or 'condition' must be provided. Got: ${routingCount}`);
|
|
21
|
+
}
|
|
22
|
+
if (input.token !== undefined && !isNonEmptyString(input.token)) {
|
|
23
|
+
throw err('Routing', "'token' must be a non-empty string");
|
|
24
|
+
}
|
|
25
|
+
if (input.topic !== undefined && !isNonEmptyString(input.topic)) {
|
|
26
|
+
throw err('Routing', "'topic' must be a non-empty string");
|
|
27
|
+
}
|
|
28
|
+
if (input.condition !== undefined && !isNonEmptyString(input.condition)) {
|
|
29
|
+
throw err('Routing', "'condition' must be a non-empty string");
|
|
30
|
+
}
|
|
31
|
+
const { notification } = input;
|
|
32
|
+
if (notification === null || typeof notification !== 'object') {
|
|
33
|
+
throw err('Validation', "'notification' is required and must be an object");
|
|
34
|
+
}
|
|
35
|
+
if (notification.id !== undefined && !isNonEmptyString(notification.id)) {
|
|
36
|
+
throw err('Validation', 'notification.id must be a non-empty string when provided');
|
|
37
|
+
}
|
|
38
|
+
if (!isNonEmptyString(notification.title)) {
|
|
39
|
+
throw err('Validation', 'notification.title is required and must be a non-empty string');
|
|
40
|
+
}
|
|
41
|
+
if (!isNonEmptyString(notification.body)) {
|
|
42
|
+
throw err('Validation', 'notification.body is required and must be a non-empty string');
|
|
43
|
+
}
|
|
44
|
+
if (notification.data !== undefined) {
|
|
45
|
+
if (notification.data === null || typeof notification.data !== 'object') {
|
|
46
|
+
throw err('Validation', "'notification.data' must be an object");
|
|
47
|
+
}
|
|
48
|
+
for (const reserved of RESERVED_DATA_KEYS) {
|
|
49
|
+
if (Object.prototype.hasOwnProperty.call(notification.data, reserved)) {
|
|
50
|
+
throw err('Validation', "'notifee_options' and 'notifee_data' are reserved keys and cannot be used in notification.data");
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
for (const [key, value] of Object.entries(notification.data)) {
|
|
54
|
+
if (typeof value !== 'string') {
|
|
55
|
+
throw err('Validation', `FCM data values must be strings. Got ${typeof value} for key '${key}'. Use JSON.stringify() if you need to pass complex values.`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const attachments = notification.ios?.attachments;
|
|
60
|
+
if (attachments !== undefined) {
|
|
61
|
+
if (!Array.isArray(attachments)) {
|
|
62
|
+
throw err('iOS', "'notification.ios.attachments' must be an array");
|
|
63
|
+
}
|
|
64
|
+
for (const attachment of attachments) {
|
|
65
|
+
if (attachment === null ||
|
|
66
|
+
typeof attachment !== 'object' ||
|
|
67
|
+
typeof attachment.url !== 'string') {
|
|
68
|
+
throw err('iOS', "each attachment must be an object with a string 'url' field");
|
|
69
|
+
}
|
|
70
|
+
if (!attachment.url.startsWith('https://')) {
|
|
71
|
+
throw err('iOS', `iOS attachments require https:// URLs. Got: ${attachment.url}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (input.options !== undefined) {
|
|
76
|
+
const { options } = input;
|
|
77
|
+
if (options === null || typeof options !== 'object') {
|
|
78
|
+
throw err('Validation', "'options' must be an object");
|
|
79
|
+
}
|
|
80
|
+
if (options.androidPriority !== undefined &&
|
|
81
|
+
options.androidPriority !== 'high' &&
|
|
82
|
+
options.androidPriority !== 'normal') {
|
|
83
|
+
throw err('Validation', `'options.androidPriority' must be 'high' or 'normal'. Got: ${String(options.androidPriority)}`);
|
|
84
|
+
}
|
|
85
|
+
if (options.iosBadgeCount !== undefined &&
|
|
86
|
+
(typeof options.iosBadgeCount !== 'number' ||
|
|
87
|
+
!Number.isFinite(options.iosBadgeCount) ||
|
|
88
|
+
options.iosBadgeCount < 0 ||
|
|
89
|
+
!Number.isInteger(options.iosBadgeCount))) {
|
|
90
|
+
throw err('Validation', "'options.iosBadgeCount' must be a non-negative integer");
|
|
91
|
+
}
|
|
92
|
+
if (options.ttl !== undefined &&
|
|
93
|
+
(typeof options.ttl !== 'number' || !Number.isInteger(options.ttl) || options.ttl <= 0)) {
|
|
94
|
+
throw err('Validation', `options.ttl must be a positive integer (seconds). Got: ${String(options.ttl)}`);
|
|
95
|
+
}
|
|
96
|
+
if (options.collapseKey !== undefined && !isNonEmptyString(options.collapseKey)) {
|
|
97
|
+
throw err('Validation', "'options.collapseKey' must be a non-empty string");
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"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"}
|
package/server/src/android.ts
CHANGED
|
@@ -5,8 +5,8 @@ type BuildAndroidContext = {
|
|
|
5
5
|
ttlSeconds?: number;
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
-
function toAndroidPriority(priority: NotifyKitOptions['androidPriority']): '
|
|
9
|
-
return priority === 'normal' ? '
|
|
8
|
+
function toAndroidPriority(priority: NotifyKitOptions['androidPriority']): 'high' | 'normal' {
|
|
9
|
+
return priority === 'normal' ? 'normal' : 'high';
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export function buildAndroidPayload(
|
|
@@ -18,10 +18,10 @@ export function buildAndroidPayload(
|
|
|
18
18
|
priority: toAndroidPriority(options.androidPriority),
|
|
19
19
|
};
|
|
20
20
|
if (context.collapseKey !== undefined) {
|
|
21
|
-
output.
|
|
21
|
+
output.collapseKey = context.collapseKey;
|
|
22
22
|
}
|
|
23
23
|
if (context.ttlSeconds !== undefined) {
|
|
24
|
-
output.ttl =
|
|
24
|
+
output.ttl = context.ttlSeconds * 1000;
|
|
25
25
|
}
|
|
26
26
|
return output;
|
|
27
27
|
}
|
|
@@ -55,7 +55,7 @@ export type NotifyKitIosConfig = {
|
|
|
55
55
|
export type NotifyKitNotification = {
|
|
56
56
|
/**
|
|
57
57
|
* Optional notification identifier. When provided, it is also used as the
|
|
58
|
-
* FCM collapse key (Android `
|
|
58
|
+
* FCM collapse key (Android `collapseKey`, iOS `apns-collapse-id`) unless
|
|
59
59
|
* `options.collapseKey` is explicitly set. Collapse key precedence (Rule 7):
|
|
60
60
|
* 1. `options.collapseKey` if set
|
|
61
61
|
* 2. `notification.id` if set
|
|
@@ -92,9 +92,9 @@ export type NotifyKitPayloadInput = {
|
|
|
92
92
|
export type ApnsInterruptionLevel = 'passive' | 'active' | 'time-sensitive' | 'critical';
|
|
93
93
|
|
|
94
94
|
export type NotifyKitAndroidOutput = {
|
|
95
|
-
priority: '
|
|
96
|
-
|
|
97
|
-
ttl?:
|
|
95
|
+
priority: 'high' | 'normal';
|
|
96
|
+
collapseKey?: string;
|
|
97
|
+
ttl?: number;
|
|
98
98
|
};
|
|
99
99
|
|
|
100
100
|
export type NotifyKitApnsAps = {
|
|
@@ -125,10 +125,12 @@ export type NotifyKitApnsOutput = {
|
|
|
125
125
|
payload: NotifyKitApnsPayload;
|
|
126
126
|
};
|
|
127
127
|
|
|
128
|
-
|
|
129
|
-
token
|
|
130
|
-
topic
|
|
131
|
-
condition
|
|
128
|
+
type NotifyKitPayloadTarget =
|
|
129
|
+
| { token: string; topic?: never; condition?: never }
|
|
130
|
+
| { topic: string; token?: never; condition?: never }
|
|
131
|
+
| { condition: string; token?: never; topic?: never };
|
|
132
|
+
|
|
133
|
+
export type NotifyKitPayloadOutput = NotifyKitPayloadTarget & {
|
|
132
134
|
data: Record<string, string>;
|
|
133
135
|
android: NotifyKitAndroidOutput;
|
|
134
136
|
apns: NotifyKitApnsOutput;
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by genversion.
|
|
2
|
-
export const version = '10.
|
|
2
|
+
export const version = '10.5.0';
|