onesignal-expo-plugin 2.0.4 → 2.2.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 CHANGED
@@ -87,6 +87,8 @@ You can pass props to the plugin config object to configure:
87
87
  | `largeIcons` | optional | An array of local paths to large notification icons for Android. Image should be white, transparent, and 256x256 in size. e.g: `["./assets/ic_onesignal_large_icon_default.png"]`. See https://documentation.onesignal.com/docs/customize-notification-icons#large-notification-icons. |
88
88
  | `smallIconAccentColor` | optional | The accent color to use for notification icons on Android. Must be a valid hex value, e.g: `"#FF0000"` |
89
89
  | `iosNSEFilePath` | optional | The local path to a custom Notification Service Extension (NSE), written in Objective-C. The NSE will typically start as a copy of the [default NSE](https://github.com/OneSignal/onesignal-expo-plugin/blob/main/support/serviceExtensionFiles/NotificationService.m), then altered to support any custom logic required. e.g: `"./assets/NotificationService.m"`. |
90
+ | `appGroupName` | optional | Used to configure a custom iOS [App Group](https://documentation.onesignal.com/docs/ios-sdk-setup#step-3-create-an-app-group) name. If not provided, defaults to `"group.{ios.bundleIdentifier}.onesignal"`. e.g: `"group.com.example.myapp.onesignal2"`. |
91
+ | `nseBundleIdentifier` | optional | Used to configure a custom bundle identifier suffix for the iOS Notification Service Extension. The full bundle identifier will be `"{ios.bundleIdentifier}.{nseBundleIdentifier}"`. If not provided, defaults to `"OneSignalNotificationServiceExtension"`. |
90
92
 
91
93
  ### OneSignal App ID
92
94
 
@@ -17,11 +17,11 @@ const SMALL_ICON_DIRS_TO_SIZE = {
17
17
  'drawable-hdpi': 36,
18
18
  'drawable-xhdpi': 48,
19
19
  'drawable-xxhdpi': 72,
20
- 'drawable-xxxhdpi': 96
20
+ 'drawable-xxxhdpi': 96,
21
21
  };
22
22
  // The name of each large icon folder resource, and the icon size for that folder.
23
23
  const LARGE_ICON_DIRS_TO_SIZE = {
24
- 'drawable-xxxhdpi': 256
24
+ 'drawable-xxxhdpi': 256,
25
25
  };
26
26
  const withSmallIcons = (config, onesignalProps) => {
27
27
  if (!onesignalProps.smallIcons && !config.notification?.icon) {
@@ -83,7 +83,7 @@ async function saveIconsArrayAsync(projectRoot, icons, dirsToSize) {
83
83
  }
84
84
  async function saveIconAsync(icon, projectRoot, dirsToSize) {
85
85
  const name = (0, path_1.parse)(icon).name;
86
- OneSignalLog_1.OneSignalLog.log("Saving icon " + icon + " as drawable resource " + name);
86
+ OneSignalLog_1.OneSignalLog.log('Saving icon ' + icon + ' as drawable resource ' + name);
87
87
  for (const iconResourceDir in dirsToSize) {
88
88
  const path = (0, path_1.resolve)(projectRoot, RESOURCE_ROOT_PATH, iconResourceDir);
89
89
  if (!(0, fs_1.existsSync)(path)) {
@@ -45,6 +45,7 @@ const config_plugins_1 = require("@expo/config-plugins");
45
45
  const fs = __importStar(require("fs"));
46
46
  const path = __importStar(require("path"));
47
47
  const iosConstants_1 = require("../support/iosConstants");
48
+ const helpers_1 = require("../support/helpers");
48
49
  const updatePodfile_1 = require("../support/updatePodfile");
49
50
  const NseUpdaterManager_1 = __importDefault(require("../support/NseUpdaterManager"));
50
51
  const OneSignalLog_1 = require("../support/OneSignalLog");
@@ -63,7 +64,7 @@ const withAppEnvironment = (config, onesignalProps) => {
63
64
  "mode" can be either "development" or "production".
64
65
  Please see onesignal-expo-plugin's README.md for more details.`);
65
66
  }
66
- newConfig.modResults["aps-environment"] = onesignalProps.mode;
67
+ newConfig.modResults['aps-environment'] = onesignalProps.mode;
67
68
  return newConfig;
68
69
  });
69
70
  };
@@ -72,7 +73,7 @@ const withAppEnvironment = (config, onesignalProps) => {
72
73
  * @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps
73
74
  */
74
75
  const withRemoteNotificationsPermissions = (config) => {
75
- const BACKGROUND_MODE_KEYS = ["remote-notification"];
76
+ const BACKGROUND_MODE_KEYS = ['remote-notification'];
76
77
  return (0, config_plugins_1.withInfoPlist)(config, (newConfig) => {
77
78
  if (!Array.isArray(newConfig.modResults.UIBackgroundModes)) {
78
79
  newConfig.modResults.UIBackgroundModes = [];
@@ -89,14 +90,14 @@ const withRemoteNotificationsPermissions = (config) => {
89
90
  * Add "App Group" permission
90
91
  * @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
  */
92
- const withAppGroupPermissions = (config) => {
93
- const APP_GROUP_KEY = "com.apple.security.application-groups";
94
- return (0, config_plugins_1.withEntitlementsPlist)(config, newConfig => {
93
+ const withAppGroupPermissions = (config, props) => {
94
+ const APP_GROUP_KEY = 'com.apple.security.application-groups';
95
+ return (0, config_plugins_1.withEntitlementsPlist)(config, (newConfig) => {
95
96
  if (!Array.isArray(newConfig.modResults[APP_GROUP_KEY])) {
96
97
  newConfig.modResults[APP_GROUP_KEY] = [];
97
98
  }
98
99
  const modResultsArray = newConfig.modResults[APP_GROUP_KEY];
99
- const entitlement = `group.${newConfig?.ios?.bundleIdentifier || ""}.onesignal`;
100
+ const entitlement = (0, helpers_1.getAppGroupIdentifier)(newConfig?.ios?.bundleIdentifier || '', props?.appGroupName);
100
101
  if (modResultsArray.indexOf(entitlement) !== -1) {
101
102
  return newConfig;
102
103
  }
@@ -104,44 +105,59 @@ const withAppGroupPermissions = (config) => {
104
105
  return newConfig;
105
106
  });
106
107
  };
107
- const withEasManagedCredentials = (config) => {
108
+ /**
109
+ * Add OneSignal_app_groups_key to Info.plist when a custom app group name is provided.
110
+ * @see https://documentation.onesignal.com/docs/ios-sdk-setup#step-3-create-an-app-group
111
+ */
112
+ const withCustomAppGroupsKey = (config, props) => {
113
+ return (0, config_plugins_1.withInfoPlist)(config, (newConfig) => {
114
+ if (props?.appGroupName) {
115
+ newConfig.modResults.OneSignal_app_groups_key = props.appGroupName;
116
+ }
117
+ return newConfig;
118
+ });
119
+ };
120
+ const withEasManagedCredentials = (config, props) => {
108
121
  (0, assert_1.default)(config.ios?.bundleIdentifier, "Missing 'ios.bundleIdentifier' in app config.");
109
- config.extra = (0, getEasManagedCredentialsConfigExtra_1.default)(config);
122
+ config.extra = (0, getEasManagedCredentialsConfigExtra_1.default)(config, props?.appGroupName, props?.nseBundleIdentifier);
110
123
  return config;
111
124
  };
112
125
  const withOneSignalPodfile = (config) => {
113
126
  return (0, config_plugins_1.withDangerousMod)(config, [
114
127
  'ios',
115
128
  async (config) => {
116
- // not awaiting in order to not block main thread
117
- const iosRoot = path.join(config.modRequest.projectRoot, "ios");
118
- (0, updatePodfile_1.updatePodfile)(iosRoot).catch(err => { OneSignalLog_1.OneSignalLog.error(err); });
129
+ const iosRoot = path.join(config.modRequest.projectRoot, 'ios');
130
+ await (0, updatePodfile_1.updatePodfile)(iosRoot);
119
131
  return config;
120
132
  },
121
133
  ]);
122
134
  };
123
135
  const withOneSignalNSE = (config, props) => {
124
136
  // support for monorepos where node_modules can be above the project directory.
125
- const pluginDir = require.resolve("onesignal-expo-plugin/package.json");
126
- const sourceDir = path.join(pluginDir, "../build/support/serviceExtensionFiles/");
137
+ const pluginDir = require.resolve('onesignal-expo-plugin/package.json');
138
+ const sourceDir = path.join(pluginDir, '../build/support/serviceExtensionFiles/');
127
139
  return (0, config_plugins_1.withDangerousMod)(config, [
128
140
  'ios',
129
141
  async (config) => {
130
- const iosPath = path.join(config.modRequest.projectRoot, "ios");
142
+ const iosPath = path.join(config.modRequest.projectRoot, 'ios');
131
143
  /* COPY OVER EXTENSION FILES */
132
- fs.mkdirSync(`${iosPath}/${iosConstants_1.NSE_TARGET_NAME}`, { recursive: true });
133
- for (let i = 0; i < iosConstants_1.NSE_EXT_FILES.length; i++) {
134
- const extFile = iosConstants_1.NSE_EXT_FILES[i];
135
- const targetFile = `${iosPath}/${iosConstants_1.NSE_TARGET_NAME}/${extFile}`;
136
- await FileManager_1.FileManager.copyFile(`${sourceDir}${extFile}`, targetFile);
144
+ fs.mkdirSync(`${iosPath}/${iosConstants_1.NSE_TARGET_NAME}`, {
145
+ recursive: true,
146
+ });
147
+ for (const file of iosConstants_1.NSE_EXT_FILES) {
148
+ const targetFile = `${iosPath}/${iosConstants_1.NSE_TARGET_NAME}/${file}`;
149
+ await FileManager_1.FileManager.copyFile(`${sourceDir}${file}`, targetFile);
137
150
  }
138
- // Copy NSE source file either from configuration-provided location, falling back to the default one.
139
151
  const sourcePath = props.iosNSEFilePath ?? `${sourceDir}${iosConstants_1.NSE_SOURCE_FILE}`;
140
152
  const targetFile = `${iosPath}/${iosConstants_1.NSE_TARGET_NAME}/${iosConstants_1.NSE_SOURCE_FILE}`;
141
153
  await FileManager_1.FileManager.copyFile(`${sourcePath}`, targetFile);
142
154
  /* MODIFY COPIED EXTENSION FILES */
143
155
  const nseUpdater = new NseUpdaterManager_1.default(iosPath);
144
- await nseUpdater.updateNSEEntitlements(`group.${config.ios?.bundleIdentifier}.onesignal`);
156
+ const appGroupId = (0, helpers_1.getAppGroupIdentifier)(config.ios?.bundleIdentifier ?? '', props.appGroupName);
157
+ await nseUpdater.updateNSEEntitlements(appGroupId);
158
+ if (props.appGroupName) {
159
+ await nseUpdater.updateNSEInfoPlistAppGroupKey(props.appGroupName);
160
+ }
145
161
  await nseUpdater.updateNSEBundleVersion(config.ios?.buildNumber ?? iosConstants_1.DEFAULT_BUNDLE_VERSION);
146
162
  await nseUpdater.updateNSEBundleShortVersion(config?.version ?? iosConstants_1.DEFAULT_BUNDLE_SHORT_VERSION);
147
163
  return config;
@@ -149,8 +165,9 @@ const withOneSignalNSE = (config, props) => {
149
165
  ]);
150
166
  };
151
167
  const withOneSignalXcodeProject = (config, props) => {
152
- return (0, config_plugins_1.withXcodeProject)(config, newConfig => {
168
+ return (0, config_plugins_1.withXcodeProject)(config, (newConfig) => {
153
169
  const xcodeProject = newConfig.modResults;
170
+ const nseBundleId = `${config.ios?.bundleIdentifier}.${props.nseBundleIdentifier ?? iosConstants_1.NSE_TARGET_NAME}`;
154
171
  if (xcodeProject.pbxTargetByName(iosConstants_1.NSE_TARGET_NAME)) {
155
172
  OneSignalLog_1.OneSignalLog.log(`${iosConstants_1.NSE_TARGET_NAME} already exists in project. Skipping...`);
156
173
  return newConfig;
@@ -159,9 +176,11 @@ const withOneSignalXcodeProject = (config, props) => {
159
176
  const extGroup = xcodeProject.addPbxGroup([...iosConstants_1.NSE_EXT_FILES, iosConstants_1.NSE_SOURCE_FILE], iosConstants_1.NSE_TARGET_NAME, iosConstants_1.NSE_TARGET_NAME);
160
177
  // Add the new PBXGroup to the top level group. This makes the
161
178
  // files / folder appear in the file explorer in Xcode.
162
- const groups = xcodeProject.hash.project.objects["PBXGroup"];
179
+ const groups = xcodeProject.hash.project.objects['PBXGroup'];
163
180
  Object.keys(groups).forEach(function (key) {
164
- if (typeof groups[key] === "object" && groups[key].name === undefined && groups[key].path === undefined) {
181
+ if (typeof groups[key] === 'object' &&
182
+ groups[key].name === undefined &&
183
+ groups[key].path === undefined) {
165
184
  xcodeProject.addToPbxGroup(extGroup.uuid, key);
166
185
  }
167
186
  });
@@ -170,38 +189,42 @@ const withOneSignalXcodeProject = (config, props) => {
170
189
  // An upstream fix should be made to the code referenced in this link:
171
190
  // - https://github.com/apache/cordova-node-xcode/blob/8b98cabc5978359db88dc9ff2d4c015cba40f150/lib/pbxProject.js#L860
172
191
  const projObjects = xcodeProject.hash.project.objects;
173
- projObjects['PBXTargetDependency'] = projObjects['PBXTargetDependency'] || {};
174
- projObjects['PBXContainerItemProxy'] = projObjects['PBXTargetDependency'] || {};
192
+ projObjects['PBXTargetDependency'] =
193
+ projObjects['PBXTargetDependency'] || {};
194
+ projObjects['PBXContainerItemProxy'] =
195
+ projObjects['PBXTargetDependency'] || {};
175
196
  // Add the NSE target
176
197
  // This adds PBXTargetDependency and PBXContainerItemProxy for you
177
- const nseTarget = xcodeProject.addTarget(iosConstants_1.NSE_TARGET_NAME, "app_extension", iosConstants_1.NSE_TARGET_NAME, `${config.ios?.bundleIdentifier}.${iosConstants_1.NSE_TARGET_NAME}`);
198
+ const nseTarget = xcodeProject.addTarget(iosConstants_1.NSE_TARGET_NAME, 'app_extension', iosConstants_1.NSE_TARGET_NAME, nseBundleId);
178
199
  // Add build phases to the new target
179
- xcodeProject.addBuildPhase(["NotificationService.m"], "PBXSourcesBuildPhase", "Sources", nseTarget.uuid);
180
- xcodeProject.addBuildPhase([], "PBXResourcesBuildPhase", "Resources", nseTarget.uuid);
181
- xcodeProject.addBuildPhase([], "PBXFrameworksBuildPhase", "Frameworks", nseTarget.uuid);
200
+ xcodeProject.addBuildPhase(['NotificationService.m'], 'PBXSourcesBuildPhase', 'Sources', nseTarget.uuid);
201
+ xcodeProject.addBuildPhase([], 'PBXResourcesBuildPhase', 'Resources', nseTarget.uuid);
202
+ xcodeProject.addBuildPhase([], 'PBXFrameworksBuildPhase', 'Frameworks', nseTarget.uuid);
182
203
  // Edit the Deployment info of the new Target, only IphoneOS and Targeted Device Family
183
204
  // However, can be more
184
205
  const configurations = xcodeProject.pbxXCBuildConfigurationSection();
185
206
  for (const key in configurations) {
186
- if (typeof configurations[key].buildSettings !== "undefined" &&
207
+ if (typeof configurations[key].buildSettings !== 'undefined' &&
187
208
  configurations[key].buildSettings.PRODUCT_NAME == `"${iosConstants_1.NSE_TARGET_NAME}"`) {
188
209
  const buildSettingsObj = configurations[key].buildSettings;
189
210
  buildSettingsObj.DEVELOPMENT_TEAM = props?.devTeam;
190
- buildSettingsObj.IPHONEOS_DEPLOYMENT_TARGET = props?.iPhoneDeploymentTarget ?? iosConstants_1.IPHONEOS_DEPLOYMENT_TARGET;
211
+ buildSettingsObj.IPHONEOS_DEPLOYMENT_TARGET =
212
+ props?.iPhoneDeploymentTarget ?? iosConstants_1.IPHONEOS_DEPLOYMENT_TARGET;
191
213
  buildSettingsObj.TARGETED_DEVICE_FAMILY = iosConstants_1.TARGETED_DEVICE_FAMILY;
192
214
  buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `${iosConstants_1.NSE_TARGET_NAME}/${iosConstants_1.NSE_TARGET_NAME}.entitlements`;
193
- buildSettingsObj.CODE_SIGN_STYLE = "Automatic";
215
+ buildSettingsObj.CODE_SIGN_STYLE = 'Automatic';
194
216
  }
195
217
  }
196
218
  // Add development teams to both your target and the original project
197
- xcodeProject.addTargetAttribute("DevelopmentTeam", props?.devTeam, nseTarget);
198
- xcodeProject.addTargetAttribute("DevelopmentTeam", props?.devTeam);
219
+ xcodeProject.addTargetAttribute('DevelopmentTeam', props?.devTeam, nseTarget);
220
+ xcodeProject.addTargetAttribute('DevelopmentTeam', props?.devTeam);
199
221
  return newConfig;
200
222
  });
201
223
  };
202
224
  const withOneSignalIos = (config, props) => {
203
225
  config = withAppEnvironment(config, props);
204
226
  config = withRemoteNotificationsPermissions(config, props);
227
+ config = withCustomAppGroupsKey(config, props);
205
228
  config = withAppGroupPermissions(config, props);
206
229
  config = withOneSignalPodfile(config, props);
207
230
  config = withOneSignalNSE(config, props);
@@ -2,11 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const FileManager_1 = require("./FileManager");
4
4
  const iosConstants_1 = require("./iosConstants");
5
- // project `ios/OneSignalNotificationServiceExtension` directory
6
- const entitlementsFileName = `OneSignalNotificationServiceExtension.entitlements`;
7
- const plistFileName = `OneSignalNotificationServiceExtension-Info.plist`;
5
+ const entitlementsFileName = `${iosConstants_1.NSE_TARGET_NAME}.entitlements`;
6
+ const plistFileName = `${iosConstants_1.NSE_TARGET_NAME}-Info.plist`;
8
7
  class NseUpdaterManager {
9
- nsePath = '';
8
+ nsePath;
10
9
  constructor(iosPath) {
11
10
  this.nsePath = `${iosPath}/${iosConstants_1.NSE_TARGET_NAME}`;
12
11
  }
@@ -28,5 +27,12 @@ class NseUpdaterManager {
28
27
  plistFile = plistFile.replace(iosConstants_1.BUNDLE_SHORT_VERSION_TEMPLATE_REGEX, version);
29
28
  await FileManager_1.FileManager.writeFile(plistFilePath, plistFile);
30
29
  }
30
+ async updateNSEInfoPlistAppGroupKey(appGroupName) {
31
+ const plistFilePath = `${this.nsePath}/${plistFileName}`;
32
+ let plistFile = await FileManager_1.FileManager.readFile(plistFilePath);
33
+ const appGroupEntry = `\t<key>OneSignal_app_groups_key</key>\n\t<string>${appGroupName}</string>\n</dict>\n</plist>`;
34
+ plistFile = plistFile.replace('</dict>\n</plist>', appGroupEntry);
35
+ await FileManager_1.FileManager.writeFile(plistFilePath, plistFile);
36
+ }
31
37
  }
32
38
  exports.default = NseUpdaterManager;
@@ -2,7 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.default = getEasManagedCredentialsConfigExtra;
4
4
  const iosConstants_1 = require("../iosConstants");
5
- function getEasManagedCredentialsConfigExtra(config) {
5
+ const helpers_1 = require("../helpers");
6
+ function getEasManagedCredentialsConfigExtra(config, appGroupName, nseBundleIdentifier) {
7
+ const bundleId = `${config?.ios?.bundleIdentifier}.${nseBundleIdentifier ?? iosConstants_1.NSE_TARGET_NAME}`;
6
8
  return {
7
9
  ...config.extra,
8
10
  eas: {
@@ -14,21 +16,21 @@ function getEasManagedCredentialsConfigExtra(config) {
14
16
  ios: {
15
17
  ...config.extra?.eas?.build?.experimental?.ios,
16
18
  appExtensions: [
17
- ...(config.extra?.eas?.build?.experimental?.ios?.appExtensions ?? []),
19
+ ...(config.extra?.eas?.build?.experimental?.ios?.appExtensions ??
20
+ []),
18
21
  {
19
- // keep in sync with native changes in NSE
20
22
  targetName: iosConstants_1.NSE_TARGET_NAME,
21
- bundleIdentifier: `${config?.ios?.bundleIdentifier}.${iosConstants_1.NSE_TARGET_NAME}`,
23
+ bundleIdentifier: bundleId,
22
24
  entitlements: {
23
25
  'com.apple.security.application-groups': [
24
- `group.${config?.ios?.bundleIdentifier}.onesignal`
25
- ]
26
+ (0, helpers_1.getAppGroupIdentifier)(config?.ios?.bundleIdentifier ?? '', appGroupName),
27
+ ],
26
28
  },
27
- }
28
- ]
29
- }
30
- }
31
- }
32
- }
29
+ },
30
+ ],
31
+ },
32
+ },
33
+ },
34
+ },
33
35
  };
34
36
  }
@@ -1,30 +1,40 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.validatePluginProps = validatePluginProps;
4
+ exports.getAppGroupIdentifier = getAppGroupIdentifier;
4
5
  const types_1 = require("../types/types");
5
6
  function validatePluginProps(props) {
6
7
  // check the type of each property
7
- if (typeof props.mode !== "string") {
8
+ if (typeof props.mode !== 'string') {
8
9
  throw new Error("OneSignal Expo Plugin: 'mode' must be a string.");
9
10
  }
10
- if (props.devTeam && typeof props.devTeam !== "string") {
11
+ if (props.devTeam && typeof props.devTeam !== 'string') {
11
12
  throw new Error("OneSignal Expo Plugin: 'devTeam' must be a string.");
12
13
  }
13
- if (props.iPhoneDeploymentTarget && typeof props.iPhoneDeploymentTarget !== "string") {
14
+ if (props.iPhoneDeploymentTarget &&
15
+ typeof props.iPhoneDeploymentTarget !== 'string') {
14
16
  throw new Error("OneSignal Expo Plugin: 'iPhoneDeploymentTarget' must be a string.");
15
17
  }
16
18
  if (props.smallIcons && !Array.isArray(props.smallIcons)) {
17
19
  throw new Error("OneSignal Expo Plugin: 'smallIcons' must be an array.");
18
20
  }
19
- if (props.smallIconAccentColor && typeof props.smallIconAccentColor !== "string") {
21
+ if (props.smallIconAccentColor &&
22
+ typeof props.smallIconAccentColor !== 'string') {
20
23
  throw new Error("OneSignal Expo Plugin: 'smallIconAccentColor' must be a string.");
21
24
  }
22
25
  if (props.largeIcons && !Array.isArray(props.largeIcons)) {
23
26
  throw new Error("OneSignal Expo Plugin: 'largeIcons' must be an array.");
24
27
  }
25
- if (props.iosNSEFilePath && typeof props.iosNSEFilePath !== "string") {
28
+ if (props.iosNSEFilePath && typeof props.iosNSEFilePath !== 'string') {
26
29
  throw new Error("OneSignal Expo Plugin: 'iosNSEFilePath' must be a string.");
27
30
  }
31
+ if (props.appGroupName && typeof props.appGroupName !== 'string') {
32
+ throw new Error("OneSignal Expo Plugin: 'appGroupName' must be a string.");
33
+ }
34
+ if (props.nseBundleIdentifier &&
35
+ typeof props.nseBundleIdentifier !== 'string') {
36
+ throw new Error("OneSignal Expo Plugin: 'nseBundleIdentifier' must be a string.");
37
+ }
28
38
  // check for extra properties
29
39
  const inputProps = Object.keys(props);
30
40
  for (const prop of inputProps) {
@@ -33,3 +43,6 @@ function validatePluginProps(props) {
33
43
  }
34
44
  }
35
45
  }
46
+ function getAppGroupIdentifier(bundleIdentifier, customAppGroupName) {
47
+ return customAppGroupName ?? `group.${bundleIdentifier}.onesignal`;
48
+ }
@@ -1,23 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.NSE_EXT_FILES = exports.NSE_SOURCE_FILE = exports.NSE_TARGET_NAME = exports.DEFAULT_BUNDLE_SHORT_VERSION = exports.DEFAULT_BUNDLE_VERSION = exports.BUNDLE_VERSION_TEMPLATE_REGEX = exports.BUNDLE_SHORT_VERSION_TEMPLATE_REGEX = exports.GROUP_IDENTIFIER_TEMPLATE_REGEX = exports.NSE_PODFILE_REGEX = exports.NSE_PODFILE_SNIPPET = exports.TARGETED_DEVICE_FAMILY = exports.IPHONEOS_DEPLOYMENT_TARGET = void 0;
4
- exports.IPHONEOS_DEPLOYMENT_TARGET = "11.0";
3
+ exports.NSE_EXT_FILES = exports.NSE_PODFILE_REGEX = exports.NSE_PODFILE_SNIPPET = exports.NSE_SOURCE_FILE = exports.NSE_TARGET_NAME = exports.DEFAULT_BUNDLE_SHORT_VERSION = exports.DEFAULT_BUNDLE_VERSION = exports.BUNDLE_VERSION_TEMPLATE_REGEX = exports.BUNDLE_SHORT_VERSION_TEMPLATE_REGEX = exports.GROUP_IDENTIFIER_TEMPLATE_REGEX = exports.TARGETED_DEVICE_FAMILY = exports.IPHONEOS_DEPLOYMENT_TARGET = void 0;
4
+ exports.IPHONEOS_DEPLOYMENT_TARGET = '11.0';
5
5
  exports.TARGETED_DEVICE_FAMILY = `"1,2"`;
6
- exports.NSE_PODFILE_SNIPPET = `
7
- target 'OneSignalNotificationServiceExtension' do
8
- pod 'OneSignalXCFramework', '>= 5.0', '< 6.0'
9
- use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks']
10
- end`;
11
- exports.NSE_PODFILE_REGEX = /target 'OneSignalNotificationServiceExtension'/;
12
6
  exports.GROUP_IDENTIFIER_TEMPLATE_REGEX = /{{GROUP_IDENTIFIER}}/gm;
13
7
  exports.BUNDLE_SHORT_VERSION_TEMPLATE_REGEX = /{{BUNDLE_SHORT_VERSION}}/gm;
14
8
  exports.BUNDLE_VERSION_TEMPLATE_REGEX = /{{BUNDLE_VERSION}}/gm;
15
9
  exports.DEFAULT_BUNDLE_VERSION = '1';
16
10
  exports.DEFAULT_BUNDLE_SHORT_VERSION = '1.0';
17
- exports.NSE_TARGET_NAME = "OneSignalNotificationServiceExtension";
18
- exports.NSE_SOURCE_FILE = "NotificationService.m";
11
+ exports.NSE_TARGET_NAME = 'OneSignalNotificationServiceExtension';
12
+ exports.NSE_SOURCE_FILE = 'NotificationService.m';
13
+ exports.NSE_PODFILE_SNIPPET = `
14
+ target '${exports.NSE_TARGET_NAME}' do
15
+ pod 'OneSignalXCFramework', '>= 5.0', '< 6.0'
16
+ use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks']
17
+ end`;
18
+ exports.NSE_PODFILE_REGEX = new RegExp(`target '${exports.NSE_TARGET_NAME}'`);
19
19
  exports.NSE_EXT_FILES = [
20
- "NotificationService.h",
20
+ 'NotificationService.h',
21
21
  `${exports.NSE_TARGET_NAME}.entitlements`,
22
- `${exports.NSE_TARGET_NAME}-Info.plist`
22
+ `${exports.NSE_TARGET_NAME}-Info.plist`,
23
23
  ];
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.updatePodfile = updatePodfile;
7
- const fs_1 = __importDefault(require("fs"));
7
+ const promises_1 = __importDefault(require("fs/promises"));
8
8
  const iosConstants_1 = require("./iosConstants");
9
9
  const OneSignalLog_1 = require("./OneSignalLog");
10
10
  const FileManager_1 = require("./FileManager");
@@ -12,13 +12,9 @@ async function updatePodfile(iosPath) {
12
12
  const podfile = await FileManager_1.FileManager.readFile(`${iosPath}/Podfile`);
13
13
  const matches = podfile.match(iosConstants_1.NSE_PODFILE_REGEX);
14
14
  if (matches) {
15
- OneSignalLog_1.OneSignalLog.log("OneSignalNotificationServiceExtension target already added to Podfile. Skipping...");
16
- }
17
- else {
18
- fs_1.default.appendFile(`${iosPath}/Podfile`, iosConstants_1.NSE_PODFILE_SNIPPET, (err) => {
19
- if (err) {
20
- OneSignalLog_1.OneSignalLog.error("Error writing to Podfile");
21
- }
22
- });
15
+ OneSignalLog_1.OneSignalLog.log(`${iosConstants_1.NSE_TARGET_NAME} target already added to Podfile. Skipping...`);
16
+ return;
23
17
  }
18
+ await promises_1.default.appendFile(`${iosPath}/Podfile`, iosConstants_1.NSE_PODFILE_SNIPPET);
19
+ OneSignalLog_1.OneSignalLog.log(`${iosConstants_1.NSE_TARGET_NAME} target added to Podfile.`);
24
20
  }
@@ -2,13 +2,15 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Mode = exports.ONESIGNAL_PLUGIN_PROPS = void 0;
4
4
  exports.ONESIGNAL_PLUGIN_PROPS = [
5
- "mode",
6
- "devTeam",
7
- "iPhoneDeploymentTarget",
8
- "smallIcons",
9
- "largeIcons",
10
- "iosNSEFilePath",
11
- "smallIconAccentColor"
5
+ 'mode',
6
+ 'devTeam',
7
+ 'iPhoneDeploymentTarget',
8
+ 'smallIcons',
9
+ 'largeIcons',
10
+ 'iosNSEFilePath',
11
+ 'smallIconAccentColor',
12
+ 'appGroupName',
13
+ 'nseBundleIdentifier',
12
14
  ];
13
15
  var Mode;
14
16
  (function (Mode) {
package/package.json CHANGED
@@ -1,17 +1,20 @@
1
1
  {
2
2
  "name": "onesignal-expo-plugin",
3
- "version": "2.0.4",
4
- "description": "The OneSignal Expo plugin allows you to use OneSignal without leaving the managed workflow. Developed in collaboration with SweetGreen.",
3
+ "version": "2.2.0",
4
+ "description": "Some Changez",
5
5
  "main": "./app.plugin.js",
6
6
  "files": [
7
7
  "build",
8
8
  "app.plugin.js"
9
9
  ],
10
10
  "scripts": {
11
- "test": "echo \"Error: no test specified\" && exit 1",
11
+ "test": "bun test",
12
+ "test:coverage": "bun test --coverage",
12
13
  "build": "bun run lint && rm -rf build && tsc && cp -a src/support/serviceExtensionFiles build/support/",
13
- "lint": "oxlint src examples",
14
- "lint:fix": "oxlint src examples --fix"
14
+ "format:check": "prettier --check \"**/*.{ts,tsx}\" --ignore-path .prettierignore",
15
+ "format:fix": "prettier --write \"**/*.{ts,tsx}\" --ignore-path .prettierignore",
16
+ "lint": "oxlint src examples && bun run format:check",
17
+ "lint:fix": "oxlint src examples --fix && bun run format:fix"
15
18
  },
16
19
  "repository": {
17
20
  "type": "git",
@@ -38,10 +41,15 @@
38
41
  },
39
42
  "homepage": "https://github.com/OneSignal/onesignal-expo-plugin#readme",
40
43
  "devDependencies": {
44
+ "@types/bun": "^1.3.9",
41
45
  "expo-module-scripts": "^5.0.8",
42
46
  "oxlint": "^1.43.0",
47
+ "prettier": "^3.8.1",
43
48
  "typescript": "^5.9.3"
44
49
  },
50
+ "peerDependencies": {
51
+ "react-native-onesignal": ">=5.0.0"
52
+ },
45
53
  "dependencies": {
46
54
  "@expo/image-utils": "^0.8.8"
47
55
  }