onesignal-expo-plugin 2.3.0 → 2.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.
Files changed (35) hide show
  1. package/README.md +66 -14
  2. package/dist/index.d.ts +101 -0
  3. package/dist/index.js +711 -0
  4. package/package.json +43 -45
  5. package/serviceExtensionFiles/NotificationService.swift +32 -0
  6. package/{build/support/serviceExtensionFiles → serviceExtensionFiles}/OneSignalNotificationServiceExtension-Info.plist +1 -1
  7. package/widgetExtensionFiles/OneSignalWidget-Info.plist +29 -0
  8. package/widgetExtensionFiles/OneSignalWidgetBundle.swift +9 -0
  9. package/widgetExtensionFiles/OneSignalWidgetLiveActivity.swift +58 -0
  10. package/app.plugin.js +0 -1
  11. package/build/onesignal/withOneSignal.d.ts +0 -8
  12. package/build/onesignal/withOneSignal.js +0 -20
  13. package/build/onesignal/withOneSignalAndroid.d.ts +0 -7
  14. package/build/onesignal/withOneSignalAndroid.js +0 -126
  15. package/build/onesignal/withOneSignalIos.d.ts +0 -7
  16. package/build/onesignal/withOneSignalIos.js +0 -238
  17. package/build/support/FileManager.d.ts +0 -9
  18. package/build/support/FileManager.js +0 -75
  19. package/build/support/NseUpdaterManager.d.ts +0 -8
  20. package/build/support/NseUpdaterManager.js +0 -38
  21. package/build/support/OneSignalLog.d.ts +0 -4
  22. package/build/support/OneSignalLog.js +0 -12
  23. package/build/support/eas/getEasManagedCredentialsConfigExtra.d.ts +0 -4
  24. package/build/support/eas/getEasManagedCredentialsConfigExtra.js +0 -36
  25. package/build/support/helpers.d.ts +0 -2
  26. package/build/support/helpers.js +0 -51
  27. package/build/support/iosConstants.d.ts +0 -12
  28. package/build/support/iosConstants.js +0 -23
  29. package/build/support/serviceExtensionFiles/NotificationService.m +0 -34
  30. package/build/support/updatePodfile.d.ts +0 -1
  31. package/build/support/updatePodfile.js +0 -20
  32. package/build/types/types.d.ts +0 -55
  33. package/build/types/types.js +0 -15
  34. /package/{build/support/serviceExtensionFiles → serviceExtensionFiles}/NotificationService.h +0 -0
  35. /package/{build/support/serviceExtensionFiles → serviceExtensionFiles}/OneSignalNotificationServiceExtension.entitlements +0 -0
