react-native-notify-kit 10.8.1 → 10.9.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.
Files changed (79) hide show
  1. package/README.md +33 -18
  2. package/android/build.gradle +50 -4
  3. package/android/src/main/AndroidManifest.xml +4 -0
  4. package/android/src/main/java/app/notifee/core/ForegroundService.java +395 -5
  5. package/android/src/main/java/app/notifee/core/ForegroundServiceRunLimitReceiver.java +15 -0
  6. package/android/src/main/java/app/notifee/core/ForegroundServiceRunLimitScheduler.java +461 -0
  7. package/android/src/main/java/app/notifee/core/NotificationManager.java +6 -0
  8. package/android/src/main/java/app/notifee/core/event/NotificationEvent.java +6 -0
  9. package/android/src/main/java/app/notifee/core/model/NotificationAndroidModel.java +29 -0
  10. package/android/src/main/kotlin/io/invertase/notifee/NotifeeEventSubscriber.kt +3 -0
  11. package/android/src/test/java/app/notifee/core/ForegroundServiceRunLimitTest.java +2357 -0
  12. package/android/src/test/java/app/notifee/core/ForegroundServiceTest.java +23 -13
  13. package/android/src/test/java/app/notifee/core/ShadowServiceCompatibilityTest.java +170 -0
  14. package/android/src/test/resources/robolectric.properties +4 -0
  15. package/cli/dist/cli.js +0 -1
  16. package/cli/dist/commands/initNse.js +1 -2
  17. package/cli/dist/lib/detectProject.js +1 -2
  18. package/cli/dist/lib/initNseCore.js +0 -1
  19. package/cli/dist/lib/logger.js +0 -1
  20. package/cli/dist/lib/patchPodfile.js +0 -1
  21. package/cli/dist/lib/patchXcodeProject.js +22 -3
  22. package/cli/dist/lib/writeTemplates.js +0 -1
  23. package/cli/dist/lib/xcode.js +6 -0
  24. package/cli/dist/templates/NotificationService.swift.tmpl +74 -6
  25. package/cli/package.json +1 -0
  26. package/cli/vendor/xcode/AUTHORS +6 -0
  27. package/cli/vendor/xcode/LICENSE +202 -0
  28. package/cli/vendor/xcode/NOTICE +5 -0
  29. package/cli/vendor/xcode/README.md +32 -0
  30. package/cli/vendor/xcode/UPSTREAM-SHA256.json +12 -0
  31. package/cli/vendor/xcode/index.js +18 -0
  32. package/cli/vendor/xcode/lib/parseJob.js +32 -0
  33. package/cli/vendor/xcode/lib/parser/pbxproj.js +1904 -0
  34. package/cli/vendor/xcode/lib/parser/pbxproj.pegjs +280 -0
  35. package/cli/vendor/xcode/lib/pbxFile.js +233 -0
  36. package/cli/vendor/xcode/lib/pbxProject.js +2205 -0
  37. package/cli/vendor/xcode/lib/pbxWriter.js +309 -0
  38. package/dist/NotifeeNativeModule.web.d.ts +2 -2
  39. package/dist/types/Notification.d.ts +12 -1
  40. package/dist/types/Notification.js +3 -0
  41. package/dist/types/Notification.js.map +1 -1
  42. package/dist/types/NotificationAndroid.d.ts +9 -0
  43. package/dist/types/NotificationAndroid.js.map +1 -1
  44. package/dist/validators/validateAndroidNotification.js +26 -1
  45. package/dist/validators/validateAndroidNotification.js.map +1 -1
  46. package/dist/validators/validateAndroidStyle.js +6 -0
  47. package/dist/validators/validateAndroidStyle.js.map +1 -1
  48. package/dist/validators/validateIOSAttachment.js +3 -1
  49. package/dist/validators/validateIOSAttachment.js.map +1 -1
  50. package/dist/version.d.ts +1 -1
  51. package/dist/version.js +1 -1
  52. package/package.json +8 -5
  53. package/src/NotifeeNativeModule.web.ts +2 -2
  54. package/src/types/Notification.ts +13 -0
  55. package/src/types/NotificationAndroid.ts +10 -0
  56. package/src/validators/validateAndroidNotification.ts +31 -1
  57. package/src/validators/validateAndroidStyle.ts +10 -2
  58. package/src/validators/validateIOSAttachment.ts +5 -1
  59. package/src/version.ts +1 -1
  60. package/cli/dist/cli.bundle.js +0 -20834
  61. package/cli/dist/cli.d.ts +0 -2
  62. package/cli/dist/cli.js.map +0 -1
  63. package/cli/dist/commands/initNse.d.ts +0 -12
  64. package/cli/dist/commands/initNse.js.map +0 -1
  65. package/cli/dist/lib/detectProject.d.ts +0 -12
  66. package/cli/dist/lib/detectProject.js.map +0 -1
  67. package/cli/dist/lib/initNseCore.d.ts +0 -8
  68. package/cli/dist/lib/initNseCore.js.map +0 -1
  69. package/cli/dist/lib/logger.d.ts +0 -4
  70. package/cli/dist/lib/logger.js.map +0 -1
  71. package/cli/dist/lib/patchPodfile.d.ts +0 -23
  72. package/cli/dist/lib/patchPodfile.js.map +0 -1
  73. package/cli/dist/lib/patchXcodeProject.d.ts +0 -41
  74. package/cli/dist/lib/patchXcodeProject.js.map +0 -1
  75. package/cli/dist/lib/writeTemplates.d.ts +0 -11
  76. package/cli/dist/lib/writeTemplates.js.map +0 -1
  77. package/cli/dist/templates/templates/Info.plist.tmpl +0 -29
  78. package/cli/dist/templates/templates/NotificationService.swift.tmpl +0 -100
  79. package/cli/dist/templates/templates/NotifyKitNSE.entitlements.tmpl +0 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-notify-kit",
