@use-voltra/expo-plugin 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -0
- package/build/cjs/android/files/assets.js +259 -0
- package/build/cjs/android/files/assets.js.map +1 -0
- package/build/cjs/android/files/fonts.js +69 -0
- package/build/cjs/android/files/fonts.js.map +1 -0
- package/build/cjs/android/files/index.js +81 -0
- package/build/cjs/android/files/index.js.map +1 -0
- package/build/cjs/android/files/initialStates.js +83 -0
- package/build/cjs/android/files/initialStates.js.map +1 -0
- package/build/cjs/android/files/kotlin.js +142 -0
- package/build/cjs/android/files/kotlin.js.map +1 -0
- package/build/cjs/android/files/xml.js +247 -0
- package/build/cjs/android/files/xml.js.map +1 -0
- package/build/cjs/android/index.js +33 -0
- package/build/cjs/android/index.js.map +1 -0
- package/build/cjs/android/manifest.js +63 -0
- package/build/cjs/android/manifest.js.map +1 -0
- package/build/cjs/constants.js +48 -0
- package/build/cjs/constants.js.map +1 -0
- package/build/cjs/index.js +71 -0
- package/build/cjs/index.js.map +1 -0
- package/build/cjs/ios/eas.js +28 -0
- package/build/cjs/ios/eas.js.map +1 -0
- package/build/cjs/ios/entitlements.js +46 -0
- package/build/cjs/ios/entitlements.js.map +1 -0
- package/build/cjs/ios/index.js +39 -0
- package/build/cjs/ios/index.js.map +1 -0
- package/build/cjs/ios/infoPlist.js +51 -0
- package/build/cjs/ios/infoPlist.js.map +1 -0
- package/build/cjs/ios/pushNotifications.js +22 -0
- package/build/cjs/ios/pushNotifications.js.map +1 -0
- package/build/cjs/ios-widget/eas.js +66 -0
- package/build/cjs/ios-widget/eas.js.map +1 -0
- package/build/cjs/ios-widget/files/assets.js +199 -0
- package/build/cjs/ios-widget/files/assets.js.map +1 -0
- package/build/cjs/ios-widget/files/entitlements.js +77 -0
- package/build/cjs/ios-widget/files/entitlements.js.map +1 -0
- package/build/cjs/ios-widget/files/index.js +92 -0
- package/build/cjs/ios-widget/files/index.js.map +1 -0
- package/build/cjs/ios-widget/files/infoPlist.js +91 -0
- package/build/cjs/ios-widget/files/infoPlist.js.map +1 -0
- package/build/cjs/ios-widget/files/swift.js +256 -0
- package/build/cjs/ios-widget/files/swift.js.map +1 -0
- package/build/cjs/ios-widget/fonts.js +151 -0
- package/build/cjs/ios-widget/fonts.js.map +1 -0
- package/build/cjs/ios-widget/index.js +46 -0
- package/build/cjs/ios-widget/index.js.map +1 -0
- package/build/cjs/ios-widget/podfile.js +43 -0
- package/build/cjs/ios-widget/podfile.js.map +1 -0
- package/build/cjs/ios-widget/widgetPlist.js +99 -0
- package/build/cjs/ios-widget/widgetPlist.js.map +1 -0
- package/build/cjs/ios-widget/xcode/buildPhases.js +245 -0
- package/build/cjs/ios-widget/xcode/buildPhases.js.map +1 -0
- package/build/cjs/ios-widget/xcode/configurationList.js +91 -0
- package/build/cjs/ios-widget/xcode/configurationList.js.map +1 -0
- package/build/cjs/ios-widget/xcode/groups.js +65 -0
- package/build/cjs/ios-widget/xcode/groups.js.map +1 -0
- package/build/cjs/ios-widget/xcode/index.js +155 -0
- package/build/cjs/ios-widget/xcode/index.js.map +1 -0
- package/build/cjs/ios-widget/xcode/mainAppSettings.js +71 -0
- package/build/cjs/ios-widget/xcode/mainAppSettings.js.map +1 -0
- package/build/cjs/ios-widget/xcode/productFile.js +74 -0
- package/build/cjs/ios-widget/xcode/productFile.js.map +1 -0
- package/build/cjs/ios-widget/xcode/target.js +113 -0
- package/build/cjs/ios-widget/xcode/target.js.map +1 -0
- package/build/cjs/package.json +3 -0
- package/build/cjs/types.js +3 -0
- package/build/cjs/types.js.map +1 -0
- package/build/cjs/utils/entitlements.js +21 -0
- package/build/cjs/utils/entitlements.js.map +1 -0
- package/build/cjs/utils/fileDiscovery.js +107 -0
- package/build/cjs/utils/fileDiscovery.js.map +1 -0
- package/build/cjs/utils/fonts.js +75 -0
- package/build/cjs/utils/fonts.js.map +1 -0
- package/build/cjs/utils/logger.js +51 -0
- package/build/cjs/utils/logger.js.map +1 -0
- package/build/cjs/utils/prerender.js +191 -0
- package/build/cjs/utils/prerender.js.map +1 -0
- package/build/cjs/utils/urlScheme.js +40 -0
- package/build/cjs/utils/urlScheme.js.map +1 -0
- package/build/cjs/validation.js +231 -0
- package/build/cjs/validation.js.map +1 -0
- package/build/esm/android/files/assets.js +223 -0
- package/build/esm/android/files/assets.js.map +1 -0
- package/build/esm/android/files/fonts.js +33 -0
- package/build/esm/android/files/fonts.js.map +1 -0
- package/build/esm/android/files/index.js +77 -0
- package/build/esm/android/files/index.js.map +1 -0
- package/build/esm/android/files/initialStates.js +44 -0
- package/build/esm/android/files/initialStates.js.map +1 -0
- package/build/esm/android/files/kotlin.js +103 -0
- package/build/esm/android/files/kotlin.js.map +1 -0
- package/build/esm/android/files/xml.js +206 -0
- package/build/esm/android/files/xml.js.map +1 -0
- package/build/esm/android/index.js +29 -0
- package/build/esm/android/index.js.map +1 -0
- package/build/esm/android/manifest.js +59 -0
- package/build/esm/android/manifest.js.map +1 -0
- package/build/esm/constants.js +45 -0
- package/build/esm/constants.js.map +1 -0
- package/build/esm/index.js +69 -0
- package/build/esm/index.js.map +1 -0
- package/build/esm/ios/eas.js +24 -0
- package/build/esm/ios/eas.js.map +1 -0
- package/build/esm/ios/entitlements.js +42 -0
- package/build/esm/ios/entitlements.js.map +1 -0
- package/build/esm/ios/index.js +34 -0
- package/build/esm/ios/index.js.map +1 -0
- package/build/esm/ios/infoPlist.js +47 -0
- package/build/esm/ios/infoPlist.js.map +1 -0
- package/build/esm/ios/pushNotifications.js +18 -0
- package/build/esm/ios/pushNotifications.js.map +1 -0
- package/build/esm/ios-widget/eas.js +62 -0
- package/build/esm/ios-widget/eas.js.map +1 -0
- package/build/esm/ios-widget/files/assets.js +163 -0
- package/build/esm/ios-widget/files/assets.js.map +1 -0
- package/build/esm/ios-widget/files/entitlements.js +37 -0
- package/build/esm/ios-widget/files/entitlements.js.map +1 -0
- package/build/esm/ios-widget/files/index.js +55 -0
- package/build/esm/ios-widget/files/index.js.map +1 -0
- package/build/esm/ios-widget/files/infoPlist.js +55 -0
- package/build/esm/ios-widget/files/infoPlist.js.map +1 -0
- package/build/esm/ios-widget/files/swift.js +217 -0
- package/build/esm/ios-widget/files/swift.js.map +1 -0
- package/build/esm/ios-widget/fonts.js +111 -0
- package/build/esm/ios-widget/fonts.js.map +1 -0
- package/build/esm/ios-widget/index.js +42 -0
- package/build/esm/ios-widget/index.js.map +1 -0
- package/build/esm/ios-widget/podfile.js +39 -0
- package/build/esm/ios-widget/podfile.js.map +1 -0
- package/build/esm/ios-widget/widgetPlist.js +92 -0
- package/build/esm/ios-widget/widgetPlist.js.map +1 -0
- package/build/esm/ios-widget/xcode/buildPhases.js +208 -0
- package/build/esm/ios-widget/xcode/buildPhases.js.map +1 -0
- package/build/esm/ios-widget/xcode/configurationList.js +87 -0
- package/build/esm/ios-widget/xcode/configurationList.js.map +1 -0
- package/build/esm/ios-widget/xcode/groups.js +61 -0
- package/build/esm/ios-widget/xcode/groups.js.map +1 -0
- package/build/esm/ios-widget/xcode/index.js +118 -0
- package/build/esm/ios-widget/xcode/index.js.map +1 -0
- package/build/esm/ios-widget/xcode/mainAppSettings.js +68 -0
- package/build/esm/ios-widget/xcode/mainAppSettings.js.map +1 -0
- package/build/esm/ios-widget/xcode/productFile.js +70 -0
- package/build/esm/ios-widget/xcode/productFile.js.map +1 -0
- package/build/esm/ios-widget/xcode/target.js +108 -0
- package/build/esm/ios-widget/xcode/target.js.map +1 -0
- package/build/esm/package.json +3 -0
- package/build/esm/types.js +2 -0
- package/build/esm/types.js.map +1 -0
- package/build/esm/utils/entitlements.js +18 -0
- package/build/esm/utils/entitlements.js.map +1 -0
- package/build/esm/utils/fileDiscovery.js +71 -0
- package/build/esm/utils/fileDiscovery.js.map +1 -0
- package/build/esm/utils/fonts.js +39 -0
- package/build/esm/utils/fonts.js.map +1 -0
- package/build/esm/utils/logger.js +48 -0
- package/build/esm/utils/logger.js.map +1 -0
- package/build/esm/utils/prerender.js +152 -0
- package/build/esm/utils/prerender.js.map +1 -0
- package/build/esm/utils/urlScheme.js +37 -0
- package/build/esm/utils/urlScheme.js.map +1 -0
- package/build/esm/validation.js +193 -0
- package/build/esm/validation.js.map +1 -0
- package/build/types/android/files/assets.d.ts +26 -0
- package/build/types/android/files/assets.d.ts.map +1 -0
- package/build/types/android/files/fonts.d.ts +19 -0
- package/build/types/android/files/fonts.d.ts.map +1 -0
- package/build/types/android/files/index.d.ts +21 -0
- package/build/types/android/files/index.d.ts.map +1 -0
- package/build/types/android/files/initialStates.d.ts +14 -0
- package/build/types/android/files/initialStates.d.ts.map +1 -0
- package/build/types/android/files/kotlin.d.ts +11 -0
- package/build/types/android/files/kotlin.d.ts.map +1 -0
- package/build/types/android/files/xml.d.ts +25 -0
- package/build/types/android/files/xml.d.ts.map +1 -0
- package/build/types/android/index.d.ts +12 -0
- package/build/types/android/index.d.ts.map +1 -0
- package/build/types/android/manifest.d.ts +15 -0
- package/build/types/android/manifest.d.ts.map +1 -0
- package/build/types/constants.d.ts +29 -0
- package/build/types/constants.d.ts.map +1 -0
- package/build/types/index.d.ts +13 -0
- package/build/types/index.d.ts.map +1 -0
- package/build/types/ios/eas.d.ts +12 -0
- package/build/types/ios/eas.d.ts.map +1 -0
- package/build/types/ios/entitlements.d.ts +14 -0
- package/build/types/ios/entitlements.d.ts.map +1 -0
- package/build/types/ios/index.d.ts +19 -0
- package/build/types/ios/index.d.ts.map +1 -0
- package/build/types/ios/infoPlist.d.ts +21 -0
- package/build/types/ios/infoPlist.d.ts.map +1 -0
- package/build/types/ios/pushNotifications.d.ts +10 -0
- package/build/types/ios/pushNotifications.d.ts.map +1 -0
- package/build/types/ios-widget/eas.d.ts +15 -0
- package/build/types/ios-widget/eas.d.ts.map +1 -0
- package/build/types/ios-widget/files/assets.d.ts +13 -0
- package/build/types/ios-widget/files/assets.d.ts.map +1 -0
- package/build/types/ios-widget/files/entitlements.d.ts +17 -0
- package/build/types/ios-widget/files/entitlements.d.ts.map +1 -0
- package/build/types/ios-widget/files/index.d.ts +24 -0
- package/build/types/ios-widget/files/index.d.ts.map +1 -0
- package/build/types/ios-widget/files/infoPlist.d.ts +10 -0
- package/build/types/ios-widget/files/infoPlist.d.ts.map +1 -0
- package/build/types/ios-widget/files/swift.d.ts +15 -0
- package/build/types/ios-widget/files/swift.d.ts.map +1 -0
- package/build/types/ios-widget/fonts.d.ts +22 -0
- package/build/types/ios-widget/fonts.d.ts.map +1 -0
- package/build/types/ios-widget/index.d.ts +31 -0
- package/build/types/ios-widget/index.d.ts.map +1 -0
- package/build/types/ios-widget/podfile.d.ts +9 -0
- package/build/types/ios-widget/podfile.d.ts.map +1 -0
- package/build/types/ios-widget/widgetPlist.d.ts +20 -0
- package/build/types/ios-widget/widgetPlist.d.ts.map +1 -0
- package/build/types/ios-widget/xcode/buildPhases.d.ts +25 -0
- package/build/types/ios-widget/xcode/buildPhases.d.ts.map +1 -0
- package/build/types/ios-widget/xcode/configurationList.d.ts +20 -0
- package/build/types/ios-widget/xcode/configurationList.d.ts.map +1 -0
- package/build/types/ios-widget/xcode/groups.d.ts +15 -0
- package/build/types/ios-widget/xcode/groups.d.ts.map +1 -0
- package/build/types/ios-widget/xcode/index.d.ts +20 -0
- package/build/types/ios-widget/xcode/index.d.ts.map +1 -0
- package/build/types/ios-widget/xcode/mainAppSettings.d.ts +15 -0
- package/build/types/ios-widget/xcode/mainAppSettings.d.ts.map +1 -0
- package/build/types/ios-widget/xcode/productFile.d.ts +14 -0
- package/build/types/ios-widget/xcode/productFile.d.ts.map +1 -0
- package/build/types/ios-widget/xcode/target.d.ts +42 -0
- package/build/types/ios-widget/xcode/target.d.ts.map +1 -0
- package/build/types/types.d.ts +261 -0
- package/build/types/types.d.ts.map +1 -0
- package/build/types/utils/entitlements.d.ts +9 -0
- package/build/types/utils/entitlements.d.ts.map +1 -0
- package/build/types/utils/fileDiscovery.d.ts +13 -0
- package/build/types/utils/fileDiscovery.d.ts.map +1 -0
- package/build/types/utils/fonts.d.ts +2 -0
- package/build/types/utils/fonts.d.ts.map +1 -0
- package/build/types/utils/logger.d.ts +30 -0
- package/build/types/utils/logger.d.ts.map +1 -0
- package/build/types/utils/prerender.d.ts +25 -0
- package/build/types/utils/prerender.d.ts.map +1 -0
- package/build/types/utils/urlScheme.d.ts +10 -0
- package/build/types/utils/urlScheme.d.ts.map +1 -0
- package/build/types/validation.d.ts +17 -0
- package/build/types/validation.d.ts.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Font configuration for Live Activity extension.
|
|
3
|
+
*
|
|
4
|
+
* This code is adapted from expo-font to support custom fonts in Live Activities.
|
|
5
|
+
* @see https://github.com/expo/expo/tree/main/packages/expo-font/plugin
|
|
6
|
+
*
|
|
7
|
+
* I would love to reuse the existing expo-font infrastructure, but it's not that easy to do. I'll most likely revisit it later.
|
|
8
|
+
*/
|
|
9
|
+
import { IOSConfig, withDangerousMod, withXcodeProject } from '@expo/config-plugins';
|
|
10
|
+
import plist from '@expo/plist';
|
|
11
|
+
import { readFileSync, writeFileSync } from 'fs';
|
|
12
|
+
import * as path from 'path';
|
|
13
|
+
import { logger } from '../utils/logger';
|
|
14
|
+
import { resolveFontPaths } from '../utils/fonts';
|
|
15
|
+
/**
|
|
16
|
+
* Plugin that adds custom fonts to the Live Activity extension.
|
|
17
|
+
*
|
|
18
|
+
* @param config - The Expo config
|
|
19
|
+
* @param fonts - Array of font file paths or directories
|
|
20
|
+
* @param targetName - Name of the Live Activity extension target
|
|
21
|
+
* @returns Modified config
|
|
22
|
+
*/
|
|
23
|
+
export const withFonts = (config, { fonts, targetName }) => {
|
|
24
|
+
if (!fonts || fonts.length === 0) {
|
|
25
|
+
return config;
|
|
26
|
+
}
|
|
27
|
+
config = addFontsToTarget(config, fonts, targetName);
|
|
28
|
+
config = addFontsToPlist(config, fonts, targetName);
|
|
29
|
+
return config;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Adds font files to the Live Activity extension target.
|
|
33
|
+
* This ensures fonts are bundled with the extension and accessible at runtime.
|
|
34
|
+
*/
|
|
35
|
+
function addFontsToTarget(config, fonts, targetName) {
|
|
36
|
+
return withXcodeProject(config, async (config) => {
|
|
37
|
+
if (config.modRequest.introspect) {
|
|
38
|
+
return config;
|
|
39
|
+
}
|
|
40
|
+
const resolvedFonts = await resolveFontPaths(fonts, config.modRequest.projectRoot);
|
|
41
|
+
const project = config.modResults;
|
|
42
|
+
const platformProjectRoot = config.modRequest.platformProjectRoot;
|
|
43
|
+
const targetUuid = project.findTargetKey(targetName);
|
|
44
|
+
if (targetUuid == null) {
|
|
45
|
+
throw new Error(`Target ${targetName} not found in Xcode project. Report this issue to the Voltra team.`);
|
|
46
|
+
}
|
|
47
|
+
IOSConfig.XcodeUtils.ensureGroupRecursively(project, 'VoltraResources');
|
|
48
|
+
for (const font of resolvedFonts) {
|
|
49
|
+
const fontPath = path.relative(platformProjectRoot, font);
|
|
50
|
+
IOSConfig.XcodeUtils.addResourceFileToGroup({
|
|
51
|
+
filepath: fontPath,
|
|
52
|
+
groupName: 'VoltraResources',
|
|
53
|
+
project,
|
|
54
|
+
isBuildFile: true,
|
|
55
|
+
verbose: true,
|
|
56
|
+
targetUuid,
|
|
57
|
+
});
|
|
58
|
+
logger.info(`Added font file: ${path.basename(font)}`);
|
|
59
|
+
}
|
|
60
|
+
return config;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Adds font filenames to the Live Activity extension's Info.plist UIAppFonts array.
|
|
65
|
+
* This makes iOS aware of the custom fonts and allows them to be used in SwiftUI.
|
|
66
|
+
*/
|
|
67
|
+
function addFontsToPlist(config, fonts, targetName) {
|
|
68
|
+
return withDangerousMod(config, [
|
|
69
|
+
'ios',
|
|
70
|
+
async (config) => {
|
|
71
|
+
if (config.modRequest.introspect) {
|
|
72
|
+
return config;
|
|
73
|
+
}
|
|
74
|
+
const resolvedFonts = await resolveFontPaths(fonts, config.modRequest.projectRoot);
|
|
75
|
+
const platformProjectRoot = config.modRequest.platformProjectRoot;
|
|
76
|
+
// Read the Live Activity extension's Info.plist directly
|
|
77
|
+
const targetPath = path.join(platformProjectRoot, targetName);
|
|
78
|
+
const infoPlistPath = path.join(targetPath, 'Info.plist');
|
|
79
|
+
try {
|
|
80
|
+
const plistContent = plist.parse(readFileSync(infoPlistPath, 'utf8'));
|
|
81
|
+
// Get existing fonts or initialize empty array
|
|
82
|
+
const existingFonts = getUIAppFonts(plistContent);
|
|
83
|
+
// Add new fonts
|
|
84
|
+
const fontList = resolvedFonts.map((font) => path.basename(font));
|
|
85
|
+
const allFonts = [...existingFonts, ...fontList];
|
|
86
|
+
plistContent.UIAppFonts = Array.from(new Set(allFonts));
|
|
87
|
+
// Write back to file
|
|
88
|
+
writeFileSync(infoPlistPath, plist.build(plistContent));
|
|
89
|
+
logger.info(`Added ${fontList.length} font(s) to ${targetName} Info.plist`);
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
logger.warn(`Could not update Info.plist for fonts: ${error}`);
|
|
93
|
+
}
|
|
94
|
+
return config;
|
|
95
|
+
},
|
|
96
|
+
]);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Retrieves existing UIAppFonts from Info.plist.
|
|
100
|
+
*
|
|
101
|
+
* @param infoPlist - Info.plist object
|
|
102
|
+
* @returns Array of font filenames
|
|
103
|
+
*/
|
|
104
|
+
function getUIAppFonts(infoPlist) {
|
|
105
|
+
const fonts = infoPlist['UIAppFonts'];
|
|
106
|
+
if (fonts != null && Array.isArray(fonts) && fonts.every((font) => typeof font === 'string')) {
|
|
107
|
+
return fonts;
|
|
108
|
+
}
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=fonts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fonts.js","sourceRoot":"","sources":["../../../src/ios-widget/fonts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { withPlugins } from '@expo/config-plugins';
|
|
2
|
+
import { configureEasBuild } from './eas';
|
|
3
|
+
import { generateWidgetExtensionFiles } from './files';
|
|
4
|
+
import { withFonts } from './fonts';
|
|
5
|
+
import { configurePodfile } from './podfile';
|
|
6
|
+
import { configureWidgetExtensionPlist } from './widgetPlist';
|
|
7
|
+
import { configureXcodeProject } from './xcode';
|
|
8
|
+
/**
|
|
9
|
+
* Main iOS configuration plugin.
|
|
10
|
+
*
|
|
11
|
+
* This orchestrates all iOS-related configuration in the correct order:
|
|
12
|
+
* 1. Add custom fonts (if provided)
|
|
13
|
+
* 2. Configure Xcode project (targets, build phases, groups)
|
|
14
|
+
* 3. Configure Podfile for widget extension
|
|
15
|
+
* 4. Configure main app Info.plist (URL schemes)
|
|
16
|
+
* 5. Configure EAS build settings
|
|
17
|
+
* 6. Generate widget extension files (Swift, assets, plist, entitlements)
|
|
18
|
+
*
|
|
19
|
+
* NOTE: Expo mods execute in REVERSE registration order. Plugins that depend
|
|
20
|
+
* on modifications from other plugins must be registered BEFORE their dependencies.
|
|
21
|
+
* For example, fonts plugin needs the target created by configureXcodeProject,
|
|
22
|
+
* so fonts must be registered before configureXcodeProject.
|
|
23
|
+
*/
|
|
24
|
+
export const withIOS = (config, props) => {
|
|
25
|
+
const { targetName, bundleIdentifier, deploymentTarget, widgets, groupIdentifier, keychainGroup, fonts, version, buildNumber, } = props;
|
|
26
|
+
const plugins = [
|
|
27
|
+
// 1. Add custom fonts if provided
|
|
28
|
+
...(fonts && fonts.length > 0 ? [[withFonts, { fonts, targetName }]] : []),
|
|
29
|
+
// 2. Configure Xcode project (creates the target - must run before fonts mod executes)
|
|
30
|
+
[configureXcodeProject, { targetName, bundleIdentifier, deploymentTarget }],
|
|
31
|
+
// 3. Configure Podfile for widget extension target
|
|
32
|
+
[configurePodfile, { targetName }],
|
|
33
|
+
// 4. Configure main app Info.plist (URL schemes, widget extension plist)
|
|
34
|
+
[configureWidgetExtensionPlist, { targetName, groupIdentifier, widgets, keychainGroup }],
|
|
35
|
+
// 5. Configure EAS build settings
|
|
36
|
+
[configureEasBuild, { targetName, bundleIdentifier, groupIdentifier }],
|
|
37
|
+
// 6. Generate widget extension files (dangerous mod should run before plist patchers)
|
|
38
|
+
[generateWidgetExtensionFiles, { targetName, widgets, groupIdentifier, keychainGroup, version, buildNumber }],
|
|
39
|
+
];
|
|
40
|
+
return withPlugins(config, plugins);
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ios-widget/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAGhE,OAAO,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAA;AACzC,OAAO,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAA;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AACnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAE,6BAA6B,EAAE,MAAM,eAAe,CAAA;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAA;AAc/C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,OAAO,GAA+B,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;IACnE,MAAM,EACJ,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,OAAO,EACP,eAAe,EACf,aAAa,EACb,KAAK,EACL,OAAO,EACP,WAAW,GACZ,GAAG,KAAK,CAAA;IAET,MAAM,OAAO,GAA+B;QAC1C,kCAAkC;QAClC,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,CAA6B,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAEtG,uFAAuF;QACvF,CAAC,qBAAqB,EAAE,EAAE,UAAU,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;QAE3E,mDAAmD;QACnD,CAAC,gBAAgB,EAAE,EAAE,UAAU,EAAE,CAAC;QAElC,yEAAyE;QACzE,CAAC,6BAA6B,EAAE,EAAE,UAAU,EAAE,eAAe,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC;QAExF,kCAAkC;QAClC,CAAC,iBAAiB,EAAE,EAAE,UAAU,EAAE,gBAAgB,EAAE,eAAe,EAAE,CAAC;QAEtE,sFAAsF;QACtF,CAAC,4BAA4B,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;KAC9G,CAAA;IAED,OAAO,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AACrC,CAAC,CAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { withPodfile as withExpoPodfile } from '@expo/config-plugins';
|
|
2
|
+
/**
|
|
3
|
+
* Generates the Podfile target content for the widget extension.
|
|
4
|
+
*/
|
|
5
|
+
function getTargetContent(targetName) {
|
|
6
|
+
return `
|
|
7
|
+
# Voltra Widget Extension Target
|
|
8
|
+
# DO NOT MODIFY THIS FILE - IT IS AUTO-GENERATED BY THE VOLTRA PLUGIN
|
|
9
|
+
target '${targetName}' do
|
|
10
|
+
use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks']
|
|
11
|
+
use_frameworks! :linkage => ENV['USE_FRAMEWORKS'].to_sym if ENV['USE_FRAMEWORKS']
|
|
12
|
+
|
|
13
|
+
require 'pathname'
|
|
14
|
+
project_root = "#{Pod::Config.instance.installation_root}/.."
|
|
15
|
+
library_name = 'voltra'
|
|
16
|
+
voltra_module = JSON.parse(\`npx expo-modules-autolinking search -p apple --json --project-root #{project_root}\`)
|
|
17
|
+
podspec_dir_path = File.join(voltra_module[library_name]['path'], 'ios')
|
|
18
|
+
podspec_dir_path = File.realpath(podspec_dir_path) if File.exist?(podspec_dir_path)
|
|
19
|
+
podspec_dir_path = Pathname.new(podspec_dir_path).relative_path_from(Pathname.new(__dir__)).to_path
|
|
20
|
+
|
|
21
|
+
pod 'VoltraWidget', :path => podspec_dir_path
|
|
22
|
+
end`;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Plugin step that adds the Podfile target for the widget extension.
|
|
26
|
+
*/
|
|
27
|
+
export const configurePodfile = (config, { targetName }) => {
|
|
28
|
+
return withExpoPodfile(config, (podfile) => {
|
|
29
|
+
const targetContent = getTargetContent(targetName);
|
|
30
|
+
// Check if target already exists (avoid duplicates)
|
|
31
|
+
const targetMarker = "target '" + targetName + "'";
|
|
32
|
+
if (podfile.modResults.contents.includes(targetMarker)) {
|
|
33
|
+
return podfile;
|
|
34
|
+
}
|
|
35
|
+
podfile.modResults.contents = podfile.modResults.contents + '\n' + targetContent;
|
|
36
|
+
return podfile;
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=podfile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"podfile.js","sourceRoot":"","sources":["../../../src/ios-widget/podfile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,WAAW,IAAI,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAEnF;;GAEG;AACH,SAAS,gBAAgB,CAAC,UAAkB;IAC1C,OAAO;;;UAGC,UAAU;;;;;;;;;;;;;IAahB,CAAA;AACJ,CAAC;AAMD;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAwC,CAAC,MAAM,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE;IAC9F,OAAO,eAAe,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE;QACzC,MAAM,aAAa,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAA;QAElD,oDAAoD;QACpD,MAAM,YAAY,GAAG,UAAU,GAAG,UAAU,GAAG,GAAG,CAAA;QAClD,IAAI,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YACvD,OAAO,OAAO,CAAA;QAChB,CAAC;QAED,OAAO,CAAC,UAAU,CAAC,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,QAAQ,GAAG,IAAI,GAAG,aAAa,CAAA;QAChF,OAAO,OAAO,CAAA;IAChB,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { withDangerousMod } from '@expo/config-plugins';
|
|
2
|
+
import plist from '@expo/plist';
|
|
3
|
+
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
|
4
|
+
import { join as joinPath } from 'path';
|
|
5
|
+
import { logger } from '../utils/logger';
|
|
6
|
+
/**
|
|
7
|
+
* Plugin step that configures the Info.plist files.
|
|
8
|
+
*
|
|
9
|
+
* This:
|
|
10
|
+
* - Updates the widget extension's Info.plist with URL schemes
|
|
11
|
+
* - Removes incompatible NSExtension keys for WidgetKit
|
|
12
|
+
* - Adds group identifier if configured
|
|
13
|
+
* - Adds server update URLs and intervals for server-driven widgets
|
|
14
|
+
* - Adds Keychain group for shared credential access
|
|
15
|
+
*/
|
|
16
|
+
export const configureWidgetExtensionPlist = (expoConfig, { targetName, groupIdentifier, widgets, keychainGroup }) => withDangerousMod(expoConfig, [
|
|
17
|
+
'ios',
|
|
18
|
+
async (config) => {
|
|
19
|
+
if (config.modRequest.introspect) {
|
|
20
|
+
return config;
|
|
21
|
+
}
|
|
22
|
+
const scheme = typeof expoConfig.scheme === 'string' ? expoConfig.scheme : expoConfig.ios?.bundleIdentifier;
|
|
23
|
+
if (scheme) {
|
|
24
|
+
const targetPath = joinPath(config.modRequest.platformProjectRoot, targetName);
|
|
25
|
+
const filePath = joinPath(targetPath, 'Info.plist');
|
|
26
|
+
if (!existsSync(filePath)) {
|
|
27
|
+
logger.warn(`Widget Info.plist not found at ${filePath}, skipping widget plist updates`);
|
|
28
|
+
return config;
|
|
29
|
+
}
|
|
30
|
+
const content = plist.parse(readFileSync(filePath, 'utf8'));
|
|
31
|
+
// WidgetKit extensions must NOT declare NSExtensionPrincipalClass/MainStoryboard.
|
|
32
|
+
// The @main WidgetBundle in Swift is the entry point.
|
|
33
|
+
const ext = content.NSExtension;
|
|
34
|
+
if (ext) {
|
|
35
|
+
delete ext.NSExtensionPrincipalClass;
|
|
36
|
+
delete ext.NSExtensionMainStoryboard;
|
|
37
|
+
}
|
|
38
|
+
// Keep URL schemes in the widget extension so Live Activity links can be resolved
|
|
39
|
+
// from relative to absolute URLs (see VoltraDeepLinkResolver.swift).
|
|
40
|
+
const existingTypes = content.CFBundleURLTypes || [];
|
|
41
|
+
const hasScheme = existingTypes.some((t) => Array.isArray(t?.CFBundleURLSchemes) && t.CFBundleURLSchemes.includes(scheme));
|
|
42
|
+
if (!hasScheme) {
|
|
43
|
+
content.CFBundleURLTypes = [
|
|
44
|
+
...existingTypes,
|
|
45
|
+
{
|
|
46
|
+
CFBundleURLSchemes: [scheme],
|
|
47
|
+
},
|
|
48
|
+
];
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
content.CFBundleURLTypes = existingTypes;
|
|
52
|
+
}
|
|
53
|
+
// Only set group identifier if provided
|
|
54
|
+
if (groupIdentifier) {
|
|
55
|
+
;
|
|
56
|
+
content['Voltra_AppGroupIdentifier'] = groupIdentifier;
|
|
57
|
+
}
|
|
58
|
+
// Configure server update URLs and intervals for widgets with serverUpdate
|
|
59
|
+
if (widgets && widgets.length > 0) {
|
|
60
|
+
const serverUrls = {};
|
|
61
|
+
const serverIntervals = {};
|
|
62
|
+
const serverRefresh = {};
|
|
63
|
+
for (const widget of widgets) {
|
|
64
|
+
if (widget.serverUpdate) {
|
|
65
|
+
serverUrls[widget.id] = widget.serverUpdate.url;
|
|
66
|
+
serverIntervals[widget.id] = widget.serverUpdate.intervalMinutes ?? 15;
|
|
67
|
+
if (widget.serverUpdate.refresh) {
|
|
68
|
+
serverRefresh[widget.id] = true;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (Object.keys(serverUrls).length > 0) {
|
|
73
|
+
;
|
|
74
|
+
content['Voltra_WidgetServerUrls'] = serverUrls;
|
|
75
|
+
content['Voltra_WidgetServerIntervals'] = serverIntervals;
|
|
76
|
+
}
|
|
77
|
+
if (Object.keys(serverRefresh).length > 0) {
|
|
78
|
+
;
|
|
79
|
+
content['Voltra_WidgetServerRefresh'] = serverRefresh;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// Add Keychain group for shared credential access
|
|
83
|
+
if (keychainGroup) {
|
|
84
|
+
;
|
|
85
|
+
content['Voltra_KeychainGroup'] = keychainGroup;
|
|
86
|
+
}
|
|
87
|
+
writeFileSync(filePath, plist.build(content));
|
|
88
|
+
}
|
|
89
|
+
return config;
|
|
90
|
+
},
|
|
91
|
+
]);
|
|
92
|
+
//# sourceMappingURL=widgetPlist.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widgetPlist.js","sourceRoot":"","sources":["../../../src/ios-widget/widgetPlist.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import * as util from 'util';
|
|
2
|
+
const pbxFile = require('xcode/lib/pbxFile');
|
|
3
|
+
/**
|
|
4
|
+
* Adds all required build phases for the widget extension target.
|
|
5
|
+
*/
|
|
6
|
+
export function addBuildPhases(xcodeProject, options) {
|
|
7
|
+
const { targetUuid, groupName, productFile, widgetFiles } = options;
|
|
8
|
+
const buildPath = `""`;
|
|
9
|
+
const folderType = 'app_extension';
|
|
10
|
+
const { swiftFiles, intentFiles, assetDirectories } = widgetFiles;
|
|
11
|
+
// Sources build phase
|
|
12
|
+
xcodeProject.addBuildPhase([...swiftFiles, ...intentFiles], 'PBXSourcesBuildPhase', 'Sources', targetUuid, folderType, buildPath);
|
|
13
|
+
// Copy files build phase
|
|
14
|
+
xcodeProject.addBuildPhase([], 'PBXCopyFilesBuildPhase', groupName, xcodeProject.getFirstTarget().uuid, folderType, buildPath);
|
|
15
|
+
xcodeProject.buildPhaseObject('PBXCopyFilesBuildPhase', groupName, productFile.target).files.push({
|
|
16
|
+
value: productFile.uuid,
|
|
17
|
+
comment: util.format('%s in %s', productFile.basename, productFile.group),
|
|
18
|
+
});
|
|
19
|
+
xcodeProject.addToPbxBuildFileSection(productFile);
|
|
20
|
+
// Frameworks build phase
|
|
21
|
+
xcodeProject.addBuildPhase([], 'PBXFrameworksBuildPhase', 'Frameworks', targetUuid, folderType, buildPath);
|
|
22
|
+
// Resources build phase
|
|
23
|
+
xcodeProject.addBuildPhase([...assetDirectories], 'PBXResourcesBuildPhase', 'Resources', targetUuid);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Ensures all required build phases and files exist for the widget extension target.
|
|
27
|
+
*/
|
|
28
|
+
export function ensureBuildPhases(xcodeProject, options) {
|
|
29
|
+
const { targetUuid, groupName, productFile, widgetFiles } = options;
|
|
30
|
+
const buildPath = `""`;
|
|
31
|
+
const folderType = 'app_extension';
|
|
32
|
+
const mainTargetUuid = options.mainTargetUuid ?? xcodeProject.getFirstTarget().uuid;
|
|
33
|
+
const { swiftFiles, intentFiles, assetDirectories } = widgetFiles;
|
|
34
|
+
dedupeBuildPhasesForTarget(xcodeProject, targetUuid, 'PBXSourcesBuildPhase', 'Sources');
|
|
35
|
+
dedupeBuildPhasesForTarget(xcodeProject, targetUuid, 'PBXFrameworksBuildPhase', 'Frameworks');
|
|
36
|
+
dedupeBuildPhasesByComment(xcodeProject, mainTargetUuid, 'PBXCopyFilesBuildPhase', groupName);
|
|
37
|
+
// Sources build phase
|
|
38
|
+
let sourcesPhase = xcodeProject.buildPhaseObject('PBXSourcesBuildPhase', 'Sources', targetUuid);
|
|
39
|
+
if (!sourcesPhase) {
|
|
40
|
+
xcodeProject.addBuildPhase([...swiftFiles, ...intentFiles], 'PBXSourcesBuildPhase', 'Sources', targetUuid, folderType, buildPath);
|
|
41
|
+
sourcesPhase = xcodeProject.buildPhaseObject('PBXSourcesBuildPhase', 'Sources', targetUuid);
|
|
42
|
+
}
|
|
43
|
+
if (sourcesPhase) {
|
|
44
|
+
ensureBuildPhaseFiles(xcodeProject, sourcesPhase, [...swiftFiles, ...intentFiles]);
|
|
45
|
+
}
|
|
46
|
+
// Copy files build phase (embed extension into main app)
|
|
47
|
+
let copyFilesPhase = xcodeProject.buildPhaseObject('PBXCopyFilesBuildPhase', groupName, mainTargetUuid);
|
|
48
|
+
if (!copyFilesPhase) {
|
|
49
|
+
xcodeProject.addBuildPhase([], 'PBXCopyFilesBuildPhase', groupName, mainTargetUuid, folderType, buildPath);
|
|
50
|
+
copyFilesPhase = xcodeProject.buildPhaseObject('PBXCopyFilesBuildPhase', groupName, mainTargetUuid);
|
|
51
|
+
}
|
|
52
|
+
if (copyFilesPhase) {
|
|
53
|
+
ensureCopyFilesPhaseProduct(xcodeProject, copyFilesPhase, productFile);
|
|
54
|
+
}
|
|
55
|
+
// Frameworks build phase
|
|
56
|
+
const frameworksPhase = xcodeProject.buildPhaseObject('PBXFrameworksBuildPhase', 'Frameworks', targetUuid);
|
|
57
|
+
if (!frameworksPhase) {
|
|
58
|
+
xcodeProject.addBuildPhase([], 'PBXFrameworksBuildPhase', 'Frameworks', targetUuid, folderType, buildPath);
|
|
59
|
+
}
|
|
60
|
+
// Resources build phase
|
|
61
|
+
let resourcesPhase = xcodeProject.buildPhaseObject('PBXResourcesBuildPhase', 'Resources', targetUuid);
|
|
62
|
+
if (!resourcesPhase) {
|
|
63
|
+
xcodeProject.addBuildPhase([...assetDirectories], 'PBXResourcesBuildPhase', 'Resources', targetUuid);
|
|
64
|
+
resourcesPhase = xcodeProject.buildPhaseObject('PBXResourcesBuildPhase', 'Resources', targetUuid);
|
|
65
|
+
}
|
|
66
|
+
if (resourcesPhase) {
|
|
67
|
+
ensureBuildPhaseFiles(xcodeProject, resourcesPhase, [...assetDirectories]);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function dedupeBuildPhasesForTarget(xcodeProject, targetUuid, phaseType, preferredComment) {
|
|
71
|
+
const nativeTargets = xcodeProject.pbxNativeTargetSection();
|
|
72
|
+
const target = nativeTargets[targetUuid];
|
|
73
|
+
if (!target?.buildPhases) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const phaseSection = xcodeProject.hash.project.objects[phaseType] || {};
|
|
77
|
+
const matching = target.buildPhases.filter((entry) => phaseSection[entry.value]);
|
|
78
|
+
if (matching.length <= 1) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const keep = matching.find((entry) => entry.comment === preferredComment) ?? matching[0];
|
|
82
|
+
keep.comment = preferredComment;
|
|
83
|
+
target.buildPhases = target.buildPhases.filter((entry) => {
|
|
84
|
+
if (!phaseSection[entry.value]) {
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
return entry.value === keep.value;
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
function dedupeBuildPhasesByComment(xcodeProject, targetUuid, phaseType, comment) {
|
|
91
|
+
const nativeTargets = xcodeProject.pbxNativeTargetSection();
|
|
92
|
+
const target = nativeTargets[targetUuid];
|
|
93
|
+
if (!target?.buildPhases) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const phaseSection = xcodeProject.hash.project.objects[phaseType] || {};
|
|
97
|
+
const matching = target.buildPhases.filter((entry) => phaseSection[entry.value] && entry.comment === comment);
|
|
98
|
+
if (matching.length <= 1) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const keep = matching[0];
|
|
102
|
+
target.buildPhases = target.buildPhases.filter((entry) => {
|
|
103
|
+
if (!phaseSection[entry.value] || entry.comment !== comment) {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
return entry.value === keep.value;
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
function normalizePath(value) {
|
|
110
|
+
if (!value) {
|
|
111
|
+
return '';
|
|
112
|
+
}
|
|
113
|
+
return value.replace(/^"|"$/g, '');
|
|
114
|
+
}
|
|
115
|
+
function findFileReferenceKey(xcodeProject, filePath) {
|
|
116
|
+
const fileReferenceSection = xcodeProject.pbxFileReferenceSection();
|
|
117
|
+
const normalizedPath = normalizePath(filePath);
|
|
118
|
+
for (const key of Object.keys(fileReferenceSection)) {
|
|
119
|
+
if (/_comment$/.test(key)) {
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
const entry = fileReferenceSection[key];
|
|
123
|
+
const entryPath = normalizePath(entry?.path);
|
|
124
|
+
if (entryPath === normalizedPath) {
|
|
125
|
+
return key;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
function findBuildFileKeyByFileRef(xcodeProject, fileRef) {
|
|
131
|
+
const buildFileSection = xcodeProject.pbxBuildFileSection();
|
|
132
|
+
for (const key of Object.keys(buildFileSection)) {
|
|
133
|
+
if (/_comment$/.test(key)) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
const entry = buildFileSection[key];
|
|
137
|
+
if (entry?.fileRef === fileRef) {
|
|
138
|
+
return key;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
function ensureFileReference(xcodeProject, filePath) {
|
|
144
|
+
const existingFileRef = findFileReferenceKey(xcodeProject, filePath);
|
|
145
|
+
const file = new pbxFile(filePath);
|
|
146
|
+
if (existingFileRef) {
|
|
147
|
+
return { fileRef: existingFileRef, basename: file.basename, group: file.group };
|
|
148
|
+
}
|
|
149
|
+
file.fileRef = xcodeProject.generateUuid();
|
|
150
|
+
xcodeProject.addToPbxFileReferenceSection(file);
|
|
151
|
+
return { fileRef: file.fileRef, basename: file.basename, group: file.group };
|
|
152
|
+
}
|
|
153
|
+
function ensureBuildFile(xcodeProject, filePath) {
|
|
154
|
+
const fileReference = ensureFileReference(xcodeProject, filePath);
|
|
155
|
+
const existingBuildFile = findBuildFileKeyByFileRef(xcodeProject, fileReference.fileRef);
|
|
156
|
+
if (existingBuildFile) {
|
|
157
|
+
return { uuid: existingBuildFile, ...fileReference };
|
|
158
|
+
}
|
|
159
|
+
const file = new pbxFile(filePath);
|
|
160
|
+
file.uuid = xcodeProject.generateUuid();
|
|
161
|
+
file.fileRef = fileReference.fileRef;
|
|
162
|
+
xcodeProject.addToPbxBuildFileSection(file);
|
|
163
|
+
return { uuid: file.uuid, ...fileReference, group: file.group };
|
|
164
|
+
}
|
|
165
|
+
function buildPhaseHasFile(xcodeProject, buildPhase, fileRef) {
|
|
166
|
+
if (!buildPhase?.files) {
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
const buildFileSection = xcodeProject.pbxBuildFileSection();
|
|
170
|
+
return buildPhase.files.some((entry) => {
|
|
171
|
+
const buildFile = buildFileSection[entry.value];
|
|
172
|
+
return buildFile?.fileRef === fileRef;
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
function ensureBuildPhaseFiles(xcodeProject, buildPhase, filePaths) {
|
|
176
|
+
if (!buildPhase.files) {
|
|
177
|
+
buildPhase.files = [];
|
|
178
|
+
}
|
|
179
|
+
for (const filePath of filePaths) {
|
|
180
|
+
const fileReference = ensureFileReference(xcodeProject, filePath);
|
|
181
|
+
if (buildPhaseHasFile(xcodeProject, buildPhase, fileReference.fileRef)) {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
const buildFile = ensureBuildFile(xcodeProject, filePath);
|
|
185
|
+
buildPhase.files.push({
|
|
186
|
+
value: buildFile.uuid,
|
|
187
|
+
comment: util.format('%s in %s', buildFile.basename, buildFile.group),
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
function ensureCopyFilesPhaseProduct(xcodeProject, buildPhase, productFile) {
|
|
192
|
+
if (!buildPhase.files) {
|
|
193
|
+
buildPhase.files = [];
|
|
194
|
+
}
|
|
195
|
+
const alreadyExists = buildPhase.files.some((entry) => entry.value === productFile.uuid);
|
|
196
|
+
if (alreadyExists) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const buildFileSection = xcodeProject.pbxBuildFileSection();
|
|
200
|
+
if (!buildFileSection[productFile.uuid]) {
|
|
201
|
+
xcodeProject.addToPbxBuildFileSection(productFile);
|
|
202
|
+
}
|
|
203
|
+
buildPhase.files.push({
|
|
204
|
+
value: productFile.uuid,
|
|
205
|
+
comment: util.format('%s in %s', productFile.basename, productFile.group),
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=buildPhases.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildPhases.js","sourceRoot":"","sources":["../../../../src/ios-widget/xcode/buildPhases.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAI5B,MAAM,OAAO,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAA;AAkB5C;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,YAA0B,EAAE,OAA8B;IACvF,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,OAAO,CAAA;IACnE,MAAM,SAAS,GAAG,IAAI,CAAA;IACtB,MAAM,UAAU,GAAG,eAAe,CAAA;IAElC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,gBAAgB,EAAE,GAAG,WAAW,CAAA;IAEjE,sBAAsB;IACtB,YAAY,CAAC,aAAa,CACxB,CAAC,GAAG,UAAU,EAAE,GAAG,WAAW,CAAC,EAC/B,sBAAsB,EACtB,SAAS,EACT,UAAU,EACV,UAAU,EACV,SAAS,CACV,CAAA;IAED,yBAAyB;IACzB,YAAY,CAAC,aAAa,CACxB,EAAE,EACF,wBAAwB,EACxB,SAAS,EACT,YAAY,CAAC,cAAc,EAAE,CAAC,IAAI,EAClC,UAAU,EACV,SAAS,CACV,CAAA;IAED,YAAY,CAAC,gBAAgB,CAAC,wBAAwB,EAAE,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;QAChG,KAAK,EAAE,WAAW,CAAC,IAAI;QACvB,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,KAAK,CAAC;KAC1E,CAAC,CAAA;IACF,YAAY,CAAC,wBAAwB,CAAC,WAAW,CAAC,CAAA;IAElD,yBAAyB;IACzB,YAAY,CAAC,aAAa,CAAC,EAAE,EAAE,yBAAyB,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,CAAC,CAAA;IAE1G,wBAAwB;IACxB,YAAY,CAAC,aAAa,CAAC,CAAC,GAAG,gBAAgB,CAAC,EAAE,wBAAwB,EAAE,WAAW,EAAE,UAAU,CAAC,CAAA;AACtG,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,YAA0B,EAAE,OAAiC;IAC7F,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,OAAO,CAAA;IACnE,MAAM,SAAS,GAAG,IAAI,CAAA;IACtB,MAAM,UAAU,GAAG,eAAe,CAAA;IAClC,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,YAAY,CAAC,cAAc,EAAE,CAAC,IAAI,CAAA;IAEnF,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,gBAAgB,EAAE,GAAG,WAAW,CAAA;IAEjE,0BAA0B,CAAC,YAAY,EAAE,UAAU,EAAE,sBAAsB,EAAE,SAAS,CAAC,CAAA;IACvF,0BAA0B,CAAC,YAAY,EAAE,UAAU,EAAE,yBAAyB,EAAE,YAAY,CAAC,CAAA;IAC7F,0BAA0B,CAAC,YAAY,EAAE,cAAc,EAAE,wBAAwB,EAAE,SAAS,CAAC,CAAA;IAE7F,sBAAsB;IACtB,IAAI,YAAY,GAAG,YAAY,CAAC,gBAAgB,CAAC,sBAAsB,EAAE,SAAS,EAAE,UAAU,CAAC,CAAA;IAC/F,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,YAAY,CAAC,aAAa,CACxB,CAAC,GAAG,UAAU,EAAE,GAAG,WAAW,CAAC,EAC/B,sBAAsB,EACtB,SAAS,EACT,UAAU,EACV,UAAU,EACV,SAAS,CACV,CAAA;QACD,YAAY,GAAG,YAAY,CAAC,gBAAgB,CAAC,sBAAsB,EAAE,SAAS,EAAE,UAAU,CAAC,CAAA;IAC7F,CAAC;IACD,IAAI,YAAY,EAAE,CAAC;QACjB,qBAAqB,CAAC,YAAY,EAAE,YAAY,EAAE,CAAC,GAAG,UAAU,EAAE,GAAG,WAAW,CAAC,CAAC,CAAA;IACpF,CAAC;IAED,yDAAyD;IACzD,IAAI,cAAc,GAAG,YAAY,CAAC,gBAAgB,CAAC,wBAAwB,EAAE,SAAS,EAAE,cAAc,CAAC,CAAA;IACvG,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,YAAY,CAAC,aAAa,CAAC,EAAE,EAAE,wBAAwB,EAAE,SAAS,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,CAAC,CAAA;QAC1G,cAAc,GAAG,YAAY,CAAC,gBAAgB,CAAC,wBAAwB,EAAE,SAAS,EAAE,cAAc,CAAC,CAAA;IACrG,CAAC;IACD,IAAI,cAAc,EAAE,CAAC;QACnB,2BAA2B,CAAC,YAAY,EAAE,cAAc,EAAE,WAAW,CAAC,CAAA;IACxE,CAAC;IAED,yBAAyB;IACzB,MAAM,eAAe,GAAG,YAAY,CAAC,gBAAgB,CAAC,yBAAyB,EAAE,YAAY,EAAE,UAAU,CAAC,CAAA;IAC1G,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,YAAY,CAAC,aAAa,CAAC,EAAE,EAAE,yBAAyB,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,CAAC,CAAA;IAC5G,CAAC;IAED,wBAAwB;IACxB,IAAI,cAAc,GAAG,YAAY,CAAC,gBAAgB,CAAC,wBAAwB,EAAE,WAAW,EAAE,UAAU,CAAC,CAAA;IACrG,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,YAAY,CAAC,aAAa,CAAC,CAAC,GAAG,gBAAgB,CAAC,EAAE,wBAAwB,EAAE,WAAW,EAAE,UAAU,CAAC,CAAA;QACpG,cAAc,GAAG,YAAY,CAAC,gBAAgB,CAAC,wBAAwB,EAAE,WAAW,EAAE,UAAU,CAAC,CAAA;IACnG,CAAC;IACD,IAAI,cAAc,EAAE,CAAC;QACnB,qBAAqB,CAAC,YAAY,EAAE,cAAc,EAAE,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAA;IAC5E,CAAC;AACH,CAAC;AAED,SAAS,0BAA0B,CACjC,YAA0B,EAC1B,UAAkB,EAClB,SAAiB,EACjB,gBAAwB;IAExB,MAAM,aAAa,GAAG,YAAY,CAAC,sBAAsB,EAAE,CAAA;IAC3D,MAAM,MAAM,GAAG,aAAa,CAAC,UAAU,CAAC,CAAA;IACxC,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC;QACzB,OAAM;IACR,CAAC;IAED,MAAM,YAAY,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,CAAA;IACvE,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAA;IACrF,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACzB,OAAM;IACR,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAU,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,KAAK,gBAAgB,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAA;IAC7F,IAAI,CAAC,OAAO,GAAG,gBAAgB,CAAA;IAE/B,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE;QAC5D,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAA;QACb,CAAC;QACD,OAAO,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAA;IACnC,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,0BAA0B,CACjC,YAA0B,EAC1B,UAAkB,EAClB,SAAiB,EACjB,OAAe;IAEf,MAAM,aAAa,GAAG,YAAY,CAAC,sBAAsB,EAAE,CAAA;IAC3D,MAAM,MAAM,GAAG,aAAa,CAAC,UAAU,CAAC,CAAA;IACxC,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC;QACzB,OAAM;IACR,CAAC;IAED,MAAM,YAAY,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,CAAA;IACvE,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,KAAK,OAAO,CAAC,CAAA;IAClH,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACzB,OAAM;IACR,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;IACxB,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE;QAC5D,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;YAC5D,OAAO,IAAI,CAAA;QACb,CAAC;QACD,OAAO,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAA;IACnC,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,KAAyB;IAC9C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,CAAA;IACX,CAAC;IACD,OAAO,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;AACpC,CAAC;AAED,SAAS,oBAAoB,CAAC,YAA0B,EAAE,QAAgB;IACxE,MAAM,oBAAoB,GAAG,YAAY,CAAC,uBAAuB,EAAE,CAAA;IACnE,MAAM,cAAc,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAA;IAE9C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,EAAE,CAAC;QACpD,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,SAAQ;QACV,CAAC;QACD,MAAM,KAAK,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAA;QACvC,MAAM,SAAS,GAAG,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QAC5C,IAAI,SAAS,KAAK,cAAc,EAAE,CAAC;YACjC,OAAO,GAAG,CAAA;QACZ,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,yBAAyB,CAAC,YAA0B,EAAE,OAAe;IAC5E,MAAM,gBAAgB,GAAG,YAAY,CAAC,mBAAmB,EAAE,CAAA;IAC3D,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAChD,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,SAAQ;QACV,CAAC;QACD,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAA;QACnC,IAAI,KAAK,EAAE,OAAO,KAAK,OAAO,EAAE,CAAC;YAC/B,OAAO,GAAG,CAAA;QACZ,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,mBAAmB,CAAC,YAA0B,EAAE,QAAgB;IACvE,MAAM,eAAe,GAAG,oBAAoB,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAA;IACpE,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAA;IAElC,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAA;IACjF,CAAC;IAED,IAAI,CAAC,OAAO,GAAG,YAAY,CAAC,YAAY,EAAE,CAAA;IAC1C,YAAY,CAAC,4BAA4B,CAAC,IAAI,CAAC,CAAA;IAC/C,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAA;AAC9E,CAAC;AAED,SAAS,eAAe,CAAC,YAA0B,EAAE,QAAgB;IACnE,MAAM,aAAa,GAAG,mBAAmB,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAA;IACjE,MAAM,iBAAiB,GAAG,yBAAyB,CAAC,YAAY,EAAE,aAAa,CAAC,OAAO,CAAC,CAAA;IAExF,IAAI,iBAAiB,EAAE,CAAC;QACtB,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE,GAAG,aAAa,EAAE,CAAA;IACtD,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAA;IAClC,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC,YAAY,EAAE,CAAA;IACvC,IAAI,CAAC,OAAO,GAAG,aAAa,CAAC,OAAO,CAAA;IACpC,YAAY,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAA;IAC3C,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,aAAa,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAA;AACjE,CAAC;AAED,SAAS,iBAAiB,CAAC,YAA0B,EAAE,UAAe,EAAE,OAAe;IACrF,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC;QACvB,OAAO,KAAK,CAAA;IACd,CAAC;IACD,MAAM,gBAAgB,GAAG,YAAY,CAAC,mBAAmB,EAAE,CAAA;IAE3D,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAU,EAAE,EAAE;QAC1C,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAC/C,OAAO,SAAS,EAAE,OAAO,KAAK,OAAO,CAAA;IACvC,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,qBAAqB,CAAC,YAA0B,EAAE,UAAe,EAAE,SAAmB;IAC7F,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACtB,UAAU,CAAC,KAAK,GAAG,EAAE,CAAA;IACvB,CAAC;IAED,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,MAAM,aAAa,GAAG,mBAAmB,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAA;QACjE,IAAI,iBAAiB,CAAC,YAAY,EAAE,UAAU,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;YACvE,SAAQ;QACV,CAAC;QAED,MAAM,SAAS,GAAG,eAAe,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAA;QACzD,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC;YACpB,KAAK,EAAE,SAAS,CAAC,IAAI;YACrB,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,KAAK,CAAC;SACtE,CAAC,CAAA;IACJ,CAAC;AACH,CAAC;AAED,SAAS,2BAA2B,CAAC,YAA0B,EAAE,UAAe,EAAE,WAAgB;IAChG,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACtB,UAAU,CAAC,KAAK,GAAG,EAAE,CAAA;IACvB,CAAC;IAED,MAAM,aAAa,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAU,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,WAAW,CAAC,IAAI,CAAC,CAAA;IAC7F,IAAI,aAAa,EAAE,CAAC;QAClB,OAAM;IACR,CAAC;IAED,MAAM,gBAAgB,GAAG,YAAY,CAAC,mBAAmB,EAAE,CAAA;IAC3D,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,YAAY,CAAC,wBAAwB,CAAC,WAAW,CAAC,CAAA;IACpD,CAAC;IAED,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC;QACpB,KAAK,EAAE,WAAW,CAAC,IAAI;QACvB,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,KAAK,CAAC;KAC1E,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { IOS } from '../../constants';
|
|
2
|
+
function createCommonBuildSettings(options) {
|
|
3
|
+
const { targetName, bundleIdentifier, deploymentTarget, codeSignStyle, developmentTeam, provisioningProfileSpecifier, } = options;
|
|
4
|
+
const commonBuildSettings = {
|
|
5
|
+
PRODUCT_NAME: `"$(TARGET_NAME)"`,
|
|
6
|
+
SWIFT_VERSION: IOS.SWIFT_VERSION,
|
|
7
|
+
TARGETED_DEVICE_FAMILY: `"${IOS.DEVICE_FAMILY}"`,
|
|
8
|
+
INFOPLIST_FILE: `${targetName}/Info.plist`,
|
|
9
|
+
INFOPLIST_OUTPUT_FORMAT: `"xml"`,
|
|
10
|
+
CURRENT_PROJECT_VERSION: `"1"`,
|
|
11
|
+
MARKETING_VERSION: `"1.0"`,
|
|
12
|
+
IPHONEOS_DEPLOYMENT_TARGET: `"${deploymentTarget}"`,
|
|
13
|
+
PRODUCT_BUNDLE_IDENTIFIER: `"${bundleIdentifier}"`,
|
|
14
|
+
SWIFT_OPTIMIZATION_LEVEL: `"-Onone"`,
|
|
15
|
+
CODE_SIGN_ENTITLEMENTS: `"${targetName}/${targetName}.entitlements"`,
|
|
16
|
+
APPLICATION_EXTENSION_API_ONLY: '"YES"',
|
|
17
|
+
ASSETCATALOG_COMPILER_APPICON_NAME: '""',
|
|
18
|
+
};
|
|
19
|
+
// Synchronize code signing settings from main app target
|
|
20
|
+
if (codeSignStyle) {
|
|
21
|
+
commonBuildSettings.CODE_SIGN_STYLE = `"${codeSignStyle}"`;
|
|
22
|
+
}
|
|
23
|
+
if (developmentTeam) {
|
|
24
|
+
commonBuildSettings.DEVELOPMENT_TEAM = `"${developmentTeam}"`;
|
|
25
|
+
}
|
|
26
|
+
if (provisioningProfileSpecifier) {
|
|
27
|
+
commonBuildSettings.PROVISIONING_PROFILE_SPECIFIER = `"${provisioningProfileSpecifier}"`;
|
|
28
|
+
}
|
|
29
|
+
return commonBuildSettings;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Adds the XCConfigurationList for the widget extension target.
|
|
33
|
+
*/
|
|
34
|
+
export function addXCConfigurationList(xcodeProject, options) {
|
|
35
|
+
const { targetName } = options;
|
|
36
|
+
const commonBuildSettings = createCommonBuildSettings(options);
|
|
37
|
+
const buildConfigurationsList = [
|
|
38
|
+
{
|
|
39
|
+
name: 'Debug',
|
|
40
|
+
isa: 'XCBuildConfiguration',
|
|
41
|
+
buildSettings: {
|
|
42
|
+
...commonBuildSettings,
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'Release',
|
|
47
|
+
isa: 'XCBuildConfiguration',
|
|
48
|
+
buildSettings: {
|
|
49
|
+
...commonBuildSettings,
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
];
|
|
53
|
+
const xCConfigurationList = xcodeProject.addXCConfigurationList(buildConfigurationsList, 'Release', `Build configuration list for PBXNativeTarget "${targetName}"`);
|
|
54
|
+
return xCConfigurationList;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Ensures an existing XCConfigurationList is updated, or adds a new one if missing.
|
|
58
|
+
*/
|
|
59
|
+
export function ensureXCConfigurationList(xcodeProject, options, existingConfigurationListId) {
|
|
60
|
+
const configurationListId = typeof existingConfigurationListId === 'string'
|
|
61
|
+
? existingConfigurationListId.split(' ')[0]
|
|
62
|
+
: existingConfigurationListId?.value?.split(' ')[0];
|
|
63
|
+
const configurationLists = xcodeProject.pbxXCConfigurationList();
|
|
64
|
+
const configurationList = configurationListId ? configurationLists?.[configurationListId] : null;
|
|
65
|
+
if (!configurationList || !configurationList.buildConfigurations) {
|
|
66
|
+
return addXCConfigurationList(xcodeProject, options);
|
|
67
|
+
}
|
|
68
|
+
const commonBuildSettings = createCommonBuildSettings(options);
|
|
69
|
+
const buildConfigurations = configurationList.buildConfigurations;
|
|
70
|
+
const buildConfigurationSection = xcodeProject.pbxXCBuildConfigurationSection();
|
|
71
|
+
for (const configRef of buildConfigurations) {
|
|
72
|
+
const configId = typeof configRef === 'string' ? configRef.split(' ')[0] : configRef.value?.split(' ')[0];
|
|
73
|
+
if (!configId) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
const buildConfiguration = buildConfigurationSection[configId];
|
|
77
|
+
if (!buildConfiguration) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
buildConfiguration.buildSettings = {
|
|
81
|
+
...(buildConfiguration.buildSettings ?? {}),
|
|
82
|
+
...commonBuildSettings,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
return { uuid: configurationListId };
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=configurationList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configurationList.js","sourceRoot":"","sources":["../../../../src/ios-widget/xcode/configurationList.ts"],"names":[],"mappings":"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"}
|