customerio-expo-plugin 2.7.0 → 2.7.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 +4 -3
- package/plugin/lib/commonjs/android/withAndroidManifestUpdates.js +5 -4
- package/plugin/lib/commonjs/android/withAndroidManifestUpdates.js.map +1 -1
- package/plugin/lib/commonjs/android/withAppGoogleServices.js +2 -1
- package/plugin/lib/commonjs/android/withAppGoogleServices.js.map +1 -1
- package/plugin/lib/commonjs/android/withCIOAndroid.js +17 -11
- package/plugin/lib/commonjs/android/withCIOAndroid.js.map +1 -1
- package/plugin/lib/commonjs/android/withGistMavenRepository.js +2 -1
- package/plugin/lib/commonjs/android/withGistMavenRepository.js.map +1 -1
- package/plugin/lib/commonjs/android/withGoogleServicesJSON.js +4 -3
- package/plugin/lib/commonjs/android/withGoogleServicesJSON.js.map +1 -1
- package/plugin/lib/commonjs/android/withMainApplicationModifications.js +2 -1
- package/plugin/lib/commonjs/android/withMainApplicationModifications.js.map +1 -1
- package/plugin/lib/commonjs/helpers/native-files/ios/CustomerIOSDKInitializer.swift +10 -4
- package/plugin/lib/commonjs/helpers/utils/fileManagement.js +5 -4
- package/plugin/lib/commonjs/helpers/utils/fileManagement.js.map +1 -1
- package/plugin/lib/commonjs/helpers/utils/injectCIOPodfileCode.js +2 -1
- package/plugin/lib/commonjs/helpers/utils/injectCIOPodfileCode.js.map +1 -1
- package/plugin/lib/commonjs/helpers/utils/patchPluginNativeCode.js +5 -1
- package/plugin/lib/commonjs/helpers/utils/patchPluginNativeCode.js.map +1 -1
- package/plugin/lib/commonjs/index.js +3 -11
- package/plugin/lib/commonjs/index.js.map +1 -1
- package/plugin/lib/commonjs/ios/withAppDelegateModifications.js +2 -1
- package/plugin/lib/commonjs/ios/withAppDelegateModifications.js.map +1 -1
- package/plugin/lib/commonjs/ios/withCIOIos.js +7 -3
- package/plugin/lib/commonjs/ios/withCIOIos.js.map +1 -1
- package/plugin/lib/commonjs/ios/withCIOIosSwift.js +11 -10
- package/plugin/lib/commonjs/ios/withCIOIosSwift.js.map +1 -1
- package/plugin/lib/commonjs/ios/withGoogleServicesJsonFile.js +8 -7
- package/plugin/lib/commonjs/ios/withGoogleServicesJsonFile.js.map +1 -1
- package/plugin/lib/commonjs/ios/withNotificationsXcodeProject.js +29 -23
- package/plugin/lib/commonjs/ios/withNotificationsXcodeProject.js.map +1 -1
- package/plugin/lib/commonjs/utils/android.js +2 -1
- package/plugin/lib/commonjs/utils/android.js.map +1 -1
- package/plugin/lib/commonjs/utils/config.js +3 -2
- package/plugin/lib/commonjs/utils/config.js.map +1 -1
- package/plugin/lib/commonjs/utils/logger.js +35 -0
- package/plugin/lib/commonjs/utils/logger.js.map +1 -0
- package/plugin/lib/commonjs/utils/validation.js +68 -25
- package/plugin/lib/commonjs/utils/validation.js.map +1 -1
- package/plugin/lib/commonjs/utils/xcode.js +2 -1
- package/plugin/lib/commonjs/utils/xcode.js.map +1 -1
- package/plugin/lib/module/android/withAndroidManifestUpdates.js +6 -4
- package/plugin/lib/module/android/withAndroidManifestUpdates.js.map +1 -1
- package/plugin/lib/module/android/withAppGoogleServices.js +2 -1
- package/plugin/lib/module/android/withAppGoogleServices.js.map +1 -1
- package/plugin/lib/module/android/withCIOAndroid.js +17 -11
- package/plugin/lib/module/android/withCIOAndroid.js.map +1 -1
- package/plugin/lib/module/android/withGistMavenRepository.js +2 -1
- package/plugin/lib/module/android/withGistMavenRepository.js.map +1 -1
- package/plugin/lib/module/android/withGoogleServicesJSON.js +4 -3
- package/plugin/lib/module/android/withGoogleServicesJSON.js.map +1 -1
- package/plugin/lib/module/android/withMainApplicationModifications.js +2 -1
- package/plugin/lib/module/android/withMainApplicationModifications.js.map +1 -1
- package/plugin/lib/module/helpers/native-files/ios/CustomerIOSDKInitializer.swift +10 -4
- package/plugin/lib/module/helpers/utils/fileManagement.js +6 -5
- package/plugin/lib/module/helpers/utils/fileManagement.js.map +1 -1
- package/plugin/lib/module/helpers/utils/injectCIOPodfileCode.js +2 -1
- package/plugin/lib/module/helpers/utils/injectCIOPodfileCode.js.map +1 -1
- package/plugin/lib/module/helpers/utils/patchPluginNativeCode.js +5 -1
- package/plugin/lib/module/helpers/utils/patchPluginNativeCode.js.map +1 -1
- package/plugin/lib/module/index.js +3 -12
- package/plugin/lib/module/index.js.map +1 -1
- package/plugin/lib/module/ios/withAppDelegateModifications.js +2 -1
- package/plugin/lib/module/ios/withAppDelegateModifications.js.map +1 -1
- package/plugin/lib/module/ios/withCIOIos.js +7 -3
- package/plugin/lib/module/ios/withCIOIos.js.map +1 -1
- package/plugin/lib/module/ios/withCIOIosSwift.js +11 -10
- package/plugin/lib/module/ios/withCIOIosSwift.js.map +1 -1
- package/plugin/lib/module/ios/withGoogleServicesJsonFile.js +8 -7
- package/plugin/lib/module/ios/withGoogleServicesJsonFile.js.map +1 -1
- package/plugin/lib/module/ios/withNotificationsXcodeProject.js +29 -23
- package/plugin/lib/module/ios/withNotificationsXcodeProject.js.map +1 -1
- package/plugin/lib/module/utils/android.js +2 -1
- package/plugin/lib/module/utils/android.js.map +1 -1
- package/plugin/lib/module/utils/config.js +4 -2
- package/plugin/lib/module/utils/config.js.map +1 -1
- package/plugin/lib/module/utils/logger.js +29 -0
- package/plugin/lib/module/utils/logger.js.map +1 -0
- package/plugin/lib/module/utils/validation.js +68 -27
- package/plugin/lib/module/utils/validation.js.map +1 -1
- package/plugin/lib/module/utils/xcode.js +2 -1
- package/plugin/lib/module/utils/xcode.js.map +1 -1
- package/plugin/lib/typescript/android/withCIOAndroid.d.ts +1 -1
- package/plugin/lib/typescript/ios/withCIOIos.d.ts +1 -1
- package/plugin/lib/typescript/ios/withCIOIosSwift.d.ts +1 -1
- package/plugin/lib/typescript/utils/logger.d.ts +8 -0
- package/plugin/lib/typescript/utils/validation.d.ts +6 -3
- package/plugin/src/android/withAndroidManifestUpdates.ts +5 -4
- package/plugin/src/android/withAppGoogleServices.ts +2 -1
- package/plugin/src/android/withCIOAndroid.ts +18 -12
- package/plugin/src/android/withGistMavenRepository.ts +3 -2
- package/plugin/src/android/withGoogleServicesJSON.ts +4 -3
- package/plugin/src/android/withMainApplicationModifications.ts +2 -1
- package/plugin/src/helpers/native-files/ios/CustomerIOSDKInitializer.swift +10 -4
- package/plugin/src/helpers/utils/fileManagement.ts +10 -9
- package/plugin/src/helpers/utils/injectCIOPodfileCode.ts +2 -1
- package/plugin/src/helpers/utils/patchPluginNativeCode.ts +6 -1
- package/plugin/src/index.ts +3 -13
- package/plugin/src/ios/withAppDelegateModifications.ts +2 -1
- package/plugin/src/ios/withCIOIos.ts +12 -8
- package/plugin/src/ios/withCIOIosSwift.ts +15 -14
- package/plugin/src/ios/withGoogleServicesJsonFile.ts +8 -7
- package/plugin/src/ios/withNotificationsXcodeProject.ts +31 -35
- package/plugin/src/utils/android.ts +2 -1
- package/plugin/src/utils/config.ts +3 -2
- package/plugin/src/utils/logger.ts +37 -0
- package/plugin/src/utils/validation.ts +96 -32
- package/plugin/src/utils/xcode.ts +2 -1
|
@@ -12,24 +12,30 @@ import { withProjectStrings } from './withProjectStrings';
|
|
|
12
12
|
|
|
13
13
|
export function withCIOAndroid(
|
|
14
14
|
config: ExpoConfig,
|
|
15
|
-
sdkConfig
|
|
16
|
-
props
|
|
15
|
+
sdkConfig?: NativeSDKConfig,
|
|
16
|
+
props?: CustomerIOPluginOptionsAndroid,
|
|
17
17
|
): ExpoConfig {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
18
|
+
// Only run notification setup if props are provided
|
|
19
|
+
if (props) {
|
|
20
|
+
config = withGistMavenRepository(config, props);
|
|
21
|
+
config = withProjectGoogleServices(config, props);
|
|
22
|
+
config = withAppGoogleServices(config, props);
|
|
23
|
+
config = withGoogleServicesJSON(config, props);
|
|
24
|
+
if (props.setHighPriorityPushHandler !== undefined) {
|
|
25
|
+
config = withAndroidManifestUpdates(config, props);
|
|
26
|
+
}
|
|
27
|
+
if (props.pushNotification?.channel) {
|
|
28
|
+
config = withNotificationChannelMetadata(config, props);
|
|
29
|
+
}
|
|
28
30
|
}
|
|
31
|
+
|
|
29
32
|
// Add auto initialization if sdkConfig is provided
|
|
30
33
|
if (sdkConfig) {
|
|
31
34
|
config = withMainApplicationModifications(config, sdkConfig);
|
|
32
35
|
}
|
|
33
36
|
|
|
37
|
+
// Update project strings for user agent metadata
|
|
38
|
+
config = withProjectStrings(config);
|
|
39
|
+
|
|
34
40
|
return config;
|
|
35
41
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { withProjectBuildGradle } from '@expo/config-plugins';
|
|
2
1
|
import type { ConfigPlugin } from '@expo/config-plugins';
|
|
2
|
+
import { withProjectBuildGradle } from '@expo/config-plugins';
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
CIO_GIST_MAVEN_REGEX,
|
|
6
6
|
CIO_PROJECT_ALLPROJECTS_REGEX,
|
|
7
7
|
CIO_PROJECT_GIST_MAVEN_SNIPPET,
|
|
8
8
|
} from '../helpers/constants/android';
|
|
9
|
+
import { logger } from '../utils/logger';
|
|
9
10
|
import type { CustomerIOPluginOptionsAndroid } from './../types/cio-types';
|
|
10
11
|
|
|
11
12
|
export const withGistMavenRepository: ConfigPlugin<
|
|
@@ -19,7 +20,7 @@ export const withGistMavenRepository: ConfigPlugin<
|
|
|
19
20
|
`$1\n${CIO_PROJECT_GIST_MAVEN_SNIPPET}`
|
|
20
21
|
);
|
|
21
22
|
} else {
|
|
22
|
-
|
|
23
|
+
logger.info('build.gradle snippet already exists. Skipping...');
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
return props;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ConfigPlugin } from '@expo/config-plugins';
|
|
2
2
|
import { withProjectBuildGradle } from '@expo/config-plugins';
|
|
3
3
|
|
|
4
|
+
import { logger } from '../utils/logger';
|
|
4
5
|
import { FileManagement } from './../helpers/utils/fileManagement';
|
|
5
6
|
import type { CustomerIOPluginOptionsAndroid } from './../types/cio-types';
|
|
6
7
|
|
|
@@ -21,17 +22,17 @@ export const withGoogleServicesJSON: ConfigPlugin<
|
|
|
21
22
|
`${androidPath}/app/google-services.json`
|
|
22
23
|
);
|
|
23
24
|
} catch {
|
|
24
|
-
|
|
25
|
+
logger.info(
|
|
25
26
|
`There was an error copying your google-services.json file. You can copy it manually into ${androidPath}/app/google-services.json`
|
|
26
27
|
);
|
|
27
28
|
}
|
|
28
29
|
} else {
|
|
29
|
-
|
|
30
|
+
logger.info(
|
|
30
31
|
`The Google Services file provided in ${googleServicesFile} doesn't seem to exist. You can copy it manually into ${androidPath}/app/google-services.json`
|
|
31
32
|
);
|
|
32
33
|
}
|
|
33
34
|
} else {
|
|
34
|
-
|
|
35
|
+
logger.info(
|
|
35
36
|
`File already exists: ${androidPath}/app/google-services.json. Skipping...`
|
|
36
37
|
);
|
|
37
38
|
}
|
|
@@ -6,6 +6,7 @@ import { PLATFORM } from '../helpers/constants/common';
|
|
|
6
6
|
import { patchNativeSDKInitializer } from '../helpers/utils/patchPluginNativeCode';
|
|
7
7
|
import type { NativeSDKConfig } from '../types/cio-types';
|
|
8
8
|
import { addCodeToMethod, addImportToFile, copyTemplateFile } from '../utils/android';
|
|
9
|
+
import { logger } from '../utils/logger';
|
|
9
10
|
|
|
10
11
|
export const withMainApplicationModifications: ConfigPlugin<NativeSDKConfig> = (configOuter, sdkConfig) => {
|
|
11
12
|
return withMainApplication(configOuter, async (config) => {
|
|
@@ -42,7 +43,7 @@ const setupCustomerIOSDKInitializer = (
|
|
|
42
43
|
content = addCodeToMethod(content, CIO_MAINAPPLICATION_ONCREATE_REGEX, CIO_NATIVE_SDK_INITIALIZE_SNIPPET);
|
|
43
44
|
}
|
|
44
45
|
} catch (error) {
|
|
45
|
-
|
|
46
|
+
logger.warn(`Could not setup ${SDK_INITIALIZER_CLASS}:`, error);
|
|
46
47
|
return config.modResults.contents;
|
|
47
48
|
}
|
|
48
49
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import CioDataPipelines
|
|
2
2
|
import CioInternalCommon
|
|
3
3
|
import CioMessagingInApp
|
|
4
|
-
import customerio_reactnative
|
|
5
4
|
|
|
6
5
|
class CustomerIOSDKInitializer {
|
|
7
6
|
static func initialize() {
|
|
@@ -27,9 +26,16 @@ class CustomerIOSDKInitializer {
|
|
|
27
26
|
CustomerIO.initialize(withConfig: builder.build())
|
|
28
27
|
|
|
29
28
|
if let siteId = siteId {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
let inAppConfig = MessagingInAppConfigBuilder(siteId: siteId, region: region).build()
|
|
30
|
+
MessagingInApp.initialize(withConfig: inAppConfig)
|
|
31
|
+
let logger = DIGraphShared.shared.logger
|
|
32
|
+
// Retrieves ReactInAppEventListener from DI graph, populated when it is accessed in React Native SDK.
|
|
33
|
+
if let listener: InAppEventListener? = DIGraphShared.shared.getOverriddenInstance() {
|
|
34
|
+
logger.debug("[Expo][InApp] React InAppEventListener found in DI graph and set")
|
|
35
|
+
MessagingInApp.shared.setEventListener(listener)
|
|
36
|
+
} else {
|
|
37
|
+
logger.debug("[Expo][InApp] React InAppEventListener not found in DI graph, will be set by React Native module when accessed")
|
|
38
|
+
}
|
|
33
39
|
}
|
|
34
40
|
}
|
|
35
41
|
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
+
import type { MakeDirectoryOptions } from 'fs';
|
|
1
2
|
import {
|
|
2
|
-
readFile,
|
|
3
|
-
writeFile,
|
|
4
3
|
appendFile,
|
|
5
|
-
existsSync,
|
|
6
4
|
copyFileSync,
|
|
5
|
+
existsSync,
|
|
7
6
|
mkdirSync,
|
|
8
|
-
|
|
7
|
+
readFile,
|
|
9
8
|
readFileSync,
|
|
9
|
+
writeFile,
|
|
10
|
+
writeFileSync,
|
|
10
11
|
} from 'fs';
|
|
11
|
-
import
|
|
12
|
+
import { logger } from '../../utils/logger';
|
|
12
13
|
|
|
13
14
|
export class FileManagement {
|
|
14
15
|
static async read(path: string): Promise<string> {
|
|
@@ -55,7 +56,7 @@ export class FileManagement {
|
|
|
55
56
|
try {
|
|
56
57
|
copyFileSync(src, dest);
|
|
57
58
|
} catch (err) {
|
|
58
|
-
|
|
59
|
+
logger.error(`Error copying file from ${src} to ${dest}: `, err);
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
62
|
|
|
@@ -63,7 +64,7 @@ export class FileManagement {
|
|
|
63
64
|
try {
|
|
64
65
|
mkdirSync(path, options);
|
|
65
66
|
} catch (err) {
|
|
66
|
-
|
|
67
|
+
logger.error(`Error creating directory ${path}: `, err);
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
|
|
@@ -71,7 +72,7 @@ export class FileManagement {
|
|
|
71
72
|
try {
|
|
72
73
|
writeFileSync(path, data);
|
|
73
74
|
} catch (err) {
|
|
74
|
-
|
|
75
|
+
logger.error(`Error writing to file ${path}: `, err);
|
|
75
76
|
}
|
|
76
77
|
}
|
|
77
78
|
|
|
@@ -79,7 +80,7 @@ export class FileManagement {
|
|
|
79
80
|
try {
|
|
80
81
|
return readFileSync(path, 'utf-8');
|
|
81
82
|
} catch (err) {
|
|
82
|
-
|
|
83
|
+
logger.error(`Error reading file ${path}: `, err);
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
return '';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CustomerIOPluginOptionsIOS } from '../../types/cio-types';
|
|
2
|
+
import { logger } from '../../utils/logger';
|
|
2
3
|
import { getRelativePathToRNSDK } from '../constants/ios';
|
|
3
4
|
import { injectCodeByRegex } from './codeInjection';
|
|
4
5
|
import { FileManagement } from './fileManagement';
|
|
@@ -36,7 +37,7 @@ ${blockEnd}
|
|
|
36
37
|
).join('\n')
|
|
37
38
|
);
|
|
38
39
|
} else {
|
|
39
|
-
|
|
40
|
+
logger.info('CustomerIO Podfile snippets already exists. Skipping...');
|
|
40
41
|
}
|
|
41
42
|
}
|
|
42
43
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { NativeSDKConfig } from '../../types/cio-types';
|
|
2
|
-
import { PLATFORM, type Platform } from '../constants/common';
|
|
3
2
|
import { getPluginVersion } from '../../utils/plugin';
|
|
3
|
+
import { validateNativeSDKConfig } from '../../utils/validation';
|
|
4
|
+
import { PLATFORM, type Platform } from '../constants/common';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Shared utility function to perform common SDK config replacements
|
|
@@ -11,6 +12,10 @@ export function patchNativeSDKInitializer(
|
|
|
11
12
|
platform: Platform,
|
|
12
13
|
sdkConfig: NativeSDKConfig
|
|
13
14
|
): string {
|
|
15
|
+
// Validate SDK configuration to ensure all fields are present and
|
|
16
|
+
// correct at the time of patching in prebuild
|
|
17
|
+
validateNativeSDKConfig(sdkConfig);
|
|
18
|
+
|
|
14
19
|
let content = rawContent;
|
|
15
20
|
|
|
16
21
|
// Helper function to replace placeholders with platform-specific fallback values
|
package/plugin/src/index.ts
CHANGED
|
@@ -4,7 +4,6 @@ import { withCIOAndroid } from './android/withCIOAndroid';
|
|
|
4
4
|
import { isExpoVersion53OrHigher } from './ios/utils';
|
|
5
5
|
import { withCIOIos } from './ios/withCIOIos';
|
|
6
6
|
import type { CustomerIOPluginOptions } from './types/cio-types';
|
|
7
|
-
import { validateNativeSDKConfig } from './utils/validation';
|
|
8
7
|
|
|
9
8
|
// Entry point for config plugin
|
|
10
9
|
function withCustomerIOPlugin(
|
|
@@ -20,18 +19,9 @@ function withCustomerIOPlugin(
|
|
|
20
19
|
);
|
|
21
20
|
}
|
|
22
21
|
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (props.ios) {
|
|
29
|
-
config = withCIOIos(config, props.config, props.ios);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if (props.android) {
|
|
33
|
-
config = withCIOAndroid(config, props.config, props.android);
|
|
34
|
-
}
|
|
22
|
+
// Apply platform specific modifications
|
|
23
|
+
config = withCIOIos(config, props.config, props.ios);
|
|
24
|
+
config = withCIOAndroid(config, props.config, props.android);
|
|
35
25
|
|
|
36
26
|
return config;
|
|
37
27
|
}
|
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
} from '../helpers/utils/codeInjection';
|
|
33
33
|
import { FileManagement } from '../helpers/utils/fileManagement';
|
|
34
34
|
import type { CustomerIOPluginOptionsIOS } from '../types/cio-types';
|
|
35
|
+
import { logger } from '../utils/logger';
|
|
35
36
|
import { isFcmPushProvider } from './utils';
|
|
36
37
|
|
|
37
38
|
const addImport = (stringContents: string, appName: string) => {
|
|
@@ -268,7 +269,7 @@ export const withAppDelegateModifications: ConfigPlugin<
|
|
|
268
269
|
|
|
269
270
|
config.modResults.contents = stringContents;
|
|
270
271
|
} else {
|
|
271
|
-
|
|
272
|
+
logger.info('Customerio AppDelegate changes already exist. Skipping...');
|
|
272
273
|
}
|
|
273
274
|
|
|
274
275
|
return config;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { ExpoConfig } from '@expo/config-types';
|
|
2
|
-
|
|
3
2
|
import type {
|
|
4
3
|
CustomerIOPluginOptionsIOS,
|
|
5
4
|
CustomerIOPluginPushNotificationOptions,
|
|
6
5
|
NativeSDKConfig,
|
|
7
6
|
} from '../types/cio-types';
|
|
8
7
|
import { mergeConfigWithEnvValues } from '../utils/config';
|
|
8
|
+
import { logger } from '../utils/logger';
|
|
9
9
|
import { isExpoVersion53OrHigher } from './utils';
|
|
10
10
|
import { withAppDelegateModifications } from './withAppDelegateModifications';
|
|
11
11
|
import { withCIOIosSwift } from './withCIOIosSwift';
|
|
@@ -15,13 +15,13 @@ import { withCioXcodeProject } from './withXcodeProject';
|
|
|
15
15
|
|
|
16
16
|
export function withCIOIos(
|
|
17
17
|
config: ExpoConfig,
|
|
18
|
-
sdkConfig
|
|
19
|
-
props
|
|
18
|
+
sdkConfig?: NativeSDKConfig,
|
|
19
|
+
props?: CustomerIOPluginOptionsIOS,
|
|
20
20
|
) {
|
|
21
21
|
const isSwiftProject = isExpoVersion53OrHigher(config);
|
|
22
22
|
const platformConfig = mergeDeprecatedPropertiesAndLogWarnings(props);
|
|
23
23
|
|
|
24
|
-
if (platformConfig
|
|
24
|
+
if (platformConfig?.pushNotification) {
|
|
25
25
|
if (isSwiftProject) {
|
|
26
26
|
config = withCIOIosSwift(config, sdkConfig, platformConfig);
|
|
27
27
|
} else {
|
|
@@ -49,14 +49,18 @@ export function withCIOIos(
|
|
|
49
49
|
while the rest of the plugin code remains unchanged.
|
|
50
50
|
*/
|
|
51
51
|
const mergeDeprecatedPropertiesAndLogWarnings = (
|
|
52
|
-
props
|
|
53
|
-
) => {
|
|
52
|
+
props?: CustomerIOPluginOptionsIOS,
|
|
53
|
+
): CustomerIOPluginOptionsIOS | undefined => {
|
|
54
54
|
// The deprecatedTopLevelProperties maps the top level properties
|
|
55
55
|
// that are deprecated to the new ios.pushNotification.* properties
|
|
56
56
|
// that should be used instead. The deprecated properties are
|
|
57
57
|
// still available for backwards compatibility, but they will
|
|
58
58
|
// be removed in the future.
|
|
59
59
|
|
|
60
|
+
if (!props) {
|
|
61
|
+
return props
|
|
62
|
+
}
|
|
63
|
+
|
|
60
64
|
const deprecatedTopLevelProperties = {
|
|
61
65
|
showPushAppInForeground: props.showPushAppInForeground,
|
|
62
66
|
autoTrackPushEvents: props.autoTrackPushEvents,
|
|
@@ -68,7 +72,7 @@ const mergeDeprecatedPropertiesAndLogWarnings = (
|
|
|
68
72
|
// loop over all the deprecated properties and log a warning if they are set
|
|
69
73
|
Object.entries(deprecatedTopLevelProperties).forEach(([key, value]) => {
|
|
70
74
|
if (value !== undefined) {
|
|
71
|
-
|
|
75
|
+
logger.warn(
|
|
72
76
|
`The ios.${key} property is deprecated. Please use ios.pushNotification.${key} instead.`
|
|
73
77
|
);
|
|
74
78
|
|
|
@@ -82,7 +86,7 @@ const mergeDeprecatedPropertiesAndLogWarnings = (
|
|
|
82
86
|
[propKey]: value,
|
|
83
87
|
};
|
|
84
88
|
} else {
|
|
85
|
-
|
|
89
|
+
logger.warn(
|
|
86
90
|
`The ios.${key} property is deprecated. Since the value of ios.pushNotification.${key} is set, it will be used.`
|
|
87
91
|
);
|
|
88
92
|
}
|
|
@@ -18,6 +18,7 @@ import { replaceCodeByRegex } from '../helpers/utils/codeInjection';
|
|
|
18
18
|
import { FileManagement } from '../helpers/utils/fileManagement';
|
|
19
19
|
import { patchNativeSDKInitializer } from '../helpers/utils/patchPluginNativeCode';
|
|
20
20
|
import type { CustomerIOPluginOptionsIOS, NativeSDKConfig } from '../types/cio-types';
|
|
21
|
+
import { logger } from '../utils/logger';
|
|
21
22
|
import { getIosNativeFilesPath } from '../utils/plugin';
|
|
22
23
|
import { copyFileToXcode, getOrCreateCustomerIOGroup } from '../utils/xcode';
|
|
23
24
|
import { isFcmPushProvider } from './utils';
|
|
@@ -31,13 +32,13 @@ const CIO_SDK_APP_DELEGATE_HANDLER_FILENAME = `${CIO_SDK_APP_DELEGATE_HANDLER_CL
|
|
|
31
32
|
*/
|
|
32
33
|
const copyAndConfigureAppDelegateHandler = (
|
|
33
34
|
config: ExportedConfigWithProps<XcodeProject>,
|
|
34
|
-
sdkConfig
|
|
35
|
-
props
|
|
35
|
+
sdkConfig?: NativeSDKConfig,
|
|
36
|
+
props?: CustomerIOPluginOptionsIOS,
|
|
36
37
|
): ExportedConfigWithProps<XcodeProject> => {
|
|
37
38
|
// Destination path in the iOS project
|
|
38
39
|
const projectName = config.modRequest.projectName || '';
|
|
39
40
|
if (!projectName) {
|
|
40
|
-
|
|
41
|
+
logger.warn(
|
|
41
42
|
'Project name is undefined, cannot copy CustomerIO files'
|
|
42
43
|
);
|
|
43
44
|
return config;
|
|
@@ -49,7 +50,7 @@ const copyAndConfigureAppDelegateHandler = (
|
|
|
49
50
|
const iosProjectRoot = path.join(projectRoot, 'ios');
|
|
50
51
|
|
|
51
52
|
const group = getOrCreateCustomerIOGroup(xcodeProject, projectName);
|
|
52
|
-
if (props
|
|
53
|
+
if (props?.pushNotification) {
|
|
53
54
|
// Copy CioSdkAppDelegateHandler.swift for full push notification + auto-init support
|
|
54
55
|
copyAndConfigurePushAppDelegateHandler({
|
|
55
56
|
xcodeProject,
|
|
@@ -193,8 +194,8 @@ const copyAndConfigureNativeSDKInitializer = ({
|
|
|
193
194
|
|
|
194
195
|
export const withCIOIosSwift = (
|
|
195
196
|
configOuter: ExpoConfig,
|
|
196
|
-
sdkConfig
|
|
197
|
-
props
|
|
197
|
+
sdkConfig?: NativeSDKConfig,
|
|
198
|
+
props?: CustomerIOPluginOptionsIOS,
|
|
198
199
|
) => {
|
|
199
200
|
// First, copy required swift files to iOS folder and add it to Xcode project
|
|
200
201
|
configOuter = withXcodeProject(configOuter, async (config) => {
|
|
@@ -202,7 +203,7 @@ export const withCIOIosSwift = (
|
|
|
202
203
|
});
|
|
203
204
|
|
|
204
205
|
// Modify the AppDelegate based on configuration
|
|
205
|
-
if (props
|
|
206
|
+
if (props?.pushNotification) {
|
|
206
207
|
// With push notifications: delegate to CioSdkAppDelegateHandler for both push and auto-init
|
|
207
208
|
return withAppDelegate(configOuter, async (config) => {
|
|
208
209
|
return modifyAppDelegateWithPushAppDelegateHandler(config, props);
|
|
@@ -230,7 +231,7 @@ const modifyAppDelegateWithPushAppDelegateHandler = (
|
|
|
230
231
|
|
|
231
232
|
// Check if modifications have already been applied
|
|
232
233
|
if (appDelegateContent.includes(CIO_SDK_APP_DELEGATE_HANDLER_CLASS)) {
|
|
233
|
-
|
|
234
|
+
logger.info(
|
|
234
235
|
'CustomerIO Swift AppDelegate changes already exist. Skipping...'
|
|
235
236
|
);
|
|
236
237
|
return config;
|
|
@@ -274,7 +275,7 @@ const modifyAppDelegateWithNativeSDKInitializer = (
|
|
|
274
275
|
|
|
275
276
|
// Check if modifications have already been applied
|
|
276
277
|
if (appDelegateContent.includes(CIO_NATIVE_SDK_INITIALIZE_CALL)) {
|
|
277
|
-
|
|
278
|
+
logger.info(
|
|
278
279
|
'CustomerIO Swift AppDelegate changes already exist. Skipping...'
|
|
279
280
|
);
|
|
280
281
|
return config;
|
|
@@ -314,7 +315,7 @@ const addHandlerPropertyDeclaration = (content: string): string => {
|
|
|
314
315
|
const match = content.match(classDeclarationRegex);
|
|
315
316
|
|
|
316
317
|
if (!match) {
|
|
317
|
-
|
|
318
|
+
logger.warn('Could not find AppDelegate class declaration');
|
|
318
319
|
return content;
|
|
319
320
|
}
|
|
320
321
|
|
|
@@ -339,7 +340,7 @@ const modifyDidFinishLaunchingWithOptions = (content: string, codeToInject: stri
|
|
|
339
340
|
const returnStatementMatch = content.match(returnStatementRegex);
|
|
340
341
|
|
|
341
342
|
if (!returnStatementMatch) {
|
|
342
|
-
|
|
343
|
+
logger.warn(
|
|
343
344
|
'Could not find return statement with super.application in didFinishLaunchingWithOptions'
|
|
344
345
|
);
|
|
345
346
|
return content;
|
|
@@ -394,7 +395,7 @@ const addDidRegisterForRemoteNotificationsWithDeviceToken = (
|
|
|
394
395
|
const classEndMatch = content.match(classEndRegex);
|
|
395
396
|
|
|
396
397
|
if (!classEndMatch) {
|
|
397
|
-
|
|
398
|
+
logger.warn('Could not find end of AppDelegate class');
|
|
398
399
|
return content;
|
|
399
400
|
}
|
|
400
401
|
|
|
@@ -452,7 +453,7 @@ const addDidFailToRegisterForRemoteNotificationsWithError = (
|
|
|
452
453
|
const classEndMatch = content.match(classEndRegex);
|
|
453
454
|
|
|
454
455
|
if (!classEndMatch) {
|
|
455
|
-
|
|
456
|
+
logger.warn('Could not find end of AppDelegate class');
|
|
456
457
|
return content;
|
|
457
458
|
}
|
|
458
459
|
|
|
@@ -489,7 +490,7 @@ const addHandleDeeplinkInKilledState = (content: string): string => {
|
|
|
489
490
|
const returnStatementMatch = content.match(returnStatementRegex);
|
|
490
491
|
|
|
491
492
|
if (!returnStatementMatch) {
|
|
492
|
-
|
|
493
|
+
logger.warn('Could not find return statement with launchOptions');
|
|
493
494
|
return content;
|
|
494
495
|
}
|
|
495
496
|
|
|
@@ -2,6 +2,7 @@ import type { ConfigPlugin, XcodeProject } from '@expo/config-plugins';
|
|
|
2
2
|
import { IOSConfig, withXcodeProject } from '@expo/config-plugins';
|
|
3
3
|
|
|
4
4
|
import type { CustomerIOPluginOptionsIOS } from '../types/cio-types';
|
|
5
|
+
import { logger } from '../utils/logger';
|
|
5
6
|
import { FileManagement } from './../helpers/utils/fileManagement';
|
|
6
7
|
import { isFcmPushProvider } from './utils';
|
|
7
8
|
|
|
@@ -15,7 +16,7 @@ export const withGoogleServicesJsonFile: ConfigPlugin<
|
|
|
15
16
|
return props;
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
logger.info(
|
|
19
20
|
'Only specify Customer.io ios.pushNotification.googleServicesFile config if you are not already including' +
|
|
20
21
|
' GoogleService-Info.plist as part of Firebase integration'
|
|
21
22
|
);
|
|
@@ -26,7 +27,7 @@ export const withGoogleServicesJsonFile: ConfigPlugin<
|
|
|
26
27
|
const appName = props.modRequest.projectName;
|
|
27
28
|
|
|
28
29
|
if (FileManagement.exists(`${iosPath}/GoogleService-Info.plist`)) {
|
|
29
|
-
|
|
30
|
+
logger.info(
|
|
30
31
|
`File already exists: ${iosPath}/GoogleService-Info.plist. Skipping...`
|
|
31
32
|
);
|
|
32
33
|
return props;
|
|
@@ -37,7 +38,7 @@ export const withGoogleServicesJsonFile: ConfigPlugin<
|
|
|
37
38
|
) {
|
|
38
39
|
// This is where RN Firebase potentially copies GoogleService-Info.plist
|
|
39
40
|
// Do not copy if it's already done by Firebase to avoid conflict in Resources
|
|
40
|
-
|
|
41
|
+
logger.info(
|
|
41
42
|
`File already exists: ${iosPath}/${appName}/GoogleService-Info.plist. Skipping...`
|
|
42
43
|
);
|
|
43
44
|
return props;
|
|
@@ -45,7 +46,7 @@ export const withGoogleServicesJsonFile: ConfigPlugin<
|
|
|
45
46
|
|
|
46
47
|
if (googleServicesFile && FileManagement.exists(googleServicesFile)) {
|
|
47
48
|
if (config.ios?.googleServicesFile) {
|
|
48
|
-
|
|
49
|
+
logger.warn(
|
|
49
50
|
'Specifying both Expo ios.googleServicesFile and Customer.io ios.pushNotification.googleServicesFile can cause a conflict' +
|
|
50
51
|
' duplicating GoogleService-Info.plist in the iOS project resources. Please remove Customer.io ios.pushNotification.googleServicesFile'
|
|
51
52
|
);
|
|
@@ -59,12 +60,12 @@ export const withGoogleServicesJsonFile: ConfigPlugin<
|
|
|
59
60
|
|
|
60
61
|
addFileToXcodeProject(props.modResults, 'GoogleService-Info.plist');
|
|
61
62
|
} catch {
|
|
62
|
-
|
|
63
|
+
logger.error(
|
|
63
64
|
`There was an error copying your GoogleService-Info.plist file. You can copy it manually into ${iosPath}/GoogleService-Info.plist`
|
|
64
65
|
);
|
|
65
66
|
}
|
|
66
67
|
} else {
|
|
67
|
-
|
|
68
|
+
logger.error(
|
|
68
69
|
`The Google Services file provided in ${googleServicesFile} doesn't seem to exist. You can copy it manually into ${iosPath}/GoogleService-Info.plist`
|
|
69
70
|
);
|
|
70
71
|
}
|
|
@@ -78,7 +79,7 @@ function addFileToXcodeProject(project: XcodeProject, fileName: string) {
|
|
|
78
79
|
const filepath = fileName;
|
|
79
80
|
|
|
80
81
|
if (!IOSConfig.XcodeUtils.ensureGroupRecursively(project, groupName)) {
|
|
81
|
-
|
|
82
|
+
logger.error(
|
|
82
83
|
`Error copying GoogleService-Info.plist. Failed to find or create '${groupName}' group in Xcode.`
|
|
83
84
|
);
|
|
84
85
|
return;
|
|
@@ -9,7 +9,9 @@ import {
|
|
|
9
9
|
import { replaceCodeByRegex } from '../helpers/utils/codeInjection';
|
|
10
10
|
import { injectCIONotificationPodfileCode } from '../helpers/utils/injectCIOPodfileCode';
|
|
11
11
|
import type { CustomerIOPluginOptionsIOS, RichPushConfig } from '../types/cio-types';
|
|
12
|
+
import { logger } from '../utils/logger';
|
|
12
13
|
import { getIosNativeFilesPath } from '../utils/plugin';
|
|
14
|
+
import { validateRichPushConfig } from '../utils/validation';
|
|
13
15
|
import { FileManagement } from './../helpers/utils/fileManagement';
|
|
14
16
|
import { isExpoVersion53OrHigher, isFcmPushProvider } from './utils';
|
|
15
17
|
|
|
@@ -34,7 +36,7 @@ const addNotificationServiceExtension = async (
|
|
|
34
36
|
}
|
|
35
37
|
return xcodeProject;
|
|
36
38
|
} catch (error: unknown) {
|
|
37
|
-
|
|
39
|
+
logger.error(String(error));
|
|
38
40
|
return null;
|
|
39
41
|
}
|
|
40
42
|
};
|
|
@@ -120,7 +122,7 @@ const addRichPushXcodeProj = async (
|
|
|
120
122
|
// Check if `CIO_NOTIFICATION_TARGET_NAME` group already exist in the project
|
|
121
123
|
// If true then skip creating a new group to avoid duplicate folders
|
|
122
124
|
if (xcodeProject.pbxTargetByName(CIO_NOTIFICATION_TARGET_NAME)) {
|
|
123
|
-
|
|
125
|
+
logger.warn(
|
|
124
126
|
`${CIO_NOTIFICATION_TARGET_NAME} already exists in project. Skipping...`
|
|
125
127
|
);
|
|
126
128
|
return;
|
|
@@ -194,7 +196,7 @@ const addRichPushXcodeProj = async (
|
|
|
194
196
|
projObjects.PBXContainerItemProxy = projObjects.PBXTargetDependency || {};
|
|
195
197
|
|
|
196
198
|
if (xcodeProject.pbxTargetByName(CIO_NOTIFICATION_TARGET_NAME)) {
|
|
197
|
-
|
|
199
|
+
logger.warn(
|
|
198
200
|
`${CIO_NOTIFICATION_TARGET_NAME} already exists in project. Skipping...`
|
|
199
201
|
);
|
|
200
202
|
return;
|
|
@@ -295,35 +297,30 @@ const updateNseEnv = (
|
|
|
295
297
|
const cdpApiKey = richPushConfig?.cdpApiKey;
|
|
296
298
|
const region = richPushConfig?.region;
|
|
297
299
|
|
|
298
|
-
if (!
|
|
299
|
-
|
|
300
|
-
'NotificationServiceExtension failed: cdpApiKey missing. Provide in config.cdpApiKey or ios.pushNotification.env.cdpApiKey.'
|
|
301
|
-
);
|
|
300
|
+
if (!validateRichPushConfig(richPushConfig)) {
|
|
301
|
+
return;
|
|
302
302
|
}
|
|
303
303
|
envFileContent = replaceCodeByRegex(
|
|
304
304
|
envFileContent,
|
|
305
305
|
CDP_API_KEY_RE,
|
|
306
|
-
cdpApiKey
|
|
306
|
+
cdpApiKey || 'MISSING_API_KEY',
|
|
307
307
|
);
|
|
308
308
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
mappedRegion
|
|
325
|
-
);
|
|
326
|
-
}
|
|
309
|
+
// Simplify region mapping with case insensitive keys and fallback for invalid regions
|
|
310
|
+
const regionKey = region?.toLowerCase() ?? '';
|
|
311
|
+
const regionMap = {
|
|
312
|
+
us: 'Region.US',
|
|
313
|
+
eu: 'Region.EU',
|
|
314
|
+
} as const;
|
|
315
|
+
const mappedRegion = regionMap[regionKey as keyof typeof regionMap];
|
|
316
|
+
if (!mappedRegion) {
|
|
317
|
+
logger.warn(
|
|
318
|
+
`${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`
|
|
319
|
+
);
|
|
320
|
+
// Fallback to US if invalid region provided
|
|
321
|
+
envFileContent = replaceCodeByRegex(envFileContent, REGION_RE, regionMap.us);
|
|
322
|
+
} else {
|
|
323
|
+
envFileContent = replaceCodeByRegex(envFileContent, REGION_RE, mappedRegion);
|
|
327
324
|
}
|
|
328
325
|
|
|
329
326
|
FileManagement.writeFile(envFileName, envFileContent);
|
|
@@ -355,7 +352,7 @@ async function addPushNotificationFile(
|
|
|
355
352
|
targetFile
|
|
356
353
|
);
|
|
357
354
|
} else {
|
|
358
|
-
|
|
355
|
+
logger.info(`${getTargetFile(targetFileName)} already exists. Skipping...`);
|
|
359
356
|
return;
|
|
360
357
|
}
|
|
361
358
|
|
|
@@ -377,18 +374,17 @@ const updatePushFile = (
|
|
|
377
374
|
let envFileContent = FileManagement.readFile(envFileName);
|
|
378
375
|
const disableNotificationRegistration =
|
|
379
376
|
options.pushNotification?.disableNotificationRegistration;
|
|
380
|
-
const
|
|
381
|
-
|
|
377
|
+
const richPushConfig = options.pushNotification?.env;
|
|
378
|
+
const { cdpApiKey, region } = richPushConfig || {
|
|
379
|
+
cdpApiKey: 'MISSING_API_KEY',
|
|
382
380
|
region: undefined,
|
|
383
381
|
};
|
|
384
|
-
if (!
|
|
385
|
-
|
|
386
|
-
'Adding NotificationServiceExtension failed: ios.pushNotification.env.cdpApiKey is missing from app.config.js or app.json.'
|
|
387
|
-
);
|
|
382
|
+
if (!validateRichPushConfig(richPushConfig)) {
|
|
383
|
+
return;
|
|
388
384
|
}
|
|
389
385
|
|
|
390
386
|
let snippet = '';
|
|
391
|
-
// unless this property is
|
|
387
|
+
// unless this property is explicitly set to true, push notification
|
|
392
388
|
// registration will be added to the AppDelegate
|
|
393
389
|
if (disableNotificationRegistration !== true) {
|
|
394
390
|
snippet = CIO_REGISTER_PUSHNOTIFICATION_SNIPPET;
|
|
@@ -398,7 +394,7 @@ const updatePushFile = (
|
|
|
398
394
|
envFileContent = replaceCodeByRegex(
|
|
399
395
|
envFileContent,
|
|
400
396
|
/\{\{CDP_API_KEY\}\}/,
|
|
401
|
-
cdpApiKey
|
|
397
|
+
cdpApiKey,
|
|
402
398
|
);
|
|
403
399
|
|
|
404
400
|
if (region) {
|