customerio-expo-plugin 3.5.0 → 3.5.2
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/package.json +1 -1
- package/plugin/lib/commonjs/helpers/constants/ios.js +13 -18
- package/plugin/lib/commonjs/helpers/constants/ios.js.map +1 -1
- package/plugin/lib/commonjs/helpers/utils/injectCIOPodfileCode.js +6 -2
- package/plugin/lib/commonjs/helpers/utils/injectCIOPodfileCode.js.map +1 -1
- package/plugin/lib/commonjs/ios/withNotificationsXcodeProject.js +1 -1
- package/plugin/lib/commonjs/ios/withNotificationsXcodeProject.js.map +1 -1
- package/plugin/lib/commonjs/utils/logger.js +15 -3
- package/plugin/lib/commonjs/utils/logger.js.map +1 -1
- package/plugin/lib/module/helpers/constants/ios.js +13 -18
- package/plugin/lib/module/helpers/constants/ios.js.map +1 -1
- package/plugin/lib/module/helpers/utils/injectCIOPodfileCode.js +6 -2
- package/plugin/lib/module/helpers/utils/injectCIOPodfileCode.js.map +1 -1
- package/plugin/lib/module/ios/withNotificationsXcodeProject.js +1 -1
- package/plugin/lib/module/ios/withNotificationsXcodeProject.js.map +1 -1
- package/plugin/lib/module/utils/logger.js +16 -3
- package/plugin/lib/module/utils/logger.js.map +1 -1
- package/plugin/lib/typescript/helpers/constants/ios.d.ts +5 -3
- package/plugin/src/helpers/constants/ios.ts +13 -19
- package/plugin/src/helpers/utils/injectCIOPodfileCode.ts +6 -2
- package/plugin/src/ios/withNotificationsXcodeProject.ts +1 -1
- package/plugin/src/utils/logger.ts +16 -3
package/package.json
CHANGED
|
@@ -8,6 +8,7 @@ exports.getRelativePathToRNSDK = getRelativePathToRNSDK;
|
|
|
8
8
|
var _fs = _interopRequireDefault(require("fs"));
|
|
9
9
|
var semver = _interopRequireWildcard(require("semver"));
|
|
10
10
|
var _resolveRNSDK = require("../../utils/resolveRNSDK");
|
|
11
|
+
var _logger = require("../../utils/logger");
|
|
11
12
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
12
13
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
14
|
const path = require('path');
|
|
@@ -17,14 +18,6 @@ const path = require('path');
|
|
|
17
18
|
// :path strings on pnpm/yarn-symlink layouts, so to keep CocoaPods happy
|
|
18
19
|
// we must match whichever flavor will resolve the same package later.
|
|
19
20
|
const RN_REALPATH_AUTOLINKING_MIN_VERSION = '0.80.0';
|
|
20
|
-
const PLUGIN_LOG_PREFIX = '[CustomerIO Plugin]';
|
|
21
|
-
|
|
22
|
-
// Always-on so the trail shows up in customer-shared `expo prebuild`
|
|
23
|
-
// output without needing a separate verbose-mode opt-in.
|
|
24
|
-
function pluginLog(message) {
|
|
25
|
-
// eslint-disable-next-line no-console
|
|
26
|
-
console.log(`${PLUGIN_LOG_PREFIX} ${message}`);
|
|
27
|
-
}
|
|
28
21
|
|
|
29
22
|
/**
|
|
30
23
|
* Returns the relative path from the iOS project dir to the installed
|
|
@@ -40,21 +33,23 @@ function pluginLog(message) {
|
|
|
40
33
|
* via Node, emitting the underlying `.pnpm/...` (or yarn-classic)
|
|
41
34
|
* path. We match by realpath'ing the resolved directory.
|
|
42
35
|
*
|
|
43
|
-
* Decision points are logged
|
|
44
|
-
*
|
|
45
|
-
*
|
|
36
|
+
* Decision points are logged through the shared logger, gated by
|
|
37
|
+
* CUSTOMERIO_DEBUG_MODE. Defaulting to silent keeps the prebuild output
|
|
38
|
+
* clean for hosts that parse it (Expo's `--json` config, EAS build
|
|
39
|
+
* tooling), while still giving support a "rerun with this flag" path
|
|
40
|
+
* for triaging path-resolution issues.
|
|
46
41
|
*/
|
|
47
42
|
function getRelativePathToRNSDK(iosPath) {
|
|
48
43
|
const rootAppPath = path.dirname(iosPath);
|
|
49
|
-
|
|
44
|
+
_logger.logger.info(`Resolving customerio-reactnative for Podfile (iosPath=${iosPath}, projectRoot=${rootAppPath})`);
|
|
50
45
|
const {
|
|
51
46
|
packageDir
|
|
52
47
|
} = (0, _resolveRNSDK.resolveRNSDK)(rootAppPath);
|
|
53
|
-
|
|
48
|
+
_logger.logger.info(`customerio-reactnative resolved to: ${packageDir}`);
|
|
54
49
|
const rnVersion = (0, _resolveRNSDK.tryReadRNVersion)(rootAppPath);
|
|
55
|
-
|
|
50
|
+
_logger.logger.info(`Detected react-native version: ${rnVersion ?? 'unknown'}`);
|
|
56
51
|
const useLexical = shouldUseLexicalPath(rnVersion);
|
|
57
|
-
|
|
52
|
+
_logger.logger.info(useLexical ? `RN <${RN_REALPATH_AUTOLINKING_MIN_VERSION} — using lexical/symlink path to match @react-native-community/cli autolinking` : `RN >=${RN_REALPATH_AUTOLINKING_MIN_VERSION} or unknown — using realpath to match expo-modules-autolinking`);
|
|
58
53
|
let absolutePath;
|
|
59
54
|
if (useLexical) {
|
|
60
55
|
absolutePath = packageDir;
|
|
@@ -62,15 +57,15 @@ function getRelativePathToRNSDK(iosPath) {
|
|
|
62
57
|
try {
|
|
63
58
|
absolutePath = _fs.default.realpathSync(packageDir);
|
|
64
59
|
if (absolutePath !== packageDir) {
|
|
65
|
-
|
|
60
|
+
_logger.logger.info(`Realpath differs from resolved dir: ${absolutePath}`);
|
|
66
61
|
}
|
|
67
62
|
} catch (err) {
|
|
68
|
-
|
|
63
|
+
_logger.logger.warn(`realpathSync failed (${err instanceof Error ? err.message : String(err)}); falling back to symlink path`);
|
|
69
64
|
absolutePath = packageDir;
|
|
70
65
|
}
|
|
71
66
|
}
|
|
72
67
|
const relativePath = path.relative(iosPath, absolutePath);
|
|
73
|
-
|
|
68
|
+
_logger.logger.info(`Final Podfile :path => '${relativePath}'`);
|
|
74
69
|
return relativePath;
|
|
75
70
|
}
|
|
76
71
|
function shouldUseLexicalPath(rnVersion) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_fs","_interopRequireDefault","require","semver","_interopRequireWildcard","_resolveRNSDK","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","path","RN_REALPATH_AUTOLINKING_MIN_VERSION","PLUGIN_LOG_PREFIX","pluginLog","message","console","log","getRelativePathToRNSDK","iosPath","rootAppPath","dirname","packageDir","resolveRNSDK","rnVersion","tryReadRNVersion","useLexical","shouldUseLexicalPath","absolutePath","fs","realpathSync","err","Error","String","relativePath","relative","coerced","valid","coerce","lt","IOS_DEPLOYMENT_TARGET","exports","GROUP_IDENTIFIER_TEMPLATE_REGEX","BUNDLE_SHORT_VERSION_TEMPLATE_REGEX","BUNDLE_VERSION_TEMPLATE_REGEX","CIO_DIDFINISHLAUNCHINGMETHOD_REGEX","CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_REGEX","CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERRORFULL_REGEX","CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_REGEX","CIO_APPDELEGATEDECLARATION_REGEX","CIO_APPDELEGATEHEADER_REGEX","CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_REGEX","CIO_LAUNCHOPTIONS_DEEPLINK_MODIFIEDOPTIONS_REGEX","CIO_DEEPLINK_COMMENT_REGEX","DEFAULT_BUNDLE_VERSION","DEFAULT_BUNDLE_SHORT_VERSION","CIO_TARGET_NAME","CIO_NOTIFICATION_TARGET_NAME","CIO_APPDELEGATEHEADER_IMPORT_SNIPPET","CIO_APPDELEGATEHEADER_USER_NOTIFICATION_CENTER_SNIPPET","CIO_PUSHNOTIFICATIONHANDLERDECLARATION_SNIPPET","CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_SNIPPET","CIO_LAUNCHOPTIONS_MODIFIEDOPTIONS_SNIPPET","CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_SNIPPET","CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_SNIPPET","CIO_CONFIGURECIOSDKPUSHNOTIFICATION_SNIPPET","CIO_INITIALIZECIOSDK_SNIPPET","CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SNIPPET","CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SWIFT_SNIPPET","CIO_REGISTER_PUSHNOTIFICATION_SNIPPET","CIO_REGISTER_PUSHNOTIFICATION_SNIPPET_v2","CIO_REGISTER_PUSH_NOTIFICATION_PLACEHOLDER","CIO_MESSAGING_PUSH_APP_DELEGATE_INIT_REGEX","CIO_NATIVE_SDK_INITIALIZE_CALL","CIO_NATIVE_SDK_INITIALIZE_SNIPPET"],"sources":["ios.ts"],"sourcesContent":["import fs from 'fs';\nimport * as semver from 'semver';\n\nconst path = require('path');\nimport { resolveRNSDK, tryReadRNVersion } from '../../utils/resolveRNSDK';\n\n// Threshold at which React Native pod autolinking moves from\n// @react-native-community/cli (lexical, symlink-preserving) to\n// expo-modules-autolinking (realpath). The two flavors emit different\n// :path strings on pnpm/yarn-symlink layouts, so to keep CocoaPods happy\n// we must match whichever flavor will resolve the same package later.\nconst RN_REALPATH_AUTOLINKING_MIN_VERSION = '0.80.0';\n\nconst PLUGIN_LOG_PREFIX = '[CustomerIO Plugin]';\n\n// Always-on so the trail shows up in customer-shared `expo prebuild`\n// output without needing a separate verbose-mode opt-in.\nfunction pluginLog(message: string): void {\n // eslint-disable-next-line no-console\n console.log(`${PLUGIN_LOG_PREFIX} ${message}`);\n}\n\n/**\n * Returns the relative path from the iOS project dir to the installed\n * customerio-reactnative directory, in the exact form React Native pod\n * autolinking will emit for the same package. The two autolinking\n * flavors disagree on path shape under pnpm/yarn symlinks:\n *\n * - RN <0.80 (`@react-native-community/cli`): walks node_modules\n * lexically, preserves symlinks. We keep the symlink path too —\n * `tryResolveRNSDK` already does this without calling realpath.\n *\n * - RN >=0.80 (`expo-modules-autolinking`): realpaths the package\n * via Node, emitting the underlying `.pnpm/...` (or yarn-classic)\n * path. We match by realpath'ing the resolved directory.\n *\n * Decision points are logged so a customer's prebuild output is enough\n * to triage path-resolution issues without a follow-up \"set\n * CUSTOMERIO_DEBUG_MODE and rerun\" round-trip.\n */\nexport function getRelativePathToRNSDK(iosPath: string) {\n const rootAppPath = path.dirname(iosPath);\n pluginLog(\n `Resolving customerio-reactnative for Podfile (iosPath=${iosPath}, projectRoot=${rootAppPath})`\n );\n\n const { packageDir } = resolveRNSDK(rootAppPath);\n pluginLog(`customerio-reactnative resolved to: ${packageDir}`);\n\n const rnVersion = tryReadRNVersion(rootAppPath);\n pluginLog(`Detected react-native version: ${rnVersion ?? 'unknown'}`);\n\n const useLexical = shouldUseLexicalPath(rnVersion);\n pluginLog(\n useLexical\n ? `RN <${RN_REALPATH_AUTOLINKING_MIN_VERSION} — using lexical/symlink path to match @react-native-community/cli autolinking`\n : `RN >=${RN_REALPATH_AUTOLINKING_MIN_VERSION} or unknown — using realpath to match expo-modules-autolinking`\n );\n\n let absolutePath: string;\n if (useLexical) {\n absolutePath = packageDir;\n } else {\n try {\n absolutePath = fs.realpathSync(packageDir);\n if (absolutePath !== packageDir) {\n pluginLog(`Realpath differs from resolved dir: ${absolutePath}`);\n }\n } catch (err) {\n pluginLog(\n `realpathSync failed (${\n err instanceof Error ? err.message : String(err)\n }); falling back to symlink path`\n );\n absolutePath = packageDir;\n }\n }\n\n const relativePath = path.relative(iosPath, absolutePath);\n pluginLog(`Final Podfile :path => '${relativePath}'`);\n return relativePath;\n}\n\nfunction shouldUseLexicalPath(rnVersion: string | null): boolean {\n if (!rnVersion) {\n // Modern Expo (realpath) has been the working path for the last few\n // SDKs, so it's the safer default when RN can't be detected.\n return false;\n }\n const coerced = semver.valid(rnVersion) || semver.coerce(rnVersion);\n if (!coerced) {\n return false;\n }\n return semver.lt(coerced, RN_REALPATH_AUTOLINKING_MIN_VERSION);\n}\n\nexport const IOS_DEPLOYMENT_TARGET = '13.0';\nexport const GROUP_IDENTIFIER_TEMPLATE_REGEX = /{{GROUP_IDENTIFIER}}/gm;\nexport const BUNDLE_SHORT_VERSION_TEMPLATE_REGEX = /{{BUNDLE_SHORT_VERSION}}/gm;\nexport const BUNDLE_VERSION_TEMPLATE_REGEX = /{{BUNDLE_VERSION}}/gm;\nexport const CIO_DIDFINISHLAUNCHINGMETHOD_REGEX =\n /.*\\[super(\\s)application:application(\\s)didFinishLaunchingWithOptions:launchOptions\\];/;\n\nexport const CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_REGEX =\n /return \\[super application:application didFailToRegisterForRemoteNotificationsWithError:error\\];/;\n\nexport const CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERRORFULL_REGEX =\n /(- \\(void\\)application:\\(UIApplication \\*\\)application didFailToRegisterForRemoteNotificationsWithError:\\(NSError \\*\\)error(\\s|\\n)*?\\{)(.|\\n){2}.*\\n\\}/;\n\nexport const CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_REGEX =\n /return \\[super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken\\];/;\n\nexport const CIO_APPDELEGATEDECLARATION_REGEX =\n /@implementation AppDelegate(.|\\n)/;\n\nexport const CIO_APPDELEGATEHEADER_REGEX =\n /(@interface AppDelegate\\s*:\\s*EXAppDelegateWrapper\\s*)(<([^>]+)>)?/;\n\nexport const CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_REGEX =\n /^\\s*RCTBridge\\s*\\*\\s*\\w+\\s*=\\s*\\[\\s*self\\.reactDelegate\\s+createBridgeWithDelegate:self\\s+launchOptions:launchOptions\\s*\\];\\s*$/gm;\n\nexport const CIO_LAUNCHOPTIONS_DEEPLINK_MODIFIEDOPTIONS_REGEX =\n /^\\s*return\\s\\[\\s*super\\s*application:\\s*application\\s*didFinishLaunchingWithOptions\\s*:\\s*launchOptions\\s*\\];/gm;\n\nexport const CIO_DEEPLINK_COMMENT_REGEX =\n /\\sDeep link workaround for app killed state start/gm;\nexport const DEFAULT_BUNDLE_VERSION = '1';\nexport const DEFAULT_BUNDLE_SHORT_VERSION = '1.0';\nexport const CIO_TARGET_NAME = 'CustomerIOSDK';\nexport const CIO_NOTIFICATION_TARGET_NAME = 'NotificationService';\n\nexport const CIO_APPDELEGATEHEADER_IMPORT_SNIPPET = `#import <UserNotifications/UserNotifications.h>`;\nexport const CIO_APPDELEGATEHEADER_USER_NOTIFICATION_CENTER_SNIPPET =\n 'UNUserNotificationCenterDelegate';\nexport const CIO_PUSHNOTIFICATIONHANDLERDECLARATION_SNIPPET = `\nCIOAppPushNotificationsHandler* pnHandlerObj = [[CIOAppPushNotificationsHandler alloc] init];\n`;\nexport const CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_SNIPPET = `\nRCTBridge *bridge = [self.reactDelegate createBridgeWithDelegate:self launchOptions:modifiedLaunchOptions];\n`;\n\nexport const CIO_LAUNCHOPTIONS_MODIFIEDOPTIONS_SNIPPET = `\nreturn [super application:application didFinishLaunchingWithOptions:modifiedLaunchOptions];`;\n\nexport const CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_SNIPPET = `\n [super application:application didFailToRegisterForRemoteNotificationsWithError:error];\n [pnHandlerObj application:application error:error];\n`;\n\nexport const CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_SNIPPET = `\n [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];\n return [pnHandlerObj application:application deviceToken:deviceToken];\n`;\n\nexport const CIO_CONFIGURECIOSDKPUSHNOTIFICATION_SNIPPET = `\n // Register for push notifications\n [pnHandlerObj registerPushNotification];\n`;\n\nexport const CIO_INITIALIZECIOSDK_SNIPPET = ` \n [pnHandlerObj initializeCioSdk];\n\n// Code to make the CIO SDK compatible with expo-notifications package.\n// \n// The CIO SDK and expo-notifications both need to handle when a push gets clicked. However, iOS only allows one click handler to be set per app.\n// To get around this limitation, we set the CIO SDK as the click handler. The CIO SDK sets itself up so that when another SDK or host iOS app \n// sets itself as the click handler, the CIO SDK will still be able to handle when the push gets clicked, even though it's not the designated \n// click handler in iOS at runtime. \n// \n// This should work for most SDKs. However, expo-notifications is unique in it's implementation. It will not setup push click handling it if detects \n// that another SDK or host iOS app has already set itself as the click handler:\n// https://github.com/expo/expo/blob/1b29637bec0b9888e8bc8c310476293a3e2d9786/packages/expo-notifications/ios/EXNotifications/Notifications/EXNotificationCenterDelegate.m#L31-L37\n// ...to get around this, we must manually set it as the click handler after the CIO SDK. That's what this code block does.\n//\n// Note: Initialize the native iOS SDK and setup SDK push click handling before running this code. \n# if __has_include(<EXNotifications/EXNotificationCenterDelegate.h>)\n // Creating a new instance, as the comments in expo-notifications suggests, does not work. With this code, if you send a CIO push to device and click on it,\n // no push metrics reporting will occur.\n // EXNotificationCenterDelegate *notificationCenterDelegate = [[EXNotificationCenterDelegate alloc] init];\n\n // ...instead, get the singleton reference from Expo. \n id<UNUserNotificationCenterDelegate> notificationCenterDelegate = (id<UNUserNotificationCenterDelegate>) [EXModuleRegistryProvider getSingletonModuleForClass:[EXNotificationCenterDelegate class]];\n UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];\n center.delegate = notificationCenterDelegate;\n# endif\n`;\n\nexport const CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SNIPPET = `\n// Deep link workaround for app killed state start\nNSMutableDictionary *modifiedLaunchOptions = [NSMutableDictionary dictionaryWithDictionary:launchOptions];\n if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) {\n NSDictionary *pushContent = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];\n if (pushContent[@\"CIO\"] && pushContent[@\"CIO\"][@\"push\"] && pushContent[@\"CIO\"][@\"push\"][@\"link\"]) {\n NSString *initialURL = pushContent[@\"CIO\"][@\"push\"][@\"link\"];\n if (!launchOptions[UIApplicationLaunchOptionsURLKey]) {\n modifiedLaunchOptions[UIApplicationLaunchOptionsURLKey] = [NSURL URLWithString:initialURL];\n }\n }\n }\n//Deep link workaround for app killed state ends\n`;\n\nexport const CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SWIFT_SNIPPET = `\n // Deep link workaround for app killed state start\n var modifiedLaunchOptions = launchOptions\n if let launchOptions = launchOptions,\n let pushContent = launchOptions[UIApplication.LaunchOptionsKey.remoteNotification] as? [AnyHashable: Any],\n let cio = pushContent[\"CIO\"] as? [String: Any],\n let push = cio[\"push\"] as? [String: Any],\n let link = push[\"link\"] as? String,\n !launchOptions.keys.contains(UIApplication.LaunchOptionsKey.url) {\n \n var mutableLaunchOptions = launchOptions\n mutableLaunchOptions[UIApplication.LaunchOptionsKey.url] = URL(string: link)\n modifiedLaunchOptions = mutableLaunchOptions\n }\n // Deep link workaround for app killed state ends\n`;\n\nexport const CIO_REGISTER_PUSHNOTIFICATION_SNIPPET = `\n@objc(registerPushNotification)\n public func registerPushNotification() {\n\n let center = UNUserNotificationCenter.current()\n center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in\n if error == nil{\n DispatchQueue.main.async {\n UIApplication.shared.registerForRemoteNotifications()\n }\n }\n }\n }`;\n\nexport const CIO_REGISTER_PUSHNOTIFICATION_SNIPPET_v2 = `\n let center = UNUserNotificationCenter.current()\n center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in\n if error == nil{\n DispatchQueue.main.async {\n UIApplication.shared.registerForRemoteNotifications()\n }\n }\n }`;\n\nexport const CIO_REGISTER_PUSH_NOTIFICATION_PLACEHOLDER = /\\{\\{REGISTER_SNIPPET\\}\\}/;\n// Regex to match MessagingPush initialization in AppDelegate (different from NSE initialization)\nexport const CIO_MESSAGING_PUSH_APP_DELEGATE_INIT_REGEX = /(MessagingPush(?:APN|FCM)\\.initialize)/;\nexport const CIO_NATIVE_SDK_INITIALIZE_CALL = 'CustomerIOSDKInitializer.initialize()';\nexport const CIO_NATIVE_SDK_INITIALIZE_SNIPPET = `// Auto Initialize Native Customer.io SDK\n ${CIO_NATIVE_SDK_INITIALIZE_CALL}\n `;\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["_fs","_interopRequireDefault","require","semver","_interopRequireWildcard","_resolveRNSDK","_logger","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","path","RN_REALPATH_AUTOLINKING_MIN_VERSION","getRelativePathToRNSDK","iosPath","rootAppPath","dirname","logger","info","packageDir","resolveRNSDK","rnVersion","tryReadRNVersion","useLexical","shouldUseLexicalPath","absolutePath","fs","realpathSync","err","warn","Error","message","String","relativePath","relative","coerced","valid","coerce","lt","IOS_DEPLOYMENT_TARGET","exports","GROUP_IDENTIFIER_TEMPLATE_REGEX","BUNDLE_SHORT_VERSION_TEMPLATE_REGEX","BUNDLE_VERSION_TEMPLATE_REGEX","CIO_DIDFINISHLAUNCHINGMETHOD_REGEX","CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_REGEX","CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERRORFULL_REGEX","CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_REGEX","CIO_APPDELEGATEDECLARATION_REGEX","CIO_APPDELEGATEHEADER_REGEX","CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_REGEX","CIO_LAUNCHOPTIONS_DEEPLINK_MODIFIEDOPTIONS_REGEX","CIO_DEEPLINK_COMMENT_REGEX","DEFAULT_BUNDLE_VERSION","DEFAULT_BUNDLE_SHORT_VERSION","CIO_TARGET_NAME","CIO_NOTIFICATION_TARGET_NAME","CIO_APPDELEGATEHEADER_IMPORT_SNIPPET","CIO_APPDELEGATEHEADER_USER_NOTIFICATION_CENTER_SNIPPET","CIO_PUSHNOTIFICATIONHANDLERDECLARATION_SNIPPET","CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_SNIPPET","CIO_LAUNCHOPTIONS_MODIFIEDOPTIONS_SNIPPET","CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_SNIPPET","CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_SNIPPET","CIO_CONFIGURECIOSDKPUSHNOTIFICATION_SNIPPET","CIO_INITIALIZECIOSDK_SNIPPET","CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SNIPPET","CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SWIFT_SNIPPET","CIO_REGISTER_PUSHNOTIFICATION_SNIPPET","CIO_REGISTER_PUSHNOTIFICATION_SNIPPET_v2","CIO_REGISTER_PUSH_NOTIFICATION_PLACEHOLDER","CIO_MESSAGING_PUSH_APP_DELEGATE_INIT_REGEX","CIO_NATIVE_SDK_INITIALIZE_CALL","CIO_NATIVE_SDK_INITIALIZE_SNIPPET"],"sources":["ios.ts"],"sourcesContent":["import fs from 'fs';\nimport * as semver from 'semver';\n\nconst path = require('path');\nimport { resolveRNSDK, tryReadRNVersion } from '../../utils/resolveRNSDK';\nimport { logger } from '../../utils/logger';\n\n// Threshold at which React Native pod autolinking moves from\n// @react-native-community/cli (lexical, symlink-preserving) to\n// expo-modules-autolinking (realpath). The two flavors emit different\n// :path strings on pnpm/yarn-symlink layouts, so to keep CocoaPods happy\n// we must match whichever flavor will resolve the same package later.\nconst RN_REALPATH_AUTOLINKING_MIN_VERSION = '0.80.0';\n\n/**\n * Returns the relative path from the iOS project dir to the installed\n * customerio-reactnative directory, in the exact form React Native pod\n * autolinking will emit for the same package. The two autolinking\n * flavors disagree on path shape under pnpm/yarn symlinks:\n *\n * - RN <0.80 (`@react-native-community/cli`): walks node_modules\n * lexically, preserves symlinks. We keep the symlink path too —\n * `tryResolveRNSDK` already does this without calling realpath.\n *\n * - RN >=0.80 (`expo-modules-autolinking`): realpaths the package\n * via Node, emitting the underlying `.pnpm/...` (or yarn-classic)\n * path. We match by realpath'ing the resolved directory.\n *\n * Decision points are logged through the shared logger, gated by\n * CUSTOMERIO_DEBUG_MODE. Defaulting to silent keeps the prebuild output\n * clean for hosts that parse it (Expo's `--json` config, EAS build\n * tooling), while still giving support a \"rerun with this flag\" path\n * for triaging path-resolution issues.\n */\nexport function getRelativePathToRNSDK(iosPath: string) {\n const rootAppPath = path.dirname(iosPath);\n logger.info(\n `Resolving customerio-reactnative for Podfile (iosPath=${iosPath}, projectRoot=${rootAppPath})`\n );\n\n const { packageDir } = resolveRNSDK(rootAppPath);\n logger.info(`customerio-reactnative resolved to: ${packageDir}`);\n\n const rnVersion = tryReadRNVersion(rootAppPath);\n logger.info(`Detected react-native version: ${rnVersion ?? 'unknown'}`);\n\n const useLexical = shouldUseLexicalPath(rnVersion);\n logger.info(\n useLexical\n ? `RN <${RN_REALPATH_AUTOLINKING_MIN_VERSION} — using lexical/symlink path to match @react-native-community/cli autolinking`\n : `RN >=${RN_REALPATH_AUTOLINKING_MIN_VERSION} or unknown — using realpath to match expo-modules-autolinking`\n );\n\n let absolutePath: string;\n if (useLexical) {\n absolutePath = packageDir;\n } else {\n try {\n absolutePath = fs.realpathSync(packageDir);\n if (absolutePath !== packageDir) {\n logger.info(`Realpath differs from resolved dir: ${absolutePath}`);\n }\n } catch (err) {\n logger.warn(\n `realpathSync failed (${\n err instanceof Error ? err.message : String(err)\n }); falling back to symlink path`\n );\n absolutePath = packageDir;\n }\n }\n\n const relativePath = path.relative(iosPath, absolutePath);\n logger.info(`Final Podfile :path => '${relativePath}'`);\n return relativePath;\n}\n\nfunction shouldUseLexicalPath(rnVersion: string | null): boolean {\n if (!rnVersion) {\n // Modern Expo (realpath) has been the working path for the last few\n // SDKs, so it's the safer default when RN can't be detected.\n return false;\n }\n const coerced = semver.valid(rnVersion) || semver.coerce(rnVersion);\n if (!coerced) {\n return false;\n }\n return semver.lt(coerced, RN_REALPATH_AUTOLINKING_MIN_VERSION);\n}\n\nexport const IOS_DEPLOYMENT_TARGET = '13.0';\nexport const GROUP_IDENTIFIER_TEMPLATE_REGEX = /{{GROUP_IDENTIFIER}}/gm;\nexport const BUNDLE_SHORT_VERSION_TEMPLATE_REGEX = /{{BUNDLE_SHORT_VERSION}}/gm;\nexport const BUNDLE_VERSION_TEMPLATE_REGEX = /{{BUNDLE_VERSION}}/gm;\nexport const CIO_DIDFINISHLAUNCHINGMETHOD_REGEX =\n /.*\\[super(\\s)application:application(\\s)didFinishLaunchingWithOptions:launchOptions\\];/;\n\nexport const CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_REGEX =\n /return \\[super application:application didFailToRegisterForRemoteNotificationsWithError:error\\];/;\n\nexport const CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERRORFULL_REGEX =\n /(- \\(void\\)application:\\(UIApplication \\*\\)application didFailToRegisterForRemoteNotificationsWithError:\\(NSError \\*\\)error(\\s|\\n)*?\\{)(.|\\n){2}.*\\n\\}/;\n\nexport const CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_REGEX =\n /return \\[super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken\\];/;\n\nexport const CIO_APPDELEGATEDECLARATION_REGEX =\n /@implementation AppDelegate(.|\\n)/;\n\nexport const CIO_APPDELEGATEHEADER_REGEX =\n /(@interface AppDelegate\\s*:\\s*EXAppDelegateWrapper\\s*)(<([^>]+)>)?/;\n\nexport const CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_REGEX =\n /^\\s*RCTBridge\\s*\\*\\s*\\w+\\s*=\\s*\\[\\s*self\\.reactDelegate\\s+createBridgeWithDelegate:self\\s+launchOptions:launchOptions\\s*\\];\\s*$/gm;\n\nexport const CIO_LAUNCHOPTIONS_DEEPLINK_MODIFIEDOPTIONS_REGEX =\n /^\\s*return\\s\\[\\s*super\\s*application:\\s*application\\s*didFinishLaunchingWithOptions\\s*:\\s*launchOptions\\s*\\];/gm;\n\nexport const CIO_DEEPLINK_COMMENT_REGEX =\n /\\sDeep link workaround for app killed state start/gm;\nexport const DEFAULT_BUNDLE_VERSION = '1';\nexport const DEFAULT_BUNDLE_SHORT_VERSION = '1.0';\nexport const CIO_TARGET_NAME = 'CustomerIOSDK';\nexport const CIO_NOTIFICATION_TARGET_NAME = 'NotificationService';\n\nexport const CIO_APPDELEGATEHEADER_IMPORT_SNIPPET = `#import <UserNotifications/UserNotifications.h>`;\nexport const CIO_APPDELEGATEHEADER_USER_NOTIFICATION_CENTER_SNIPPET =\n 'UNUserNotificationCenterDelegate';\nexport const CIO_PUSHNOTIFICATIONHANDLERDECLARATION_SNIPPET = `\nCIOAppPushNotificationsHandler* pnHandlerObj = [[CIOAppPushNotificationsHandler alloc] init];\n`;\nexport const CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_SNIPPET = `\nRCTBridge *bridge = [self.reactDelegate createBridgeWithDelegate:self launchOptions:modifiedLaunchOptions];\n`;\n\nexport const CIO_LAUNCHOPTIONS_MODIFIEDOPTIONS_SNIPPET = `\nreturn [super application:application didFinishLaunchingWithOptions:modifiedLaunchOptions];`;\n\nexport const CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_SNIPPET = `\n [super application:application didFailToRegisterForRemoteNotificationsWithError:error];\n [pnHandlerObj application:application error:error];\n`;\n\nexport const CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_SNIPPET = `\n [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];\n return [pnHandlerObj application:application deviceToken:deviceToken];\n`;\n\nexport const CIO_CONFIGURECIOSDKPUSHNOTIFICATION_SNIPPET = `\n // Register for push notifications\n [pnHandlerObj registerPushNotification];\n`;\n\nexport const CIO_INITIALIZECIOSDK_SNIPPET = ` \n [pnHandlerObj initializeCioSdk];\n\n// Code to make the CIO SDK compatible with expo-notifications package.\n// \n// The CIO SDK and expo-notifications both need to handle when a push gets clicked. However, iOS only allows one click handler to be set per app.\n// To get around this limitation, we set the CIO SDK as the click handler. The CIO SDK sets itself up so that when another SDK or host iOS app \n// sets itself as the click handler, the CIO SDK will still be able to handle when the push gets clicked, even though it's not the designated \n// click handler in iOS at runtime. \n// \n// This should work for most SDKs. However, expo-notifications is unique in it's implementation. It will not setup push click handling it if detects \n// that another SDK or host iOS app has already set itself as the click handler:\n// https://github.com/expo/expo/blob/1b29637bec0b9888e8bc8c310476293a3e2d9786/packages/expo-notifications/ios/EXNotifications/Notifications/EXNotificationCenterDelegate.m#L31-L37\n// ...to get around this, we must manually set it as the click handler after the CIO SDK. That's what this code block does.\n//\n// Note: Initialize the native iOS SDK and setup SDK push click handling before running this code. \n# if __has_include(<EXNotifications/EXNotificationCenterDelegate.h>)\n // Creating a new instance, as the comments in expo-notifications suggests, does not work. With this code, if you send a CIO push to device and click on it,\n // no push metrics reporting will occur.\n // EXNotificationCenterDelegate *notificationCenterDelegate = [[EXNotificationCenterDelegate alloc] init];\n\n // ...instead, get the singleton reference from Expo. \n id<UNUserNotificationCenterDelegate> notificationCenterDelegate = (id<UNUserNotificationCenterDelegate>) [EXModuleRegistryProvider getSingletonModuleForClass:[EXNotificationCenterDelegate class]];\n UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];\n center.delegate = notificationCenterDelegate;\n# endif\n`;\n\nexport const CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SNIPPET = `\n// Deep link workaround for app killed state start\nNSMutableDictionary *modifiedLaunchOptions = [NSMutableDictionary dictionaryWithDictionary:launchOptions];\n if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) {\n NSDictionary *pushContent = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];\n if (pushContent[@\"CIO\"] && pushContent[@\"CIO\"][@\"push\"] && pushContent[@\"CIO\"][@\"push\"][@\"link\"]) {\n NSString *initialURL = pushContent[@\"CIO\"][@\"push\"][@\"link\"];\n if (!launchOptions[UIApplicationLaunchOptionsURLKey]) {\n modifiedLaunchOptions[UIApplicationLaunchOptionsURLKey] = [NSURL URLWithString:initialURL];\n }\n }\n }\n//Deep link workaround for app killed state ends\n`;\n\nexport const CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SWIFT_SNIPPET = `\n // Deep link workaround for app killed state start\n var modifiedLaunchOptions = launchOptions\n if let launchOptions = launchOptions,\n let pushContent = launchOptions[UIApplication.LaunchOptionsKey.remoteNotification] as? [AnyHashable: Any],\n let cio = pushContent[\"CIO\"] as? [String: Any],\n let push = cio[\"push\"] as? [String: Any],\n let link = push[\"link\"] as? String,\n !launchOptions.keys.contains(UIApplication.LaunchOptionsKey.url) {\n \n var mutableLaunchOptions = launchOptions\n mutableLaunchOptions[UIApplication.LaunchOptionsKey.url] = URL(string: link)\n modifiedLaunchOptions = mutableLaunchOptions\n }\n // Deep link workaround for app killed state ends\n`;\n\nexport const CIO_REGISTER_PUSHNOTIFICATION_SNIPPET = `\n@objc(registerPushNotification)\n public func registerPushNotification() {\n\n let center = UNUserNotificationCenter.current()\n center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in\n if error == nil{\n DispatchQueue.main.async {\n UIApplication.shared.registerForRemoteNotifications()\n }\n }\n }\n }`;\n\nexport const CIO_REGISTER_PUSHNOTIFICATION_SNIPPET_v2 = `\n let center = UNUserNotificationCenter.current()\n center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in\n if error == nil{\n DispatchQueue.main.async {\n UIApplication.shared.registerForRemoteNotifications()\n }\n }\n }`;\n\nexport const CIO_REGISTER_PUSH_NOTIFICATION_PLACEHOLDER = /\\{\\{REGISTER_SNIPPET\\}\\}/;\n// Regex to match MessagingPush initialization in AppDelegate (different from NSE initialization)\nexport const CIO_MESSAGING_PUSH_APP_DELEGATE_INIT_REGEX = /(MessagingPush(?:APN|FCM)\\.initialize)/;\nexport const CIO_NATIVE_SDK_INITIALIZE_CALL = 'CustomerIOSDKInitializer.initialize()';\nexport const CIO_NATIVE_SDK_INITIALIZE_SNIPPET = `// Auto Initialize Native Customer.io SDK\n ${CIO_NATIVE_SDK_INITIALIZE_CALL}\n `;\n"],"mappings":";;;;;;;AAAA,IAAAA,GAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,MAAA,GAAAC,uBAAA,CAAAF,OAAA;AAGA,IAAAG,aAAA,GAAAH,OAAA;AACA,IAAAI,OAAA,GAAAJ,OAAA;AAA4C,SAAAE,wBAAAG,CAAA,EAAAC,CAAA,6BAAAC,OAAA,MAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAL,uBAAA,YAAAA,CAAAG,CAAA,EAAAC,CAAA,SAAAA,CAAA,IAAAD,CAAA,IAAAA,CAAA,CAAAK,UAAA,SAAAL,CAAA,MAAAM,CAAA,EAAAC,CAAA,EAAAC,CAAA,KAAAC,SAAA,QAAAC,OAAA,EAAAV,CAAA,iBAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,SAAAQ,CAAA,MAAAF,CAAA,GAAAL,CAAA,GAAAG,CAAA,GAAAD,CAAA,QAAAG,CAAA,CAAAK,GAAA,CAAAX,CAAA,UAAAM,CAAA,CAAAM,GAAA,CAAAZ,CAAA,GAAAM,CAAA,CAAAO,GAAA,CAAAb,CAAA,EAAAQ,CAAA,gBAAAP,CAAA,IAAAD,CAAA,gBAAAC,CAAA,OAAAa,cAAA,CAAAC,IAAA,CAAAf,CAAA,EAAAC,CAAA,OAAAM,CAAA,IAAAD,CAAA,GAAAU,MAAA,CAAAC,cAAA,KAAAD,MAAA,CAAAE,wBAAA,CAAAlB,CAAA,EAAAC,CAAA,OAAAM,CAAA,CAAAK,GAAA,IAAAL,CAAA,CAAAM,GAAA,IAAAP,CAAA,CAAAE,CAAA,EAAAP,CAAA,EAAAM,CAAA,IAAAC,CAAA,CAAAP,CAAA,IAAAD,CAAA,CAAAC,CAAA,WAAAO,CAAA,KAAAR,CAAA,EAAAC,CAAA;AAAA,SAAAP,uBAAAM,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAK,UAAA,GAAAL,CAAA,KAAAU,OAAA,EAAAV,CAAA;AAF5C,MAAMmB,IAAI,GAAGxB,OAAO,CAAC,MAAM,CAAC;AAI5B;AACA;AACA;AACA;AACA;AACA,MAAMyB,mCAAmC,GAAG,QAAQ;;AAEpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,sBAAsBA,CAACC,OAAe,EAAE;EACtD,MAAMC,WAAW,GAAGJ,IAAI,CAACK,OAAO,CAACF,OAAO,CAAC;EACzCG,cAAM,CAACC,IAAI,CACT,yDAAyDJ,OAAO,iBAAiBC,WAAW,GAC9F,CAAC;EAED,MAAM;IAAEI;EAAW,CAAC,GAAG,IAAAC,0BAAY,EAACL,WAAW,CAAC;EAChDE,cAAM,CAACC,IAAI,CAAC,uCAAuCC,UAAU,EAAE,CAAC;EAEhE,MAAME,SAAS,GAAG,IAAAC,8BAAgB,EAACP,WAAW,CAAC;EAC/CE,cAAM,CAACC,IAAI,CAAC,kCAAkCG,SAAS,IAAI,SAAS,EAAE,CAAC;EAEvE,MAAME,UAAU,GAAGC,oBAAoB,CAACH,SAAS,CAAC;EAClDJ,cAAM,CAACC,IAAI,CACTK,UAAU,GACN,OAAOX,mCAAmC,gFAAgF,GAC1H,QAAQA,mCAAmC,gEACjD,CAAC;EAED,IAAIa,YAAoB;EACxB,IAAIF,UAAU,EAAE;IACdE,YAAY,GAAGN,UAAU;EAC3B,CAAC,MAAM;IACL,IAAI;MACFM,YAAY,GAAGC,WAAE,CAACC,YAAY,CAACR,UAAU,CAAC;MAC1C,IAAIM,YAAY,KAAKN,UAAU,EAAE;QAC/BF,cAAM,CAACC,IAAI,CAAC,uCAAuCO,YAAY,EAAE,CAAC;MACpE;IACF,CAAC,CAAC,OAAOG,GAAG,EAAE;MACZX,cAAM,CAACY,IAAI,CACT,wBACED,GAAG,YAAYE,KAAK,GAAGF,GAAG,CAACG,OAAO,GAAGC,MAAM,CAACJ,GAAG,CAAC,iCAEpD,CAAC;MACDH,YAAY,GAAGN,UAAU;IAC3B;EACF;EAEA,MAAMc,YAAY,GAAGtB,IAAI,CAACuB,QAAQ,CAACpB,OAAO,EAAEW,YAAY,CAAC;EACzDR,cAAM,CAACC,IAAI,CAAC,2BAA2Be,YAAY,GAAG,CAAC;EACvD,OAAOA,YAAY;AACrB;AAEA,SAAST,oBAAoBA,CAACH,SAAwB,EAAW;EAC/D,IAAI,CAACA,SAAS,EAAE;IACd;IACA;IACA,OAAO,KAAK;EACd;EACA,MAAMc,OAAO,GAAG/C,MAAM,CAACgD,KAAK,CAACf,SAAS,CAAC,IAAIjC,MAAM,CAACiD,MAAM,CAAChB,SAAS,CAAC;EACnE,IAAI,CAACc,OAAO,EAAE;IACZ,OAAO,KAAK;EACd;EACA,OAAO/C,MAAM,CAACkD,EAAE,CAACH,OAAO,EAAEvB,mCAAmC,CAAC;AAChE;AAEO,MAAM2B,qBAAqB,GAAAC,OAAA,CAAAD,qBAAA,GAAG,MAAM;AACpC,MAAME,+BAA+B,GAAAD,OAAA,CAAAC,+BAAA,GAAG,wBAAwB;AAChE,MAAMC,mCAAmC,GAAAF,OAAA,CAAAE,mCAAA,GAAG,4BAA4B;AACxE,MAAMC,6BAA6B,GAAAH,OAAA,CAAAG,6BAAA,GAAG,sBAAsB;AAC5D,MAAMC,kCAAkC,GAAAJ,OAAA,CAAAI,kCAAA,GAC7C,wFAAwF;AAEnF,MAAMC,0DAA0D,GAAAL,OAAA,CAAAK,0DAAA,GACrE,kGAAkG;AAE7F,MAAMC,8DAA8D,GAAAN,OAAA,CAAAM,8DAAA,GACzE,wJAAwJ;AAEnJ,MAAMC,0DAA0D,GAAAP,OAAA,CAAAO,0DAAA,GACrE,wGAAwG;AAEnG,MAAMC,gCAAgC,GAAAR,OAAA,CAAAQ,gCAAA,GAC3C,mCAAmC;AAE9B,MAAMC,2BAA2B,GAAAT,OAAA,CAAAS,2BAAA,GACtC,oEAAoE;AAE/D,MAAMC,4CAA4C,GAAAV,OAAA,CAAAU,4CAAA,GACvD,mIAAmI;AAE9H,MAAMC,gDAAgD,GAAAX,OAAA,CAAAW,gDAAA,GAC3D,iHAAiH;AAE5G,MAAMC,0BAA0B,GAAAZ,OAAA,CAAAY,0BAAA,GACrC,qDAAqD;AAChD,MAAMC,sBAAsB,GAAAb,OAAA,CAAAa,sBAAA,GAAG,GAAG;AAClC,MAAMC,4BAA4B,GAAAd,OAAA,CAAAc,4BAAA,GAAG,KAAK;AAC1C,MAAMC,eAAe,GAAAf,OAAA,CAAAe,eAAA,GAAG,eAAe;AACvC,MAAMC,4BAA4B,GAAAhB,OAAA,CAAAgB,4BAAA,GAAG,qBAAqB;AAE1D,MAAMC,oCAAoC,GAAAjB,OAAA,CAAAiB,oCAAA,GAAG,iDAAiD;AAC9F,MAAMC,sDAAsD,GAAAlB,OAAA,CAAAkB,sDAAA,GACjE,kCAAkC;AAC7B,MAAMC,8CAA8C,GAAAnB,OAAA,CAAAmB,8CAAA,GAAG;AAC9D;AACA,CAAC;AACM,MAAMC,8CAA8C,GAAApB,OAAA,CAAAoB,8CAAA,GAAG;AAC9D;AACA,CAAC;AAEM,MAAMC,yCAAyC,GAAArB,OAAA,CAAAqB,yCAAA,GAAG;AACzD,4FAA4F;AAErF,MAAMC,4DAA4D,GAAAtB,OAAA,CAAAsB,4DAAA,GAAG;AAC5E;AACA;AACA,CAAC;AAEM,MAAMC,4DAA4D,GAAAvB,OAAA,CAAAuB,4DAAA,GAAG;AAC5E;AACA;AACA,CAAC;AAEM,MAAMC,2CAA2C,GAAAxB,OAAA,CAAAwB,2CAAA,GAAG;AAC3D;AACA;AACA,CAAC;AAEM,MAAMC,4BAA4B,GAAAzB,OAAA,CAAAyB,4BAAA,GAAG;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAEM,MAAMC,yCAAyC,GAAA1B,OAAA,CAAA0B,yCAAA,GAAG;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAEM,MAAMC,+CAA+C,GAAA3B,OAAA,CAAA2B,+CAAA,GAAG;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAEM,MAAMC,qCAAqC,GAAA5B,OAAA,CAAA4B,qCAAA,GAAG;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AAEG,MAAMC,wCAAwC,GAAA7B,OAAA,CAAA6B,wCAAA,GAAG;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AAEC,MAAMC,0CAA0C,GAAA9B,OAAA,CAAA8B,0CAAA,GAAG,0BAA0B;AACpF;AACO,MAAMC,0CAA0C,GAAA/B,OAAA,CAAA+B,0CAAA,GAAG,wCAAwC;AAC3F,MAAMC,8BAA8B,GAAAhC,OAAA,CAAAgC,8BAAA,GAAG,uCAAuC;AAC9E,MAAMC,iCAAiC,GAAAjC,OAAA,CAAAiC,iCAAA,GAAG;AACjD,MAAMD,8BAA8B;AACpC,KAAK","ignoreList":[]}
|
|
@@ -70,7 +70,11 @@ async function injectCIOPodfileCode(iosPath, isFcmPushProvider, options) {
|
|
|
70
70
|
const podfile = await _fileManagement.FileManagement.read(filename);
|
|
71
71
|
const next = injectHostAppPodfileCode(podfile, iosPath, isFcmPushProvider, options);
|
|
72
72
|
if (next !== podfile) {
|
|
73
|
-
|
|
73
|
+
// Await: the next iOS mod (withCioNotificationsXcodeProject) reads this
|
|
74
|
+
// same Podfile. Returning before the write flushes lets the next read
|
|
75
|
+
// race against the in-flight truncate, which (via FileManagement.read's
|
|
76
|
+
// empty-data fallback) rejects with null and aborts the NSE pipeline.
|
|
77
|
+
await _fileManagement.FileManagement.write(filename, next);
|
|
74
78
|
} else {
|
|
75
79
|
_logger.logger.info('CustomerIO Podfile snippets already exists. Skipping...');
|
|
76
80
|
}
|
|
@@ -107,7 +111,7 @@ async function injectCIONotificationPodfileCode(iosPath, useFrameworks, isFcmPus
|
|
|
107
111
|
if (next !== podfile) {
|
|
108
112
|
// FileManagement.append matches what the previous direct-append did.
|
|
109
113
|
// Slice off the leading content (already on disk) and append only the new tail.
|
|
110
|
-
_fileManagement.FileManagement.append(filename, next.slice(podfile.length));
|
|
114
|
+
await _fileManagement.FileManagement.append(filename, next.slice(podfile.length));
|
|
111
115
|
}
|
|
112
116
|
}
|
|
113
117
|
//# sourceMappingURL=injectCIOPodfileCode.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_logger","require","_ios","_codeInjection","_fileManagement","buildHostAppPodSnippet","iosPath","isFcmPushProvider","options","resolvedPath","getRelativePathToRNSDK","locationEnabled","hasPush","subspec","pushSubspec","HOST_APP_BLOCK_START","HOST_APP_BLOCK_END","NOTIFICATION_BLOCK_START","NOTIFICATION_BLOCK_END","injectHostAppPodfileCode","podfileContent","match","RegExp","lineInPodfileToInjectSnippetBefore","podLine","snippetToInjectInPodfile","trim","injectCodeByRegex","join","injectCIOPodfileCode","filename","podfile","FileManagement","read","next","write","logger","info","appendNotificationTargetToPodfile","useFrameworks","snippetToAppend","injectCIONotificationPodfileCode","append","slice","length"],"sources":["injectCIOPodfileCode.ts"],"sourcesContent":["import type { CustomerIOPluginOptionsIOS } from '../../types/cio-types';\nimport { logger } from '../../utils/logger';\nimport { getRelativePathToRNSDK } from '../constants/ios';\nimport { injectCodeByRegex } from './codeInjection';\nimport { FileManagement } from './fileManagement';\n\nexport type InjectCIOPodfileOptions = {\n /** When true, add the location subspec. When false/omit, use single push subspec only. */\n locationEnabled?: boolean;\n /** When false and locationEnabled, inject only :subspecs => ['location']. When true, use push + location. */\n hasPush?: boolean;\n};\n\n/** Builds the host-app pod snippet for the Podfile.\n *\n * The :path is resolved at prebuild time by `getRelativePathToRNSDK`,\n * which dispatches on the installed React Native version so the path\n * matches what RN pod autolinking will emit (lexical for RN <0.80,\n * realpath for RN >=0.80). Baking the resolved string directly avoids\n * any Ruby/install-time logic in the Podfile and keeps the snippet\n * trivially diff-able.\n *\n * Exported for tests.\n */\nexport function buildHostAppPodSnippet(\n iosPath: string,\n isFcmPushProvider: boolean,\n options?: InjectCIOPodfileOptions\n): string {\n const resolvedPath = getRelativePathToRNSDK(iosPath);\n const locationEnabled = options?.locationEnabled === true;\n const hasPush = options?.hasPush !== false;\n\n if (!locationEnabled) {\n const subspec = isFcmPushProvider ? 'fcm' : 'apn';\n return `pod 'customerio-reactnative/${subspec}', :path => '${resolvedPath}'`;\n }\n if (!hasPush) {\n return `pod 'customerio-reactnative', :subspecs => ['location'], :path => '${resolvedPath}'`;\n }\n const pushSubspec = isFcmPushProvider ? 'fcm' : 'apn';\n return `pod 'customerio-reactnative', :subspecs => ['${pushSubspec}', 'location'], :path => '${resolvedPath}'`;\n}\n\nconst HOST_APP_BLOCK_START = '# --- CustomerIO Host App START ---';\nconst HOST_APP_BLOCK_END = '# --- CustomerIO Host App END ---';\nconst NOTIFICATION_BLOCK_START = '# --- CustomerIO Notification START ---';\nconst NOTIFICATION_BLOCK_END = '# --- CustomerIO Notification END ---';\n\n/**\n * Pure string transform: given the existing Podfile contents, returns the\n * Podfile with the CustomerIO host-app block injected before the Expo\n * `post_install do |installer|` anchor. Idempotent — returns input unchanged\n * if the block is already present.\n */\nexport function injectHostAppPodfileCode(\n podfileContent: string,\n iosPath: string,\n isFcmPushProvider: boolean,\n options?: InjectCIOPodfileOptions\n): string {\n if (podfileContent.match(new RegExp(HOST_APP_BLOCK_START))) {\n return podfileContent;\n }\n\n // We need to decide what line of code in the Podfile to insert our native code.\n // The \"post_install\" line is always present in an Expo project Podfile so it's reliable.\n // Find that line in the Podfile and then we will insert our code above that line.\n const lineInPodfileToInjectSnippetBefore = /post_install do \\|installer\\|/;\n const podLine = buildHostAppPodSnippet(iosPath, isFcmPushProvider, options);\n\n const snippetToInjectInPodfile = `\n${HOST_APP_BLOCK_START}\n ${podLine}\n${HOST_APP_BLOCK_END}\n`.trim();\n\n return injectCodeByRegex(\n podfileContent,\n lineInPodfileToInjectSnippetBefore,\n snippetToInjectInPodfile,\n ).join('\\n');\n}\n\nexport async function injectCIOPodfileCode(\n iosPath: string,\n isFcmPushProvider: boolean,\n options?: InjectCIOPodfileOptions\n) {\n const filename = `${iosPath}/Podfile`;\n const podfile = await FileManagement.read(filename);\n const next = injectHostAppPodfileCode(podfile, iosPath, isFcmPushProvider, options);\n if (next !== podfile) {\n FileManagement.write(filename, next);\n } else {\n logger.info('CustomerIO Podfile snippets already exists. Skipping...');\n }\n}\n\n/**\n * Pure string transform: given the existing Podfile contents, returns the\n * Podfile with the rich-push NotificationService target block appended at\n * the end. Idempotent — returns input unchanged if the block is already\n * present.\n */\nexport function appendNotificationTargetToPodfile(\n podfileContent: string,\n iosPath: string,\n isFcmPushProvider: boolean,\n useFrameworks: CustomerIOPluginOptionsIOS['useFrameworks'],\n): string {\n if (podfileContent.match(new RegExp(NOTIFICATION_BLOCK_START))) {\n return podfileContent;\n }\n\n const snippetToAppend = `\n${NOTIFICATION_BLOCK_START}\ntarget 'NotificationService' do\n ${useFrameworks === 'static' ? 'use_frameworks! :linkage => :static' : ''}\n pod 'customerio-reactnative-richpush/${isFcmPushProvider ? 'fcm' : 'apn'}', :path => '${getRelativePathToRNSDK(iosPath)}'\nend\n${NOTIFICATION_BLOCK_END}\n`.trim();\n\n // Mirror FileManagement.append: append directly with no separator (real\n // Podfiles end with a trailing newline, so the appended block starts on a\n // fresh line in practice).\n return `${podfileContent}${snippetToAppend}`;\n}\n\nexport async function injectCIONotificationPodfileCode(\n iosPath: string,\n useFrameworks: CustomerIOPluginOptionsIOS['useFrameworks'],\n isFcmPushProvider: boolean\n) {\n const filename = `${iosPath}/Podfile`;\n const podfile = await FileManagement.read(filename);\n const next = appendNotificationTargetToPodfile(\n podfile,\n iosPath,\n isFcmPushProvider,\n useFrameworks,\n );\n if (next !== podfile) {\n // FileManagement.append matches what the previous direct-append did.\n // Slice off the leading content (already on disk) and append only the new tail.\n FileManagement.append(filename, next.slice(podfile.length));\n }\n}\n"],"mappings":";;;;;;;;;;AACA,IAAAA,OAAA,GAAAC,OAAA;AACA,IAAAC,IAAA,GAAAD,OAAA;AACA,IAAAE,cAAA,GAAAF,OAAA;AACA,IAAAG,eAAA,GAAAH,OAAA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASI,sBAAsBA,CACpCC,OAAe,EACfC,iBAA0B,EAC1BC,OAAiC,EACzB;EACR,MAAMC,YAAY,GAAG,IAAAC,2BAAsB,EAACJ,OAAO,CAAC;EACpD,MAAMK,eAAe,GAAG,CAAAH,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEG,eAAe,MAAK,IAAI;EACzD,MAAMC,OAAO,GAAG,CAAAJ,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEI,OAAO,MAAK,KAAK;EAE1C,IAAI,CAACD,eAAe,EAAE;IACpB,MAAME,OAAO,GAAGN,iBAAiB,GAAG,KAAK,GAAG,KAAK;IACjD,OAAO,+BAA+BM,OAAO,gBAAgBJ,YAAY,GAAG;EAC9E;EACA,IAAI,CAACG,OAAO,EAAE;IACZ,OAAO,sEAAsEH,YAAY,GAAG;EAC9F;EACA,MAAMK,WAAW,GAAGP,iBAAiB,GAAG,KAAK,GAAG,KAAK;EACrD,OAAO,gDAAgDO,WAAW,6BAA6BL,YAAY,GAAG;AAChH;AAEA,MAAMM,oBAAoB,GAAG,qCAAqC;AAClE,MAAMC,kBAAkB,GAAG,mCAAmC;AAC9D,MAAMC,wBAAwB,GAAG,yCAAyC;AAC1E,MAAMC,sBAAsB,GAAG,uCAAuC;;AAEtE;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,wBAAwBA,CACtCC,cAAsB,EACtBd,OAAe,EACfC,iBAA0B,EAC1BC,OAAiC,EACzB;EACR,IAAIY,cAAc,CAACC,KAAK,CAAC,IAAIC,MAAM,CAACP,oBAAoB,CAAC,CAAC,EAAE;IAC1D,OAAOK,cAAc;EACvB;;EAEA;EACA;EACA;EACA,MAAMG,kCAAkC,GAAG,+BAA+B;EAC1E,MAAMC,OAAO,GAAGnB,sBAAsB,CAACC,OAAO,EAAEC,iBAAiB,EAAEC,OAAO,CAAC;EAE3E,MAAMiB,wBAAwB,GAAG;AACnC,EAAEV,oBAAoB;AACtB,IAAIS,OAAO;AACX,EAAER,kBAAkB;AACpB,CAAC,CAACU,IAAI,CAAC,CAAC;EAEN,OAAO,IAAAC,gCAAiB,EACtBP,cAAc,EACdG,kCAAkC,EAClCE,wBACF,CAAC,CAACG,IAAI,CAAC,IAAI,CAAC;AACd;AAEO,eAAeC,oBAAoBA,CACxCvB,OAAe,EACfC,iBAA0B,EAC1BC,OAAiC,EACjC;EACA,MAAMsB,QAAQ,GAAG,GAAGxB,OAAO,UAAU;EACrC,MAAMyB,OAAO,GAAG,MAAMC,8BAAc,CAACC,IAAI,CAACH,QAAQ,CAAC;EACnD,MAAMI,IAAI,GAAGf,wBAAwB,CAACY,OAAO,EAAEzB,OAAO,EAAEC,iBAAiB,EAAEC,OAAO,CAAC;EACnF,IAAI0B,IAAI,KAAKH,OAAO,EAAE;
|
|
1
|
+
{"version":3,"names":["_logger","require","_ios","_codeInjection","_fileManagement","buildHostAppPodSnippet","iosPath","isFcmPushProvider","options","resolvedPath","getRelativePathToRNSDK","locationEnabled","hasPush","subspec","pushSubspec","HOST_APP_BLOCK_START","HOST_APP_BLOCK_END","NOTIFICATION_BLOCK_START","NOTIFICATION_BLOCK_END","injectHostAppPodfileCode","podfileContent","match","RegExp","lineInPodfileToInjectSnippetBefore","podLine","snippetToInjectInPodfile","trim","injectCodeByRegex","join","injectCIOPodfileCode","filename","podfile","FileManagement","read","next","write","logger","info","appendNotificationTargetToPodfile","useFrameworks","snippetToAppend","injectCIONotificationPodfileCode","append","slice","length"],"sources":["injectCIOPodfileCode.ts"],"sourcesContent":["import type { CustomerIOPluginOptionsIOS } from '../../types/cio-types';\nimport { logger } from '../../utils/logger';\nimport { getRelativePathToRNSDK } from '../constants/ios';\nimport { injectCodeByRegex } from './codeInjection';\nimport { FileManagement } from './fileManagement';\n\nexport type InjectCIOPodfileOptions = {\n /** When true, add the location subspec. When false/omit, use single push subspec only. */\n locationEnabled?: boolean;\n /** When false and locationEnabled, inject only :subspecs => ['location']. When true, use push + location. */\n hasPush?: boolean;\n};\n\n/** Builds the host-app pod snippet for the Podfile.\n *\n * The :path is resolved at prebuild time by `getRelativePathToRNSDK`,\n * which dispatches on the installed React Native version so the path\n * matches what RN pod autolinking will emit (lexical for RN <0.80,\n * realpath for RN >=0.80). Baking the resolved string directly avoids\n * any Ruby/install-time logic in the Podfile and keeps the snippet\n * trivially diff-able.\n *\n * Exported for tests.\n */\nexport function buildHostAppPodSnippet(\n iosPath: string,\n isFcmPushProvider: boolean,\n options?: InjectCIOPodfileOptions\n): string {\n const resolvedPath = getRelativePathToRNSDK(iosPath);\n const locationEnabled = options?.locationEnabled === true;\n const hasPush = options?.hasPush !== false;\n\n if (!locationEnabled) {\n const subspec = isFcmPushProvider ? 'fcm' : 'apn';\n return `pod 'customerio-reactnative/${subspec}', :path => '${resolvedPath}'`;\n }\n if (!hasPush) {\n return `pod 'customerio-reactnative', :subspecs => ['location'], :path => '${resolvedPath}'`;\n }\n const pushSubspec = isFcmPushProvider ? 'fcm' : 'apn';\n return `pod 'customerio-reactnative', :subspecs => ['${pushSubspec}', 'location'], :path => '${resolvedPath}'`;\n}\n\nconst HOST_APP_BLOCK_START = '# --- CustomerIO Host App START ---';\nconst HOST_APP_BLOCK_END = '# --- CustomerIO Host App END ---';\nconst NOTIFICATION_BLOCK_START = '# --- CustomerIO Notification START ---';\nconst NOTIFICATION_BLOCK_END = '# --- CustomerIO Notification END ---';\n\n/**\n * Pure string transform: given the existing Podfile contents, returns the\n * Podfile with the CustomerIO host-app block injected before the Expo\n * `post_install do |installer|` anchor. Idempotent — returns input unchanged\n * if the block is already present.\n */\nexport function injectHostAppPodfileCode(\n podfileContent: string,\n iosPath: string,\n isFcmPushProvider: boolean,\n options?: InjectCIOPodfileOptions\n): string {\n if (podfileContent.match(new RegExp(HOST_APP_BLOCK_START))) {\n return podfileContent;\n }\n\n // We need to decide what line of code in the Podfile to insert our native code.\n // The \"post_install\" line is always present in an Expo project Podfile so it's reliable.\n // Find that line in the Podfile and then we will insert our code above that line.\n const lineInPodfileToInjectSnippetBefore = /post_install do \\|installer\\|/;\n const podLine = buildHostAppPodSnippet(iosPath, isFcmPushProvider, options);\n\n const snippetToInjectInPodfile = `\n${HOST_APP_BLOCK_START}\n ${podLine}\n${HOST_APP_BLOCK_END}\n`.trim();\n\n return injectCodeByRegex(\n podfileContent,\n lineInPodfileToInjectSnippetBefore,\n snippetToInjectInPodfile,\n ).join('\\n');\n}\n\nexport async function injectCIOPodfileCode(\n iosPath: string,\n isFcmPushProvider: boolean,\n options?: InjectCIOPodfileOptions\n) {\n const filename = `${iosPath}/Podfile`;\n const podfile = await FileManagement.read(filename);\n const next = injectHostAppPodfileCode(podfile, iosPath, isFcmPushProvider, options);\n if (next !== podfile) {\n // Await: the next iOS mod (withCioNotificationsXcodeProject) reads this\n // same Podfile. Returning before the write flushes lets the next read\n // race against the in-flight truncate, which (via FileManagement.read's\n // empty-data fallback) rejects with null and aborts the NSE pipeline.\n await FileManagement.write(filename, next);\n } else {\n logger.info('CustomerIO Podfile snippets already exists. Skipping...');\n }\n}\n\n/**\n * Pure string transform: given the existing Podfile contents, returns the\n * Podfile with the rich-push NotificationService target block appended at\n * the end. Idempotent — returns input unchanged if the block is already\n * present.\n */\nexport function appendNotificationTargetToPodfile(\n podfileContent: string,\n iosPath: string,\n isFcmPushProvider: boolean,\n useFrameworks: CustomerIOPluginOptionsIOS['useFrameworks'],\n): string {\n if (podfileContent.match(new RegExp(NOTIFICATION_BLOCK_START))) {\n return podfileContent;\n }\n\n const snippetToAppend = `\n${NOTIFICATION_BLOCK_START}\ntarget 'NotificationService' do\n ${useFrameworks === 'static' ? 'use_frameworks! :linkage => :static' : ''}\n pod 'customerio-reactnative-richpush/${isFcmPushProvider ? 'fcm' : 'apn'}', :path => '${getRelativePathToRNSDK(iosPath)}'\nend\n${NOTIFICATION_BLOCK_END}\n`.trim();\n\n // Mirror FileManagement.append: append directly with no separator (real\n // Podfiles end with a trailing newline, so the appended block starts on a\n // fresh line in practice).\n return `${podfileContent}${snippetToAppend}`;\n}\n\nexport async function injectCIONotificationPodfileCode(\n iosPath: string,\n useFrameworks: CustomerIOPluginOptionsIOS['useFrameworks'],\n isFcmPushProvider: boolean\n) {\n const filename = `${iosPath}/Podfile`;\n const podfile = await FileManagement.read(filename);\n const next = appendNotificationTargetToPodfile(\n podfile,\n iosPath,\n isFcmPushProvider,\n useFrameworks,\n );\n if (next !== podfile) {\n // FileManagement.append matches what the previous direct-append did.\n // Slice off the leading content (already on disk) and append only the new tail.\n await FileManagement.append(filename, next.slice(podfile.length));\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -146,7 +146,7 @@ function addNotificationServiceExtensionToXcodeProject(xcodeProject, options) {
|
|
|
146
146
|
// - https://github.com/apache/cordova-node-xcode/blob/8b98cabc5978359db88dc9ff2d4c015cba40f150/lib/pbxProject.js#L860
|
|
147
147
|
const projObjects = xcodeProject.hash.project.objects;
|
|
148
148
|
projObjects.PBXTargetDependency = projObjects.PBXTargetDependency || {};
|
|
149
|
-
projObjects.PBXContainerItemProxy = projObjects.
|
|
149
|
+
projObjects.PBXContainerItemProxy = projObjects.PBXContainerItemProxy || {};
|
|
150
150
|
|
|
151
151
|
// Add the NSE target. This also adds PBXTargetDependency and PBXContainerItemProxy.
|
|
152
152
|
const nseTarget = xcodeProject.addTarget(_ios.CIO_NOTIFICATION_TARGET_NAME, 'app_extension', _ios.CIO_NOTIFICATION_TARGET_NAME, `${bundleIdentifier}.richpush`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_configPlugins","require","_ios","_codeInjection","_injectCIOPodfileCode","_logger","_plugin","_validation","_fileManagement","_utils","PLIST_FILENAME","CIO_NOTIFICATION_TARGET_NAME","ENV_FILENAME","NSE_PLATFORM_SPECIFIC_FILES","NSE_COMMON_FILES","TARGETED_DEVICE_FAMILY","addNotificationServiceExtension","options","xcodeProject","isExpo53OrHigher","_options$pushNotifica","pushNotification","addPushNotificationFile","useRichPush","addRichPushXcodeProj","error","logger","String","withCioNotificationsXcodeProject","configOuter","props","withXcodeProject","config","modRequest","ios","version","bundleShortVersion","appleTeamId","iosDeploymentTarget","useFrameworks","undefined","Error","projectName","platformProjectRoot","bundleIdentifier","buildNumber","bundleVersion","DEFAULT_BUNDLE_VERSION","iosPath","appName","modifiedProjectFile","modResults","isExpoVersion53OrHigher","exports","NSE_ENTITLEMENTS_FILENAME","addNotificationServiceExtensionToXcodeProject","pbxTargetByName","warn","appGroupId","allGroupFiles","extGroup","addPbxGroup","groups","hash","project","objects","PBXGroup","Object","keys","forEach","key","name","path","addToPbxGroup","uuid","projObjects","PBXTargetDependency","PBXContainerItemProxy","nseTarget","addTarget","addBuildPhase","configurations","pbxXCBuildConfigurationSection","buildSettings","PRODUCT_NAME","buildSettingsObj","DEVELOPMENT_TEAM","IPHONEOS_DEPLOYMENT_TARGET","CODE_SIGN_STYLE","SWIFT_VERSION","CODE_SIGN_ENTITLEMENTS","addTargetAttribute","_options$pushNotifica2","_options$pushNotifica3","isFcmProvider","isFcmPushProvider","injectCIONotificationPodfileCode","nsePath","FileManagement","mkdir","recursive","nseEntitlementsContent","writeFile","getTargetFile","filename","copyFile","getIosNativeFilesPath","updateNseInfoPlist","infoPlistTargetFile","updateNseEnv","env","updateNseNotificationService","applyBundleVersionToNsePlist","content","payload","next","replaceCodeByRegex","readFile","applyAppGroupIdToNotificationService","builderLine","JSON","stringify","notificationServiceFile","applyRichPushConfigToEnv","richPushConfig","cdpApiKey","region","regionKey","toLowerCase","regionMap","us","eu","mappedRegion","envFileName","validateRichPushConfig","sourceFile","targetFileName","appPath","targetFile","exists","info","updatePushFile","group","pbxCreateGroup","classesKey","findPBXGroupKey","addSourceFile","applyConfigToPushFile","_options$pushNotifica4","_options$pushNotifica5","_options$pushNotifica6","_options$pushNotifica7","_options$pushNotifica8","_options$pushNotifica9","disableNotificationRegistration","registerSnippet","CIO_REGISTER_PUSHNOTIFICATION_SNIPPET","toUpperCase","autoTrackPushEvents","toString","autoFetchDeviceToken","showPushAppInForeground","appGroupIdBuilderLine","_options$pushNotifica0"],"sources":["withNotificationsXcodeProject.ts"],"sourcesContent":["import type { ConfigPlugin, XcodeProject } from '@expo/config-plugins';\nimport { withXcodeProject } from '@expo/config-plugins';\n\nimport {\n CIO_NOTIFICATION_TARGET_NAME,\n CIO_REGISTER_PUSHNOTIFICATION_SNIPPET,\n DEFAULT_BUNDLE_VERSION,\n} from '../helpers/constants/ios';\nimport { replaceCodeByRegex } from '../helpers/utils/codeInjection';\nimport { injectCIONotificationPodfileCode } from '../helpers/utils/injectCIOPodfileCode';\nimport type { CustomerIOPluginOptionsIOS, RichPushConfig } from '../types/cio-types';\nimport { logger } from '../utils/logger';\nimport { getIosNativeFilesPath } from '../utils/plugin';\nimport { validateRichPushConfig } from '../utils/validation';\nimport { FileManagement } from './../helpers/utils/fileManagement';\nimport { isExpoVersion53OrHigher, isFcmPushProvider } from './utils';\n\nconst PLIST_FILENAME = `${CIO_NOTIFICATION_TARGET_NAME}-Info.plist`;\nconst ENV_FILENAME = 'Env.swift';\n\n// NSE source files registered in the Xcode group AND copied to the target\n// directory. Single source of truth — both `addNotificationServiceExtensionToXcodeProject`\n// (registers them in the PBXGroup) and `addRichPushXcodeProj` (copies them\n// from the plugin's native-files dir) read the same arrays. Keeping these\n// in sync is load-bearing: the Xcode group must reference the same files\n// that exist on disk, or the build fails with \"no such file\" / unresolved\n// references.\nconst NSE_PLATFORM_SPECIFIC_FILES = ['NotificationService.swift'];\nconst NSE_COMMON_FILES = [\n PLIST_FILENAME,\n 'NotificationService.h',\n 'NotificationService.m',\n ENV_FILENAME,\n];\n\nconst TARGETED_DEVICE_FAMILY = `\"1,2\"`;\n\nconst addNotificationServiceExtension = async (\n options: CustomerIOPluginOptionsIOS,\n xcodeProject: XcodeProject,\n isExpo53OrHigher: boolean,\n) => {\n try {\n // PushService file is only needed for pre-Expo 53 code generation\n if (options.pushNotification && !isExpo53OrHigher) {\n await addPushNotificationFile(options, xcodeProject);\n }\n\n if (options.pushNotification?.useRichPush === true) {\n await addRichPushXcodeProj(options, xcodeProject);\n }\n return xcodeProject;\n } catch (error: unknown) {\n logger.error(String(error));\n return null;\n }\n};\n\nexport const withCioNotificationsXcodeProject: ConfigPlugin<\n CustomerIOPluginOptionsIOS\n> = (configOuter, props) => {\n return withXcodeProject(configOuter, async (config) => {\n const { modRequest, ios, version: bundleShortVersion } = config;\n const { appleTeamId, iosDeploymentTarget, useFrameworks } = props;\n\n if (ios === undefined)\n throw new Error(\n 'Adding NotificationServiceExtension failed: ios config missing from app.config.js or app.json.'\n );\n\n // projectName and platformProjectRoot translates to appName and iosPath in addNotificationServiceExtension()\n const { projectName, platformProjectRoot } = modRequest;\n const { bundleIdentifier, buildNumber } = ios;\n\n if (bundleShortVersion === undefined) {\n throw new Error(\n 'Adding NotificationServiceExtension failed: version missing from app.config.js or app.json'\n );\n }\n\n if (bundleIdentifier === undefined) {\n throw new Error(\n 'Adding NotificationServiceExtension failed: ios.bundleIdentifier missing from app.config.js or app.json'\n );\n }\n\n if (projectName === undefined) {\n throw new Error(\n 'Adding NotificationServiceExtension failed: name missing from app.config.js or app.json'\n );\n }\n\n const options = {\n ...props,\n appleTeamId,\n bundleIdentifier,\n bundleShortVersion,\n bundleVersion: buildNumber || DEFAULT_BUNDLE_VERSION,\n iosPath: platformProjectRoot,\n appName: projectName,\n useFrameworks,\n iosDeploymentTarget,\n } satisfies CustomerIOPluginOptionsIOS;\n\n const modifiedProjectFile = await addNotificationServiceExtension(\n options,\n config.modResults,\n isExpoVersion53OrHigher(configOuter),\n );\n\n if (modifiedProjectFile) {\n config.modResults = modifiedProjectFile;\n }\n\n return config;\n });\n};\n\nconst NSE_ENTITLEMENTS_FILENAME = 'NotificationService.entitlements';\n\nexport type AddNseTargetToXcodeProjectOptions = {\n appleTeamId?: string;\n bundleIdentifier?: string;\n iosDeploymentTarget?: string;\n appGroupId?: string;\n};\n\n/**\n * Mutates the parsed XcodeProject to register the rich-push NotificationService\n * extension target: creates a PBXGroup for its files, registers the group under\n * the project's top-level group, adds the app_extension target, wires three\n * build phases (Sources, Resources, Frameworks), configures the target's build\n * settings (DEVELOPMENT_TEAM, IPHONEOS_DEPLOYMENT_TARGET, code-sign style,\n * Swift version, and CODE_SIGN_ENTITLEMENTS when `appGroupId` is set), and\n * stamps the development team attribute on both the new target and the\n * project's main target attributes.\n *\n * Idempotent — returns the project unchanged if a target named\n * `CIO_NOTIFICATION_TARGET_NAME` is already present.\n */\nexport function addNotificationServiceExtensionToXcodeProject(\n xcodeProject: XcodeProject,\n options: AddNseTargetToXcodeProjectOptions,\n): XcodeProject {\n if (xcodeProject.pbxTargetByName(CIO_NOTIFICATION_TARGET_NAME)) {\n logger.warn(\n `${CIO_NOTIFICATION_TARGET_NAME} already exists in project. Skipping...`,\n );\n return xcodeProject;\n }\n\n const { appleTeamId, bundleIdentifier, iosDeploymentTarget, appGroupId } = options;\n\n // The entitlements file is generated (not copied from source), so it's listed separately\n // for the Xcode group so it appears in the file navigator.\n const allGroupFiles = [\n ...NSE_PLATFORM_SPECIFIC_FILES,\n ...NSE_COMMON_FILES,\n ...(appGroupId ? [NSE_ENTITLEMENTS_FILENAME] : []),\n ];\n\n // Create new PBXGroup for the extension\n const extGroup = xcodeProject.addPbxGroup(\n allGroupFiles,\n CIO_NOTIFICATION_TARGET_NAME,\n CIO_NOTIFICATION_TARGET_NAME,\n );\n\n // Add the new PBXGroup to the top level group. This makes the\n // files / folder appear in the file explorer in Xcode.\n const groups = xcodeProject.hash.project.objects.PBXGroup;\n Object.keys(groups).forEach((key) => {\n if (groups[key].name === undefined && groups[key].path === undefined) {\n xcodeProject.addToPbxGroup(extGroup.uuid, key);\n }\n });\n\n // WORK AROUND for codeProject.addTarget BUG\n // Xcode projects don't contain these if there is only one target\n // An upstream fix should be made to the code referenced in this link:\n // - https://github.com/apache/cordova-node-xcode/blob/8b98cabc5978359db88dc9ff2d4c015cba40f150/lib/pbxProject.js#L860\n const projObjects = xcodeProject.hash.project.objects;\n projObjects.PBXTargetDependency = projObjects.PBXTargetDependency || {};\n projObjects.PBXContainerItemProxy = projObjects.PBXTargetDependency || {};\n\n // Add the NSE target. This also adds PBXTargetDependency and PBXContainerItemProxy.\n const nseTarget = xcodeProject.addTarget(\n CIO_NOTIFICATION_TARGET_NAME,\n 'app_extension',\n CIO_NOTIFICATION_TARGET_NAME,\n `${bundleIdentifier}.richpush`,\n );\n\n // Add build phases to the new target\n xcodeProject.addBuildPhase(\n ['NotificationService.m', 'NotificationService.swift', 'Env.swift'],\n 'PBXSourcesBuildPhase',\n 'Sources',\n nseTarget.uuid,\n );\n xcodeProject.addBuildPhase([], 'PBXResourcesBuildPhase', 'Resources', nseTarget.uuid);\n xcodeProject.addBuildPhase([], 'PBXFrameworksBuildPhase', 'Frameworks', nseTarget.uuid);\n\n // Edit the Deployment info of the target\n const configurations = xcodeProject.pbxXCBuildConfigurationSection();\n for (const key in configurations) {\n if (\n typeof configurations[key].buildSettings !== 'undefined' &&\n configurations[key].buildSettings.PRODUCT_NAME ===\n `\"${CIO_NOTIFICATION_TARGET_NAME}\"`\n ) {\n const buildSettingsObj = configurations[key].buildSettings;\n buildSettingsObj.DEVELOPMENT_TEAM = appleTeamId;\n buildSettingsObj.IPHONEOS_DEPLOYMENT_TARGET = iosDeploymentTarget || '15.1';\n buildSettingsObj.TARGETED_DEVICE_FAMILY = TARGETED_DEVICE_FAMILY;\n buildSettingsObj.CODE_SIGN_STYLE = 'Automatic';\n buildSettingsObj.SWIFT_VERSION = 4.2;\n if (appGroupId) {\n buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `${CIO_NOTIFICATION_TARGET_NAME}/${NSE_ENTITLEMENTS_FILENAME}`;\n }\n }\n }\n\n // Add development team to the target & the main\n xcodeProject.addTargetAttribute('DevelopmentTeam', appleTeamId, nseTarget);\n xcodeProject.addTargetAttribute('DevelopmentTeam', appleTeamId);\n\n return xcodeProject;\n}\n\nconst addRichPushXcodeProj = async (\n options: CustomerIOPluginOptionsIOS,\n xcodeProject: XcodeProject,\n) => {\n const {\n appleTeamId,\n bundleIdentifier,\n bundleShortVersion,\n bundleVersion,\n iosPath,\n iosDeploymentTarget,\n useFrameworks,\n } = options;\n\n const isFcmProvider = isFcmPushProvider(options);\n const appGroupId = options.pushNotification?.appGroupId;\n\n await injectCIONotificationPodfileCode(iosPath, useFrameworks, isFcmProvider);\n\n // Skip the rest of the work if the NSE target is already in place. The pbxproj-mutating\n // helper has its own idempotency check, but bailing out here also avoids redundant file\n // copies and entitlements writes when prebuild re-runs against an already-prepared project.\n if (xcodeProject.pbxTargetByName(CIO_NOTIFICATION_TARGET_NAME)) {\n logger.warn(\n `${CIO_NOTIFICATION_TARGET_NAME} already exists in project. Skipping...`,\n );\n return;\n }\n\n const nsePath = `${iosPath}/${CIO_NOTIFICATION_TARGET_NAME}`;\n FileManagement.mkdir(nsePath, { recursive: true });\n\n // Write NSE entitlements file only when appGroupId is explicitly configured\n if (appGroupId) {\n const nseEntitlementsContent = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>com.apple.security.application-groups</key>\n <array>\n <string>${appGroupId}</string>\n </array>\n</dict>\n</plist>\n`;\n FileManagement.writeFile(`${nsePath}/${NSE_ENTITLEMENTS_FILENAME}`, nseEntitlementsContent);\n }\n\n const getTargetFile = (filename: string) => `${nsePath}/${filename}`;\n\n // Copy platform-specific files\n NSE_PLATFORM_SPECIFIC_FILES.forEach((filename) => {\n FileManagement.copyFile(\n `${getIosNativeFilesPath()}/${isFcmProvider ? 'fcm' : 'apn'}/${filename}`,\n getTargetFile(filename),\n );\n });\n\n // Copy common files\n NSE_COMMON_FILES.forEach((filename) => {\n FileManagement.copyFile(\n `${getIosNativeFilesPath()}/common/${filename}`,\n getTargetFile(filename),\n );\n });\n\n /* MODIFY COPIED EXTENSION FILES */\n updateNseInfoPlist({\n bundleVersion,\n bundleShortVersion,\n infoPlistTargetFile: getTargetFile(PLIST_FILENAME),\n });\n updateNseEnv(getTargetFile(ENV_FILENAME), options.pushNotification?.env);\n updateNseNotificationService(getTargetFile('NotificationService.swift'), appGroupId);\n\n // Register the NSE target in the parsed Xcode project\n addNotificationServiceExtensionToXcodeProject(xcodeProject, {\n appleTeamId,\n bundleIdentifier,\n iosDeploymentTarget,\n appGroupId,\n });\n};\n\n/**\n * Pure string transform: substitutes the `{{BUNDLE_VERSION}}` and\n * `{{BUNDLE_SHORT_VERSION}}` placeholders in the NSE Info.plist template.\n * Either or both may be provided; missing values leave the corresponding\n * placeholder untouched.\n */\nexport function applyBundleVersionToNsePlist(\n content: string,\n payload: { bundleVersion?: string; bundleShortVersion?: string }\n): string {\n let next = content;\n if (payload.bundleVersion) {\n next = replaceCodeByRegex(next, /\\{\\{BUNDLE_VERSION\\}\\}/, payload.bundleVersion);\n }\n if (payload.bundleShortVersion) {\n next = replaceCodeByRegex(next, /\\{\\{BUNDLE_SHORT_VERSION\\}\\}/, payload.bundleShortVersion);\n }\n return next;\n}\n\nconst updateNseInfoPlist = (payload: {\n bundleVersion?: string;\n bundleShortVersion?: string;\n infoPlistTargetFile: string;\n}) => {\n const next = applyBundleVersionToNsePlist(\n FileManagement.readFile(payload.infoPlistTargetFile),\n payload,\n );\n FileManagement.writeFile(payload.infoPlistTargetFile, next);\n};\n\n/**\n * Pure string transform: substitutes the `{{APP_GROUP_ID_BUILDER_LINE}}`\n * placeholder in NotificationService.swift with either the configured\n * appGroupId builder line or an empty string.\n */\nexport function applyAppGroupIdToNotificationService(\n content: string,\n appGroupId?: string\n): string {\n const builderLine = appGroupId\n ? ` .appGroupId(${JSON.stringify(appGroupId)})\\n`\n : '';\n return replaceCodeByRegex(content, /\\{\\{APP_GROUP_ID_BUILDER_LINE\\}\\}/, builderLine);\n}\n\nconst updateNseNotificationService = (\n notificationServiceFile: string,\n appGroupId?: string,\n) => {\n const next = applyAppGroupIdToNotificationService(\n FileManagement.readFile(notificationServiceFile),\n appGroupId,\n );\n FileManagement.writeFile(notificationServiceFile, next);\n};\n\n/**\n * Pure string transform: substitutes the `{{CDP_API_KEY}}` and `{{REGION}}`\n * placeholders in the NSE Env.swift template. Missing or invalid region\n * falls back to `Region.US` and logs a warning.\n */\nexport function applyRichPushConfigToEnv(\n content: string,\n richPushConfig?: RichPushConfig,\n): string {\n const cdpApiKey = richPushConfig?.cdpApiKey;\n const region = richPushConfig?.region;\n\n let next = replaceCodeByRegex(\n content,\n /\\{\\{CDP_API_KEY\\}\\}/,\n cdpApiKey || 'MISSING_API_KEY',\n );\n\n const regionKey = region?.toLowerCase() ?? '';\n const regionMap = { us: 'Region.US', eu: 'Region.EU' } as const;\n const mappedRegion = regionMap[regionKey as keyof typeof regionMap];\n if (!mappedRegion) {\n logger.warn(\n `${regionKey} is an invalid region. Please use the values from the docs: https://docs.customer.io/integrations/sdk/expo/getting-started/packages-options/#configuring-the-expo-plugin`\n );\n next = replaceCodeByRegex(next, /\\{\\{REGION\\}\\}/, regionMap.us);\n } else {\n next = replaceCodeByRegex(next, /\\{\\{REGION\\}\\}/, mappedRegion);\n }\n return next;\n}\n\nconst updateNseEnv = (\n envFileName: string,\n richPushConfig?: RichPushConfig\n) => {\n if (!validateRichPushConfig(richPushConfig)) {\n return;\n }\n const next = applyRichPushConfigToEnv(\n FileManagement.readFile(envFileName),\n richPushConfig,\n );\n FileManagement.writeFile(envFileName, next);\n};\n\nasync function addPushNotificationFile(\n options: CustomerIOPluginOptionsIOS,\n xcodeProject: XcodeProject\n) {\n // Maybe copy a different file with FCM config based on config\n const { iosPath, appName } = options;\n const isFcmProvider = isFcmPushProvider(options);\n // PushService.swift is platform-specific and always lives in the platform folder\n const sourceFile = `${isFcmProvider ? 'fcm' : 'apn'}/PushService.swift`;\n const targetFileName = 'PushService.swift';\n const appPath = `${iosPath}/${appName}`;\n const getTargetFile = (filename: string) => `${appPath}/${filename}`;\n const targetFile = getTargetFile(targetFileName);\n\n // Check whether {file} exists in the project. If false, then add the file\n // If {file} exists then skip and return\n if (!FileManagement.exists(getTargetFile(targetFileName))) {\n FileManagement.mkdir(appPath, {\n recursive: true,\n });\n\n FileManagement.copyFile(\n `${getIosNativeFilesPath()}/${sourceFile}`,\n targetFile\n );\n } else {\n logger.info(`${getTargetFile(targetFileName)} already exists. Skipping...`);\n return;\n }\n\n updatePushFile(options, targetFile);\n\n const group = xcodeProject.pbxCreateGroup('CustomerIONotifications');\n const classesKey = xcodeProject.findPBXGroupKey({ name: `${appName}` });\n xcodeProject.addToPbxGroup(group, classesKey);\n\n xcodeProject.addSourceFile(`${appName}/${targetFileName}`, null, group);\n}\n\n/**\n * Pure string transform: substitutes every PushService.swift placeholder\n * (`{{REGISTER_SNIPPET}}`, `{{CDP_API_KEY}}`, `{{REGION}}`,\n * `{{AUTO_TRACK_PUSH_EVENTS}}`, `{{AUTO_FETCH_DEVICE_TOKEN}}`,\n * `{{SHOW_PUSH_APP_IN_FOREGROUND}}`, `{{APP_GROUP_ID_BUILDER_LINE}}`) using\n * the configured push-notification options. Validation of the rich-push\n * config (cdpApiKey/region required) is the wrapper's responsibility.\n */\nexport function applyConfigToPushFile(\n content: string,\n options: CustomerIOPluginOptionsIOS,\n): string {\n const richPushConfig = options.pushNotification?.env;\n const { cdpApiKey, region } = richPushConfig || {\n cdpApiKey: 'MISSING_API_KEY',\n region: undefined,\n };\n const disableNotificationRegistration =\n options.pushNotification?.disableNotificationRegistration;\n\n // unless this property is explicitly set to true, push notification\n // registration will be added to the AppDelegate\n const registerSnippet = disableNotificationRegistration !== true\n ? CIO_REGISTER_PUSHNOTIFICATION_SNIPPET\n : '';\n\n let next = replaceCodeByRegex(content, /\\{\\{REGISTER_SNIPPET\\}\\}/, registerSnippet);\n next = replaceCodeByRegex(next, /\\{\\{CDP_API_KEY\\}\\}/, cdpApiKey);\n\n if (region) {\n next = replaceCodeByRegex(next, /\\{\\{REGION\\}\\}/, region.toUpperCase());\n }\n\n const autoTrackPushEvents =\n options.pushNotification?.autoTrackPushEvents !== false;\n next = replaceCodeByRegex(\n next,\n /\\{\\{AUTO_TRACK_PUSH_EVENTS\\}\\}/,\n autoTrackPushEvents.toString(),\n );\n\n const autoFetchDeviceToken =\n options.pushNotification?.autoFetchDeviceToken !== false;\n next = replaceCodeByRegex(\n next,\n /\\{\\{AUTO_FETCH_DEVICE_TOKEN\\}\\}/,\n autoFetchDeviceToken.toString(),\n );\n\n const showPushAppInForeground =\n options.pushNotification?.showPushAppInForeground !== false;\n next = replaceCodeByRegex(\n next,\n /\\{\\{SHOW_PUSH_APP_IN_FOREGROUND\\}\\}/,\n showPushAppInForeground.toString(),\n );\n\n const appGroupId = options.pushNotification?.appGroupId;\n const appGroupIdBuilderLine = appGroupId\n ? ` .appGroupId(${JSON.stringify(appGroupId)})\\n`\n : '';\n next = replaceCodeByRegex(\n next,\n /\\{\\{APP_GROUP_ID_BUILDER_LINE\\}\\}/,\n appGroupIdBuilderLine,\n );\n\n return next;\n}\n\nconst updatePushFile = (\n options: CustomerIOPluginOptionsIOS,\n envFileName: string\n) => {\n const richPushConfig = options.pushNotification?.env;\n if (!validateRichPushConfig(richPushConfig)) {\n return;\n }\n const next = applyConfigToPushFile(FileManagement.readFile(envFileName), options);\n FileManagement.writeFile(envFileName, next);\n};\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["_configPlugins","require","_ios","_codeInjection","_injectCIOPodfileCode","_logger","_plugin","_validation","_fileManagement","_utils","PLIST_FILENAME","CIO_NOTIFICATION_TARGET_NAME","ENV_FILENAME","NSE_PLATFORM_SPECIFIC_FILES","NSE_COMMON_FILES","TARGETED_DEVICE_FAMILY","addNotificationServiceExtension","options","xcodeProject","isExpo53OrHigher","_options$pushNotifica","pushNotification","addPushNotificationFile","useRichPush","addRichPushXcodeProj","error","logger","String","withCioNotificationsXcodeProject","configOuter","props","withXcodeProject","config","modRequest","ios","version","bundleShortVersion","appleTeamId","iosDeploymentTarget","useFrameworks","undefined","Error","projectName","platformProjectRoot","bundleIdentifier","buildNumber","bundleVersion","DEFAULT_BUNDLE_VERSION","iosPath","appName","modifiedProjectFile","modResults","isExpoVersion53OrHigher","exports","NSE_ENTITLEMENTS_FILENAME","addNotificationServiceExtensionToXcodeProject","pbxTargetByName","warn","appGroupId","allGroupFiles","extGroup","addPbxGroup","groups","hash","project","objects","PBXGroup","Object","keys","forEach","key","name","path","addToPbxGroup","uuid","projObjects","PBXTargetDependency","PBXContainerItemProxy","nseTarget","addTarget","addBuildPhase","configurations","pbxXCBuildConfigurationSection","buildSettings","PRODUCT_NAME","buildSettingsObj","DEVELOPMENT_TEAM","IPHONEOS_DEPLOYMENT_TARGET","CODE_SIGN_STYLE","SWIFT_VERSION","CODE_SIGN_ENTITLEMENTS","addTargetAttribute","_options$pushNotifica2","_options$pushNotifica3","isFcmProvider","isFcmPushProvider","injectCIONotificationPodfileCode","nsePath","FileManagement","mkdir","recursive","nseEntitlementsContent","writeFile","getTargetFile","filename","copyFile","getIosNativeFilesPath","updateNseInfoPlist","infoPlistTargetFile","updateNseEnv","env","updateNseNotificationService","applyBundleVersionToNsePlist","content","payload","next","replaceCodeByRegex","readFile","applyAppGroupIdToNotificationService","builderLine","JSON","stringify","notificationServiceFile","applyRichPushConfigToEnv","richPushConfig","cdpApiKey","region","regionKey","toLowerCase","regionMap","us","eu","mappedRegion","envFileName","validateRichPushConfig","sourceFile","targetFileName","appPath","targetFile","exists","info","updatePushFile","group","pbxCreateGroup","classesKey","findPBXGroupKey","addSourceFile","applyConfigToPushFile","_options$pushNotifica4","_options$pushNotifica5","_options$pushNotifica6","_options$pushNotifica7","_options$pushNotifica8","_options$pushNotifica9","disableNotificationRegistration","registerSnippet","CIO_REGISTER_PUSHNOTIFICATION_SNIPPET","toUpperCase","autoTrackPushEvents","toString","autoFetchDeviceToken","showPushAppInForeground","appGroupIdBuilderLine","_options$pushNotifica0"],"sources":["withNotificationsXcodeProject.ts"],"sourcesContent":["import type { ConfigPlugin, XcodeProject } from '@expo/config-plugins';\nimport { withXcodeProject } from '@expo/config-plugins';\n\nimport {\n CIO_NOTIFICATION_TARGET_NAME,\n CIO_REGISTER_PUSHNOTIFICATION_SNIPPET,\n DEFAULT_BUNDLE_VERSION,\n} from '../helpers/constants/ios';\nimport { replaceCodeByRegex } from '../helpers/utils/codeInjection';\nimport { injectCIONotificationPodfileCode } from '../helpers/utils/injectCIOPodfileCode';\nimport type { CustomerIOPluginOptionsIOS, RichPushConfig } from '../types/cio-types';\nimport { logger } from '../utils/logger';\nimport { getIosNativeFilesPath } from '../utils/plugin';\nimport { validateRichPushConfig } from '../utils/validation';\nimport { FileManagement } from './../helpers/utils/fileManagement';\nimport { isExpoVersion53OrHigher, isFcmPushProvider } from './utils';\n\nconst PLIST_FILENAME = `${CIO_NOTIFICATION_TARGET_NAME}-Info.plist`;\nconst ENV_FILENAME = 'Env.swift';\n\n// NSE source files registered in the Xcode group AND copied to the target\n// directory. Single source of truth — both `addNotificationServiceExtensionToXcodeProject`\n// (registers them in the PBXGroup) and `addRichPushXcodeProj` (copies them\n// from the plugin's native-files dir) read the same arrays. Keeping these\n// in sync is load-bearing: the Xcode group must reference the same files\n// that exist on disk, or the build fails with \"no such file\" / unresolved\n// references.\nconst NSE_PLATFORM_SPECIFIC_FILES = ['NotificationService.swift'];\nconst NSE_COMMON_FILES = [\n PLIST_FILENAME,\n 'NotificationService.h',\n 'NotificationService.m',\n ENV_FILENAME,\n];\n\nconst TARGETED_DEVICE_FAMILY = `\"1,2\"`;\n\nconst addNotificationServiceExtension = async (\n options: CustomerIOPluginOptionsIOS,\n xcodeProject: XcodeProject,\n isExpo53OrHigher: boolean,\n) => {\n try {\n // PushService file is only needed for pre-Expo 53 code generation\n if (options.pushNotification && !isExpo53OrHigher) {\n await addPushNotificationFile(options, xcodeProject);\n }\n\n if (options.pushNotification?.useRichPush === true) {\n await addRichPushXcodeProj(options, xcodeProject);\n }\n return xcodeProject;\n } catch (error: unknown) {\n logger.error(String(error));\n return null;\n }\n};\n\nexport const withCioNotificationsXcodeProject: ConfigPlugin<\n CustomerIOPluginOptionsIOS\n> = (configOuter, props) => {\n return withXcodeProject(configOuter, async (config) => {\n const { modRequest, ios, version: bundleShortVersion } = config;\n const { appleTeamId, iosDeploymentTarget, useFrameworks } = props;\n\n if (ios === undefined)\n throw new Error(\n 'Adding NotificationServiceExtension failed: ios config missing from app.config.js or app.json.'\n );\n\n // projectName and platformProjectRoot translates to appName and iosPath in addNotificationServiceExtension()\n const { projectName, platformProjectRoot } = modRequest;\n const { bundleIdentifier, buildNumber } = ios;\n\n if (bundleShortVersion === undefined) {\n throw new Error(\n 'Adding NotificationServiceExtension failed: version missing from app.config.js or app.json'\n );\n }\n\n if (bundleIdentifier === undefined) {\n throw new Error(\n 'Adding NotificationServiceExtension failed: ios.bundleIdentifier missing from app.config.js or app.json'\n );\n }\n\n if (projectName === undefined) {\n throw new Error(\n 'Adding NotificationServiceExtension failed: name missing from app.config.js or app.json'\n );\n }\n\n const options = {\n ...props,\n appleTeamId,\n bundleIdentifier,\n bundleShortVersion,\n bundleVersion: buildNumber || DEFAULT_BUNDLE_VERSION,\n iosPath: platformProjectRoot,\n appName: projectName,\n useFrameworks,\n iosDeploymentTarget,\n } satisfies CustomerIOPluginOptionsIOS;\n\n const modifiedProjectFile = await addNotificationServiceExtension(\n options,\n config.modResults,\n isExpoVersion53OrHigher(configOuter),\n );\n\n if (modifiedProjectFile) {\n config.modResults = modifiedProjectFile;\n }\n\n return config;\n });\n};\n\nconst NSE_ENTITLEMENTS_FILENAME = 'NotificationService.entitlements';\n\nexport type AddNseTargetToXcodeProjectOptions = {\n appleTeamId?: string;\n bundleIdentifier?: string;\n iosDeploymentTarget?: string;\n appGroupId?: string;\n};\n\n/**\n * Mutates the parsed XcodeProject to register the rich-push NotificationService\n * extension target: creates a PBXGroup for its files, registers the group under\n * the project's top-level group, adds the app_extension target, wires three\n * build phases (Sources, Resources, Frameworks), configures the target's build\n * settings (DEVELOPMENT_TEAM, IPHONEOS_DEPLOYMENT_TARGET, code-sign style,\n * Swift version, and CODE_SIGN_ENTITLEMENTS when `appGroupId` is set), and\n * stamps the development team attribute on both the new target and the\n * project's main target attributes.\n *\n * Idempotent — returns the project unchanged if a target named\n * `CIO_NOTIFICATION_TARGET_NAME` is already present.\n */\nexport function addNotificationServiceExtensionToXcodeProject(\n xcodeProject: XcodeProject,\n options: AddNseTargetToXcodeProjectOptions,\n): XcodeProject {\n if (xcodeProject.pbxTargetByName(CIO_NOTIFICATION_TARGET_NAME)) {\n logger.warn(\n `${CIO_NOTIFICATION_TARGET_NAME} already exists in project. Skipping...`,\n );\n return xcodeProject;\n }\n\n const { appleTeamId, bundleIdentifier, iosDeploymentTarget, appGroupId } = options;\n\n // The entitlements file is generated (not copied from source), so it's listed separately\n // for the Xcode group so it appears in the file navigator.\n const allGroupFiles = [\n ...NSE_PLATFORM_SPECIFIC_FILES,\n ...NSE_COMMON_FILES,\n ...(appGroupId ? [NSE_ENTITLEMENTS_FILENAME] : []),\n ];\n\n // Create new PBXGroup for the extension\n const extGroup = xcodeProject.addPbxGroup(\n allGroupFiles,\n CIO_NOTIFICATION_TARGET_NAME,\n CIO_NOTIFICATION_TARGET_NAME,\n );\n\n // Add the new PBXGroup to the top level group. This makes the\n // files / folder appear in the file explorer in Xcode.\n const groups = xcodeProject.hash.project.objects.PBXGroup;\n Object.keys(groups).forEach((key) => {\n if (groups[key].name === undefined && groups[key].path === undefined) {\n xcodeProject.addToPbxGroup(extGroup.uuid, key);\n }\n });\n\n // WORK AROUND for codeProject.addTarget BUG\n // Xcode projects don't contain these if there is only one target\n // An upstream fix should be made to the code referenced in this link:\n // - https://github.com/apache/cordova-node-xcode/blob/8b98cabc5978359db88dc9ff2d4c015cba40f150/lib/pbxProject.js#L860\n const projObjects = xcodeProject.hash.project.objects;\n projObjects.PBXTargetDependency = projObjects.PBXTargetDependency || {};\n projObjects.PBXContainerItemProxy = projObjects.PBXContainerItemProxy || {};\n\n // Add the NSE target. This also adds PBXTargetDependency and PBXContainerItemProxy.\n const nseTarget = xcodeProject.addTarget(\n CIO_NOTIFICATION_TARGET_NAME,\n 'app_extension',\n CIO_NOTIFICATION_TARGET_NAME,\n `${bundleIdentifier}.richpush`,\n );\n\n // Add build phases to the new target\n xcodeProject.addBuildPhase(\n ['NotificationService.m', 'NotificationService.swift', 'Env.swift'],\n 'PBXSourcesBuildPhase',\n 'Sources',\n nseTarget.uuid,\n );\n xcodeProject.addBuildPhase([], 'PBXResourcesBuildPhase', 'Resources', nseTarget.uuid);\n xcodeProject.addBuildPhase([], 'PBXFrameworksBuildPhase', 'Frameworks', nseTarget.uuid);\n\n // Edit the Deployment info of the target\n const configurations = xcodeProject.pbxXCBuildConfigurationSection();\n for (const key in configurations) {\n if (\n typeof configurations[key].buildSettings !== 'undefined' &&\n configurations[key].buildSettings.PRODUCT_NAME ===\n `\"${CIO_NOTIFICATION_TARGET_NAME}\"`\n ) {\n const buildSettingsObj = configurations[key].buildSettings;\n buildSettingsObj.DEVELOPMENT_TEAM = appleTeamId;\n buildSettingsObj.IPHONEOS_DEPLOYMENT_TARGET = iosDeploymentTarget || '15.1';\n buildSettingsObj.TARGETED_DEVICE_FAMILY = TARGETED_DEVICE_FAMILY;\n buildSettingsObj.CODE_SIGN_STYLE = 'Automatic';\n buildSettingsObj.SWIFT_VERSION = 4.2;\n if (appGroupId) {\n buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `${CIO_NOTIFICATION_TARGET_NAME}/${NSE_ENTITLEMENTS_FILENAME}`;\n }\n }\n }\n\n // Add development team to the target & the main\n xcodeProject.addTargetAttribute('DevelopmentTeam', appleTeamId, nseTarget);\n xcodeProject.addTargetAttribute('DevelopmentTeam', appleTeamId);\n\n return xcodeProject;\n}\n\nconst addRichPushXcodeProj = async (\n options: CustomerIOPluginOptionsIOS,\n xcodeProject: XcodeProject,\n) => {\n const {\n appleTeamId,\n bundleIdentifier,\n bundleShortVersion,\n bundleVersion,\n iosPath,\n iosDeploymentTarget,\n useFrameworks,\n } = options;\n\n const isFcmProvider = isFcmPushProvider(options);\n const appGroupId = options.pushNotification?.appGroupId;\n\n await injectCIONotificationPodfileCode(iosPath, useFrameworks, isFcmProvider);\n\n // Skip the rest of the work if the NSE target is already in place. The pbxproj-mutating\n // helper has its own idempotency check, but bailing out here also avoids redundant file\n // copies and entitlements writes when prebuild re-runs against an already-prepared project.\n if (xcodeProject.pbxTargetByName(CIO_NOTIFICATION_TARGET_NAME)) {\n logger.warn(\n `${CIO_NOTIFICATION_TARGET_NAME} already exists in project. Skipping...`,\n );\n return;\n }\n\n const nsePath = `${iosPath}/${CIO_NOTIFICATION_TARGET_NAME}`;\n FileManagement.mkdir(nsePath, { recursive: true });\n\n // Write NSE entitlements file only when appGroupId is explicitly configured\n if (appGroupId) {\n const nseEntitlementsContent = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>com.apple.security.application-groups</key>\n <array>\n <string>${appGroupId}</string>\n </array>\n</dict>\n</plist>\n`;\n FileManagement.writeFile(`${nsePath}/${NSE_ENTITLEMENTS_FILENAME}`, nseEntitlementsContent);\n }\n\n const getTargetFile = (filename: string) => `${nsePath}/${filename}`;\n\n // Copy platform-specific files\n NSE_PLATFORM_SPECIFIC_FILES.forEach((filename) => {\n FileManagement.copyFile(\n `${getIosNativeFilesPath()}/${isFcmProvider ? 'fcm' : 'apn'}/${filename}`,\n getTargetFile(filename),\n );\n });\n\n // Copy common files\n NSE_COMMON_FILES.forEach((filename) => {\n FileManagement.copyFile(\n `${getIosNativeFilesPath()}/common/${filename}`,\n getTargetFile(filename),\n );\n });\n\n /* MODIFY COPIED EXTENSION FILES */\n updateNseInfoPlist({\n bundleVersion,\n bundleShortVersion,\n infoPlistTargetFile: getTargetFile(PLIST_FILENAME),\n });\n updateNseEnv(getTargetFile(ENV_FILENAME), options.pushNotification?.env);\n updateNseNotificationService(getTargetFile('NotificationService.swift'), appGroupId);\n\n // Register the NSE target in the parsed Xcode project\n addNotificationServiceExtensionToXcodeProject(xcodeProject, {\n appleTeamId,\n bundleIdentifier,\n iosDeploymentTarget,\n appGroupId,\n });\n};\n\n/**\n * Pure string transform: substitutes the `{{BUNDLE_VERSION}}` and\n * `{{BUNDLE_SHORT_VERSION}}` placeholders in the NSE Info.plist template.\n * Either or both may be provided; missing values leave the corresponding\n * placeholder untouched.\n */\nexport function applyBundleVersionToNsePlist(\n content: string,\n payload: { bundleVersion?: string; bundleShortVersion?: string }\n): string {\n let next = content;\n if (payload.bundleVersion) {\n next = replaceCodeByRegex(next, /\\{\\{BUNDLE_VERSION\\}\\}/, payload.bundleVersion);\n }\n if (payload.bundleShortVersion) {\n next = replaceCodeByRegex(next, /\\{\\{BUNDLE_SHORT_VERSION\\}\\}/, payload.bundleShortVersion);\n }\n return next;\n}\n\nconst updateNseInfoPlist = (payload: {\n bundleVersion?: string;\n bundleShortVersion?: string;\n infoPlistTargetFile: string;\n}) => {\n const next = applyBundleVersionToNsePlist(\n FileManagement.readFile(payload.infoPlistTargetFile),\n payload,\n );\n FileManagement.writeFile(payload.infoPlistTargetFile, next);\n};\n\n/**\n * Pure string transform: substitutes the `{{APP_GROUP_ID_BUILDER_LINE}}`\n * placeholder in NotificationService.swift with either the configured\n * appGroupId builder line or an empty string.\n */\nexport function applyAppGroupIdToNotificationService(\n content: string,\n appGroupId?: string\n): string {\n const builderLine = appGroupId\n ? ` .appGroupId(${JSON.stringify(appGroupId)})\\n`\n : '';\n return replaceCodeByRegex(content, /\\{\\{APP_GROUP_ID_BUILDER_LINE\\}\\}/, builderLine);\n}\n\nconst updateNseNotificationService = (\n notificationServiceFile: string,\n appGroupId?: string,\n) => {\n const next = applyAppGroupIdToNotificationService(\n FileManagement.readFile(notificationServiceFile),\n appGroupId,\n );\n FileManagement.writeFile(notificationServiceFile, next);\n};\n\n/**\n * Pure string transform: substitutes the `{{CDP_API_KEY}}` and `{{REGION}}`\n * placeholders in the NSE Env.swift template. Missing or invalid region\n * falls back to `Region.US` and logs a warning.\n */\nexport function applyRichPushConfigToEnv(\n content: string,\n richPushConfig?: RichPushConfig,\n): string {\n const cdpApiKey = richPushConfig?.cdpApiKey;\n const region = richPushConfig?.region;\n\n let next = replaceCodeByRegex(\n content,\n /\\{\\{CDP_API_KEY\\}\\}/,\n cdpApiKey || 'MISSING_API_KEY',\n );\n\n const regionKey = region?.toLowerCase() ?? '';\n const regionMap = { us: 'Region.US', eu: 'Region.EU' } as const;\n const mappedRegion = regionMap[regionKey as keyof typeof regionMap];\n if (!mappedRegion) {\n logger.warn(\n `${regionKey} is an invalid region. Please use the values from the docs: https://docs.customer.io/integrations/sdk/expo/getting-started/packages-options/#configuring-the-expo-plugin`\n );\n next = replaceCodeByRegex(next, /\\{\\{REGION\\}\\}/, regionMap.us);\n } else {\n next = replaceCodeByRegex(next, /\\{\\{REGION\\}\\}/, mappedRegion);\n }\n return next;\n}\n\nconst updateNseEnv = (\n envFileName: string,\n richPushConfig?: RichPushConfig\n) => {\n if (!validateRichPushConfig(richPushConfig)) {\n return;\n }\n const next = applyRichPushConfigToEnv(\n FileManagement.readFile(envFileName),\n richPushConfig,\n );\n FileManagement.writeFile(envFileName, next);\n};\n\nasync function addPushNotificationFile(\n options: CustomerIOPluginOptionsIOS,\n xcodeProject: XcodeProject\n) {\n // Maybe copy a different file with FCM config based on config\n const { iosPath, appName } = options;\n const isFcmProvider = isFcmPushProvider(options);\n // PushService.swift is platform-specific and always lives in the platform folder\n const sourceFile = `${isFcmProvider ? 'fcm' : 'apn'}/PushService.swift`;\n const targetFileName = 'PushService.swift';\n const appPath = `${iosPath}/${appName}`;\n const getTargetFile = (filename: string) => `${appPath}/${filename}`;\n const targetFile = getTargetFile(targetFileName);\n\n // Check whether {file} exists in the project. If false, then add the file\n // If {file} exists then skip and return\n if (!FileManagement.exists(getTargetFile(targetFileName))) {\n FileManagement.mkdir(appPath, {\n recursive: true,\n });\n\n FileManagement.copyFile(\n `${getIosNativeFilesPath()}/${sourceFile}`,\n targetFile\n );\n } else {\n logger.info(`${getTargetFile(targetFileName)} already exists. Skipping...`);\n return;\n }\n\n updatePushFile(options, targetFile);\n\n const group = xcodeProject.pbxCreateGroup('CustomerIONotifications');\n const classesKey = xcodeProject.findPBXGroupKey({ name: `${appName}` });\n xcodeProject.addToPbxGroup(group, classesKey);\n\n xcodeProject.addSourceFile(`${appName}/${targetFileName}`, null, group);\n}\n\n/**\n * Pure string transform: substitutes every PushService.swift placeholder\n * (`{{REGISTER_SNIPPET}}`, `{{CDP_API_KEY}}`, `{{REGION}}`,\n * `{{AUTO_TRACK_PUSH_EVENTS}}`, `{{AUTO_FETCH_DEVICE_TOKEN}}`,\n * `{{SHOW_PUSH_APP_IN_FOREGROUND}}`, `{{APP_GROUP_ID_BUILDER_LINE}}`) using\n * the configured push-notification options. Validation of the rich-push\n * config (cdpApiKey/region required) is the wrapper's responsibility.\n */\nexport function applyConfigToPushFile(\n content: string,\n options: CustomerIOPluginOptionsIOS,\n): string {\n const richPushConfig = options.pushNotification?.env;\n const { cdpApiKey, region } = richPushConfig || {\n cdpApiKey: 'MISSING_API_KEY',\n region: undefined,\n };\n const disableNotificationRegistration =\n options.pushNotification?.disableNotificationRegistration;\n\n // unless this property is explicitly set to true, push notification\n // registration will be added to the AppDelegate\n const registerSnippet = disableNotificationRegistration !== true\n ? CIO_REGISTER_PUSHNOTIFICATION_SNIPPET\n : '';\n\n let next = replaceCodeByRegex(content, /\\{\\{REGISTER_SNIPPET\\}\\}/, registerSnippet);\n next = replaceCodeByRegex(next, /\\{\\{CDP_API_KEY\\}\\}/, cdpApiKey);\n\n if (region) {\n next = replaceCodeByRegex(next, /\\{\\{REGION\\}\\}/, region.toUpperCase());\n }\n\n const autoTrackPushEvents =\n options.pushNotification?.autoTrackPushEvents !== false;\n next = replaceCodeByRegex(\n next,\n /\\{\\{AUTO_TRACK_PUSH_EVENTS\\}\\}/,\n autoTrackPushEvents.toString(),\n );\n\n const autoFetchDeviceToken =\n options.pushNotification?.autoFetchDeviceToken !== false;\n next = replaceCodeByRegex(\n next,\n /\\{\\{AUTO_FETCH_DEVICE_TOKEN\\}\\}/,\n autoFetchDeviceToken.toString(),\n );\n\n const showPushAppInForeground =\n options.pushNotification?.showPushAppInForeground !== false;\n next = replaceCodeByRegex(\n next,\n /\\{\\{SHOW_PUSH_APP_IN_FOREGROUND\\}\\}/,\n showPushAppInForeground.toString(),\n );\n\n const appGroupId = options.pushNotification?.appGroupId;\n const appGroupIdBuilderLine = appGroupId\n ? ` .appGroupId(${JSON.stringify(appGroupId)})\\n`\n : '';\n next = replaceCodeByRegex(\n next,\n /\\{\\{APP_GROUP_ID_BUILDER_LINE\\}\\}/,\n appGroupIdBuilderLine,\n );\n\n return next;\n}\n\nconst updatePushFile = (\n options: CustomerIOPluginOptionsIOS,\n envFileName: string\n) => {\n const richPushConfig = options.pushNotification?.env;\n if (!validateRichPushConfig(richPushConfig)) {\n return;\n }\n const next = applyConfigToPushFile(FileManagement.readFile(envFileName), options);\n FileManagement.writeFile(envFileName, next);\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -4,10 +4,22 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.logger = void 0;
|
|
7
|
+
var _util = require("util");
|
|
7
8
|
// Use CUSTOMERIO_DEBUG_MODE if defined; otherwise enable in development mode only
|
|
8
9
|
const VERBOSE_MODE = process.env.CUSTOMERIO_DEBUG_MODE !== undefined ? process.env.CUSTOMERIO_DEBUG_MODE === 'true' : process.env.NODE_ENV === 'development';
|
|
9
10
|
const PREFIX = '[CustomerIO]';
|
|
10
11
|
const formatMessage = message => `${PREFIX} ${message}`;
|
|
12
|
+
|
|
13
|
+
// `info`/`log`/`debug` go straight to stderr via `process.stderr.write` rather
|
|
14
|
+
// than `console.log/info/debug` (which default to stdout). Expo's CLI parses
|
|
15
|
+
// `expo config --json` stdout as JSON and eas-cli no longer falls back on a
|
|
16
|
+
// parse failure — a single stray verbose line aborts the build. Keeping
|
|
17
|
+
// verbose output on stderr makes the trace impossible to leak into that
|
|
18
|
+
// stream, regardless of host console rebinding.
|
|
19
|
+
const writeStderr = (message, args) => {
|
|
20
|
+
const line = args.length > 0 ? (0, _util.format)(message, ...args) : message;
|
|
21
|
+
process.stderr.write(`${line}\n`);
|
|
22
|
+
};
|
|
11
23
|
const logger = exports.logger = {
|
|
12
24
|
format: formatMessage,
|
|
13
25
|
error: (message, ...args) => {
|
|
@@ -18,17 +30,17 @@ const logger = exports.logger = {
|
|
|
18
30
|
},
|
|
19
31
|
info: (message, ...args) => {
|
|
20
32
|
if (VERBOSE_MODE) {
|
|
21
|
-
|
|
33
|
+
writeStderr(formatMessage(message), args);
|
|
22
34
|
}
|
|
23
35
|
},
|
|
24
36
|
log: (message, ...args) => {
|
|
25
37
|
if (VERBOSE_MODE) {
|
|
26
|
-
|
|
38
|
+
writeStderr(formatMessage(message), args);
|
|
27
39
|
}
|
|
28
40
|
},
|
|
29
41
|
debug: (message, ...args) => {
|
|
30
42
|
if (VERBOSE_MODE) {
|
|
31
|
-
|
|
43
|
+
writeStderr(formatMessage(message), args);
|
|
32
44
|
}
|
|
33
45
|
}
|
|
34
46
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["VERBOSE_MODE","process","env","CUSTOMERIO_DEBUG_MODE","undefined","NODE_ENV","PREFIX","formatMessage","message","
|
|
1
|
+
{"version":3,"names":["_util","require","VERBOSE_MODE","process","env","CUSTOMERIO_DEBUG_MODE","undefined","NODE_ENV","PREFIX","formatMessage","message","writeStderr","args","line","length","format","stderr","write","logger","exports","error","console","warn","info","log","debug"],"sources":["logger.ts"],"sourcesContent":["import { format } from 'util';\n\n// Use CUSTOMERIO_DEBUG_MODE if defined; otherwise enable in development mode only\nconst VERBOSE_MODE =\n process.env.CUSTOMERIO_DEBUG_MODE !== undefined\n ? process.env.CUSTOMERIO_DEBUG_MODE === 'true'\n : process.env.NODE_ENV === 'development';\nconst PREFIX = '[CustomerIO]';\nconst formatMessage = (message: string): string => `${PREFIX} ${message}`;\n\n// `info`/`log`/`debug` go straight to stderr via `process.stderr.write` rather\n// than `console.log/info/debug` (which default to stdout). Expo's CLI parses\n// `expo config --json` stdout as JSON and eas-cli no longer falls back on a\n// parse failure — a single stray verbose line aborts the build. Keeping\n// verbose output on stderr makes the trace impossible to leak into that\n// stream, regardless of host console rebinding.\nconst writeStderr = (message: string, args: unknown[]): void => {\n const line = args.length > 0 ? format(message, ...args) : message;\n process.stderr.write(`${line}\\n`);\n};\n\nexport const logger = {\n format: formatMessage,\n\n error: (message: string, ...args: unknown[]): void => {\n console.error(formatMessage(message), ...args);\n },\n\n warn: (message: string, ...args: unknown[]): void => {\n console.warn(formatMessage(message), ...args);\n },\n\n info: (message: string, ...args: unknown[]): void => {\n if (VERBOSE_MODE) {\n writeStderr(formatMessage(message), args);\n }\n },\n\n log: (message: string, ...args: unknown[]): void => {\n if (VERBOSE_MODE) {\n writeStderr(formatMessage(message), args);\n }\n },\n\n debug: (message: string, ...args: unknown[]): void => {\n if (VERBOSE_MODE) {\n writeStderr(formatMessage(message), args);\n }\n }\n};\n"],"mappings":";;;;;;AAAA,IAAAA,KAAA,GAAAC,OAAA;AAEA;AACA,MAAMC,YAAY,GAChBC,OAAO,CAACC,GAAG,CAACC,qBAAqB,KAAKC,SAAS,GAC3CH,OAAO,CAACC,GAAG,CAACC,qBAAqB,KAAK,MAAM,GAC5CF,OAAO,CAACC,GAAG,CAACG,QAAQ,KAAK,aAAa;AAC5C,MAAMC,MAAM,GAAG,cAAc;AAC7B,MAAMC,aAAa,GAAIC,OAAe,IAAa,GAAGF,MAAM,IAAIE,OAAO,EAAE;;AAEzE;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,WAAW,GAAGA,CAACD,OAAe,EAAEE,IAAe,KAAW;EAC9D,MAAMC,IAAI,GAAGD,IAAI,CAACE,MAAM,GAAG,CAAC,GAAG,IAAAC,YAAM,EAACL,OAAO,EAAE,GAAGE,IAAI,CAAC,GAAGF,OAAO;EACjEP,OAAO,CAACa,MAAM,CAACC,KAAK,CAAC,GAAGJ,IAAI,IAAI,CAAC;AACnC,CAAC;AAEM,MAAMK,MAAM,GAAAC,OAAA,CAAAD,MAAA,GAAG;EACpBH,MAAM,EAAEN,aAAa;EAErBW,KAAK,EAAEA,CAACV,OAAe,EAAE,GAAGE,IAAe,KAAW;IACpDS,OAAO,CAACD,KAAK,CAACX,aAAa,CAACC,OAAO,CAAC,EAAE,GAAGE,IAAI,CAAC;EAChD,CAAC;EAEDU,IAAI,EAAEA,CAACZ,OAAe,EAAE,GAAGE,IAAe,KAAW;IACnDS,OAAO,CAACC,IAAI,CAACb,aAAa,CAACC,OAAO,CAAC,EAAE,GAAGE,IAAI,CAAC;EAC/C,CAAC;EAEDW,IAAI,EAAEA,CAACb,OAAe,EAAE,GAAGE,IAAe,KAAW;IACnD,IAAIV,YAAY,EAAE;MAChBS,WAAW,CAACF,aAAa,CAACC,OAAO,CAAC,EAAEE,IAAI,CAAC;IAC3C;EACF,CAAC;EAEDY,GAAG,EAAEA,CAACd,OAAe,EAAE,GAAGE,IAAe,KAAW;IAClD,IAAIV,YAAY,EAAE;MAChBS,WAAW,CAACF,aAAa,CAACC,OAAO,CAAC,EAAEE,IAAI,CAAC;IAC3C;EACF,CAAC;EAEDa,KAAK,EAAEA,CAACf,OAAe,EAAE,GAAGE,IAAe,KAAW;IACpD,IAAIV,YAAY,EAAE;MAChBS,WAAW,CAACF,aAAa,CAACC,OAAO,CAAC,EAAEE,IAAI,CAAC;IAC3C;EACF;AACF,CAAC","ignoreList":[]}
|
|
@@ -2,6 +2,7 @@ import fs from 'fs';
|
|
|
2
2
|
import * as semver from 'semver';
|
|
3
3
|
const path = require('path');
|
|
4
4
|
import { resolveRNSDK, tryReadRNVersion } from '../../utils/resolveRNSDK';
|
|
5
|
+
import { logger } from '../../utils/logger';
|
|
5
6
|
|
|
6
7
|
// Threshold at which React Native pod autolinking moves from
|
|
7
8
|
// @react-native-community/cli (lexical, symlink-preserving) to
|
|
@@ -9,14 +10,6 @@ import { resolveRNSDK, tryReadRNVersion } from '../../utils/resolveRNSDK';
|
|
|
9
10
|
// :path strings on pnpm/yarn-symlink layouts, so to keep CocoaPods happy
|
|
10
11
|
// we must match whichever flavor will resolve the same package later.
|
|
11
12
|
const RN_REALPATH_AUTOLINKING_MIN_VERSION = '0.80.0';
|
|
12
|
-
const PLUGIN_LOG_PREFIX = '[CustomerIO Plugin]';
|
|
13
|
-
|
|
14
|
-
// Always-on so the trail shows up in customer-shared `expo prebuild`
|
|
15
|
-
// output without needing a separate verbose-mode opt-in.
|
|
16
|
-
function pluginLog(message) {
|
|
17
|
-
// eslint-disable-next-line no-console
|
|
18
|
-
console.log(`${PLUGIN_LOG_PREFIX} ${message}`);
|
|
19
|
-
}
|
|
20
13
|
|
|
21
14
|
/**
|
|
22
15
|
* Returns the relative path from the iOS project dir to the installed
|
|
@@ -32,21 +25,23 @@ function pluginLog(message) {
|
|
|
32
25
|
* via Node, emitting the underlying `.pnpm/...` (or yarn-classic)
|
|
33
26
|
* path. We match by realpath'ing the resolved directory.
|
|
34
27
|
*
|
|
35
|
-
* Decision points are logged
|
|
36
|
-
*
|
|
37
|
-
*
|
|
28
|
+
* Decision points are logged through the shared logger, gated by
|
|
29
|
+
* CUSTOMERIO_DEBUG_MODE. Defaulting to silent keeps the prebuild output
|
|
30
|
+
* clean for hosts that parse it (Expo's `--json` config, EAS build
|
|
31
|
+
* tooling), while still giving support a "rerun with this flag" path
|
|
32
|
+
* for triaging path-resolution issues.
|
|
38
33
|
*/
|
|
39
34
|
export function getRelativePathToRNSDK(iosPath) {
|
|
40
35
|
const rootAppPath = path.dirname(iosPath);
|
|
41
|
-
|
|
36
|
+
logger.info(`Resolving customerio-reactnative for Podfile (iosPath=${iosPath}, projectRoot=${rootAppPath})`);
|
|
42
37
|
const {
|
|
43
38
|
packageDir
|
|
44
39
|
} = resolveRNSDK(rootAppPath);
|
|
45
|
-
|
|
40
|
+
logger.info(`customerio-reactnative resolved to: ${packageDir}`);
|
|
46
41
|
const rnVersion = tryReadRNVersion(rootAppPath);
|
|
47
|
-
|
|
42
|
+
logger.info(`Detected react-native version: ${rnVersion ?? 'unknown'}`);
|
|
48
43
|
const useLexical = shouldUseLexicalPath(rnVersion);
|
|
49
|
-
|
|
44
|
+
logger.info(useLexical ? `RN <${RN_REALPATH_AUTOLINKING_MIN_VERSION} — using lexical/symlink path to match @react-native-community/cli autolinking` : `RN >=${RN_REALPATH_AUTOLINKING_MIN_VERSION} or unknown — using realpath to match expo-modules-autolinking`);
|
|
50
45
|
let absolutePath;
|
|
51
46
|
if (useLexical) {
|
|
52
47
|
absolutePath = packageDir;
|
|
@@ -54,15 +49,15 @@ export function getRelativePathToRNSDK(iosPath) {
|
|
|
54
49
|
try {
|
|
55
50
|
absolutePath = fs.realpathSync(packageDir);
|
|
56
51
|
if (absolutePath !== packageDir) {
|
|
57
|
-
|
|
52
|
+
logger.info(`Realpath differs from resolved dir: ${absolutePath}`);
|
|
58
53
|
}
|
|
59
54
|
} catch (err) {
|
|
60
|
-
|
|
55
|
+
logger.warn(`realpathSync failed (${err instanceof Error ? err.message : String(err)}); falling back to symlink path`);
|
|
61
56
|
absolutePath = packageDir;
|
|
62
57
|
}
|
|
63
58
|
}
|
|
64
59
|
const relativePath = path.relative(iosPath, absolutePath);
|
|
65
|
-
|
|
60
|
+
logger.info(`Final Podfile :path => '${relativePath}'`);
|
|
66
61
|
return relativePath;
|
|
67
62
|
}
|
|
68
63
|
function shouldUseLexicalPath(rnVersion) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["fs","semver","path","require","resolveRNSDK","tryReadRNVersion","RN_REALPATH_AUTOLINKING_MIN_VERSION","PLUGIN_LOG_PREFIX","pluginLog","message","console","log","getRelativePathToRNSDK","iosPath","rootAppPath","dirname","packageDir","rnVersion","useLexical","shouldUseLexicalPath","absolutePath","realpathSync","err","Error","String","relativePath","relative","coerced","valid","coerce","lt","IOS_DEPLOYMENT_TARGET","GROUP_IDENTIFIER_TEMPLATE_REGEX","BUNDLE_SHORT_VERSION_TEMPLATE_REGEX","BUNDLE_VERSION_TEMPLATE_REGEX","CIO_DIDFINISHLAUNCHINGMETHOD_REGEX","CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_REGEX","CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERRORFULL_REGEX","CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_REGEX","CIO_APPDELEGATEDECLARATION_REGEX","CIO_APPDELEGATEHEADER_REGEX","CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_REGEX","CIO_LAUNCHOPTIONS_DEEPLINK_MODIFIEDOPTIONS_REGEX","CIO_DEEPLINK_COMMENT_REGEX","DEFAULT_BUNDLE_VERSION","DEFAULT_BUNDLE_SHORT_VERSION","CIO_TARGET_NAME","CIO_NOTIFICATION_TARGET_NAME","CIO_APPDELEGATEHEADER_IMPORT_SNIPPET","CIO_APPDELEGATEHEADER_USER_NOTIFICATION_CENTER_SNIPPET","CIO_PUSHNOTIFICATIONHANDLERDECLARATION_SNIPPET","CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_SNIPPET","CIO_LAUNCHOPTIONS_MODIFIEDOPTIONS_SNIPPET","CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_SNIPPET","CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_SNIPPET","CIO_CONFIGURECIOSDKPUSHNOTIFICATION_SNIPPET","CIO_INITIALIZECIOSDK_SNIPPET","CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SNIPPET","CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SWIFT_SNIPPET","CIO_REGISTER_PUSHNOTIFICATION_SNIPPET","CIO_REGISTER_PUSHNOTIFICATION_SNIPPET_v2","CIO_REGISTER_PUSH_NOTIFICATION_PLACEHOLDER","CIO_MESSAGING_PUSH_APP_DELEGATE_INIT_REGEX","CIO_NATIVE_SDK_INITIALIZE_CALL","CIO_NATIVE_SDK_INITIALIZE_SNIPPET"],"sources":["ios.ts"],"sourcesContent":["import fs from 'fs';\nimport * as semver from 'semver';\n\nconst path = require('path');\nimport { resolveRNSDK, tryReadRNVersion } from '../../utils/resolveRNSDK';\n\n// Threshold at which React Native pod autolinking moves from\n// @react-native-community/cli (lexical, symlink-preserving) to\n// expo-modules-autolinking (realpath). The two flavors emit different\n// :path strings on pnpm/yarn-symlink layouts, so to keep CocoaPods happy\n// we must match whichever flavor will resolve the same package later.\nconst RN_REALPATH_AUTOLINKING_MIN_VERSION = '0.80.0';\n\nconst PLUGIN_LOG_PREFIX = '[CustomerIO Plugin]';\n\n// Always-on so the trail shows up in customer-shared `expo prebuild`\n// output without needing a separate verbose-mode opt-in.\nfunction pluginLog(message: string): void {\n // eslint-disable-next-line no-console\n console.log(`${PLUGIN_LOG_PREFIX} ${message}`);\n}\n\n/**\n * Returns the relative path from the iOS project dir to the installed\n * customerio-reactnative directory, in the exact form React Native pod\n * autolinking will emit for the same package. The two autolinking\n * flavors disagree on path shape under pnpm/yarn symlinks:\n *\n * - RN <0.80 (`@react-native-community/cli`): walks node_modules\n * lexically, preserves symlinks. We keep the symlink path too —\n * `tryResolveRNSDK` already does this without calling realpath.\n *\n * - RN >=0.80 (`expo-modules-autolinking`): realpaths the package\n * via Node, emitting the underlying `.pnpm/...` (or yarn-classic)\n * path. We match by realpath'ing the resolved directory.\n *\n * Decision points are logged so a customer's prebuild output is enough\n * to triage path-resolution issues without a follow-up \"set\n * CUSTOMERIO_DEBUG_MODE and rerun\" round-trip.\n */\nexport function getRelativePathToRNSDK(iosPath: string) {\n const rootAppPath = path.dirname(iosPath);\n pluginLog(\n `Resolving customerio-reactnative for Podfile (iosPath=${iosPath}, projectRoot=${rootAppPath})`\n );\n\n const { packageDir } = resolveRNSDK(rootAppPath);\n pluginLog(`customerio-reactnative resolved to: ${packageDir}`);\n\n const rnVersion = tryReadRNVersion(rootAppPath);\n pluginLog(`Detected react-native version: ${rnVersion ?? 'unknown'}`);\n\n const useLexical = shouldUseLexicalPath(rnVersion);\n pluginLog(\n useLexical\n ? `RN <${RN_REALPATH_AUTOLINKING_MIN_VERSION} — using lexical/symlink path to match @react-native-community/cli autolinking`\n : `RN >=${RN_REALPATH_AUTOLINKING_MIN_VERSION} or unknown — using realpath to match expo-modules-autolinking`\n );\n\n let absolutePath: string;\n if (useLexical) {\n absolutePath = packageDir;\n } else {\n try {\n absolutePath = fs.realpathSync(packageDir);\n if (absolutePath !== packageDir) {\n pluginLog(`Realpath differs from resolved dir: ${absolutePath}`);\n }\n } catch (err) {\n pluginLog(\n `realpathSync failed (${\n err instanceof Error ? err.message : String(err)\n }); falling back to symlink path`\n );\n absolutePath = packageDir;\n }\n }\n\n const relativePath = path.relative(iosPath, absolutePath);\n pluginLog(`Final Podfile :path => '${relativePath}'`);\n return relativePath;\n}\n\nfunction shouldUseLexicalPath(rnVersion: string | null): boolean {\n if (!rnVersion) {\n // Modern Expo (realpath) has been the working path for the last few\n // SDKs, so it's the safer default when RN can't be detected.\n return false;\n }\n const coerced = semver.valid(rnVersion) || semver.coerce(rnVersion);\n if (!coerced) {\n return false;\n }\n return semver.lt(coerced, RN_REALPATH_AUTOLINKING_MIN_VERSION);\n}\n\nexport const IOS_DEPLOYMENT_TARGET = '13.0';\nexport const GROUP_IDENTIFIER_TEMPLATE_REGEX = /{{GROUP_IDENTIFIER}}/gm;\nexport const BUNDLE_SHORT_VERSION_TEMPLATE_REGEX = /{{BUNDLE_SHORT_VERSION}}/gm;\nexport const BUNDLE_VERSION_TEMPLATE_REGEX = /{{BUNDLE_VERSION}}/gm;\nexport const CIO_DIDFINISHLAUNCHINGMETHOD_REGEX =\n /.*\\[super(\\s)application:application(\\s)didFinishLaunchingWithOptions:launchOptions\\];/;\n\nexport const CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_REGEX =\n /return \\[super application:application didFailToRegisterForRemoteNotificationsWithError:error\\];/;\n\nexport const CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERRORFULL_REGEX =\n /(- \\(void\\)application:\\(UIApplication \\*\\)application didFailToRegisterForRemoteNotificationsWithError:\\(NSError \\*\\)error(\\s|\\n)*?\\{)(.|\\n){2}.*\\n\\}/;\n\nexport const CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_REGEX =\n /return \\[super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken\\];/;\n\nexport const CIO_APPDELEGATEDECLARATION_REGEX =\n /@implementation AppDelegate(.|\\n)/;\n\nexport const CIO_APPDELEGATEHEADER_REGEX =\n /(@interface AppDelegate\\s*:\\s*EXAppDelegateWrapper\\s*)(<([^>]+)>)?/;\n\nexport const CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_REGEX =\n /^\\s*RCTBridge\\s*\\*\\s*\\w+\\s*=\\s*\\[\\s*self\\.reactDelegate\\s+createBridgeWithDelegate:self\\s+launchOptions:launchOptions\\s*\\];\\s*$/gm;\n\nexport const CIO_LAUNCHOPTIONS_DEEPLINK_MODIFIEDOPTIONS_REGEX =\n /^\\s*return\\s\\[\\s*super\\s*application:\\s*application\\s*didFinishLaunchingWithOptions\\s*:\\s*launchOptions\\s*\\];/gm;\n\nexport const CIO_DEEPLINK_COMMENT_REGEX =\n /\\sDeep link workaround for app killed state start/gm;\nexport const DEFAULT_BUNDLE_VERSION = '1';\nexport const DEFAULT_BUNDLE_SHORT_VERSION = '1.0';\nexport const CIO_TARGET_NAME = 'CustomerIOSDK';\nexport const CIO_NOTIFICATION_TARGET_NAME = 'NotificationService';\n\nexport const CIO_APPDELEGATEHEADER_IMPORT_SNIPPET = `#import <UserNotifications/UserNotifications.h>`;\nexport const CIO_APPDELEGATEHEADER_USER_NOTIFICATION_CENTER_SNIPPET =\n 'UNUserNotificationCenterDelegate';\nexport const CIO_PUSHNOTIFICATIONHANDLERDECLARATION_SNIPPET = `\nCIOAppPushNotificationsHandler* pnHandlerObj = [[CIOAppPushNotificationsHandler alloc] init];\n`;\nexport const CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_SNIPPET = `\nRCTBridge *bridge = [self.reactDelegate createBridgeWithDelegate:self launchOptions:modifiedLaunchOptions];\n`;\n\nexport const CIO_LAUNCHOPTIONS_MODIFIEDOPTIONS_SNIPPET = `\nreturn [super application:application didFinishLaunchingWithOptions:modifiedLaunchOptions];`;\n\nexport const CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_SNIPPET = `\n [super application:application didFailToRegisterForRemoteNotificationsWithError:error];\n [pnHandlerObj application:application error:error];\n`;\n\nexport const CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_SNIPPET = `\n [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];\n return [pnHandlerObj application:application deviceToken:deviceToken];\n`;\n\nexport const CIO_CONFIGURECIOSDKPUSHNOTIFICATION_SNIPPET = `\n // Register for push notifications\n [pnHandlerObj registerPushNotification];\n`;\n\nexport const CIO_INITIALIZECIOSDK_SNIPPET = ` \n [pnHandlerObj initializeCioSdk];\n\n// Code to make the CIO SDK compatible with expo-notifications package.\n// \n// The CIO SDK and expo-notifications both need to handle when a push gets clicked. However, iOS only allows one click handler to be set per app.\n// To get around this limitation, we set the CIO SDK as the click handler. The CIO SDK sets itself up so that when another SDK or host iOS app \n// sets itself as the click handler, the CIO SDK will still be able to handle when the push gets clicked, even though it's not the designated \n// click handler in iOS at runtime. \n// \n// This should work for most SDKs. However, expo-notifications is unique in it's implementation. It will not setup push click handling it if detects \n// that another SDK or host iOS app has already set itself as the click handler:\n// https://github.com/expo/expo/blob/1b29637bec0b9888e8bc8c310476293a3e2d9786/packages/expo-notifications/ios/EXNotifications/Notifications/EXNotificationCenterDelegate.m#L31-L37\n// ...to get around this, we must manually set it as the click handler after the CIO SDK. That's what this code block does.\n//\n// Note: Initialize the native iOS SDK and setup SDK push click handling before running this code. \n# if __has_include(<EXNotifications/EXNotificationCenterDelegate.h>)\n // Creating a new instance, as the comments in expo-notifications suggests, does not work. With this code, if you send a CIO push to device and click on it,\n // no push metrics reporting will occur.\n // EXNotificationCenterDelegate *notificationCenterDelegate = [[EXNotificationCenterDelegate alloc] init];\n\n // ...instead, get the singleton reference from Expo. \n id<UNUserNotificationCenterDelegate> notificationCenterDelegate = (id<UNUserNotificationCenterDelegate>) [EXModuleRegistryProvider getSingletonModuleForClass:[EXNotificationCenterDelegate class]];\n UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];\n center.delegate = notificationCenterDelegate;\n# endif\n`;\n\nexport const CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SNIPPET = `\n// Deep link workaround for app killed state start\nNSMutableDictionary *modifiedLaunchOptions = [NSMutableDictionary dictionaryWithDictionary:launchOptions];\n if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) {\n NSDictionary *pushContent = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];\n if (pushContent[@\"CIO\"] && pushContent[@\"CIO\"][@\"push\"] && pushContent[@\"CIO\"][@\"push\"][@\"link\"]) {\n NSString *initialURL = pushContent[@\"CIO\"][@\"push\"][@\"link\"];\n if (!launchOptions[UIApplicationLaunchOptionsURLKey]) {\n modifiedLaunchOptions[UIApplicationLaunchOptionsURLKey] = [NSURL URLWithString:initialURL];\n }\n }\n }\n//Deep link workaround for app killed state ends\n`;\n\nexport const CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SWIFT_SNIPPET = `\n // Deep link workaround for app killed state start\n var modifiedLaunchOptions = launchOptions\n if let launchOptions = launchOptions,\n let pushContent = launchOptions[UIApplication.LaunchOptionsKey.remoteNotification] as? [AnyHashable: Any],\n let cio = pushContent[\"CIO\"] as? [String: Any],\n let push = cio[\"push\"] as? [String: Any],\n let link = push[\"link\"] as? String,\n !launchOptions.keys.contains(UIApplication.LaunchOptionsKey.url) {\n \n var mutableLaunchOptions = launchOptions\n mutableLaunchOptions[UIApplication.LaunchOptionsKey.url] = URL(string: link)\n modifiedLaunchOptions = mutableLaunchOptions\n }\n // Deep link workaround for app killed state ends\n`;\n\nexport const CIO_REGISTER_PUSHNOTIFICATION_SNIPPET = `\n@objc(registerPushNotification)\n public func registerPushNotification() {\n\n let center = UNUserNotificationCenter.current()\n center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in\n if error == nil{\n DispatchQueue.main.async {\n UIApplication.shared.registerForRemoteNotifications()\n }\n }\n }\n }`;\n\nexport const CIO_REGISTER_PUSHNOTIFICATION_SNIPPET_v2 = `\n let center = UNUserNotificationCenter.current()\n center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in\n if error == nil{\n DispatchQueue.main.async {\n UIApplication.shared.registerForRemoteNotifications()\n }\n }\n }`;\n\nexport const CIO_REGISTER_PUSH_NOTIFICATION_PLACEHOLDER = /\\{\\{REGISTER_SNIPPET\\}\\}/;\n// Regex to match MessagingPush initialization in AppDelegate (different from NSE initialization)\nexport const CIO_MESSAGING_PUSH_APP_DELEGATE_INIT_REGEX = /(MessagingPush(?:APN|FCM)\\.initialize)/;\nexport const CIO_NATIVE_SDK_INITIALIZE_CALL = 'CustomerIOSDKInitializer.initialize()';\nexport const CIO_NATIVE_SDK_INITIALIZE_SNIPPET = `// Auto Initialize Native Customer.io SDK\n ${CIO_NATIVE_SDK_INITIALIZE_CALL}\n `;\n"],"mappings":"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CpC,OAAO,MAAMC,8CAA8C,GAAG;AAC9D;AACA,CAAC;AACD,OAAO,MAAMC,8CAA8C,GAAG;AAC9D;AACA,CAAC;AAED,OAAO,MAAMC,yCAAyC,GAAG;AACzD,4FAA4F;AAE5F,OAAO,MAAMC,4DAA4D,GAAG;AAC5E;AACA;AACA,CAAC;AAED,OAAO,MAAMC,4DAA4D,GAAG;AAC5E;AACA;AACA,CAAC;AAED,OAAO,MAAMC,2CAA2C,GAAG;AAC3D;AACA;AACA,CAAC;AAED,OAAO,MAAMC,4BAA4B,GAAG;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAED,OAAO,MAAMC,yCAAyC,GAAG;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAED,OAAO,MAAMC,+CAA+C,GAAG;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAED,OAAO,MAAMC,qCAAqC,GAAG;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AAEJ,OAAO,MAAMC,wCAAwC,GAAG;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AAEN,OAAO,MAAMC,0CAA0C,GAAG,0BAA0B;AACpF;AACA,OAAO,MAAMC,0CAA0C,GAAG,wCAAwC;AAClG,OAAO,MAAMC,8BAA8B,GAAG,uCAAuC;AACrF,OAAO,MAAMC,iCAAiC,GAAG;AACjD,MAAMD,8BAA8B;AACpC,KAAK","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["fs","semver","path","require","resolveRNSDK","tryReadRNVersion","logger","RN_REALPATH_AUTOLINKING_MIN_VERSION","getRelativePathToRNSDK","iosPath","rootAppPath","dirname","info","packageDir","rnVersion","useLexical","shouldUseLexicalPath","absolutePath","realpathSync","err","warn","Error","message","String","relativePath","relative","coerced","valid","coerce","lt","IOS_DEPLOYMENT_TARGET","GROUP_IDENTIFIER_TEMPLATE_REGEX","BUNDLE_SHORT_VERSION_TEMPLATE_REGEX","BUNDLE_VERSION_TEMPLATE_REGEX","CIO_DIDFINISHLAUNCHINGMETHOD_REGEX","CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_REGEX","CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERRORFULL_REGEX","CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_REGEX","CIO_APPDELEGATEDECLARATION_REGEX","CIO_APPDELEGATEHEADER_REGEX","CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_REGEX","CIO_LAUNCHOPTIONS_DEEPLINK_MODIFIEDOPTIONS_REGEX","CIO_DEEPLINK_COMMENT_REGEX","DEFAULT_BUNDLE_VERSION","DEFAULT_BUNDLE_SHORT_VERSION","CIO_TARGET_NAME","CIO_NOTIFICATION_TARGET_NAME","CIO_APPDELEGATEHEADER_IMPORT_SNIPPET","CIO_APPDELEGATEHEADER_USER_NOTIFICATION_CENTER_SNIPPET","CIO_PUSHNOTIFICATIONHANDLERDECLARATION_SNIPPET","CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_SNIPPET","CIO_LAUNCHOPTIONS_MODIFIEDOPTIONS_SNIPPET","CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_SNIPPET","CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_SNIPPET","CIO_CONFIGURECIOSDKPUSHNOTIFICATION_SNIPPET","CIO_INITIALIZECIOSDK_SNIPPET","CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SNIPPET","CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SWIFT_SNIPPET","CIO_REGISTER_PUSHNOTIFICATION_SNIPPET","CIO_REGISTER_PUSHNOTIFICATION_SNIPPET_v2","CIO_REGISTER_PUSH_NOTIFICATION_PLACEHOLDER","CIO_MESSAGING_PUSH_APP_DELEGATE_INIT_REGEX","CIO_NATIVE_SDK_INITIALIZE_CALL","CIO_NATIVE_SDK_INITIALIZE_SNIPPET"],"sources":["ios.ts"],"sourcesContent":["import fs from 'fs';\nimport * as semver from 'semver';\n\nconst path = require('path');\nimport { resolveRNSDK, tryReadRNVersion } from '../../utils/resolveRNSDK';\nimport { logger } from '../../utils/logger';\n\n// Threshold at which React Native pod autolinking moves from\n// @react-native-community/cli (lexical, symlink-preserving) to\n// expo-modules-autolinking (realpath). The two flavors emit different\n// :path strings on pnpm/yarn-symlink layouts, so to keep CocoaPods happy\n// we must match whichever flavor will resolve the same package later.\nconst RN_REALPATH_AUTOLINKING_MIN_VERSION = '0.80.0';\n\n/**\n * Returns the relative path from the iOS project dir to the installed\n * customerio-reactnative directory, in the exact form React Native pod\n * autolinking will emit for the same package. The two autolinking\n * flavors disagree on path shape under pnpm/yarn symlinks:\n *\n * - RN <0.80 (`@react-native-community/cli`): walks node_modules\n * lexically, preserves symlinks. We keep the symlink path too —\n * `tryResolveRNSDK` already does this without calling realpath.\n *\n * - RN >=0.80 (`expo-modules-autolinking`): realpaths the package\n * via Node, emitting the underlying `.pnpm/...` (or yarn-classic)\n * path. We match by realpath'ing the resolved directory.\n *\n * Decision points are logged through the shared logger, gated by\n * CUSTOMERIO_DEBUG_MODE. Defaulting to silent keeps the prebuild output\n * clean for hosts that parse it (Expo's `--json` config, EAS build\n * tooling), while still giving support a \"rerun with this flag\" path\n * for triaging path-resolution issues.\n */\nexport function getRelativePathToRNSDK(iosPath: string) {\n const rootAppPath = path.dirname(iosPath);\n logger.info(\n `Resolving customerio-reactnative for Podfile (iosPath=${iosPath}, projectRoot=${rootAppPath})`\n );\n\n const { packageDir } = resolveRNSDK(rootAppPath);\n logger.info(`customerio-reactnative resolved to: ${packageDir}`);\n\n const rnVersion = tryReadRNVersion(rootAppPath);\n logger.info(`Detected react-native version: ${rnVersion ?? 'unknown'}`);\n\n const useLexical = shouldUseLexicalPath(rnVersion);\n logger.info(\n useLexical\n ? `RN <${RN_REALPATH_AUTOLINKING_MIN_VERSION} — using lexical/symlink path to match @react-native-community/cli autolinking`\n : `RN >=${RN_REALPATH_AUTOLINKING_MIN_VERSION} or unknown — using realpath to match expo-modules-autolinking`\n );\n\n let absolutePath: string;\n if (useLexical) {\n absolutePath = packageDir;\n } else {\n try {\n absolutePath = fs.realpathSync(packageDir);\n if (absolutePath !== packageDir) {\n logger.info(`Realpath differs from resolved dir: ${absolutePath}`);\n }\n } catch (err) {\n logger.warn(\n `realpathSync failed (${\n err instanceof Error ? err.message : String(err)\n }); falling back to symlink path`\n );\n absolutePath = packageDir;\n }\n }\n\n const relativePath = path.relative(iosPath, absolutePath);\n logger.info(`Final Podfile :path => '${relativePath}'`);\n return relativePath;\n}\n\nfunction shouldUseLexicalPath(rnVersion: string | null): boolean {\n if (!rnVersion) {\n // Modern Expo (realpath) has been the working path for the last few\n // SDKs, so it's the safer default when RN can't be detected.\n return false;\n }\n const coerced = semver.valid(rnVersion) || semver.coerce(rnVersion);\n if (!coerced) {\n return false;\n }\n return semver.lt(coerced, RN_REALPATH_AUTOLINKING_MIN_VERSION);\n}\n\nexport const IOS_DEPLOYMENT_TARGET = '13.0';\nexport const GROUP_IDENTIFIER_TEMPLATE_REGEX = /{{GROUP_IDENTIFIER}}/gm;\nexport const BUNDLE_SHORT_VERSION_TEMPLATE_REGEX = /{{BUNDLE_SHORT_VERSION}}/gm;\nexport const BUNDLE_VERSION_TEMPLATE_REGEX = /{{BUNDLE_VERSION}}/gm;\nexport const CIO_DIDFINISHLAUNCHINGMETHOD_REGEX =\n /.*\\[super(\\s)application:application(\\s)didFinishLaunchingWithOptions:launchOptions\\];/;\n\nexport const CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_REGEX =\n /return \\[super application:application didFailToRegisterForRemoteNotificationsWithError:error\\];/;\n\nexport const CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERRORFULL_REGEX =\n /(- \\(void\\)application:\\(UIApplication \\*\\)application didFailToRegisterForRemoteNotificationsWithError:\\(NSError \\*\\)error(\\s|\\n)*?\\{)(.|\\n){2}.*\\n\\}/;\n\nexport const CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_REGEX =\n /return \\[super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken\\];/;\n\nexport const CIO_APPDELEGATEDECLARATION_REGEX =\n /@implementation AppDelegate(.|\\n)/;\n\nexport const CIO_APPDELEGATEHEADER_REGEX =\n /(@interface AppDelegate\\s*:\\s*EXAppDelegateWrapper\\s*)(<([^>]+)>)?/;\n\nexport const CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_REGEX =\n /^\\s*RCTBridge\\s*\\*\\s*\\w+\\s*=\\s*\\[\\s*self\\.reactDelegate\\s+createBridgeWithDelegate:self\\s+launchOptions:launchOptions\\s*\\];\\s*$/gm;\n\nexport const CIO_LAUNCHOPTIONS_DEEPLINK_MODIFIEDOPTIONS_REGEX =\n /^\\s*return\\s\\[\\s*super\\s*application:\\s*application\\s*didFinishLaunchingWithOptions\\s*:\\s*launchOptions\\s*\\];/gm;\n\nexport const CIO_DEEPLINK_COMMENT_REGEX =\n /\\sDeep link workaround for app killed state start/gm;\nexport const DEFAULT_BUNDLE_VERSION = '1';\nexport const DEFAULT_BUNDLE_SHORT_VERSION = '1.0';\nexport const CIO_TARGET_NAME = 'CustomerIOSDK';\nexport const CIO_NOTIFICATION_TARGET_NAME = 'NotificationService';\n\nexport const CIO_APPDELEGATEHEADER_IMPORT_SNIPPET = `#import <UserNotifications/UserNotifications.h>`;\nexport const CIO_APPDELEGATEHEADER_USER_NOTIFICATION_CENTER_SNIPPET =\n 'UNUserNotificationCenterDelegate';\nexport const CIO_PUSHNOTIFICATIONHANDLERDECLARATION_SNIPPET = `\nCIOAppPushNotificationsHandler* pnHandlerObj = [[CIOAppPushNotificationsHandler alloc] init];\n`;\nexport const CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_SNIPPET = `\nRCTBridge *bridge = [self.reactDelegate createBridgeWithDelegate:self launchOptions:modifiedLaunchOptions];\n`;\n\nexport const CIO_LAUNCHOPTIONS_MODIFIEDOPTIONS_SNIPPET = `\nreturn [super application:application didFinishLaunchingWithOptions:modifiedLaunchOptions];`;\n\nexport const CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_SNIPPET = `\n [super application:application didFailToRegisterForRemoteNotificationsWithError:error];\n [pnHandlerObj application:application error:error];\n`;\n\nexport const CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_SNIPPET = `\n [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];\n return [pnHandlerObj application:application deviceToken:deviceToken];\n`;\n\nexport const CIO_CONFIGURECIOSDKPUSHNOTIFICATION_SNIPPET = `\n // Register for push notifications\n [pnHandlerObj registerPushNotification];\n`;\n\nexport const CIO_INITIALIZECIOSDK_SNIPPET = ` \n [pnHandlerObj initializeCioSdk];\n\n// Code to make the CIO SDK compatible with expo-notifications package.\n// \n// The CIO SDK and expo-notifications both need to handle when a push gets clicked. However, iOS only allows one click handler to be set per app.\n// To get around this limitation, we set the CIO SDK as the click handler. The CIO SDK sets itself up so that when another SDK or host iOS app \n// sets itself as the click handler, the CIO SDK will still be able to handle when the push gets clicked, even though it's not the designated \n// click handler in iOS at runtime. \n// \n// This should work for most SDKs. However, expo-notifications is unique in it's implementation. It will not setup push click handling it if detects \n// that another SDK or host iOS app has already set itself as the click handler:\n// https://github.com/expo/expo/blob/1b29637bec0b9888e8bc8c310476293a3e2d9786/packages/expo-notifications/ios/EXNotifications/Notifications/EXNotificationCenterDelegate.m#L31-L37\n// ...to get around this, we must manually set it as the click handler after the CIO SDK. That's what this code block does.\n//\n// Note: Initialize the native iOS SDK and setup SDK push click handling before running this code. \n# if __has_include(<EXNotifications/EXNotificationCenterDelegate.h>)\n // Creating a new instance, as the comments in expo-notifications suggests, does not work. With this code, if you send a CIO push to device and click on it,\n // no push metrics reporting will occur.\n // EXNotificationCenterDelegate *notificationCenterDelegate = [[EXNotificationCenterDelegate alloc] init];\n\n // ...instead, get the singleton reference from Expo. \n id<UNUserNotificationCenterDelegate> notificationCenterDelegate = (id<UNUserNotificationCenterDelegate>) [EXModuleRegistryProvider getSingletonModuleForClass:[EXNotificationCenterDelegate class]];\n UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];\n center.delegate = notificationCenterDelegate;\n# endif\n`;\n\nexport const CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SNIPPET = `\n// Deep link workaround for app killed state start\nNSMutableDictionary *modifiedLaunchOptions = [NSMutableDictionary dictionaryWithDictionary:launchOptions];\n if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) {\n NSDictionary *pushContent = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];\n if (pushContent[@\"CIO\"] && pushContent[@\"CIO\"][@\"push\"] && pushContent[@\"CIO\"][@\"push\"][@\"link\"]) {\n NSString *initialURL = pushContent[@\"CIO\"][@\"push\"][@\"link\"];\n if (!launchOptions[UIApplicationLaunchOptionsURLKey]) {\n modifiedLaunchOptions[UIApplicationLaunchOptionsURLKey] = [NSURL URLWithString:initialURL];\n }\n }\n }\n//Deep link workaround for app killed state ends\n`;\n\nexport const CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SWIFT_SNIPPET = `\n // Deep link workaround for app killed state start\n var modifiedLaunchOptions = launchOptions\n if let launchOptions = launchOptions,\n let pushContent = launchOptions[UIApplication.LaunchOptionsKey.remoteNotification] as? [AnyHashable: Any],\n let cio = pushContent[\"CIO\"] as? [String: Any],\n let push = cio[\"push\"] as? [String: Any],\n let link = push[\"link\"] as? String,\n !launchOptions.keys.contains(UIApplication.LaunchOptionsKey.url) {\n \n var mutableLaunchOptions = launchOptions\n mutableLaunchOptions[UIApplication.LaunchOptionsKey.url] = URL(string: link)\n modifiedLaunchOptions = mutableLaunchOptions\n }\n // Deep link workaround for app killed state ends\n`;\n\nexport const CIO_REGISTER_PUSHNOTIFICATION_SNIPPET = `\n@objc(registerPushNotification)\n public func registerPushNotification() {\n\n let center = UNUserNotificationCenter.current()\n center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in\n if error == nil{\n DispatchQueue.main.async {\n UIApplication.shared.registerForRemoteNotifications()\n }\n }\n }\n }`;\n\nexport const CIO_REGISTER_PUSHNOTIFICATION_SNIPPET_v2 = `\n let center = UNUserNotificationCenter.current()\n center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in\n if error == nil{\n DispatchQueue.main.async {\n UIApplication.shared.registerForRemoteNotifications()\n }\n }\n }`;\n\nexport const CIO_REGISTER_PUSH_NOTIFICATION_PLACEHOLDER = /\\{\\{REGISTER_SNIPPET\\}\\}/;\n// Regex to match MessagingPush initialization in AppDelegate (different from NSE initialization)\nexport const CIO_MESSAGING_PUSH_APP_DELEGATE_INIT_REGEX = /(MessagingPush(?:APN|FCM)\\.initialize)/;\nexport const CIO_NATIVE_SDK_INITIALIZE_CALL = 'CustomerIOSDKInitializer.initialize()';\nexport const CIO_NATIVE_SDK_INITIALIZE_SNIPPET = `// Auto Initialize Native Customer.io SDK\n ${CIO_NATIVE_SDK_INITIALIZE_CALL}\n `;\n"],"mappings":"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AACA,CAAC;AACD,OAAO,MAAMC,8CAA8C,GAAG;AAC9D;AACA,CAAC;AAED,OAAO,MAAMC,yCAAyC,GAAG;AACzD,4FAA4F;AAE5F,OAAO,MAAMC,4DAA4D,GAAG;AAC5E;AACA;AACA,CAAC;AAED,OAAO,MAAMC,4DAA4D,GAAG;AAC5E;AACA;AACA,CAAC;AAED,OAAO,MAAMC,2CAA2C,GAAG;AAC3D;AACA;AACA,CAAC;AAED,OAAO,MAAMC,4BAA4B,GAAG;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAED,OAAO,MAAMC,yCAAyC,GAAG;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAED,OAAO,MAAMC,+CAA+C,GAAG;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAED,OAAO,MAAMC,qCAAqC,GAAG;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AAEJ,OAAO,MAAMC,wCAAwC,GAAG;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AAEN,OAAO,MAAMC,0CAA0C,GAAG,0BAA0B;AACpF;AACA,OAAO,MAAMC,0CAA0C,GAAG,wCAAwC;AAClG,OAAO,MAAMC,8BAA8B,GAAG,uCAAuC;AACrF,OAAO,MAAMC,iCAAiC,GAAG;AACjD,MAAMD,8BAA8B;AACpC,KAAK","ignoreList":[]}
|
|
@@ -60,7 +60,11 @@ export async function injectCIOPodfileCode(iosPath, isFcmPushProvider, options)
|
|
|
60
60
|
const podfile = await FileManagement.read(filename);
|
|
61
61
|
const next = injectHostAppPodfileCode(podfile, iosPath, isFcmPushProvider, options);
|
|
62
62
|
if (next !== podfile) {
|
|
63
|
-
|
|
63
|
+
// Await: the next iOS mod (withCioNotificationsXcodeProject) reads this
|
|
64
|
+
// same Podfile. Returning before the write flushes lets the next read
|
|
65
|
+
// race against the in-flight truncate, which (via FileManagement.read's
|
|
66
|
+
// empty-data fallback) rejects with null and aborts the NSE pipeline.
|
|
67
|
+
await FileManagement.write(filename, next);
|
|
64
68
|
} else {
|
|
65
69
|
logger.info('CustomerIO Podfile snippets already exists. Skipping...');
|
|
66
70
|
}
|
|
@@ -97,7 +101,7 @@ export async function injectCIONotificationPodfileCode(iosPath, useFrameworks, i
|
|
|
97
101
|
if (next !== podfile) {
|
|
98
102
|
// FileManagement.append matches what the previous direct-append did.
|
|
99
103
|
// Slice off the leading content (already on disk) and append only the new tail.
|
|
100
|
-
FileManagement.append(filename, next.slice(podfile.length));
|
|
104
|
+
await FileManagement.append(filename, next.slice(podfile.length));
|
|
101
105
|
}
|
|
102
106
|
}
|
|
103
107
|
//# sourceMappingURL=injectCIOPodfileCode.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["logger","getRelativePathToRNSDK","injectCodeByRegex","FileManagement","buildHostAppPodSnippet","iosPath","isFcmPushProvider","options","resolvedPath","locationEnabled","hasPush","subspec","pushSubspec","HOST_APP_BLOCK_START","HOST_APP_BLOCK_END","NOTIFICATION_BLOCK_START","NOTIFICATION_BLOCK_END","injectHostAppPodfileCode","podfileContent","match","RegExp","lineInPodfileToInjectSnippetBefore","podLine","snippetToInjectInPodfile","trim","join","injectCIOPodfileCode","filename","podfile","read","next","write","info","appendNotificationTargetToPodfile","useFrameworks","snippetToAppend","injectCIONotificationPodfileCode","append","slice","length"],"sources":["injectCIOPodfileCode.ts"],"sourcesContent":["import type { CustomerIOPluginOptionsIOS } from '../../types/cio-types';\nimport { logger } from '../../utils/logger';\nimport { getRelativePathToRNSDK } from '../constants/ios';\nimport { injectCodeByRegex } from './codeInjection';\nimport { FileManagement } from './fileManagement';\n\nexport type InjectCIOPodfileOptions = {\n /** When true, add the location subspec. When false/omit, use single push subspec only. */\n locationEnabled?: boolean;\n /** When false and locationEnabled, inject only :subspecs => ['location']. When true, use push + location. */\n hasPush?: boolean;\n};\n\n/** Builds the host-app pod snippet for the Podfile.\n *\n * The :path is resolved at prebuild time by `getRelativePathToRNSDK`,\n * which dispatches on the installed React Native version so the path\n * matches what RN pod autolinking will emit (lexical for RN <0.80,\n * realpath for RN >=0.80). Baking the resolved string directly avoids\n * any Ruby/install-time logic in the Podfile and keeps the snippet\n * trivially diff-able.\n *\n * Exported for tests.\n */\nexport function buildHostAppPodSnippet(\n iosPath: string,\n isFcmPushProvider: boolean,\n options?: InjectCIOPodfileOptions\n): string {\n const resolvedPath = getRelativePathToRNSDK(iosPath);\n const locationEnabled = options?.locationEnabled === true;\n const hasPush = options?.hasPush !== false;\n\n if (!locationEnabled) {\n const subspec = isFcmPushProvider ? 'fcm' : 'apn';\n return `pod 'customerio-reactnative/${subspec}', :path => '${resolvedPath}'`;\n }\n if (!hasPush) {\n return `pod 'customerio-reactnative', :subspecs => ['location'], :path => '${resolvedPath}'`;\n }\n const pushSubspec = isFcmPushProvider ? 'fcm' : 'apn';\n return `pod 'customerio-reactnative', :subspecs => ['${pushSubspec}', 'location'], :path => '${resolvedPath}'`;\n}\n\nconst HOST_APP_BLOCK_START = '# --- CustomerIO Host App START ---';\nconst HOST_APP_BLOCK_END = '# --- CustomerIO Host App END ---';\nconst NOTIFICATION_BLOCK_START = '# --- CustomerIO Notification START ---';\nconst NOTIFICATION_BLOCK_END = '# --- CustomerIO Notification END ---';\n\n/**\n * Pure string transform: given the existing Podfile contents, returns the\n * Podfile with the CustomerIO host-app block injected before the Expo\n * `post_install do |installer|` anchor. Idempotent — returns input unchanged\n * if the block is already present.\n */\nexport function injectHostAppPodfileCode(\n podfileContent: string,\n iosPath: string,\n isFcmPushProvider: boolean,\n options?: InjectCIOPodfileOptions\n): string {\n if (podfileContent.match(new RegExp(HOST_APP_BLOCK_START))) {\n return podfileContent;\n }\n\n // We need to decide what line of code in the Podfile to insert our native code.\n // The \"post_install\" line is always present in an Expo project Podfile so it's reliable.\n // Find that line in the Podfile and then we will insert our code above that line.\n const lineInPodfileToInjectSnippetBefore = /post_install do \\|installer\\|/;\n const podLine = buildHostAppPodSnippet(iosPath, isFcmPushProvider, options);\n\n const snippetToInjectInPodfile = `\n${HOST_APP_BLOCK_START}\n ${podLine}\n${HOST_APP_BLOCK_END}\n`.trim();\n\n return injectCodeByRegex(\n podfileContent,\n lineInPodfileToInjectSnippetBefore,\n snippetToInjectInPodfile,\n ).join('\\n');\n}\n\nexport async function injectCIOPodfileCode(\n iosPath: string,\n isFcmPushProvider: boolean,\n options?: InjectCIOPodfileOptions\n) {\n const filename = `${iosPath}/Podfile`;\n const podfile = await FileManagement.read(filename);\n const next = injectHostAppPodfileCode(podfile, iosPath, isFcmPushProvider, options);\n if (next !== podfile) {\n FileManagement.write(filename, next);\n } else {\n logger.info('CustomerIO Podfile snippets already exists. Skipping...');\n }\n}\n\n/**\n * Pure string transform: given the existing Podfile contents, returns the\n * Podfile with the rich-push NotificationService target block appended at\n * the end. Idempotent — returns input unchanged if the block is already\n * present.\n */\nexport function appendNotificationTargetToPodfile(\n podfileContent: string,\n iosPath: string,\n isFcmPushProvider: boolean,\n useFrameworks: CustomerIOPluginOptionsIOS['useFrameworks'],\n): string {\n if (podfileContent.match(new RegExp(NOTIFICATION_BLOCK_START))) {\n return podfileContent;\n }\n\n const snippetToAppend = `\n${NOTIFICATION_BLOCK_START}\ntarget 'NotificationService' do\n ${useFrameworks === 'static' ? 'use_frameworks! :linkage => :static' : ''}\n pod 'customerio-reactnative-richpush/${isFcmPushProvider ? 'fcm' : 'apn'}', :path => '${getRelativePathToRNSDK(iosPath)}'\nend\n${NOTIFICATION_BLOCK_END}\n`.trim();\n\n // Mirror FileManagement.append: append directly with no separator (real\n // Podfiles end with a trailing newline, so the appended block starts on a\n // fresh line in practice).\n return `${podfileContent}${snippetToAppend}`;\n}\n\nexport async function injectCIONotificationPodfileCode(\n iosPath: string,\n useFrameworks: CustomerIOPluginOptionsIOS['useFrameworks'],\n isFcmPushProvider: boolean\n) {\n const filename = `${iosPath}/Podfile`;\n const podfile = await FileManagement.read(filename);\n const next = appendNotificationTargetToPodfile(\n podfile,\n iosPath,\n isFcmPushProvider,\n useFrameworks,\n );\n if (next !== podfile) {\n // FileManagement.append matches what the previous direct-append did.\n // Slice off the leading content (already on disk) and append only the new tail.\n FileManagement.append(filename, next.slice(podfile.length));\n }\n}\n"],"mappings":"AACA,SAASA,MAAM,QAAQ,oBAAoB;AAC3C,SAASC,sBAAsB,QAAQ,kBAAkB;AACzD,SAASC,iBAAiB,QAAQ,iBAAiB;AACnD,SAASC,cAAc,QAAQ,kBAAkB;AASjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,sBAAsBA,CACpCC,OAAe,EACfC,iBAA0B,EAC1BC,OAAiC,EACzB;EACR,MAAMC,YAAY,GAAGP,sBAAsB,CAACI,OAAO,CAAC;EACpD,MAAMI,eAAe,GAAG,CAAAF,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEE,eAAe,MAAK,IAAI;EACzD,MAAMC,OAAO,GAAG,CAAAH,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEG,OAAO,MAAK,KAAK;EAE1C,IAAI,CAACD,eAAe,EAAE;IACpB,MAAME,OAAO,GAAGL,iBAAiB,GAAG,KAAK,GAAG,KAAK;IACjD,OAAO,+BAA+BK,OAAO,gBAAgBH,YAAY,GAAG;EAC9E;EACA,IAAI,CAACE,OAAO,EAAE;IACZ,OAAO,sEAAsEF,YAAY,GAAG;EAC9F;EACA,MAAMI,WAAW,GAAGN,iBAAiB,GAAG,KAAK,GAAG,KAAK;EACrD,OAAO,gDAAgDM,WAAW,6BAA6BJ,YAAY,GAAG;AAChH;AAEA,MAAMK,oBAAoB,GAAG,qCAAqC;AAClE,MAAMC,kBAAkB,GAAG,mCAAmC;AAC9D,MAAMC,wBAAwB,GAAG,yCAAyC;AAC1E,MAAMC,sBAAsB,GAAG,uCAAuC;;AAEtE;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,wBAAwBA,CACtCC,cAAsB,EACtBb,OAAe,EACfC,iBAA0B,EAC1BC,OAAiC,EACzB;EACR,IAAIW,cAAc,CAACC,KAAK,CAAC,IAAIC,MAAM,CAACP,oBAAoB,CAAC,CAAC,EAAE;IAC1D,OAAOK,cAAc;EACvB;;EAEA;EACA;EACA;EACA,MAAMG,kCAAkC,GAAG,+BAA+B;EAC1E,MAAMC,OAAO,GAAGlB,sBAAsB,CAACC,OAAO,EAAEC,iBAAiB,EAAEC,OAAO,CAAC;EAE3E,MAAMgB,wBAAwB,GAAG;AACnC,EAAEV,oBAAoB;AACtB,IAAIS,OAAO;AACX,EAAER,kBAAkB;AACpB,CAAC,CAACU,IAAI,CAAC,CAAC;EAEN,OAAOtB,iBAAiB,CACtBgB,cAAc,EACdG,kCAAkC,EAClCE,wBACF,CAAC,CAACE,IAAI,CAAC,IAAI,CAAC;AACd;AAEA,OAAO,eAAeC,oBAAoBA,CACxCrB,OAAe,EACfC,iBAA0B,EAC1BC,OAAiC,EACjC;EACA,MAAMoB,QAAQ,GAAG,GAAGtB,OAAO,UAAU;EACrC,MAAMuB,OAAO,GAAG,MAAMzB,cAAc,CAAC0B,IAAI,CAACF,QAAQ,CAAC;EACnD,MAAMG,IAAI,GAAGb,wBAAwB,CAACW,OAAO,EAAEvB,OAAO,EAAEC,iBAAiB,EAAEC,OAAO,CAAC;EACnF,IAAIuB,IAAI,KAAKF,OAAO,EAAE;
|
|
1
|
+
{"version":3,"names":["logger","getRelativePathToRNSDK","injectCodeByRegex","FileManagement","buildHostAppPodSnippet","iosPath","isFcmPushProvider","options","resolvedPath","locationEnabled","hasPush","subspec","pushSubspec","HOST_APP_BLOCK_START","HOST_APP_BLOCK_END","NOTIFICATION_BLOCK_START","NOTIFICATION_BLOCK_END","injectHostAppPodfileCode","podfileContent","match","RegExp","lineInPodfileToInjectSnippetBefore","podLine","snippetToInjectInPodfile","trim","join","injectCIOPodfileCode","filename","podfile","read","next","write","info","appendNotificationTargetToPodfile","useFrameworks","snippetToAppend","injectCIONotificationPodfileCode","append","slice","length"],"sources":["injectCIOPodfileCode.ts"],"sourcesContent":["import type { CustomerIOPluginOptionsIOS } from '../../types/cio-types';\nimport { logger } from '../../utils/logger';\nimport { getRelativePathToRNSDK } from '../constants/ios';\nimport { injectCodeByRegex } from './codeInjection';\nimport { FileManagement } from './fileManagement';\n\nexport type InjectCIOPodfileOptions = {\n /** When true, add the location subspec. When false/omit, use single push subspec only. */\n locationEnabled?: boolean;\n /** When false and locationEnabled, inject only :subspecs => ['location']. When true, use push + location. */\n hasPush?: boolean;\n};\n\n/** Builds the host-app pod snippet for the Podfile.\n *\n * The :path is resolved at prebuild time by `getRelativePathToRNSDK`,\n * which dispatches on the installed React Native version so the path\n * matches what RN pod autolinking will emit (lexical for RN <0.80,\n * realpath for RN >=0.80). Baking the resolved string directly avoids\n * any Ruby/install-time logic in the Podfile and keeps the snippet\n * trivially diff-able.\n *\n * Exported for tests.\n */\nexport function buildHostAppPodSnippet(\n iosPath: string,\n isFcmPushProvider: boolean,\n options?: InjectCIOPodfileOptions\n): string {\n const resolvedPath = getRelativePathToRNSDK(iosPath);\n const locationEnabled = options?.locationEnabled === true;\n const hasPush = options?.hasPush !== false;\n\n if (!locationEnabled) {\n const subspec = isFcmPushProvider ? 'fcm' : 'apn';\n return `pod 'customerio-reactnative/${subspec}', :path => '${resolvedPath}'`;\n }\n if (!hasPush) {\n return `pod 'customerio-reactnative', :subspecs => ['location'], :path => '${resolvedPath}'`;\n }\n const pushSubspec = isFcmPushProvider ? 'fcm' : 'apn';\n return `pod 'customerio-reactnative', :subspecs => ['${pushSubspec}', 'location'], :path => '${resolvedPath}'`;\n}\n\nconst HOST_APP_BLOCK_START = '# --- CustomerIO Host App START ---';\nconst HOST_APP_BLOCK_END = '# --- CustomerIO Host App END ---';\nconst NOTIFICATION_BLOCK_START = '# --- CustomerIO Notification START ---';\nconst NOTIFICATION_BLOCK_END = '# --- CustomerIO Notification END ---';\n\n/**\n * Pure string transform: given the existing Podfile contents, returns the\n * Podfile with the CustomerIO host-app block injected before the Expo\n * `post_install do |installer|` anchor. Idempotent — returns input unchanged\n * if the block is already present.\n */\nexport function injectHostAppPodfileCode(\n podfileContent: string,\n iosPath: string,\n isFcmPushProvider: boolean,\n options?: InjectCIOPodfileOptions\n): string {\n if (podfileContent.match(new RegExp(HOST_APP_BLOCK_START))) {\n return podfileContent;\n }\n\n // We need to decide what line of code in the Podfile to insert our native code.\n // The \"post_install\" line is always present in an Expo project Podfile so it's reliable.\n // Find that line in the Podfile and then we will insert our code above that line.\n const lineInPodfileToInjectSnippetBefore = /post_install do \\|installer\\|/;\n const podLine = buildHostAppPodSnippet(iosPath, isFcmPushProvider, options);\n\n const snippetToInjectInPodfile = `\n${HOST_APP_BLOCK_START}\n ${podLine}\n${HOST_APP_BLOCK_END}\n`.trim();\n\n return injectCodeByRegex(\n podfileContent,\n lineInPodfileToInjectSnippetBefore,\n snippetToInjectInPodfile,\n ).join('\\n');\n}\n\nexport async function injectCIOPodfileCode(\n iosPath: string,\n isFcmPushProvider: boolean,\n options?: InjectCIOPodfileOptions\n) {\n const filename = `${iosPath}/Podfile`;\n const podfile = await FileManagement.read(filename);\n const next = injectHostAppPodfileCode(podfile, iosPath, isFcmPushProvider, options);\n if (next !== podfile) {\n // Await: the next iOS mod (withCioNotificationsXcodeProject) reads this\n // same Podfile. Returning before the write flushes lets the next read\n // race against the in-flight truncate, which (via FileManagement.read's\n // empty-data fallback) rejects with null and aborts the NSE pipeline.\n await FileManagement.write(filename, next);\n } else {\n logger.info('CustomerIO Podfile snippets already exists. Skipping...');\n }\n}\n\n/**\n * Pure string transform: given the existing Podfile contents, returns the\n * Podfile with the rich-push NotificationService target block appended at\n * the end. Idempotent — returns input unchanged if the block is already\n * present.\n */\nexport function appendNotificationTargetToPodfile(\n podfileContent: string,\n iosPath: string,\n isFcmPushProvider: boolean,\n useFrameworks: CustomerIOPluginOptionsIOS['useFrameworks'],\n): string {\n if (podfileContent.match(new RegExp(NOTIFICATION_BLOCK_START))) {\n return podfileContent;\n }\n\n const snippetToAppend = `\n${NOTIFICATION_BLOCK_START}\ntarget 'NotificationService' do\n ${useFrameworks === 'static' ? 'use_frameworks! :linkage => :static' : ''}\n pod 'customerio-reactnative-richpush/${isFcmPushProvider ? 'fcm' : 'apn'}', :path => '${getRelativePathToRNSDK(iosPath)}'\nend\n${NOTIFICATION_BLOCK_END}\n`.trim();\n\n // Mirror FileManagement.append: append directly with no separator (real\n // Podfiles end with a trailing newline, so the appended block starts on a\n // fresh line in practice).\n return `${podfileContent}${snippetToAppend}`;\n}\n\nexport async function injectCIONotificationPodfileCode(\n iosPath: string,\n useFrameworks: CustomerIOPluginOptionsIOS['useFrameworks'],\n isFcmPushProvider: boolean\n) {\n const filename = `${iosPath}/Podfile`;\n const podfile = await FileManagement.read(filename);\n const next = appendNotificationTargetToPodfile(\n podfile,\n iosPath,\n isFcmPushProvider,\n useFrameworks,\n );\n if (next !== podfile) {\n // FileManagement.append matches what the previous direct-append did.\n // Slice off the leading content (already on disk) and append only the new tail.\n await FileManagement.append(filename, next.slice(podfile.length));\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -134,7 +134,7 @@ export function addNotificationServiceExtensionToXcodeProject(xcodeProject, opti
|
|
|
134
134
|
// - https://github.com/apache/cordova-node-xcode/blob/8b98cabc5978359db88dc9ff2d4c015cba40f150/lib/pbxProject.js#L860
|
|
135
135
|
const projObjects = xcodeProject.hash.project.objects;
|
|
136
136
|
projObjects.PBXTargetDependency = projObjects.PBXTargetDependency || {};
|
|
137
|
-
projObjects.PBXContainerItemProxy = projObjects.
|
|
137
|
+
projObjects.PBXContainerItemProxy = projObjects.PBXContainerItemProxy || {};
|
|
138
138
|
|
|
139
139
|
// Add the NSE target. This also adds PBXTargetDependency and PBXContainerItemProxy.
|
|
140
140
|
const nseTarget = xcodeProject.addTarget(CIO_NOTIFICATION_TARGET_NAME, 'app_extension', CIO_NOTIFICATION_TARGET_NAME, `${bundleIdentifier}.richpush`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["withXcodeProject","CIO_NOTIFICATION_TARGET_NAME","CIO_REGISTER_PUSHNOTIFICATION_SNIPPET","DEFAULT_BUNDLE_VERSION","replaceCodeByRegex","injectCIONotificationPodfileCode","logger","getIosNativeFilesPath","validateRichPushConfig","FileManagement","isExpoVersion53OrHigher","isFcmPushProvider","PLIST_FILENAME","ENV_FILENAME","NSE_PLATFORM_SPECIFIC_FILES","NSE_COMMON_FILES","TARGETED_DEVICE_FAMILY","addNotificationServiceExtension","options","xcodeProject","isExpo53OrHigher","_options$pushNotifica","pushNotification","addPushNotificationFile","useRichPush","addRichPushXcodeProj","error","String","withCioNotificationsXcodeProject","configOuter","props","config","modRequest","ios","version","bundleShortVersion","appleTeamId","iosDeploymentTarget","useFrameworks","undefined","Error","projectName","platformProjectRoot","bundleIdentifier","buildNumber","bundleVersion","iosPath","appName","modifiedProjectFile","modResults","NSE_ENTITLEMENTS_FILENAME","addNotificationServiceExtensionToXcodeProject","pbxTargetByName","warn","appGroupId","allGroupFiles","extGroup","addPbxGroup","groups","hash","project","objects","PBXGroup","Object","keys","forEach","key","name","path","addToPbxGroup","uuid","projObjects","PBXTargetDependency","PBXContainerItemProxy","nseTarget","addTarget","addBuildPhase","configurations","pbxXCBuildConfigurationSection","buildSettings","PRODUCT_NAME","buildSettingsObj","DEVELOPMENT_TEAM","IPHONEOS_DEPLOYMENT_TARGET","CODE_SIGN_STYLE","SWIFT_VERSION","CODE_SIGN_ENTITLEMENTS","addTargetAttribute","_options$pushNotifica2","_options$pushNotifica3","isFcmProvider","nsePath","mkdir","recursive","nseEntitlementsContent","writeFile","getTargetFile","filename","copyFile","updateNseInfoPlist","infoPlistTargetFile","updateNseEnv","env","updateNseNotificationService","applyBundleVersionToNsePlist","content","payload","next","readFile","applyAppGroupIdToNotificationService","builderLine","JSON","stringify","notificationServiceFile","applyRichPushConfigToEnv","richPushConfig","cdpApiKey","region","regionKey","toLowerCase","regionMap","us","eu","mappedRegion","envFileName","sourceFile","targetFileName","appPath","targetFile","exists","info","updatePushFile","group","pbxCreateGroup","classesKey","findPBXGroupKey","addSourceFile","applyConfigToPushFile","_options$pushNotifica4","_options$pushNotifica5","_options$pushNotifica6","_options$pushNotifica7","_options$pushNotifica8","_options$pushNotifica9","disableNotificationRegistration","registerSnippet","toUpperCase","autoTrackPushEvents","toString","autoFetchDeviceToken","showPushAppInForeground","appGroupIdBuilderLine","_options$pushNotifica0"],"sources":["withNotificationsXcodeProject.ts"],"sourcesContent":["import type { ConfigPlugin, XcodeProject } from '@expo/config-plugins';\nimport { withXcodeProject } from '@expo/config-plugins';\n\nimport {\n CIO_NOTIFICATION_TARGET_NAME,\n CIO_REGISTER_PUSHNOTIFICATION_SNIPPET,\n DEFAULT_BUNDLE_VERSION,\n} from '../helpers/constants/ios';\nimport { replaceCodeByRegex } from '../helpers/utils/codeInjection';\nimport { injectCIONotificationPodfileCode } from '../helpers/utils/injectCIOPodfileCode';\nimport type { CustomerIOPluginOptionsIOS, RichPushConfig } from '../types/cio-types';\nimport { logger } from '../utils/logger';\nimport { getIosNativeFilesPath } from '../utils/plugin';\nimport { validateRichPushConfig } from '../utils/validation';\nimport { FileManagement } from './../helpers/utils/fileManagement';\nimport { isExpoVersion53OrHigher, isFcmPushProvider } from './utils';\n\nconst PLIST_FILENAME = `${CIO_NOTIFICATION_TARGET_NAME}-Info.plist`;\nconst ENV_FILENAME = 'Env.swift';\n\n// NSE source files registered in the Xcode group AND copied to the target\n// directory. Single source of truth — both `addNotificationServiceExtensionToXcodeProject`\n// (registers them in the PBXGroup) and `addRichPushXcodeProj` (copies them\n// from the plugin's native-files dir) read the same arrays. Keeping these\n// in sync is load-bearing: the Xcode group must reference the same files\n// that exist on disk, or the build fails with \"no such file\" / unresolved\n// references.\nconst NSE_PLATFORM_SPECIFIC_FILES = ['NotificationService.swift'];\nconst NSE_COMMON_FILES = [\n PLIST_FILENAME,\n 'NotificationService.h',\n 'NotificationService.m',\n ENV_FILENAME,\n];\n\nconst TARGETED_DEVICE_FAMILY = `\"1,2\"`;\n\nconst addNotificationServiceExtension = async (\n options: CustomerIOPluginOptionsIOS,\n xcodeProject: XcodeProject,\n isExpo53OrHigher: boolean,\n) => {\n try {\n // PushService file is only needed for pre-Expo 53 code generation\n if (options.pushNotification && !isExpo53OrHigher) {\n await addPushNotificationFile(options, xcodeProject);\n }\n\n if (options.pushNotification?.useRichPush === true) {\n await addRichPushXcodeProj(options, xcodeProject);\n }\n return xcodeProject;\n } catch (error: unknown) {\n logger.error(String(error));\n return null;\n }\n};\n\nexport const withCioNotificationsXcodeProject: ConfigPlugin<\n CustomerIOPluginOptionsIOS\n> = (configOuter, props) => {\n return withXcodeProject(configOuter, async (config) => {\n const { modRequest, ios, version: bundleShortVersion } = config;\n const { appleTeamId, iosDeploymentTarget, useFrameworks } = props;\n\n if (ios === undefined)\n throw new Error(\n 'Adding NotificationServiceExtension failed: ios config missing from app.config.js or app.json.'\n );\n\n // projectName and platformProjectRoot translates to appName and iosPath in addNotificationServiceExtension()\n const { projectName, platformProjectRoot } = modRequest;\n const { bundleIdentifier, buildNumber } = ios;\n\n if (bundleShortVersion === undefined) {\n throw new Error(\n 'Adding NotificationServiceExtension failed: version missing from app.config.js or app.json'\n );\n }\n\n if (bundleIdentifier === undefined) {\n throw new Error(\n 'Adding NotificationServiceExtension failed: ios.bundleIdentifier missing from app.config.js or app.json'\n );\n }\n\n if (projectName === undefined) {\n throw new Error(\n 'Adding NotificationServiceExtension failed: name missing from app.config.js or app.json'\n );\n }\n\n const options = {\n ...props,\n appleTeamId,\n bundleIdentifier,\n bundleShortVersion,\n bundleVersion: buildNumber || DEFAULT_BUNDLE_VERSION,\n iosPath: platformProjectRoot,\n appName: projectName,\n useFrameworks,\n iosDeploymentTarget,\n } satisfies CustomerIOPluginOptionsIOS;\n\n const modifiedProjectFile = await addNotificationServiceExtension(\n options,\n config.modResults,\n isExpoVersion53OrHigher(configOuter),\n );\n\n if (modifiedProjectFile) {\n config.modResults = modifiedProjectFile;\n }\n\n return config;\n });\n};\n\nconst NSE_ENTITLEMENTS_FILENAME = 'NotificationService.entitlements';\n\nexport type AddNseTargetToXcodeProjectOptions = {\n appleTeamId?: string;\n bundleIdentifier?: string;\n iosDeploymentTarget?: string;\n appGroupId?: string;\n};\n\n/**\n * Mutates the parsed XcodeProject to register the rich-push NotificationService\n * extension target: creates a PBXGroup for its files, registers the group under\n * the project's top-level group, adds the app_extension target, wires three\n * build phases (Sources, Resources, Frameworks), configures the target's build\n * settings (DEVELOPMENT_TEAM, IPHONEOS_DEPLOYMENT_TARGET, code-sign style,\n * Swift version, and CODE_SIGN_ENTITLEMENTS when `appGroupId` is set), and\n * stamps the development team attribute on both the new target and the\n * project's main target attributes.\n *\n * Idempotent — returns the project unchanged if a target named\n * `CIO_NOTIFICATION_TARGET_NAME` is already present.\n */\nexport function addNotificationServiceExtensionToXcodeProject(\n xcodeProject: XcodeProject,\n options: AddNseTargetToXcodeProjectOptions,\n): XcodeProject {\n if (xcodeProject.pbxTargetByName(CIO_NOTIFICATION_TARGET_NAME)) {\n logger.warn(\n `${CIO_NOTIFICATION_TARGET_NAME} already exists in project. Skipping...`,\n );\n return xcodeProject;\n }\n\n const { appleTeamId, bundleIdentifier, iosDeploymentTarget, appGroupId } = options;\n\n // The entitlements file is generated (not copied from source), so it's listed separately\n // for the Xcode group so it appears in the file navigator.\n const allGroupFiles = [\n ...NSE_PLATFORM_SPECIFIC_FILES,\n ...NSE_COMMON_FILES,\n ...(appGroupId ? [NSE_ENTITLEMENTS_FILENAME] : []),\n ];\n\n // Create new PBXGroup for the extension\n const extGroup = xcodeProject.addPbxGroup(\n allGroupFiles,\n CIO_NOTIFICATION_TARGET_NAME,\n CIO_NOTIFICATION_TARGET_NAME,\n );\n\n // Add the new PBXGroup to the top level group. This makes the\n // files / folder appear in the file explorer in Xcode.\n const groups = xcodeProject.hash.project.objects.PBXGroup;\n Object.keys(groups).forEach((key) => {\n if (groups[key].name === undefined && groups[key].path === undefined) {\n xcodeProject.addToPbxGroup(extGroup.uuid, key);\n }\n });\n\n // WORK AROUND for codeProject.addTarget BUG\n // Xcode projects don't contain these if there is only one target\n // An upstream fix should be made to the code referenced in this link:\n // - https://github.com/apache/cordova-node-xcode/blob/8b98cabc5978359db88dc9ff2d4c015cba40f150/lib/pbxProject.js#L860\n const projObjects = xcodeProject.hash.project.objects;\n projObjects.PBXTargetDependency = projObjects.PBXTargetDependency || {};\n projObjects.PBXContainerItemProxy = projObjects.PBXTargetDependency || {};\n\n // Add the NSE target. This also adds PBXTargetDependency and PBXContainerItemProxy.\n const nseTarget = xcodeProject.addTarget(\n CIO_NOTIFICATION_TARGET_NAME,\n 'app_extension',\n CIO_NOTIFICATION_TARGET_NAME,\n `${bundleIdentifier}.richpush`,\n );\n\n // Add build phases to the new target\n xcodeProject.addBuildPhase(\n ['NotificationService.m', 'NotificationService.swift', 'Env.swift'],\n 'PBXSourcesBuildPhase',\n 'Sources',\n nseTarget.uuid,\n );\n xcodeProject.addBuildPhase([], 'PBXResourcesBuildPhase', 'Resources', nseTarget.uuid);\n xcodeProject.addBuildPhase([], 'PBXFrameworksBuildPhase', 'Frameworks', nseTarget.uuid);\n\n // Edit the Deployment info of the target\n const configurations = xcodeProject.pbxXCBuildConfigurationSection();\n for (const key in configurations) {\n if (\n typeof configurations[key].buildSettings !== 'undefined' &&\n configurations[key].buildSettings.PRODUCT_NAME ===\n `\"${CIO_NOTIFICATION_TARGET_NAME}\"`\n ) {\n const buildSettingsObj = configurations[key].buildSettings;\n buildSettingsObj.DEVELOPMENT_TEAM = appleTeamId;\n buildSettingsObj.IPHONEOS_DEPLOYMENT_TARGET = iosDeploymentTarget || '15.1';\n buildSettingsObj.TARGETED_DEVICE_FAMILY = TARGETED_DEVICE_FAMILY;\n buildSettingsObj.CODE_SIGN_STYLE = 'Automatic';\n buildSettingsObj.SWIFT_VERSION = 4.2;\n if (appGroupId) {\n buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `${CIO_NOTIFICATION_TARGET_NAME}/${NSE_ENTITLEMENTS_FILENAME}`;\n }\n }\n }\n\n // Add development team to the target & the main\n xcodeProject.addTargetAttribute('DevelopmentTeam', appleTeamId, nseTarget);\n xcodeProject.addTargetAttribute('DevelopmentTeam', appleTeamId);\n\n return xcodeProject;\n}\n\nconst addRichPushXcodeProj = async (\n options: CustomerIOPluginOptionsIOS,\n xcodeProject: XcodeProject,\n) => {\n const {\n appleTeamId,\n bundleIdentifier,\n bundleShortVersion,\n bundleVersion,\n iosPath,\n iosDeploymentTarget,\n useFrameworks,\n } = options;\n\n const isFcmProvider = isFcmPushProvider(options);\n const appGroupId = options.pushNotification?.appGroupId;\n\n await injectCIONotificationPodfileCode(iosPath, useFrameworks, isFcmProvider);\n\n // Skip the rest of the work if the NSE target is already in place. The pbxproj-mutating\n // helper has its own idempotency check, but bailing out here also avoids redundant file\n // copies and entitlements writes when prebuild re-runs against an already-prepared project.\n if (xcodeProject.pbxTargetByName(CIO_NOTIFICATION_TARGET_NAME)) {\n logger.warn(\n `${CIO_NOTIFICATION_TARGET_NAME} already exists in project. Skipping...`,\n );\n return;\n }\n\n const nsePath = `${iosPath}/${CIO_NOTIFICATION_TARGET_NAME}`;\n FileManagement.mkdir(nsePath, { recursive: true });\n\n // Write NSE entitlements file only when appGroupId is explicitly configured\n if (appGroupId) {\n const nseEntitlementsContent = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>com.apple.security.application-groups</key>\n <array>\n <string>${appGroupId}</string>\n </array>\n</dict>\n</plist>\n`;\n FileManagement.writeFile(`${nsePath}/${NSE_ENTITLEMENTS_FILENAME}`, nseEntitlementsContent);\n }\n\n const getTargetFile = (filename: string) => `${nsePath}/${filename}`;\n\n // Copy platform-specific files\n NSE_PLATFORM_SPECIFIC_FILES.forEach((filename) => {\n FileManagement.copyFile(\n `${getIosNativeFilesPath()}/${isFcmProvider ? 'fcm' : 'apn'}/${filename}`,\n getTargetFile(filename),\n );\n });\n\n // Copy common files\n NSE_COMMON_FILES.forEach((filename) => {\n FileManagement.copyFile(\n `${getIosNativeFilesPath()}/common/${filename}`,\n getTargetFile(filename),\n );\n });\n\n /* MODIFY COPIED EXTENSION FILES */\n updateNseInfoPlist({\n bundleVersion,\n bundleShortVersion,\n infoPlistTargetFile: getTargetFile(PLIST_FILENAME),\n });\n updateNseEnv(getTargetFile(ENV_FILENAME), options.pushNotification?.env);\n updateNseNotificationService(getTargetFile('NotificationService.swift'), appGroupId);\n\n // Register the NSE target in the parsed Xcode project\n addNotificationServiceExtensionToXcodeProject(xcodeProject, {\n appleTeamId,\n bundleIdentifier,\n iosDeploymentTarget,\n appGroupId,\n });\n};\n\n/**\n * Pure string transform: substitutes the `{{BUNDLE_VERSION}}` and\n * `{{BUNDLE_SHORT_VERSION}}` placeholders in the NSE Info.plist template.\n * Either or both may be provided; missing values leave the corresponding\n * placeholder untouched.\n */\nexport function applyBundleVersionToNsePlist(\n content: string,\n payload: { bundleVersion?: string; bundleShortVersion?: string }\n): string {\n let next = content;\n if (payload.bundleVersion) {\n next = replaceCodeByRegex(next, /\\{\\{BUNDLE_VERSION\\}\\}/, payload.bundleVersion);\n }\n if (payload.bundleShortVersion) {\n next = replaceCodeByRegex(next, /\\{\\{BUNDLE_SHORT_VERSION\\}\\}/, payload.bundleShortVersion);\n }\n return next;\n}\n\nconst updateNseInfoPlist = (payload: {\n bundleVersion?: string;\n bundleShortVersion?: string;\n infoPlistTargetFile: string;\n}) => {\n const next = applyBundleVersionToNsePlist(\n FileManagement.readFile(payload.infoPlistTargetFile),\n payload,\n );\n FileManagement.writeFile(payload.infoPlistTargetFile, next);\n};\n\n/**\n * Pure string transform: substitutes the `{{APP_GROUP_ID_BUILDER_LINE}}`\n * placeholder in NotificationService.swift with either the configured\n * appGroupId builder line or an empty string.\n */\nexport function applyAppGroupIdToNotificationService(\n content: string,\n appGroupId?: string\n): string {\n const builderLine = appGroupId\n ? ` .appGroupId(${JSON.stringify(appGroupId)})\\n`\n : '';\n return replaceCodeByRegex(content, /\\{\\{APP_GROUP_ID_BUILDER_LINE\\}\\}/, builderLine);\n}\n\nconst updateNseNotificationService = (\n notificationServiceFile: string,\n appGroupId?: string,\n) => {\n const next = applyAppGroupIdToNotificationService(\n FileManagement.readFile(notificationServiceFile),\n appGroupId,\n );\n FileManagement.writeFile(notificationServiceFile, next);\n};\n\n/**\n * Pure string transform: substitutes the `{{CDP_API_KEY}}` and `{{REGION}}`\n * placeholders in the NSE Env.swift template. Missing or invalid region\n * falls back to `Region.US` and logs a warning.\n */\nexport function applyRichPushConfigToEnv(\n content: string,\n richPushConfig?: RichPushConfig,\n): string {\n const cdpApiKey = richPushConfig?.cdpApiKey;\n const region = richPushConfig?.region;\n\n let next = replaceCodeByRegex(\n content,\n /\\{\\{CDP_API_KEY\\}\\}/,\n cdpApiKey || 'MISSING_API_KEY',\n );\n\n const regionKey = region?.toLowerCase() ?? '';\n const regionMap = { us: 'Region.US', eu: 'Region.EU' } as const;\n const mappedRegion = regionMap[regionKey as keyof typeof regionMap];\n if (!mappedRegion) {\n logger.warn(\n `${regionKey} is an invalid region. Please use the values from the docs: https://docs.customer.io/integrations/sdk/expo/getting-started/packages-options/#configuring-the-expo-plugin`\n );\n next = replaceCodeByRegex(next, /\\{\\{REGION\\}\\}/, regionMap.us);\n } else {\n next = replaceCodeByRegex(next, /\\{\\{REGION\\}\\}/, mappedRegion);\n }\n return next;\n}\n\nconst updateNseEnv = (\n envFileName: string,\n richPushConfig?: RichPushConfig\n) => {\n if (!validateRichPushConfig(richPushConfig)) {\n return;\n }\n const next = applyRichPushConfigToEnv(\n FileManagement.readFile(envFileName),\n richPushConfig,\n );\n FileManagement.writeFile(envFileName, next);\n};\n\nasync function addPushNotificationFile(\n options: CustomerIOPluginOptionsIOS,\n xcodeProject: XcodeProject\n) {\n // Maybe copy a different file with FCM config based on config\n const { iosPath, appName } = options;\n const isFcmProvider = isFcmPushProvider(options);\n // PushService.swift is platform-specific and always lives in the platform folder\n const sourceFile = `${isFcmProvider ? 'fcm' : 'apn'}/PushService.swift`;\n const targetFileName = 'PushService.swift';\n const appPath = `${iosPath}/${appName}`;\n const getTargetFile = (filename: string) => `${appPath}/${filename}`;\n const targetFile = getTargetFile(targetFileName);\n\n // Check whether {file} exists in the project. If false, then add the file\n // If {file} exists then skip and return\n if (!FileManagement.exists(getTargetFile(targetFileName))) {\n FileManagement.mkdir(appPath, {\n recursive: true,\n });\n\n FileManagement.copyFile(\n `${getIosNativeFilesPath()}/${sourceFile}`,\n targetFile\n );\n } else {\n logger.info(`${getTargetFile(targetFileName)} already exists. Skipping...`);\n return;\n }\n\n updatePushFile(options, targetFile);\n\n const group = xcodeProject.pbxCreateGroup('CustomerIONotifications');\n const classesKey = xcodeProject.findPBXGroupKey({ name: `${appName}` });\n xcodeProject.addToPbxGroup(group, classesKey);\n\n xcodeProject.addSourceFile(`${appName}/${targetFileName}`, null, group);\n}\n\n/**\n * Pure string transform: substitutes every PushService.swift placeholder\n * (`{{REGISTER_SNIPPET}}`, `{{CDP_API_KEY}}`, `{{REGION}}`,\n * `{{AUTO_TRACK_PUSH_EVENTS}}`, `{{AUTO_FETCH_DEVICE_TOKEN}}`,\n * `{{SHOW_PUSH_APP_IN_FOREGROUND}}`, `{{APP_GROUP_ID_BUILDER_LINE}}`) using\n * the configured push-notification options. Validation of the rich-push\n * config (cdpApiKey/region required) is the wrapper's responsibility.\n */\nexport function applyConfigToPushFile(\n content: string,\n options: CustomerIOPluginOptionsIOS,\n): string {\n const richPushConfig = options.pushNotification?.env;\n const { cdpApiKey, region } = richPushConfig || {\n cdpApiKey: 'MISSING_API_KEY',\n region: undefined,\n };\n const disableNotificationRegistration =\n options.pushNotification?.disableNotificationRegistration;\n\n // unless this property is explicitly set to true, push notification\n // registration will be added to the AppDelegate\n const registerSnippet = disableNotificationRegistration !== true\n ? CIO_REGISTER_PUSHNOTIFICATION_SNIPPET\n : '';\n\n let next = replaceCodeByRegex(content, /\\{\\{REGISTER_SNIPPET\\}\\}/, registerSnippet);\n next = replaceCodeByRegex(next, /\\{\\{CDP_API_KEY\\}\\}/, cdpApiKey);\n\n if (region) {\n next = replaceCodeByRegex(next, /\\{\\{REGION\\}\\}/, region.toUpperCase());\n }\n\n const autoTrackPushEvents =\n options.pushNotification?.autoTrackPushEvents !== false;\n next = replaceCodeByRegex(\n next,\n /\\{\\{AUTO_TRACK_PUSH_EVENTS\\}\\}/,\n autoTrackPushEvents.toString(),\n );\n\n const autoFetchDeviceToken =\n options.pushNotification?.autoFetchDeviceToken !== false;\n next = replaceCodeByRegex(\n next,\n /\\{\\{AUTO_FETCH_DEVICE_TOKEN\\}\\}/,\n autoFetchDeviceToken.toString(),\n );\n\n const showPushAppInForeground =\n options.pushNotification?.showPushAppInForeground !== false;\n next = replaceCodeByRegex(\n next,\n /\\{\\{SHOW_PUSH_APP_IN_FOREGROUND\\}\\}/,\n showPushAppInForeground.toString(),\n );\n\n const appGroupId = options.pushNotification?.appGroupId;\n const appGroupIdBuilderLine = appGroupId\n ? ` .appGroupId(${JSON.stringify(appGroupId)})\\n`\n : '';\n next = replaceCodeByRegex(\n next,\n /\\{\\{APP_GROUP_ID_BUILDER_LINE\\}\\}/,\n appGroupIdBuilderLine,\n );\n\n return next;\n}\n\nconst updatePushFile = (\n options: CustomerIOPluginOptionsIOS,\n envFileName: string\n) => {\n const richPushConfig = options.pushNotification?.env;\n if (!validateRichPushConfig(richPushConfig)) {\n return;\n }\n const next = applyConfigToPushFile(FileManagement.readFile(envFileName), options);\n FileManagement.writeFile(envFileName, next);\n};\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["withXcodeProject","CIO_NOTIFICATION_TARGET_NAME","CIO_REGISTER_PUSHNOTIFICATION_SNIPPET","DEFAULT_BUNDLE_VERSION","replaceCodeByRegex","injectCIONotificationPodfileCode","logger","getIosNativeFilesPath","validateRichPushConfig","FileManagement","isExpoVersion53OrHigher","isFcmPushProvider","PLIST_FILENAME","ENV_FILENAME","NSE_PLATFORM_SPECIFIC_FILES","NSE_COMMON_FILES","TARGETED_DEVICE_FAMILY","addNotificationServiceExtension","options","xcodeProject","isExpo53OrHigher","_options$pushNotifica","pushNotification","addPushNotificationFile","useRichPush","addRichPushXcodeProj","error","String","withCioNotificationsXcodeProject","configOuter","props","config","modRequest","ios","version","bundleShortVersion","appleTeamId","iosDeploymentTarget","useFrameworks","undefined","Error","projectName","platformProjectRoot","bundleIdentifier","buildNumber","bundleVersion","iosPath","appName","modifiedProjectFile","modResults","NSE_ENTITLEMENTS_FILENAME","addNotificationServiceExtensionToXcodeProject","pbxTargetByName","warn","appGroupId","allGroupFiles","extGroup","addPbxGroup","groups","hash","project","objects","PBXGroup","Object","keys","forEach","key","name","path","addToPbxGroup","uuid","projObjects","PBXTargetDependency","PBXContainerItemProxy","nseTarget","addTarget","addBuildPhase","configurations","pbxXCBuildConfigurationSection","buildSettings","PRODUCT_NAME","buildSettingsObj","DEVELOPMENT_TEAM","IPHONEOS_DEPLOYMENT_TARGET","CODE_SIGN_STYLE","SWIFT_VERSION","CODE_SIGN_ENTITLEMENTS","addTargetAttribute","_options$pushNotifica2","_options$pushNotifica3","isFcmProvider","nsePath","mkdir","recursive","nseEntitlementsContent","writeFile","getTargetFile","filename","copyFile","updateNseInfoPlist","infoPlistTargetFile","updateNseEnv","env","updateNseNotificationService","applyBundleVersionToNsePlist","content","payload","next","readFile","applyAppGroupIdToNotificationService","builderLine","JSON","stringify","notificationServiceFile","applyRichPushConfigToEnv","richPushConfig","cdpApiKey","region","regionKey","toLowerCase","regionMap","us","eu","mappedRegion","envFileName","sourceFile","targetFileName","appPath","targetFile","exists","info","updatePushFile","group","pbxCreateGroup","classesKey","findPBXGroupKey","addSourceFile","applyConfigToPushFile","_options$pushNotifica4","_options$pushNotifica5","_options$pushNotifica6","_options$pushNotifica7","_options$pushNotifica8","_options$pushNotifica9","disableNotificationRegistration","registerSnippet","toUpperCase","autoTrackPushEvents","toString","autoFetchDeviceToken","showPushAppInForeground","appGroupIdBuilderLine","_options$pushNotifica0"],"sources":["withNotificationsXcodeProject.ts"],"sourcesContent":["import type { ConfigPlugin, XcodeProject } from '@expo/config-plugins';\nimport { withXcodeProject } from '@expo/config-plugins';\n\nimport {\n CIO_NOTIFICATION_TARGET_NAME,\n CIO_REGISTER_PUSHNOTIFICATION_SNIPPET,\n DEFAULT_BUNDLE_VERSION,\n} from '../helpers/constants/ios';\nimport { replaceCodeByRegex } from '../helpers/utils/codeInjection';\nimport { injectCIONotificationPodfileCode } from '../helpers/utils/injectCIOPodfileCode';\nimport type { CustomerIOPluginOptionsIOS, RichPushConfig } from '../types/cio-types';\nimport { logger } from '../utils/logger';\nimport { getIosNativeFilesPath } from '../utils/plugin';\nimport { validateRichPushConfig } from '../utils/validation';\nimport { FileManagement } from './../helpers/utils/fileManagement';\nimport { isExpoVersion53OrHigher, isFcmPushProvider } from './utils';\n\nconst PLIST_FILENAME = `${CIO_NOTIFICATION_TARGET_NAME}-Info.plist`;\nconst ENV_FILENAME = 'Env.swift';\n\n// NSE source files registered in the Xcode group AND copied to the target\n// directory. Single source of truth — both `addNotificationServiceExtensionToXcodeProject`\n// (registers them in the PBXGroup) and `addRichPushXcodeProj` (copies them\n// from the plugin's native-files dir) read the same arrays. Keeping these\n// in sync is load-bearing: the Xcode group must reference the same files\n// that exist on disk, or the build fails with \"no such file\" / unresolved\n// references.\nconst NSE_PLATFORM_SPECIFIC_FILES = ['NotificationService.swift'];\nconst NSE_COMMON_FILES = [\n PLIST_FILENAME,\n 'NotificationService.h',\n 'NotificationService.m',\n ENV_FILENAME,\n];\n\nconst TARGETED_DEVICE_FAMILY = `\"1,2\"`;\n\nconst addNotificationServiceExtension = async (\n options: CustomerIOPluginOptionsIOS,\n xcodeProject: XcodeProject,\n isExpo53OrHigher: boolean,\n) => {\n try {\n // PushService file is only needed for pre-Expo 53 code generation\n if (options.pushNotification && !isExpo53OrHigher) {\n await addPushNotificationFile(options, xcodeProject);\n }\n\n if (options.pushNotification?.useRichPush === true) {\n await addRichPushXcodeProj(options, xcodeProject);\n }\n return xcodeProject;\n } catch (error: unknown) {\n logger.error(String(error));\n return null;\n }\n};\n\nexport const withCioNotificationsXcodeProject: ConfigPlugin<\n CustomerIOPluginOptionsIOS\n> = (configOuter, props) => {\n return withXcodeProject(configOuter, async (config) => {\n const { modRequest, ios, version: bundleShortVersion } = config;\n const { appleTeamId, iosDeploymentTarget, useFrameworks } = props;\n\n if (ios === undefined)\n throw new Error(\n 'Adding NotificationServiceExtension failed: ios config missing from app.config.js or app.json.'\n );\n\n // projectName and platformProjectRoot translates to appName and iosPath in addNotificationServiceExtension()\n const { projectName, platformProjectRoot } = modRequest;\n const { bundleIdentifier, buildNumber } = ios;\n\n if (bundleShortVersion === undefined) {\n throw new Error(\n 'Adding NotificationServiceExtension failed: version missing from app.config.js or app.json'\n );\n }\n\n if (bundleIdentifier === undefined) {\n throw new Error(\n 'Adding NotificationServiceExtension failed: ios.bundleIdentifier missing from app.config.js or app.json'\n );\n }\n\n if (projectName === undefined) {\n throw new Error(\n 'Adding NotificationServiceExtension failed: name missing from app.config.js or app.json'\n );\n }\n\n const options = {\n ...props,\n appleTeamId,\n bundleIdentifier,\n bundleShortVersion,\n bundleVersion: buildNumber || DEFAULT_BUNDLE_VERSION,\n iosPath: platformProjectRoot,\n appName: projectName,\n useFrameworks,\n iosDeploymentTarget,\n } satisfies CustomerIOPluginOptionsIOS;\n\n const modifiedProjectFile = await addNotificationServiceExtension(\n options,\n config.modResults,\n isExpoVersion53OrHigher(configOuter),\n );\n\n if (modifiedProjectFile) {\n config.modResults = modifiedProjectFile;\n }\n\n return config;\n });\n};\n\nconst NSE_ENTITLEMENTS_FILENAME = 'NotificationService.entitlements';\n\nexport type AddNseTargetToXcodeProjectOptions = {\n appleTeamId?: string;\n bundleIdentifier?: string;\n iosDeploymentTarget?: string;\n appGroupId?: string;\n};\n\n/**\n * Mutates the parsed XcodeProject to register the rich-push NotificationService\n * extension target: creates a PBXGroup for its files, registers the group under\n * the project's top-level group, adds the app_extension target, wires three\n * build phases (Sources, Resources, Frameworks), configures the target's build\n * settings (DEVELOPMENT_TEAM, IPHONEOS_DEPLOYMENT_TARGET, code-sign style,\n * Swift version, and CODE_SIGN_ENTITLEMENTS when `appGroupId` is set), and\n * stamps the development team attribute on both the new target and the\n * project's main target attributes.\n *\n * Idempotent — returns the project unchanged if a target named\n * `CIO_NOTIFICATION_TARGET_NAME` is already present.\n */\nexport function addNotificationServiceExtensionToXcodeProject(\n xcodeProject: XcodeProject,\n options: AddNseTargetToXcodeProjectOptions,\n): XcodeProject {\n if (xcodeProject.pbxTargetByName(CIO_NOTIFICATION_TARGET_NAME)) {\n logger.warn(\n `${CIO_NOTIFICATION_TARGET_NAME} already exists in project. Skipping...`,\n );\n return xcodeProject;\n }\n\n const { appleTeamId, bundleIdentifier, iosDeploymentTarget, appGroupId } = options;\n\n // The entitlements file is generated (not copied from source), so it's listed separately\n // for the Xcode group so it appears in the file navigator.\n const allGroupFiles = [\n ...NSE_PLATFORM_SPECIFIC_FILES,\n ...NSE_COMMON_FILES,\n ...(appGroupId ? [NSE_ENTITLEMENTS_FILENAME] : []),\n ];\n\n // Create new PBXGroup for the extension\n const extGroup = xcodeProject.addPbxGroup(\n allGroupFiles,\n CIO_NOTIFICATION_TARGET_NAME,\n CIO_NOTIFICATION_TARGET_NAME,\n );\n\n // Add the new PBXGroup to the top level group. This makes the\n // files / folder appear in the file explorer in Xcode.\n const groups = xcodeProject.hash.project.objects.PBXGroup;\n Object.keys(groups).forEach((key) => {\n if (groups[key].name === undefined && groups[key].path === undefined) {\n xcodeProject.addToPbxGroup(extGroup.uuid, key);\n }\n });\n\n // WORK AROUND for codeProject.addTarget BUG\n // Xcode projects don't contain these if there is only one target\n // An upstream fix should be made to the code referenced in this link:\n // - https://github.com/apache/cordova-node-xcode/blob/8b98cabc5978359db88dc9ff2d4c015cba40f150/lib/pbxProject.js#L860\n const projObjects = xcodeProject.hash.project.objects;\n projObjects.PBXTargetDependency = projObjects.PBXTargetDependency || {};\n projObjects.PBXContainerItemProxy = projObjects.PBXContainerItemProxy || {};\n\n // Add the NSE target. This also adds PBXTargetDependency and PBXContainerItemProxy.\n const nseTarget = xcodeProject.addTarget(\n CIO_NOTIFICATION_TARGET_NAME,\n 'app_extension',\n CIO_NOTIFICATION_TARGET_NAME,\n `${bundleIdentifier}.richpush`,\n );\n\n // Add build phases to the new target\n xcodeProject.addBuildPhase(\n ['NotificationService.m', 'NotificationService.swift', 'Env.swift'],\n 'PBXSourcesBuildPhase',\n 'Sources',\n nseTarget.uuid,\n );\n xcodeProject.addBuildPhase([], 'PBXResourcesBuildPhase', 'Resources', nseTarget.uuid);\n xcodeProject.addBuildPhase([], 'PBXFrameworksBuildPhase', 'Frameworks', nseTarget.uuid);\n\n // Edit the Deployment info of the target\n const configurations = xcodeProject.pbxXCBuildConfigurationSection();\n for (const key in configurations) {\n if (\n typeof configurations[key].buildSettings !== 'undefined' &&\n configurations[key].buildSettings.PRODUCT_NAME ===\n `\"${CIO_NOTIFICATION_TARGET_NAME}\"`\n ) {\n const buildSettingsObj = configurations[key].buildSettings;\n buildSettingsObj.DEVELOPMENT_TEAM = appleTeamId;\n buildSettingsObj.IPHONEOS_DEPLOYMENT_TARGET = iosDeploymentTarget || '15.1';\n buildSettingsObj.TARGETED_DEVICE_FAMILY = TARGETED_DEVICE_FAMILY;\n buildSettingsObj.CODE_SIGN_STYLE = 'Automatic';\n buildSettingsObj.SWIFT_VERSION = 4.2;\n if (appGroupId) {\n buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `${CIO_NOTIFICATION_TARGET_NAME}/${NSE_ENTITLEMENTS_FILENAME}`;\n }\n }\n }\n\n // Add development team to the target & the main\n xcodeProject.addTargetAttribute('DevelopmentTeam', appleTeamId, nseTarget);\n xcodeProject.addTargetAttribute('DevelopmentTeam', appleTeamId);\n\n return xcodeProject;\n}\n\nconst addRichPushXcodeProj = async (\n options: CustomerIOPluginOptionsIOS,\n xcodeProject: XcodeProject,\n) => {\n const {\n appleTeamId,\n bundleIdentifier,\n bundleShortVersion,\n bundleVersion,\n iosPath,\n iosDeploymentTarget,\n useFrameworks,\n } = options;\n\n const isFcmProvider = isFcmPushProvider(options);\n const appGroupId = options.pushNotification?.appGroupId;\n\n await injectCIONotificationPodfileCode(iosPath, useFrameworks, isFcmProvider);\n\n // Skip the rest of the work if the NSE target is already in place. The pbxproj-mutating\n // helper has its own idempotency check, but bailing out here also avoids redundant file\n // copies and entitlements writes when prebuild re-runs against an already-prepared project.\n if (xcodeProject.pbxTargetByName(CIO_NOTIFICATION_TARGET_NAME)) {\n logger.warn(\n `${CIO_NOTIFICATION_TARGET_NAME} already exists in project. Skipping...`,\n );\n return;\n }\n\n const nsePath = `${iosPath}/${CIO_NOTIFICATION_TARGET_NAME}`;\n FileManagement.mkdir(nsePath, { recursive: true });\n\n // Write NSE entitlements file only when appGroupId is explicitly configured\n if (appGroupId) {\n const nseEntitlementsContent = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>com.apple.security.application-groups</key>\n <array>\n <string>${appGroupId}</string>\n </array>\n</dict>\n</plist>\n`;\n FileManagement.writeFile(`${nsePath}/${NSE_ENTITLEMENTS_FILENAME}`, nseEntitlementsContent);\n }\n\n const getTargetFile = (filename: string) => `${nsePath}/${filename}`;\n\n // Copy platform-specific files\n NSE_PLATFORM_SPECIFIC_FILES.forEach((filename) => {\n FileManagement.copyFile(\n `${getIosNativeFilesPath()}/${isFcmProvider ? 'fcm' : 'apn'}/${filename}`,\n getTargetFile(filename),\n );\n });\n\n // Copy common files\n NSE_COMMON_FILES.forEach((filename) => {\n FileManagement.copyFile(\n `${getIosNativeFilesPath()}/common/${filename}`,\n getTargetFile(filename),\n );\n });\n\n /* MODIFY COPIED EXTENSION FILES */\n updateNseInfoPlist({\n bundleVersion,\n bundleShortVersion,\n infoPlistTargetFile: getTargetFile(PLIST_FILENAME),\n });\n updateNseEnv(getTargetFile(ENV_FILENAME), options.pushNotification?.env);\n updateNseNotificationService(getTargetFile('NotificationService.swift'), appGroupId);\n\n // Register the NSE target in the parsed Xcode project\n addNotificationServiceExtensionToXcodeProject(xcodeProject, {\n appleTeamId,\n bundleIdentifier,\n iosDeploymentTarget,\n appGroupId,\n });\n};\n\n/**\n * Pure string transform: substitutes the `{{BUNDLE_VERSION}}` and\n * `{{BUNDLE_SHORT_VERSION}}` placeholders in the NSE Info.plist template.\n * Either or both may be provided; missing values leave the corresponding\n * placeholder untouched.\n */\nexport function applyBundleVersionToNsePlist(\n content: string,\n payload: { bundleVersion?: string; bundleShortVersion?: string }\n): string {\n let next = content;\n if (payload.bundleVersion) {\n next = replaceCodeByRegex(next, /\\{\\{BUNDLE_VERSION\\}\\}/, payload.bundleVersion);\n }\n if (payload.bundleShortVersion) {\n next = replaceCodeByRegex(next, /\\{\\{BUNDLE_SHORT_VERSION\\}\\}/, payload.bundleShortVersion);\n }\n return next;\n}\n\nconst updateNseInfoPlist = (payload: {\n bundleVersion?: string;\n bundleShortVersion?: string;\n infoPlistTargetFile: string;\n}) => {\n const next = applyBundleVersionToNsePlist(\n FileManagement.readFile(payload.infoPlistTargetFile),\n payload,\n );\n FileManagement.writeFile(payload.infoPlistTargetFile, next);\n};\n\n/**\n * Pure string transform: substitutes the `{{APP_GROUP_ID_BUILDER_LINE}}`\n * placeholder in NotificationService.swift with either the configured\n * appGroupId builder line or an empty string.\n */\nexport function applyAppGroupIdToNotificationService(\n content: string,\n appGroupId?: string\n): string {\n const builderLine = appGroupId\n ? ` .appGroupId(${JSON.stringify(appGroupId)})\\n`\n : '';\n return replaceCodeByRegex(content, /\\{\\{APP_GROUP_ID_BUILDER_LINE\\}\\}/, builderLine);\n}\n\nconst updateNseNotificationService = (\n notificationServiceFile: string,\n appGroupId?: string,\n) => {\n const next = applyAppGroupIdToNotificationService(\n FileManagement.readFile(notificationServiceFile),\n appGroupId,\n );\n FileManagement.writeFile(notificationServiceFile, next);\n};\n\n/**\n * Pure string transform: substitutes the `{{CDP_API_KEY}}` and `{{REGION}}`\n * placeholders in the NSE Env.swift template. Missing or invalid region\n * falls back to `Region.US` and logs a warning.\n */\nexport function applyRichPushConfigToEnv(\n content: string,\n richPushConfig?: RichPushConfig,\n): string {\n const cdpApiKey = richPushConfig?.cdpApiKey;\n const region = richPushConfig?.region;\n\n let next = replaceCodeByRegex(\n content,\n /\\{\\{CDP_API_KEY\\}\\}/,\n cdpApiKey || 'MISSING_API_KEY',\n );\n\n const regionKey = region?.toLowerCase() ?? '';\n const regionMap = { us: 'Region.US', eu: 'Region.EU' } as const;\n const mappedRegion = regionMap[regionKey as keyof typeof regionMap];\n if (!mappedRegion) {\n logger.warn(\n `${regionKey} is an invalid region. Please use the values from the docs: https://docs.customer.io/integrations/sdk/expo/getting-started/packages-options/#configuring-the-expo-plugin`\n );\n next = replaceCodeByRegex(next, /\\{\\{REGION\\}\\}/, regionMap.us);\n } else {\n next = replaceCodeByRegex(next, /\\{\\{REGION\\}\\}/, mappedRegion);\n }\n return next;\n}\n\nconst updateNseEnv = (\n envFileName: string,\n richPushConfig?: RichPushConfig\n) => {\n if (!validateRichPushConfig(richPushConfig)) {\n return;\n }\n const next = applyRichPushConfigToEnv(\n FileManagement.readFile(envFileName),\n richPushConfig,\n );\n FileManagement.writeFile(envFileName, next);\n};\n\nasync function addPushNotificationFile(\n options: CustomerIOPluginOptionsIOS,\n xcodeProject: XcodeProject\n) {\n // Maybe copy a different file with FCM config based on config\n const { iosPath, appName } = options;\n const isFcmProvider = isFcmPushProvider(options);\n // PushService.swift is platform-specific and always lives in the platform folder\n const sourceFile = `${isFcmProvider ? 'fcm' : 'apn'}/PushService.swift`;\n const targetFileName = 'PushService.swift';\n const appPath = `${iosPath}/${appName}`;\n const getTargetFile = (filename: string) => `${appPath}/${filename}`;\n const targetFile = getTargetFile(targetFileName);\n\n // Check whether {file} exists in the project. If false, then add the file\n // If {file} exists then skip and return\n if (!FileManagement.exists(getTargetFile(targetFileName))) {\n FileManagement.mkdir(appPath, {\n recursive: true,\n });\n\n FileManagement.copyFile(\n `${getIosNativeFilesPath()}/${sourceFile}`,\n targetFile\n );\n } else {\n logger.info(`${getTargetFile(targetFileName)} already exists. Skipping...`);\n return;\n }\n\n updatePushFile(options, targetFile);\n\n const group = xcodeProject.pbxCreateGroup('CustomerIONotifications');\n const classesKey = xcodeProject.findPBXGroupKey({ name: `${appName}` });\n xcodeProject.addToPbxGroup(group, classesKey);\n\n xcodeProject.addSourceFile(`${appName}/${targetFileName}`, null, group);\n}\n\n/**\n * Pure string transform: substitutes every PushService.swift placeholder\n * (`{{REGISTER_SNIPPET}}`, `{{CDP_API_KEY}}`, `{{REGION}}`,\n * `{{AUTO_TRACK_PUSH_EVENTS}}`, `{{AUTO_FETCH_DEVICE_TOKEN}}`,\n * `{{SHOW_PUSH_APP_IN_FOREGROUND}}`, `{{APP_GROUP_ID_BUILDER_LINE}}`) using\n * the configured push-notification options. Validation of the rich-push\n * config (cdpApiKey/region required) is the wrapper's responsibility.\n */\nexport function applyConfigToPushFile(\n content: string,\n options: CustomerIOPluginOptionsIOS,\n): string {\n const richPushConfig = options.pushNotification?.env;\n const { cdpApiKey, region } = richPushConfig || {\n cdpApiKey: 'MISSING_API_KEY',\n region: undefined,\n };\n const disableNotificationRegistration =\n options.pushNotification?.disableNotificationRegistration;\n\n // unless this property is explicitly set to true, push notification\n // registration will be added to the AppDelegate\n const registerSnippet = disableNotificationRegistration !== true\n ? CIO_REGISTER_PUSHNOTIFICATION_SNIPPET\n : '';\n\n let next = replaceCodeByRegex(content, /\\{\\{REGISTER_SNIPPET\\}\\}/, registerSnippet);\n next = replaceCodeByRegex(next, /\\{\\{CDP_API_KEY\\}\\}/, cdpApiKey);\n\n if (region) {\n next = replaceCodeByRegex(next, /\\{\\{REGION\\}\\}/, region.toUpperCase());\n }\n\n const autoTrackPushEvents =\n options.pushNotification?.autoTrackPushEvents !== false;\n next = replaceCodeByRegex(\n next,\n /\\{\\{AUTO_TRACK_PUSH_EVENTS\\}\\}/,\n autoTrackPushEvents.toString(),\n );\n\n const autoFetchDeviceToken =\n options.pushNotification?.autoFetchDeviceToken !== false;\n next = replaceCodeByRegex(\n next,\n /\\{\\{AUTO_FETCH_DEVICE_TOKEN\\}\\}/,\n autoFetchDeviceToken.toString(),\n );\n\n const showPushAppInForeground =\n options.pushNotification?.showPushAppInForeground !== false;\n next = replaceCodeByRegex(\n next,\n /\\{\\{SHOW_PUSH_APP_IN_FOREGROUND\\}\\}/,\n showPushAppInForeground.toString(),\n );\n\n const appGroupId = options.pushNotification?.appGroupId;\n const appGroupIdBuilderLine = appGroupId\n ? ` .appGroupId(${JSON.stringify(appGroupId)})\\n`\n : '';\n next = replaceCodeByRegex(\n next,\n /\\{\\{APP_GROUP_ID_BUILDER_LINE\\}\\}/,\n appGroupIdBuilderLine,\n );\n\n return next;\n}\n\nconst updatePushFile = (\n options: CustomerIOPluginOptionsIOS,\n envFileName: string\n) => {\n const richPushConfig = options.pushNotification?.env;\n if (!validateRichPushConfig(richPushConfig)) {\n return;\n }\n const next = applyConfigToPushFile(FileManagement.readFile(envFileName), options);\n FileManagement.writeFile(envFileName, next);\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,7 +1,20 @@
|
|
|
1
|
+
import { format } from 'util';
|
|
2
|
+
|
|
1
3
|
// Use CUSTOMERIO_DEBUG_MODE if defined; otherwise enable in development mode only
|
|
2
4
|
const VERBOSE_MODE = process.env.CUSTOMERIO_DEBUG_MODE !== undefined ? process.env.CUSTOMERIO_DEBUG_MODE === 'true' : process.env.NODE_ENV === 'development';
|
|
3
5
|
const PREFIX = '[CustomerIO]';
|
|
4
6
|
const formatMessage = message => `${PREFIX} ${message}`;
|
|
7
|
+
|
|
8
|
+
// `info`/`log`/`debug` go straight to stderr via `process.stderr.write` rather
|
|
9
|
+
// than `console.log/info/debug` (which default to stdout). Expo's CLI parses
|
|
10
|
+
// `expo config --json` stdout as JSON and eas-cli no longer falls back on a
|
|
11
|
+
// parse failure — a single stray verbose line aborts the build. Keeping
|
|
12
|
+
// verbose output on stderr makes the trace impossible to leak into that
|
|
13
|
+
// stream, regardless of host console rebinding.
|
|
14
|
+
const writeStderr = (message, args) => {
|
|
15
|
+
const line = args.length > 0 ? format(message, ...args) : message;
|
|
16
|
+
process.stderr.write(`${line}\n`);
|
|
17
|
+
};
|
|
5
18
|
export const logger = {
|
|
6
19
|
format: formatMessage,
|
|
7
20
|
error: (message, ...args) => {
|
|
@@ -12,17 +25,17 @@ export const logger = {
|
|
|
12
25
|
},
|
|
13
26
|
info: (message, ...args) => {
|
|
14
27
|
if (VERBOSE_MODE) {
|
|
15
|
-
|
|
28
|
+
writeStderr(formatMessage(message), args);
|
|
16
29
|
}
|
|
17
30
|
},
|
|
18
31
|
log: (message, ...args) => {
|
|
19
32
|
if (VERBOSE_MODE) {
|
|
20
|
-
|
|
33
|
+
writeStderr(formatMessage(message), args);
|
|
21
34
|
}
|
|
22
35
|
},
|
|
23
36
|
debug: (message, ...args) => {
|
|
24
37
|
if (VERBOSE_MODE) {
|
|
25
|
-
|
|
38
|
+
writeStderr(formatMessage(message), args);
|
|
26
39
|
}
|
|
27
40
|
}
|
|
28
41
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["VERBOSE_MODE","process","env","CUSTOMERIO_DEBUG_MODE","undefined","NODE_ENV","PREFIX","formatMessage","message","
|
|
1
|
+
{"version":3,"names":["format","VERBOSE_MODE","process","env","CUSTOMERIO_DEBUG_MODE","undefined","NODE_ENV","PREFIX","formatMessage","message","writeStderr","args","line","length","stderr","write","logger","error","console","warn","info","log","debug"],"sources":["logger.ts"],"sourcesContent":["import { format } from 'util';\n\n// Use CUSTOMERIO_DEBUG_MODE if defined; otherwise enable in development mode only\nconst VERBOSE_MODE =\n process.env.CUSTOMERIO_DEBUG_MODE !== undefined\n ? process.env.CUSTOMERIO_DEBUG_MODE === 'true'\n : process.env.NODE_ENV === 'development';\nconst PREFIX = '[CustomerIO]';\nconst formatMessage = (message: string): string => `${PREFIX} ${message}`;\n\n// `info`/`log`/`debug` go straight to stderr via `process.stderr.write` rather\n// than `console.log/info/debug` (which default to stdout). Expo's CLI parses\n// `expo config --json` stdout as JSON and eas-cli no longer falls back on a\n// parse failure — a single stray verbose line aborts the build. Keeping\n// verbose output on stderr makes the trace impossible to leak into that\n// stream, regardless of host console rebinding.\nconst writeStderr = (message: string, args: unknown[]): void => {\n const line = args.length > 0 ? format(message, ...args) : message;\n process.stderr.write(`${line}\\n`);\n};\n\nexport const logger = {\n format: formatMessage,\n\n error: (message: string, ...args: unknown[]): void => {\n console.error(formatMessage(message), ...args);\n },\n\n warn: (message: string, ...args: unknown[]): void => {\n console.warn(formatMessage(message), ...args);\n },\n\n info: (message: string, ...args: unknown[]): void => {\n if (VERBOSE_MODE) {\n writeStderr(formatMessage(message), args);\n }\n },\n\n log: (message: string, ...args: unknown[]): void => {\n if (VERBOSE_MODE) {\n writeStderr(formatMessage(message), args);\n }\n },\n\n debug: (message: string, ...args: unknown[]): void => {\n if (VERBOSE_MODE) {\n writeStderr(formatMessage(message), args);\n }\n }\n};\n"],"mappings":"AAAA,SAASA,MAAM,QAAQ,MAAM;;AAE7B;AACA,MAAMC,YAAY,GAChBC,OAAO,CAACC,GAAG,CAACC,qBAAqB,KAAKC,SAAS,GAC3CH,OAAO,CAACC,GAAG,CAACC,qBAAqB,KAAK,MAAM,GAC5CF,OAAO,CAACC,GAAG,CAACG,QAAQ,KAAK,aAAa;AAC5C,MAAMC,MAAM,GAAG,cAAc;AAC7B,MAAMC,aAAa,GAAIC,OAAe,IAAa,GAAGF,MAAM,IAAIE,OAAO,EAAE;;AAEzE;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,WAAW,GAAGA,CAACD,OAAe,EAAEE,IAAe,KAAW;EAC9D,MAAMC,IAAI,GAAGD,IAAI,CAACE,MAAM,GAAG,CAAC,GAAGb,MAAM,CAACS,OAAO,EAAE,GAAGE,IAAI,CAAC,GAAGF,OAAO;EACjEP,OAAO,CAACY,MAAM,CAACC,KAAK,CAAC,GAAGH,IAAI,IAAI,CAAC;AACnC,CAAC;AAED,OAAO,MAAMI,MAAM,GAAG;EACpBhB,MAAM,EAAEQ,aAAa;EAErBS,KAAK,EAAEA,CAACR,OAAe,EAAE,GAAGE,IAAe,KAAW;IACpDO,OAAO,CAACD,KAAK,CAACT,aAAa,CAACC,OAAO,CAAC,EAAE,GAAGE,IAAI,CAAC;EAChD,CAAC;EAEDQ,IAAI,EAAEA,CAACV,OAAe,EAAE,GAAGE,IAAe,KAAW;IACnDO,OAAO,CAACC,IAAI,CAACX,aAAa,CAACC,OAAO,CAAC,EAAE,GAAGE,IAAI,CAAC;EAC/C,CAAC;EAEDS,IAAI,EAAEA,CAACX,OAAe,EAAE,GAAGE,IAAe,KAAW;IACnD,IAAIV,YAAY,EAAE;MAChBS,WAAW,CAACF,aAAa,CAACC,OAAO,CAAC,EAAEE,IAAI,CAAC;IAC3C;EACF,CAAC;EAEDU,GAAG,EAAEA,CAACZ,OAAe,EAAE,GAAGE,IAAe,KAAW;IAClD,IAAIV,YAAY,EAAE;MAChBS,WAAW,CAACF,aAAa,CAACC,OAAO,CAAC,EAAEE,IAAI,CAAC;IAC3C;EACF,CAAC;EAEDW,KAAK,EAAEA,CAACb,OAAe,EAAE,GAAGE,IAAe,KAAW;IACpD,IAAIV,YAAY,EAAE;MAChBS,WAAW,CAACF,aAAa,CAACC,OAAO,CAAC,EAAEE,IAAI,CAAC;IAC3C;EACF;AACF,CAAC","ignoreList":[]}
|
|
@@ -12,9 +12,11 @@
|
|
|
12
12
|
* via Node, emitting the underlying `.pnpm/...` (or yarn-classic)
|
|
13
13
|
* path. We match by realpath'ing the resolved directory.
|
|
14
14
|
*
|
|
15
|
-
* Decision points are logged
|
|
16
|
-
*
|
|
17
|
-
*
|
|
15
|
+
* Decision points are logged through the shared logger, gated by
|
|
16
|
+
* CUSTOMERIO_DEBUG_MODE. Defaulting to silent keeps the prebuild output
|
|
17
|
+
* clean for hosts that parse it (Expo's `--json` config, EAS build
|
|
18
|
+
* tooling), while still giving support a "rerun with this flag" path
|
|
19
|
+
* for triaging path-resolution issues.
|
|
18
20
|
*/
|
|
19
21
|
export declare function getRelativePathToRNSDK(iosPath: string): any;
|
|
20
22
|
export declare const IOS_DEPLOYMENT_TARGET = "13.0";
|
|
@@ -3,6 +3,7 @@ import * as semver from 'semver';
|
|
|
3
3
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
import { resolveRNSDK, tryReadRNVersion } from '../../utils/resolveRNSDK';
|
|
6
|
+
import { logger } from '../../utils/logger';
|
|
6
7
|
|
|
7
8
|
// Threshold at which React Native pod autolinking moves from
|
|
8
9
|
// @react-native-community/cli (lexical, symlink-preserving) to
|
|
@@ -11,15 +12,6 @@ import { resolveRNSDK, tryReadRNVersion } from '../../utils/resolveRNSDK';
|
|
|
11
12
|
// we must match whichever flavor will resolve the same package later.
|
|
12
13
|
const RN_REALPATH_AUTOLINKING_MIN_VERSION = '0.80.0';
|
|
13
14
|
|
|
14
|
-
const PLUGIN_LOG_PREFIX = '[CustomerIO Plugin]';
|
|
15
|
-
|
|
16
|
-
// Always-on so the trail shows up in customer-shared `expo prebuild`
|
|
17
|
-
// output without needing a separate verbose-mode opt-in.
|
|
18
|
-
function pluginLog(message: string): void {
|
|
19
|
-
// eslint-disable-next-line no-console
|
|
20
|
-
console.log(`${PLUGIN_LOG_PREFIX} ${message}`);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
15
|
/**
|
|
24
16
|
* Returns the relative path from the iOS project dir to the installed
|
|
25
17
|
* customerio-reactnative directory, in the exact form React Native pod
|
|
@@ -34,24 +26,26 @@ function pluginLog(message: string): void {
|
|
|
34
26
|
* via Node, emitting the underlying `.pnpm/...` (or yarn-classic)
|
|
35
27
|
* path. We match by realpath'ing the resolved directory.
|
|
36
28
|
*
|
|
37
|
-
* Decision points are logged
|
|
38
|
-
*
|
|
39
|
-
*
|
|
29
|
+
* Decision points are logged through the shared logger, gated by
|
|
30
|
+
* CUSTOMERIO_DEBUG_MODE. Defaulting to silent keeps the prebuild output
|
|
31
|
+
* clean for hosts that parse it (Expo's `--json` config, EAS build
|
|
32
|
+
* tooling), while still giving support a "rerun with this flag" path
|
|
33
|
+
* for triaging path-resolution issues.
|
|
40
34
|
*/
|
|
41
35
|
export function getRelativePathToRNSDK(iosPath: string) {
|
|
42
36
|
const rootAppPath = path.dirname(iosPath);
|
|
43
|
-
|
|
37
|
+
logger.info(
|
|
44
38
|
`Resolving customerio-reactnative for Podfile (iosPath=${iosPath}, projectRoot=${rootAppPath})`
|
|
45
39
|
);
|
|
46
40
|
|
|
47
41
|
const { packageDir } = resolveRNSDK(rootAppPath);
|
|
48
|
-
|
|
42
|
+
logger.info(`customerio-reactnative resolved to: ${packageDir}`);
|
|
49
43
|
|
|
50
44
|
const rnVersion = tryReadRNVersion(rootAppPath);
|
|
51
|
-
|
|
45
|
+
logger.info(`Detected react-native version: ${rnVersion ?? 'unknown'}`);
|
|
52
46
|
|
|
53
47
|
const useLexical = shouldUseLexicalPath(rnVersion);
|
|
54
|
-
|
|
48
|
+
logger.info(
|
|
55
49
|
useLexical
|
|
56
50
|
? `RN <${RN_REALPATH_AUTOLINKING_MIN_VERSION} — using lexical/symlink path to match @react-native-community/cli autolinking`
|
|
57
51
|
: `RN >=${RN_REALPATH_AUTOLINKING_MIN_VERSION} or unknown — using realpath to match expo-modules-autolinking`
|
|
@@ -64,10 +58,10 @@ export function getRelativePathToRNSDK(iosPath: string) {
|
|
|
64
58
|
try {
|
|
65
59
|
absolutePath = fs.realpathSync(packageDir);
|
|
66
60
|
if (absolutePath !== packageDir) {
|
|
67
|
-
|
|
61
|
+
logger.info(`Realpath differs from resolved dir: ${absolutePath}`);
|
|
68
62
|
}
|
|
69
63
|
} catch (err) {
|
|
70
|
-
|
|
64
|
+
logger.warn(
|
|
71
65
|
`realpathSync failed (${
|
|
72
66
|
err instanceof Error ? err.message : String(err)
|
|
73
67
|
}); falling back to symlink path`
|
|
@@ -77,7 +71,7 @@ export function getRelativePathToRNSDK(iosPath: string) {
|
|
|
77
71
|
}
|
|
78
72
|
|
|
79
73
|
const relativePath = path.relative(iosPath, absolutePath);
|
|
80
|
-
|
|
74
|
+
logger.info(`Final Podfile :path => '${relativePath}'`);
|
|
81
75
|
return relativePath;
|
|
82
76
|
}
|
|
83
77
|
|
|
@@ -91,7 +91,11 @@ export async function injectCIOPodfileCode(
|
|
|
91
91
|
const podfile = await FileManagement.read(filename);
|
|
92
92
|
const next = injectHostAppPodfileCode(podfile, iosPath, isFcmPushProvider, options);
|
|
93
93
|
if (next !== podfile) {
|
|
94
|
-
|
|
94
|
+
// Await: the next iOS mod (withCioNotificationsXcodeProject) reads this
|
|
95
|
+
// same Podfile. Returning before the write flushes lets the next read
|
|
96
|
+
// race against the in-flight truncate, which (via FileManagement.read's
|
|
97
|
+
// empty-data fallback) rejects with null and aborts the NSE pipeline.
|
|
98
|
+
await FileManagement.write(filename, next);
|
|
95
99
|
} else {
|
|
96
100
|
logger.info('CustomerIO Podfile snippets already exists. Skipping...');
|
|
97
101
|
}
|
|
@@ -144,6 +148,6 @@ export async function injectCIONotificationPodfileCode(
|
|
|
144
148
|
if (next !== podfile) {
|
|
145
149
|
// FileManagement.append matches what the previous direct-append did.
|
|
146
150
|
// Slice off the leading content (already on disk) and append only the new tail.
|
|
147
|
-
FileManagement.append(filename, next.slice(podfile.length));
|
|
151
|
+
await FileManagement.append(filename, next.slice(podfile.length));
|
|
148
152
|
}
|
|
149
153
|
}
|
|
@@ -181,7 +181,7 @@ export function addNotificationServiceExtensionToXcodeProject(
|
|
|
181
181
|
// - https://github.com/apache/cordova-node-xcode/blob/8b98cabc5978359db88dc9ff2d4c015cba40f150/lib/pbxProject.js#L860
|
|
182
182
|
const projObjects = xcodeProject.hash.project.objects;
|
|
183
183
|
projObjects.PBXTargetDependency = projObjects.PBXTargetDependency || {};
|
|
184
|
-
projObjects.PBXContainerItemProxy = projObjects.
|
|
184
|
+
projObjects.PBXContainerItemProxy = projObjects.PBXContainerItemProxy || {};
|
|
185
185
|
|
|
186
186
|
// Add the NSE target. This also adds PBXTargetDependency and PBXContainerItemProxy.
|
|
187
187
|
const nseTarget = xcodeProject.addTarget(
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { format } from 'util';
|
|
2
|
+
|
|
1
3
|
// Use CUSTOMERIO_DEBUG_MODE if defined; otherwise enable in development mode only
|
|
2
4
|
const VERBOSE_MODE =
|
|
3
5
|
process.env.CUSTOMERIO_DEBUG_MODE !== undefined
|
|
@@ -6,6 +8,17 @@ const VERBOSE_MODE =
|
|
|
6
8
|
const PREFIX = '[CustomerIO]';
|
|
7
9
|
const formatMessage = (message: string): string => `${PREFIX} ${message}`;
|
|
8
10
|
|
|
11
|
+
// `info`/`log`/`debug` go straight to stderr via `process.stderr.write` rather
|
|
12
|
+
// than `console.log/info/debug` (which default to stdout). Expo's CLI parses
|
|
13
|
+
// `expo config --json` stdout as JSON and eas-cli no longer falls back on a
|
|
14
|
+
// parse failure — a single stray verbose line aborts the build. Keeping
|
|
15
|
+
// verbose output on stderr makes the trace impossible to leak into that
|
|
16
|
+
// stream, regardless of host console rebinding.
|
|
17
|
+
const writeStderr = (message: string, args: unknown[]): void => {
|
|
18
|
+
const line = args.length > 0 ? format(message, ...args) : message;
|
|
19
|
+
process.stderr.write(`${line}\n`);
|
|
20
|
+
};
|
|
21
|
+
|
|
9
22
|
export const logger = {
|
|
10
23
|
format: formatMessage,
|
|
11
24
|
|
|
@@ -19,19 +32,19 @@ export const logger = {
|
|
|
19
32
|
|
|
20
33
|
info: (message: string, ...args: unknown[]): void => {
|
|
21
34
|
if (VERBOSE_MODE) {
|
|
22
|
-
|
|
35
|
+
writeStderr(formatMessage(message), args);
|
|
23
36
|
}
|
|
24
37
|
},
|
|
25
38
|
|
|
26
39
|
log: (message: string, ...args: unknown[]): void => {
|
|
27
40
|
if (VERBOSE_MODE) {
|
|
28
|
-
|
|
41
|
+
writeStderr(formatMessage(message), args);
|
|
29
42
|
}
|
|
30
43
|
},
|
|
31
44
|
|
|
32
45
|
debug: (message: string, ...args: unknown[]): void => {
|
|
33
46
|
if (VERBOSE_MODE) {
|
|
34
|
-
|
|
47
|
+
writeStderr(formatMessage(message), args);
|
|
35
48
|
}
|
|
36
49
|
}
|
|
37
50
|
};
|