3
- "version": "10.8.1",
3
+ "version": "10.9.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",
@@ -33,7 +33,7 @@
33
33
  "test:server": "jest --config jest.config.server.js",
34
34
  "prepare": "yarn run build",
35
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
- "postpack": "rm -rf cli",
36
+ "postpack": "node ../../scripts/cli-artifacts.cjs postpack",
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/*\")",
39
39
  "format:android:check": "google-java-format --set-exit-if-changed --replace -i $(find . -type f -name \"*.java\" ! -path \"*/node_modules/*\" ! -path \"*/generated/*\")",
@@ -56,13 +56,14 @@
56
56
  "react-native": "0.85.3",
57
57
  "rimraf": "^3.0.2",
58
58
  "ts-jest": "^29.2.5",
59
- "typescript": "^5.9.3"
59
+ "typescript": "^5.9.3",
60
+ "xcode": "^3.0.1"
60
61
  },
61
62
  "optionalDependencies": {
62
63
  "chalk": "^4.1.0",
63
64
  "commander": "^12.0.0",
64
65
  "plist": "^3.1.0",
65
- "xcode": "^3.0.1"
66
+ "simple-plist": "^1.3.1"
66
67
  },
67
68
  "peerDependencies": {
68
69
  "expo": "*",
@@ -131,6 +132,8 @@
131
132
  "/server/tsconfig.json",
132
133
  "/server/package.json",
133
134
  "/cli/dist",
134
- "/cli/bin"
135
+ "/cli/bin",
136
+ "/cli/vendor",
137
+ "/cli/package.json"
135
138
  ]
136
139
  }
@@ -1,4 +1,4 @@
1
- import { NativeModulesStatic } from 'react-native';
1
+ import type { NativeModules } from 'react-native';
2
2
  import NotifeeJSEventEmitter from './NotifeeJSEventEmitter';
3
3
 
4
4
  export interface NativeModuleConfig {
@@ -19,7 +19,7 @@ export default class NotifeeNativeModule {
19
19
  return NotifeeJSEventEmitter;
20
20
  }
21
21
 
22
- public get native(): NativeModulesStatic {
22
+ public get native(): typeof NativeModules {
23
23
  return {};
24
24
  }
25
25
  }
@@ -428,6 +428,10 @@ export enum EventType {
428
428
  * @platform android
429
429
  */
430
430
  FG_TIMEOUT = 9,
431
+
432
+ /** Best-effort Android voluntary run-limit handling, after native teardown attempts.
433
+ * Does not certify AMS teardown, task completion or JavaScript cancellation. */
434
+ FG_RUN_LIMIT_REACHED = 10,
431
435
  }
432
436
 
433
437
  /**
@@ -436,6 +440,15 @@ export enum EventType {
436
440
  * View the [Events](/react-native/events) documentation to learn more.
437
441
  */