package/package.json CHANGED
@@ -1,62 +1,60 @@
1
1
  {
2
2
  "name": "onesignal-expo-plugin",
3
- "version": "2.3.0",
3
+ "version": "2.5.0",
4
4
  "description": "Some Changez",
5
- "main": "./app.plugin.js",
6
- "types": "./build/types/types.d.ts",
7
- "files": [
8
- "build",
9
- "app.plugin.js"
5
+ "keywords": [
6
+ "EAS",
7
+ "expo",
8
+ "notifications",
9
+ "onesignal",
10
+ "push"
10
11
  ],
11
- "scripts": {
12
- "test": "bun test",
13
- "test:coverage": "bun test --coverage",
14
- "build": "rm -rf build && tsc && cp -a src/support/serviceExtensionFiles build/support/",
15
- "format:spotless": "./examples/demo/android/gradlew spotlessApply",
16
- "format:prettier": "prettier --write \"**/*.{ts,tsx}\" --ignore-path .gitignore",
17
- "format": "concurrently \"bun run format:spotless\" \"bun run format:prettier\"",
18
- "format:check:spotless": "./examples/demo/android/gradlew spotlessCheck",
19
- "format:check:prettier": "prettier --check \"**/*.{ts,tsx}\" --ignore-path .gitignore",
20
- "format:check": "concurrently \"bun run format:check:spotless\" \"bun run format:check:prettier\"",
21
- "lint": "oxlint src examples && bun run format:check",
22
- "lint:fix": "oxlint src examples --fix && bun run format"
12
+ "homepage": "https://github.com/OneSignal/onesignal-expo-plugin#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/OneSignal/onesignal-expo-plugin/issues"
23
15
  },
16
+ "license": "MIT",
24
17
  "repository": {
25
18
  "type": "git",
26
19
  "url": "git+https://github.com/OneSignal/onesignal-expo-plugin.git"
27
20
  },
28
- "keywords": [
29
- "expo",
30
- "onesignal",
31
- "push",
32
- "notifications",
33
- "EAS"
34
- ],
35
- "author": "rgomezp",
36
- "contributors": [
37
- "Karen Grigoryan",
38
- "Rodrigo Gomez-Palacio",
39
- "Charlie Cruzan",
40
- "Wojciech Kozyra",
41
- "Brian Smith"
21
+ "files": [
22
+ "dist",
23
+ "serviceExtensionFiles",
24
+ "widgetExtensionFiles"
42
25
  ],
43
- "license": "MIT",
44
- "bugs": {
45
- "url": "https://github.com/OneSignal/onesignal-expo-plugin/issues"
26
+ "main": "./dist/index.js",
27
+ "types": "./dist/index.d.ts",
28
+ "exports": {
29
+ ".": {
30
+ "types": "./dist/index.d.ts",
31
+ "default": "./dist/index.js"
32
+ },
33
+ "./package.json": "./package.json"
34
+ },
35
+ "scripts": {
36
+ "build": "vp pack",
37
+ "format:spotless": "./examples/demo/android/gradlew spotlessApply",
38
+ "format": "vp fmt && npm run format:spotless",
39
+ "format:check:spotless": "./examples/demo/android/gradlew spotlessCheck",
40
+ "format:check": "vp fmt --check && npm run format:check:spotless",
41
+ "lint": "vp check src && npm run format:check",
42
+ "lint:fix": "vp check --fix src && npm run format",
43
+ "test": "vp test"
44
+ },
45
+ "dependencies": {
46
+ "@expo/image-utils": "^0.8.8"
46
47
  },
47
- "homepage": "https://github.com/OneSignal/onesignal-expo-plugin#readme",
48
48
  "devDependencies": {
49
- "@types/bun": "^1.3.9",
50
- "concurrently": "^9.2.1",
51
- "expo-module-scripts": "^5.0.8",
52
- "oxlint": "^1.43.0",
53
- "prettier": "^3.8.1",
54
- "typescript": "^5.9.3"
49
+ "@expo/config-types": "^55.0.5",
50
+ "@types/node": "^22.19.3",
51
+ "@vitest/coverage-v8": "^4.1.5",
52
+ "typescript": "^6.0.3",
53
+ "vite-plus": "0.1.19"
55
54
  },
56
55
  "peerDependencies": {
56
+ "@expo/config-plugins": ">=7.0.0",
57
57
  "react-native-onesignal": ">=5.0.0"
58
58
  },
59
- "dependencies": {
60
- "@expo/image-utils": "^0.8.8"
61
- }
59
+ "packageManager": "bun@1.3.13"
62
60
  }
@@ -0,0 +1,32 @@
1
+ import UserNotifications
2
+ import OneSignalExtension
3
+
4
+ class NotificationService: UNNotificationServiceExtension {
5
+ var contentHandler: ((UNNotificationContent) -> Void)?
6
+ var receivedRequest: UNNotificationRequest!
7
+ var bestAttemptContent: UNMutableNotificationContent?
8
+
9
+ // Note this extension only runs when `mutable_content` is set
10
+ // Setting an attachment or action buttons automatically sets the property to true
11
+ override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
12
+ self.receivedRequest = request
13
+ self.contentHandler = contentHandler
14
+ self.bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
15
+
16
+ if let bestAttemptContent = bestAttemptContent {
17
+ // DEBUGGING: Uncomment the 2 lines below to check this extension is executing
18
+ // print("Running NotificationServiceExtension")
19
+ // bestAttemptContent.body = "[Modified] " + bestAttemptContent.body
20
+
21
+ OneSignalExtension.didReceiveNotificationExtensionRequest(self.receivedRequest, with: bestAttemptContent, withContentHandler: self.contentHandler)
22
+ }
23
+ }
24
+
25
+ override func serviceExtensionTimeWillExpire() {
26
+ // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
27
+ if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
28
+ OneSignalExtension.serviceExtensionTimeWillExpireRequest(self.receivedRequest, with: self.bestAttemptContent)
29
+ contentHandler(bestAttemptContent)
30
+ }
31
+ }
32
+ }
@@ -25,7 +25,7 @@
25
25
  <key>NSExtensionPointIdentifier</key>
26
26
  <string>com.apple.usernotifications.service</string>
27
27
  <key>NSExtensionPrincipalClass</key>
28
- <string>NotificationService</string>
28
+ <string>{{NSE_PRINCIPAL_CLASS}}</string>
29
29
  </dict>
30
30
  </dict>
31
31
  </plist>
@@ -0,0 +1,29 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>CFBundleDevelopmentRegion</key>
6
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
7
+ <key>CFBundleDisplayName</key>
8
+ <string>OneSignalWidget</string>
9
+ <key>CFBundleExecutable</key>
10
+ <string>$(EXECUTABLE_NAME)</string>
11
+ <key>CFBundleIdentifier</key>
12
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
13
+ <key>CFBundleInfoDictionaryVersion</key>
14
+ <string>6.0</string>
15
+ <key>CFBundleName</key>
16
+ <string>$(PRODUCT_NAME)</string>
17
+ <key>CFBundlePackageType</key>
18
+ <string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
19
+ <key>CFBundleShortVersionString</key>
20
+ <string>{{BUNDLE_SHORT_VERSION}}</string>
21
+ <key>CFBundleVersion</key>
22
+ <string>{{BUNDLE_VERSION}}</string>
23
+ <key>NSExtension</key>
24
+ <dict>
25
+ <key>NSExtensionPointIdentifier</key>
26
+ <string>com.apple.widgetkit-extension</string>
27
+ </dict>
28
+ </dict>
29
+ </plist>
@@ -0,0 +1,9 @@
1
+ import WidgetKit
2
+ import SwiftUI
3
+
4
+ @main
5
+ struct OneSignalWidgetBundle: WidgetBundle {
6
+ var body: some Widget {
7
+ OneSignalWidgetLiveActivity()
8
+ }
9
+ }
@@ -0,0 +1,58 @@
1
+ // This default Live Activity widget uses OneSignal's `DefaultLiveActivityAttributes`
2
+ // so you can drive it entirely from JS via `OneSignal.LiveActivities.setupDefault()`.
3
+ // To use a custom attributes type, replace this file via the plugin's
4
+ // `liveActivities.widgetFilePath` prop.
5
+ //
6
+ // See: https://documentation.onesignal.com/docs/cross-platform-live-activity-setup
7
+
8
+ import ActivityKit
9
+ import WidgetKit
10
+ import SwiftUI
11
+ import OneSignalLiveActivities
12
+
13
+ struct OneSignalWidgetLiveActivity: Widget {
14
+ var body: some WidgetConfiguration {
15
+ ActivityConfiguration(for: DefaultLiveActivityAttributes.self) { context in
16
+ // Lock screen / banner UI
17
+ VStack {
18
+ Spacer()
19
+
20
+ Text("Title: " + (context.attributes.data["title"]?.asString() ?? ""))
21
+ .font(.headline)
22
+
23
+ Spacer()
24
+
25
+ HStack {
26
+ Spacer()
27
+ Text(context.state.data["message"]?.asDict()?["en"]?.asString() ?? "Default Message")
28
+ Spacer()
29
+ }
30
+
31
+ Spacer()
32
+ }
33
+ .activitySystemActionForegroundColor(.black)
34
+ .activityBackgroundTint(.white)
35
+
36
+ } dynamicIsland: { _ in
37
+ DynamicIsland {
38
+ DynamicIslandExpandedRegion(.leading) {
39
+ Text("Leading")
40
+ }
41
+ DynamicIslandExpandedRegion(.trailing) {
42
+ Text("Trailing")
43
+ }
44
+ DynamicIslandExpandedRegion(.bottom) {
45
+ Text("Bottom")
46
+ }
47
+ } compactLeading: {
48
+ Text("L")
49
+ } compactTrailing: {
50
+ Text("T")
51
+ } minimal: {
52
+ Text("Min")
53
+ }
54
+ .widgetURL(URL(string: "http://www.apple.com"))
55
+ .keylineTint(Color.red)
56
+ }
57
+ }
58
+ }
package/app.plugin.js DELETED
@@ -1 +0,0 @@
1
- module.exports = require('./build/onesignal/withOneSignal.js');
@@ -1,8 +0,0 @@
1
- /**
2
- * Expo config plugin for One Signal
3
- * @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps
4
- */
5
- import { ConfigPlugin } from '@expo/config-plugins';
6
- import { OneSignalPluginProps } from '../types/types';
7
- declare const withOneSignal: ConfigPlugin<OneSignalPluginProps>;
8
- export default withOneSignal;
@@ -1,20 +0,0 @@
1
- "use strict";
2
- /**
3
- * Expo config plugin for One Signal
4
- * @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- const withOneSignalAndroid_1 = require("./withOneSignalAndroid");
8
- const withOneSignalIos_1 = require("./withOneSignalIos");
9
- const helpers_1 = require("../support/helpers");
10
- const withOneSignal = (config, props) => {
11
- // if props are undefined, throw error
12
- if (!props) {
13
- throw new Error('You are trying to use the OneSignal plugin without any props. Property "mode" is required. Please see https://github.com/OneSignal/onesignal-expo-plugin for more info.');
14
- }
15
- (0, helpers_1.validatePluginProps)(props);
16
- config = (0, withOneSignalIos_1.withOneSignalIos)(config, props);
17
- config = (0, withOneSignalAndroid_1.withOneSignalAndroid)(config, props);
18
- return config;
19
- };
20
- exports.default = withOneSignal;
@@ -1,7 +0,0 @@
1
- /**
2
- * Expo config plugin for OneSignal (Android)
3
- * @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps
4
- */
5
- import { ConfigPlugin } from '@expo/config-plugins';
6
- import { OneSignalPluginProps } from '../types/types';
7
- export declare const withOneSignalAndroid: ConfigPlugin<OneSignalPluginProps>;
@@ -1,126 +0,0 @@
1
- "use strict";
2
- /**
3
- * Expo config plugin for OneSignal (Android)
4
- * @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.withOneSignalAndroid = void 0;
8
- const config_plugins_1 = require("@expo/config-plugins");
9
- const image_utils_1 = require("@expo/image-utils");
10
- const OneSignalLog_1 = require("../support/OneSignalLog");
11
- const path_1 = require("path");
12
- const fs_1 = require("fs");
13
- const RESOURCE_ROOT_PATH = 'android/app/src/main/res/';
14
- // The name of each small icon folder resource, and the icon size for that folder.
15
- const SMALL_ICON_DIRS_TO_SIZE = {
16
- 'drawable-mdpi': 24,
17
- 'drawable-hdpi': 36,
18
- 'drawable-xhdpi': 48,
19
- 'drawable-xxhdpi': 72,
20
- 'drawable-xxxhdpi': 96,
21
- };
22
- // The name of each large icon folder resource, and the icon size for that folder.
23
- const LARGE_ICON_DIRS_TO_SIZE = {
24
- 'drawable-xxxhdpi': 256,
25
- };
26
- const SMALL_ICON_DEFAULT_NAME = 'ic_stat_onesignal_default';
27
- const withSmallIcons = (config, onesignalProps) => {
28
- if (!onesignalProps.smallIcons && !config.notification?.icon) {
29
- return config;
30
- }
31
- return (0, config_plugins_1.withDangerousMod)(config, [
32
- 'android',
33
- async (config) => {
34
- if (config.notification?.icon) {
35
- await saveIconAsync(config.notification.icon, config.modRequest.projectRoot, SMALL_ICON_DIRS_TO_SIZE, SMALL_ICON_DEFAULT_NAME);
36
- }
37
- if (onesignalProps.smallIcons) {
38
- await saveIconsArrayAsync(config.modRequest.projectRoot, onesignalProps.smallIcons, SMALL_ICON_DIRS_TO_SIZE, SMALL_ICON_DEFAULT_NAME);
39
- }
40
- return config;
41
- },
42
- ]);
43
- };
44
- const LARGE_ICON_DEFAULT_NAME = 'ic_onesignal_large_icon_default';
45
- const withLargeIcons = (config, onesignalProps) => {
46
- if (!onesignalProps.largeIcons) {
47
- return config;
48
- }
49
- return (0, config_plugins_1.withDangerousMod)(config, [
50
- 'android',
51
- async (config) => {
52
- if (onesignalProps.largeIcons) {
53
- await saveIconsArrayAsync(config.modRequest.projectRoot, onesignalProps.largeIcons, LARGE_ICON_DIRS_TO_SIZE, LARGE_ICON_DEFAULT_NAME);
54
- }
55
- return config;
56
- },
57
- ]);
58
- };
59
- const withSmallIconAccentColor = (config, onesignalProps) => {
60
- if (!onesignalProps.smallIconAccentColor) {
61
- return config;
62
- }
63
- return (0, config_plugins_1.withStringsXml)(config, (config) => {
64
- const colorInARGB = `FF${onesignalProps.smallIconAccentColor?.replace('#', '')}`;
65
- const strings = config.modResults.resources.string ?? [];
66
- // Check if the accent color entry already exists
67
- const hasAccentColor = strings.some((stringEntry) => stringEntry.$?.name === 'onesignal_notification_accent_color' &&
68
- stringEntry._ === colorInARGB);
69
- if (!hasAccentColor) {
70
- const accentColorEntry = {
71
- $: { name: 'onesignal_notification_accent_color' },
72
- _: colorInARGB,
73
- };
74
- config.modResults.resources.string = [...strings, accentColorEntry];
75
- }
76
- return config;
77
- });
78
- };
79
- async function saveIconsArrayAsync(projectRoot, icons, dirsToSize, defaultName) {
80
- for (let i = 0; i < icons.length; i++) {
81
- // the first icon should use OneSignal’s required default drawable name; others keep their file-derived names.
82
- const outputName = i === 0 ? defaultName : undefined;
83
- await saveIconAsync(icons[i], projectRoot, dirsToSize, outputName);
84
- }
85
- }
86
- async function saveIconAsync(icon, projectRoot, dirsToSize, outputName) {
87
- const name = outputName ?? (0, path_1.parse)(icon).name;
88
- OneSignalLog_1.OneSignalLog.log('Saving icon ' + icon + ' as drawable resource ' + name);
89
- for (const iconResourceDir in dirsToSize) {
90
- const path = (0, path_1.resolve)(projectRoot, RESOURCE_ROOT_PATH, iconResourceDir);
91
- if (!(0, fs_1.existsSync)(path)) {
92
- (0, fs_1.mkdirSync)(path, { recursive: true });
93
- }
94
- const resizedIcon = (await (0, image_utils_1.generateImageAsync)({ projectRoot, cacheType: 'onesignal-icon' }, {
95
- src: icon,
96
- width: dirsToSize[iconResourceDir],
97
- height: dirsToSize[iconResourceDir],
98
- resizeMode: 'cover',
99
- backgroundColor: 'transparent',
100
- })).source;
101
- (0, fs_1.writeFileSync)((0, path_1.resolve)(path, name + '.png'), resizedIcon);
102
- }
103
- }
104
- const OKHTTP_FORCE_FIX = `
105
- subprojects {
106
- project.configurations.all {
107
- resolutionStrategy.force 'com.squareup.okhttp3:okhttp:4.12.0'
108
- }
109
- }`;
110
- const withOkHttpFix = (config) => {
111
- return (0, config_plugins_1.withProjectBuildGradle)(config, (config) => {
112
- if (config.modResults.contents.includes("force 'com.squareup.okhttp3:okhttp:4.12.0'")) {
113
- return config;
114
- }
115
- config.modResults.contents += OKHTTP_FORCE_FIX;
116
- return config;
117
- });
118
- };
119
- const withOneSignalAndroid = (config, props) => {
120
- config = withSmallIcons(config, props);
121
- config = withLargeIcons(config, props);
122
- config = withSmallIconAccentColor(config, props);
123
- config = withOkHttpFix(config);
124
- return config;
125
- };
126
- exports.withOneSignalAndroid = withOneSignalAndroid;
@@ -1,7 +0,0 @@
1
- /**
2
- * Expo config plugin for One Signal (iOS)
3
- * @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps
4
- */
5
- import { ConfigPlugin } from '@expo/config-plugins';
6
- import { OneSignalPluginProps } from '../types/types';
7
- export declare const withOneSignalIos: ConfigPlugin<OneSignalPluginProps>;
@@ -1,238 +0,0 @@
1
- "use strict";
2
- /**
3
- * Expo config plugin for One Signal (iOS)
4
- * @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps
5
- */
6
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
- if (k2 === undefined) k2 = k;
8
- var desc = Object.getOwnPropertyDescriptor(m, k);
9
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
- desc = { enumerable: true, get: function() { return m[k]; } };
11
- }
12
- Object.defineProperty(o, k2, desc);
13
- }) : (function(o, m, k, k2) {
14
- if (k2 === undefined) k2 = k;
15
- o[k2] = m[k];
16
- }));
17
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
- Object.defineProperty(o, "default", { enumerable: true, value: v });
19
- }) : function(o, v) {
20
- o["default"] = v;
21
- });
22
- var __importStar = (this && this.__importStar) || (function () {
23
- var ownKeys = function(o) {
24
- ownKeys = Object.getOwnPropertyNames || function (o) {
25
- var ar = [];
26
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
- return ar;
28
- };
29
- return ownKeys(o);
30
- };
31
- return function (mod) {
32
- if (mod && mod.__esModule) return mod;
33
- var result = {};
34
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
- __setModuleDefault(result, mod);
36
- return result;
37
- };
38
- })();
39
- var __importDefault = (this && this.__importDefault) || function (mod) {
40
- return (mod && mod.__esModule) ? mod : { "default": mod };
41
- };
42
- Object.defineProperty(exports, "__esModule", { value: true });
43
- exports.withOneSignalIos = void 0;
44
- const config_plugins_1 = require("@expo/config-plugins");
45
- const fs = __importStar(require("fs"));
46
- const path = __importStar(require("path"));
47
- const iosConstants_1 = require("../support/iosConstants");
48
- const helpers_1 = require("../support/helpers");
49
- const updatePodfile_1 = require("../support/updatePodfile");
50
- const NseUpdaterManager_1 = __importDefault(require("../support/NseUpdaterManager"));
51
- const OneSignalLog_1 = require("../support/OneSignalLog");
52
- const FileManager_1 = require("../support/FileManager");
53
- const getEasManagedCredentialsConfigExtra_1 = __importDefault(require("../support/eas/getEasManagedCredentialsConfigExtra"));
54
- /**
55
- * Add 'aps-environment' record with current environment to '<project-name>.entitlements' file
56
- * @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps
57
- */
58
- const withAppEnvironment = (config, onesignalProps) => {
59
- return (0, config_plugins_1.withEntitlementsPlist)(config, (newConfig) => {
60
- if (onesignalProps?.mode == null) {
61
- throw new Error(`
62
- Missing required "mode" key in your app.json or app.config.js file for "onesignal-expo-plugin".
63
- "mode" can be either "development" or "production".
64
- Please see onesignal-expo-plugin's README.md for more details.`);
65
- }
66
- newConfig.modResults['aps-environment'] = onesignalProps.mode;
67
- return newConfig;
68
- });
69
- };
70
- /**
71
- * Add "Background Modes -> Remote notifications" and "App Group" permissions
72
- * @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps
73
- */
74
- const withRemoteNotificationsPermissions = (config) => {
75
- const BACKGROUND_MODE_KEYS = ['remote-notification'];
76
- return (0, config_plugins_1.withInfoPlist)(config, (newConfig) => {
77
- if (!Array.isArray(newConfig.modResults.UIBackgroundModes)) {
78
- newConfig.modResults.UIBackgroundModes = [];
79
- }
80
- for (const key of BACKGROUND_MODE_KEYS) {
81
- if (!newConfig.modResults.UIBackgroundModes.includes(key)) {
82
- newConfig.modResults.UIBackgroundModes.push(key);
83
- }
84
- }
85
- return newConfig;
86
- });
87
- };
88
- /**
89
- * Add "App Group" permission
90
- * @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps (step 4.4)
91
- */
92
- const withAppGroupPermissions = (config, props) => {
93
- const APP_GROUP_KEY = 'com.apple.security.application-groups';
94
- return (0, config_plugins_1.withEntitlementsPlist)(config, (newConfig) => {
95
- if (!Array.isArray(newConfig.modResults[APP_GROUP_KEY])) {
96
- newConfig.modResults[APP_GROUP_KEY] = [];
97
- }
98
- const modResultsArray = newConfig.modResults[APP_GROUP_KEY];
99
- const entitlement = (0, helpers_1.getAppGroupIdentifier)(newConfig?.ios?.bundleIdentifier || '', props?.appGroupName);
100
- if (modResultsArray.indexOf(entitlement) !== -1) {
101
- return newConfig;
102
- }
103
- modResultsArray.push(entitlement);
104
- return newConfig;
105
- });
106
- };
107
- /**
108
- * Add OneSignal_app_groups_key to Info.plist when a custom app group name is provided.
109
- * @see https://documentation.onesignal.com/docs/ios-sdk-setup#step-3-create-an-app-group
110
- */
111
- const withCustomAppGroupsKey = (config, props) => {
112
- return (0, config_plugins_1.withInfoPlist)(config, (newConfig) => {
113
- if (props?.appGroupName) {
114
- newConfig.modResults.OneSignal_app_groups_key = props.appGroupName;
115
- }
116
- return newConfig;
117
- });
118
- };
119
- const withEasManagedCredentials = (config, props) => {
120
- if (!config.ios?.bundleIdentifier) {
121
- return config;
122
- }
123
- config.extra = (0, getEasManagedCredentialsConfigExtra_1.default)(config, props?.appGroupName, props?.nseBundleIdentifier);
124
- return config;
125
- };
126
- const withOneSignalPodfile = (config) => {
127
- return (0, config_plugins_1.withDangerousMod)(config, [
128
- 'ios',
129
- async (config) => {
130
- const iosRoot = path.join(config.modRequest.projectRoot, 'ios');
131
- await (0, updatePodfile_1.updatePodfile)(iosRoot);
132
- return config;
133
- },
134
- ]);
135
- };
136
- const withOneSignalNSE = (config, props) => {
137
- return (0, config_plugins_1.withDangerousMod)(config, [
138
- 'ios',
139
- async (config) => {
140
- // support for monorepos where node_modules can be above the project directory.
141
- const pluginDir = require.resolve('onesignal-expo-plugin/package.json');
142
- const sourceDir = path.join(pluginDir, '../build/support/serviceExtensionFiles/');
143
- const iosPath = path.join(config.modRequest.projectRoot, 'ios');
144
- /* COPY OVER EXTENSION FILES */
145
- fs.mkdirSync(`${iosPath}/${iosConstants_1.NSE_TARGET_NAME}`, {
146
- recursive: true,
147
- });
148
- for (const file of iosConstants_1.NSE_EXT_FILES) {
149
- const targetFile = `${iosPath}/${iosConstants_1.NSE_TARGET_NAME}/${file}`;
150
- await FileManager_1.FileManager.copyFile(`${sourceDir}${file}`, targetFile);
151
- }
152
- const sourcePath = props.iosNSEFilePath ?? `${sourceDir}${iosConstants_1.NSE_SOURCE_FILE}`;
153
- const targetFile = `${iosPath}/${iosConstants_1.NSE_TARGET_NAME}/${iosConstants_1.NSE_SOURCE_FILE}`;
154
- await FileManager_1.FileManager.copyFile(`${sourcePath}`, targetFile);
155
- /* MODIFY COPIED EXTENSION FILES */
156
- const nseUpdater = new NseUpdaterManager_1.default(iosPath);
157
- const appGroupId = (0, helpers_1.getAppGroupIdentifier)(config.ios?.bundleIdentifier ?? '', props.appGroupName);
158
- await nseUpdater.updateNSEEntitlements(appGroupId);
159
- if (props.appGroupName) {
160
- await nseUpdater.updateNSEInfoPlistAppGroupKey(props.appGroupName);
161
- }
162
- await nseUpdater.updateNSEBundleVersion(config.ios?.buildNumber ?? iosConstants_1.DEFAULT_BUNDLE_VERSION);
163
- await nseUpdater.updateNSEBundleShortVersion(config?.version ?? iosConstants_1.DEFAULT_BUNDLE_SHORT_VERSION);
164
- return config;
165
- },
166
- ]);
167
- };
168
- const withOneSignalXcodeProject = (config, props) => {
169
- return (0, config_plugins_1.withXcodeProject)(config, (newConfig) => {
170
- const xcodeProject = newConfig.modResults;
171
- const nseBundleId = `${config.ios?.bundleIdentifier}.${props.nseBundleIdentifier ?? iosConstants_1.NSE_TARGET_NAME}`;
172
- if (xcodeProject.pbxTargetByName(iosConstants_1.NSE_TARGET_NAME)) {
173
- OneSignalLog_1.OneSignalLog.log(`${iosConstants_1.NSE_TARGET_NAME} already exists in project. Skipping...`);
174
- return newConfig;
175
- }
176
- // Create new PBXGroup for the extension
177
- const extGroup = xcodeProject.addPbxGroup([...iosConstants_1.NSE_EXT_FILES, iosConstants_1.NSE_SOURCE_FILE], iosConstants_1.NSE_TARGET_NAME, iosConstants_1.NSE_TARGET_NAME);
178
- // Add the new PBXGroup to the top level group. This makes the
179
- // files / folder appear in the file explorer in Xcode.
180
- const groups = xcodeProject.hash.project.objects['PBXGroup'];
181
- Object.keys(groups).forEach(function (key) {
182
- if (typeof groups[key] === 'object' &&
183
- groups[key].name === undefined &&
184
- groups[key].path === undefined) {
185
- xcodeProject.addToPbxGroup(extGroup.uuid, key);
186
- }
187
- });
188
- // WORK AROUND for codeProject.addTarget BUG
189
- // Xcode projects don't contain these if there is only one target
190
- // An upstream fix should be made to the code referenced in this link:
191
- // - https://github.com/apache/cordova-node-xcode/blob/8b98cabc5978359db88dc9ff2d4c015cba40f150/lib/pbxProject.js#L860
192
- const projObjects = xcodeProject.hash.project.objects;
193
- projObjects['PBXTargetDependency'] =
194
- projObjects['PBXTargetDependency'] || {};
195
- projObjects['PBXContainerItemProxy'] =
196
- projObjects['PBXTargetDependency'] || {};
197
- // Add the NSE target
198
- // This adds PBXTargetDependency and PBXContainerItemProxy for you
199
- const nseTarget = xcodeProject.addTarget(iosConstants_1.NSE_TARGET_NAME, 'app_extension', iosConstants_1.NSE_TARGET_NAME, nseBundleId);
200
- // Add build phases to the new target
201
- xcodeProject.addBuildPhase(['NotificationService.m'], 'PBXSourcesBuildPhase', 'Sources', nseTarget.uuid);
202
- xcodeProject.addBuildPhase([], 'PBXResourcesBuildPhase', 'Resources', nseTarget.uuid);
203
- xcodeProject.addBuildPhase([], 'PBXFrameworksBuildPhase', 'Frameworks', nseTarget.uuid);
204
- // Edit the Deployment info of the new Target, only IphoneOS and Targeted Device Family
205
- // However, can be more
206
- const configurations = xcodeProject.pbxXCBuildConfigurationSection();
207
- for (const key in configurations) {
208
- if (typeof configurations[key].buildSettings !== 'undefined' &&
209
- configurations[key].buildSettings.PRODUCT_NAME == `"${iosConstants_1.NSE_TARGET_NAME}"`) {
210
- const buildSettingsObj = configurations[key].buildSettings;
211
- buildSettingsObj.DEVELOPMENT_TEAM = props?.devTeam;
212
- buildSettingsObj.IPHONEOS_DEPLOYMENT_TARGET =
213
- props?.iPhoneDeploymentTarget ?? iosConstants_1.IPHONEOS_DEPLOYMENT_TARGET;
214
- buildSettingsObj.TARGETED_DEVICE_FAMILY = iosConstants_1.TARGETED_DEVICE_FAMILY;
215
- buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `${iosConstants_1.NSE_TARGET_NAME}/${iosConstants_1.NSE_TARGET_NAME}.entitlements`;
216
- buildSettingsObj.CODE_SIGN_STYLE = 'Automatic';
217
- }
218
- }
219
- // Add development teams to both your target and the original project
220
- xcodeProject.addTargetAttribute('DevelopmentTeam', props?.devTeam, nseTarget);
221
- xcodeProject.addTargetAttribute('DevelopmentTeam', props?.devTeam);
222
- return newConfig;
223
- });
224
- };
225
- const withOneSignalIos = (config, props) => {
226
- config = withAppEnvironment(config, props);
227
- config = withRemoteNotificationsPermissions(config, props);
228
- if (!props.disableNSE) {
229
- config = withCustomAppGroupsKey(config, props);
230
- config = withAppGroupPermissions(config, props);
231
- config = withOneSignalPodfile(config, props);
232
- config = withOneSignalNSE(config, props);
233
- config = withOneSignalXcodeProject(config, props);
234
- config = withEasManagedCredentials(config, props);
235
- }
236
- return config;
237
- };
238
- exports.withOneSignalIos = withOneSignalIos;