438
442
  export interface EventDetail {
443
+ /** Native handling of an accepted voluntary expiry; no delivery guarantee. */
444
+ foregroundServiceRunLimit?: {
445
+ requestedDurationMs: number;
446
+ deadlineElapsed: number;
447
+ deliveredElapsed: number;
448
+ demotion: 'returned' | 'failed';
449
+ conditionalStop: 'accepted' | 'refused' | 'deferred' | 'failed';
450
+ };
451
+
439
452
  /**
440
453
  * The notification this event relates to.
441
454
  *
@@ -39,6 +39,16 @@ export interface NotificationAndroid {
39
39
  */
40
40
  asForegroundService?: boolean;
41
41
 
42
+ /**
43
+ * Best-effort attempt to demote (REMOVE) and stop a single dataSync foreground run.
44
+ * Android API 35+ only. Disabled when undefined. Integer milliseconds, 60,000–18,000,000.
45
+ * Measured from the first successful promotion using elapsed realtime, including sleep.
46
+ * Same-ID updates do not extend the deadline; changing/enabling it requires a new run.
47
+ * Inexact alarms may arrive minutes late or never. A resolved displayNotification Promise
48
+ * does not confirm scheduling. This does not cancel JavaScript or application work.
49
+ */
50
+ foregroundServiceBestEffortStopAfterMs?: number;
51
+
42
52
  /**
43
53
  * When set to `true` the screen will light up when the notification is displayed.
44
54
  *
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * Copyright (c) 2016-present Invertase Limited
3
3
  */
4
- import { Image } from 'react-native';
4
+ import { Image, Platform } from 'react-native';
5
5
 
6
6
  import {
7
7
  objectHasProperty,
@@ -126,6 +126,31 @@ export default function validateAndroidNotification(
126
126
  out.asForegroundService = android.asForegroundService;
127
127
  }
128
128
 
129
+ const runLimit = android.foregroundServiceBestEffortStopAfterMs;
130
+ if (!isUndefined(runLimit)) {
131
+ const path = "'notification.android.foregroundServiceBestEffortStopAfterMs'";
132
+ if (!Number.isSafeInteger(runLimit) || runLimit < 60000 || runLimit > 18000000) {
133
+ throw new Error(`${path} expected a safe integer between 60000 and 18000000 milliseconds.`);
134
+ }
135
+ if (!out.asForegroundService) {
136
+ throw new Error(`${path} requires asForegroundService: true.`);
137
+ }
138
+ if (Platform.OS === 'android' && Number(Platform.Version) < 35) {
139
+ throw new Error(`${path} requires Android API 35+.`);
140
+ }
141
+ if (
142
+ android.foregroundServiceTypes !== undefined &&
143
+ (!isArray(android.foregroundServiceTypes) ||
144
+ android.foregroundServiceTypes.length !== 1 ||
145
+ android.foregroundServiceTypes[0] !==
146
+ AndroidForegroundServiceType.FOREGROUND_SERVICE_TYPE_DATA_SYNC)
147
+ ) {
148
+ throw new Error(`${path} requires a single dataSync foreground service type.`);
149
+ }
150
+ // An omitted type is resolved and checked against the merged manifest before native START.
151
+ out.foregroundServiceBestEffortStopAfterMs = runLimit;
152
+ }
153
+
129
154
  /**
130
155
  * foregroundServiceBehavior
131
156
  */
@@ -341,6 +366,11 @@ export default function validateAndroidNotification(
341
366
 
342
367
  if (isNumber(android.largeIcon) || isObject(android.largeIcon)) {
343
368
  const image = Image.resolveAssetSource(android.largeIcon);
369
+ if (!image || !isString(image.uri) || /^[\s\u0085]*$/.test(image.uri)) {
370
+ throw new Error(
371
+ "'notification.android.largeIcon' expected a React Native ImageResource value or a valid string URL.",
372
+ );
373
+ }
344
374
  out.largeIcon = image.uri;
345
375
  } else {
346
376
  out.largeIcon = android.largeIcon;
@@ -36,7 +36,11 @@ export function validateAndroidBigPictureStyle(
36
36
 
37
37
  if (isNumber(style.picture) || isObject(style.picture)) {
38
38
  const image = Image.resolveAssetSource(style.picture);
39
-
39
+ if (!image || !isString(image.uri) || /^[\s\u0085]*$/.test(image.uri)) {
40
+ throw new Error(
41
+ "'notification.android.style' BigPictureStyle: 'picture' expected a number or object created using the 'require()' method or a valid string URL.",
42
+ );
43
+ }
40
44
  out.picture = image.uri;
41
45
  }
42
46
 
@@ -53,7 +57,11 @@ export function validateAndroidBigPictureStyle(
53
57
  }
54
58
  if (isNumber(style.largeIcon) || isObject(style.largeIcon)) {
55
59
  const image = Image.resolveAssetSource(style.largeIcon);
56
-
60
+ if (!image || !isString(image.uri) || /^[\s\u0085]*$/.test(image.uri)) {
61
+ throw new Error(
62
+ "'notification.android.style' BigPictureStyle: 'largeIcon' expected a React Native ImageResource value or a valid string URL.",
63
+ );
64
+ }
57
65
  out.largeIcon = image.uri;
58
66
  } else {
59
67
  out.largeIcon = style.largeIcon;
@@ -2,7 +2,6 @@
2
2
  * Copyright (c) 2016-present Invertase Limited
3
3
  */
4
4
 
5
- // @ts-ignore
6
5
  import { Image } from 'react-native';
7
6
 
8
7
  import {
@@ -42,6 +41,11 @@ export default function validateIOSAttachment(
42
41
 
43
42
  if (isNumber(attachment.url) || isObject(attachment.url)) {
44
43
  const image = Image.resolveAssetSource(attachment.url);
44
+ if (!image || !isString(image.uri) || /^[\s\u0085]*$/.test(image.uri)) {
45
+ throw new Error(
46
+ "'attachment.url' expected a React Native ImageResource value or a valid string URL.",
47
+ );
48
+ }
45
49
  out.url = image.uri;
46
50
  }
47
51
 
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  // Generated by genversion.
2
- export const version = '10.8.1';
2
+ export const version = '10.9.0';