@use-voltra/ios-client 2.1.1 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/README.md +61 -8
  2. package/build/commonjs/dynamic-widget/api.js +15 -0
  3. package/build/commonjs/dynamic-widget/api.js.map +1 -0
  4. package/build/commonjs/index.js +15 -7
  5. package/build/commonjs/index.js.map +1 -1
  6. package/build/commonjs/native/NativeVoltra.js.map +1 -1
  7. package/build/module/dynamic-widget/api.js +10 -0
  8. package/build/module/dynamic-widget/api.js.map +1 -0
  9. package/build/module/index.js +1 -0
  10. package/build/module/index.js.map +1 -1
  11. package/build/module/native/NativeVoltra.js.map +1 -1
  12. package/build/typescript/commonjs/dynamic-widget/api.d.ts +8 -0
  13. package/build/typescript/commonjs/dynamic-widget/api.d.ts.map +1 -0
  14. package/build/typescript/commonjs/index.d.ts +1 -0
  15. package/build/typescript/commonjs/index.d.ts.map +1 -1
  16. package/build/typescript/commonjs/native/NativeVoltra.d.ts +1 -0
  17. package/build/typescript/commonjs/native/NativeVoltra.d.ts.map +1 -1
  18. package/build/typescript/module/dynamic-widget/api.d.ts +8 -0
  19. package/build/typescript/module/dynamic-widget/api.d.ts.map +1 -0
  20. package/build/typescript/module/index.d.ts +1 -0
  21. package/build/typescript/module/index.d.ts.map +1 -1
  22. package/build/typescript/module/native/NativeVoltra.d.ts +1 -0
  23. package/build/typescript/module/native/NativeVoltra.d.ts.map +1 -1
  24. package/expo-plugin/build/cjs/index.js +3 -1
  25. package/expo-plugin/build/cjs/index.js.map +1 -1
  26. package/expo-plugin/build/cjs/ios-widget/index.js +1 -1
  27. package/expo-plugin/build/cjs/ios-widget/index.js.map +1 -1
  28. package/expo-plugin/build/cjs/ios-widget/podfile.js +38 -12
  29. package/expo-plugin/build/cjs/ios-widget/podfile.js.map +1 -1
  30. package/expo-plugin/build/cjs/ios-widget/xcode/buildPhases.js +143 -107
  31. package/expo-plugin/build/cjs/ios-widget/xcode/buildPhases.js.map +1 -1
  32. package/expo-plugin/build/cjs/ios-widget/xcode/configurationList.js +30 -22
  33. package/expo-plugin/build/cjs/ios-widget/xcode/configurationList.js.map +1 -1
  34. package/expo-plugin/build/cjs/ios-widget/xcode/fileReferences.js +50 -0
  35. package/expo-plugin/build/cjs/ios-widget/xcode/fileReferences.js.map +1 -0
  36. package/expo-plugin/build/cjs/ios-widget/xcode/groups.js +45 -43
  37. package/expo-plugin/build/cjs/ios-widget/xcode/groups.js.map +1 -1
  38. package/expo-plugin/build/cjs/ios-widget/xcode/index.js +77 -91
  39. package/expo-plugin/build/cjs/ios-widget/xcode/index.js.map +1 -1
  40. package/expo-plugin/build/cjs/ios-widget/xcode/mainAppSettings.js +41 -39
  41. package/expo-plugin/build/cjs/ios-widget/xcode/mainAppSettings.js.map +1 -1
  42. package/expo-plugin/build/cjs/ios-widget/xcode/productFile.js +2 -2
  43. package/expo-plugin/build/cjs/ios-widget/xcode/productFile.js.map +1 -1
  44. package/expo-plugin/build/cjs/ios-widget/xcode/target.js +29 -63
  45. package/expo-plugin/build/cjs/ios-widget/xcode/target.js.map +1 -1
  46. package/expo-plugin/build/esm/index.js +3 -1
  47. package/expo-plugin/build/esm/index.js.map +1 -1
  48. package/expo-plugin/build/esm/ios-widget/index.js +1 -1
  49. package/expo-plugin/build/esm/ios-widget/index.js.map +1 -1
  50. package/expo-plugin/build/esm/ios-widget/podfile.js +36 -11
  51. package/expo-plugin/build/esm/ios-widget/podfile.js.map +1 -1
  52. package/expo-plugin/build/esm/ios-widget/xcode/buildPhases.js +143 -106
  53. package/expo-plugin/build/esm/ios-widget/xcode/buildPhases.js.map +1 -1
  54. package/expo-plugin/build/esm/ios-widget/xcode/configurationList.js +31 -22
  55. package/expo-plugin/build/esm/ios-widget/xcode/configurationList.js.map +1 -1
  56. package/expo-plugin/build/esm/ios-widget/xcode/fileReferences.js +45 -0
  57. package/expo-plugin/build/esm/ios-widget/xcode/fileReferences.js.map +1 -0
  58. package/expo-plugin/build/esm/ios-widget/xcode/groups.js +45 -42
  59. package/expo-plugin/build/esm/ios-widget/xcode/groups.js.map +1 -1
  60. package/expo-plugin/build/esm/ios-widget/xcode/index.js +81 -96
  61. package/expo-plugin/build/esm/ios-widget/xcode/index.js.map +1 -1
  62. package/expo-plugin/build/esm/ios-widget/xcode/mainAppSettings.js +41 -39
  63. package/expo-plugin/build/esm/ios-widget/xcode/mainAppSettings.js.map +1 -1
  64. package/expo-plugin/build/esm/ios-widget/xcode/productFile.js +3 -2
  65. package/expo-plugin/build/esm/ios-widget/xcode/productFile.js.map +1 -1
  66. package/expo-plugin/build/esm/ios-widget/xcode/target.js +28 -62
  67. package/expo-plugin/build/esm/ios-widget/xcode/target.js.map +1 -1
  68. package/expo-plugin/build/types/index.d.ts.map +1 -1
  69. package/expo-plugin/build/types/ios-widget/podfile.d.ts +19 -1
  70. package/expo-plugin/build/types/ios-widget/podfile.d.ts.map +1 -1
  71. package/expo-plugin/build/types/ios-widget/xcode/buildPhases.d.ts +3 -7
  72. package/expo-plugin/build/types/ios-widget/xcode/buildPhases.d.ts.map +1 -1
  73. package/expo-plugin/build/types/ios-widget/xcode/configurationList.d.ts +15 -10
  74. package/expo-plugin/build/types/ios-widget/xcode/configurationList.d.ts.map +1 -1
  75. package/expo-plugin/build/types/ios-widget/xcode/fileReferences.d.ts +16 -0
  76. package/expo-plugin/build/types/ios-widget/xcode/fileReferences.d.ts.map +1 -0
  77. package/expo-plugin/build/types/ios-widget/xcode/groups.d.ts +0 -4
  78. package/expo-plugin/build/types/ios-widget/xcode/groups.d.ts.map +1 -1
  79. package/expo-plugin/build/types/ios-widget/xcode/index.d.ts +22 -3
  80. package/expo-plugin/build/types/ios-widget/xcode/index.d.ts.map +1 -1
  81. package/expo-plugin/build/types/ios-widget/xcode/mainAppSettings.d.ts +16 -4
  82. package/expo-plugin/build/types/ios-widget/xcode/mainAppSettings.d.ts.map +1 -1
  83. package/expo-plugin/build/types/ios-widget/xcode/productFile.d.ts +0 -4
  84. package/expo-plugin/build/types/ios-widget/xcode/productFile.d.ts.map +1 -1
  85. package/expo-plugin/build/types/ios-widget/xcode/target.d.ts +11 -26
  86. package/expo-plugin/build/types/ios-widget/xcode/target.d.ts.map +1 -1
  87. package/expo-plugin/src/index.ts +5 -1
  88. package/expo-plugin/src/ios-widget/index.ts +1 -1
  89. package/expo-plugin/src/ios-widget/podfile.ts +46 -13
  90. package/expo-plugin/src/ios-widget/xcode/__fixtures__/fresh.pbxproj +197 -0
  91. package/expo-plugin/src/ios-widget/xcode/__fixtures__/with-existing-extension.pbxproj +321 -0
  92. package/expo-plugin/src/ios-widget/xcode/__fixtures__/with-per-config-signing.pbxproj +203 -0
  93. package/expo-plugin/src/ios-widget/xcode/__snapshots__/applyXcodeChanges.node.test.ts.snap +357 -0
  94. package/expo-plugin/src/ios-widget/xcode/__tests__/pbxConsistency.ts +130 -0
  95. package/expo-plugin/src/ios-widget/xcode/buildPhases.ts +151 -152
  96. package/expo-plugin/src/ios-widget/xcode/configurationList.ts +52 -35
  97. package/expo-plugin/src/ios-widget/xcode/fileReferences.ts +51 -0
  98. package/expo-plugin/src/ios-widget/xcode/groups.ts +52 -54
  99. package/expo-plugin/src/ios-widget/xcode/index.ts +107 -119
  100. package/expo-plugin/src/ios-widget/xcode/mainAppSettings.ts +59 -54
  101. package/expo-plugin/src/ios-widget/xcode/productFile.ts +3 -2
  102. package/expo-plugin/src/ios-widget/xcode/target.ts +31 -83
  103. package/ios/Package.swift +7 -1
  104. package/ios/app/NativeVoltra.mm +19 -0
  105. package/ios/app/VoltraModule.swift +18 -0
  106. package/ios/app/VoltraModuleImpl.swift +16 -0
  107. package/ios/shared/DynamicWidgetPropsCodec.swift +51 -0
  108. package/ios/shared/DynamicWidgetPropsStorage.swift +53 -0
  109. package/ios/shared/DynamicWidgetPropsStore.swift +50 -0
  110. package/ios/shared/DynamicWidgetRenderCoordinator.swift +31 -0
  111. package/ios/shared/DynamicWidgetUpdater.swift +30 -0
  112. package/ios/shared/VoltraConstants.swift +4 -0
  113. package/ios/shared/VoltraJSRenderer.swift +3 -1
  114. package/ios/shared/VoltraNode.swift +6 -2
  115. package/ios/shared/VoltraWidgetDefaults.swift +9 -1
  116. package/ios/target/VoltraClientWidgetRuntime.swift +17 -5
  117. package/ios/target/VoltraHomeWidget.swift +6 -2
  118. package/ios/target/VoltraWidget.swift +3 -1
  119. package/ios/ui/Helpers/VoltraDeepLinkResolver.swift +3 -1
  120. package/ios/ui/Helpers/VoltraProgressDriver.swift +6 -2
  121. package/ios/ui/Layout/VoltraFlexStackLayout.swift +9 -3
  122. package/ios/ui/Style/JSColorParser.swift +24 -8
  123. package/ios/ui/Style/JSGradientParser.swift +36 -12
  124. package/ios/ui/Style/JSStyleParser.swift +36 -12
  125. package/ios/ui/Style/LayoutStyle.swift +12 -4
  126. package/ios/ui/Views/VoltraChart.swift +52 -16
  127. package/ios/ui/Views/VoltraLinearGradient.swift +6 -2
  128. package/package.json +5 -5
  129. package/src/dynamic-widget/api.ts +25 -0
  130. package/src/index.ts +1 -0
  131. package/src/native/NativeVoltra.ts +1 -0
@@ -1,14 +1,25 @@
1
1
  import { IOS } from '../../constants';
2
- function createCommonBuildSettings(options) {
3
- const { targetName, bundleIdentifier, deploymentTarget, codeSignStyle, developmentTeam, provisioningProfileSpecifier, } = options;
4
- const commonBuildSettings = {
2
+ /**
3
+ * Resolves the main app signing settings for a widget configuration name: an exact name match
4
+ * wins, otherwise the first available configuration's settings are used as fallback.
5
+ */
6
+ function signingForConfiguration(mainAppSettings, configurationName) {
7
+ if (!mainAppSettings) {
8
+ return {};
9
+ }
10
+ return mainAppSettings.byConfigurationName[configurationName] ?? mainAppSettings.fallback;
11
+ }
12
+ function createBuildSettings(options, configurationName) {
13
+ const { targetName, bundleIdentifier, deploymentTarget, version, buildNumber, mainAppSettings } = options;
14
+ const { codeSignStyle, developmentTeam, provisioningProfileSpecifier } = signingForConfiguration(mainAppSettings, configurationName);
15
+ const buildSettings = {
5
16
  PRODUCT_NAME: `"$(TARGET_NAME)"`,
6
17
  SWIFT_VERSION: IOS.SWIFT_VERSION,
7
18
  TARGETED_DEVICE_FAMILY: `"${IOS.DEVICE_FAMILY}"`,
8
19
  INFOPLIST_FILE: `${targetName}/Info.plist`,
9
20
  INFOPLIST_OUTPUT_FORMAT: `"xml"`,
10
- CURRENT_PROJECT_VERSION: `"1"`,
11
- MARKETING_VERSION: `"1.0"`,
21
+ CURRENT_PROJECT_VERSION: `"${buildNumber ?? '1'}"`,
22
+ MARKETING_VERSION: `"${version ?? '1.0'}"`,
12
23
  IPHONEOS_DEPLOYMENT_TARGET: `"${deploymentTarget}"`,
13
24
  PRODUCT_BUNDLE_IDENTIFIER: `"${bundleIdentifier}"`,
14
25
  SWIFT_OPTIMIZATION_LEVEL: `"-Onone"`,
@@ -16,45 +27,43 @@ function createCommonBuildSettings(options) {
16
27
  APPLICATION_EXTENSION_API_ONLY: '"YES"',
17
28
  ASSETCATALOG_COMPILER_APPICON_NAME: '""',
18
29
  };
19
- // Synchronize code signing settings from main app target
30
+ // Synchronize code signing settings from the main app target's matching configuration
20
31
  if (codeSignStyle) {
21
- commonBuildSettings.CODE_SIGN_STYLE = `"${codeSignStyle}"`;
32
+ buildSettings.CODE_SIGN_STYLE = `"${codeSignStyle}"`;
22
33
  }
23
34
  if (developmentTeam) {
24
- commonBuildSettings.DEVELOPMENT_TEAM = `"${developmentTeam}"`;
35
+ buildSettings.DEVELOPMENT_TEAM = `"${developmentTeam}"`;
25
36
  }
26
37
  if (provisioningProfileSpecifier) {
27
- commonBuildSettings.PROVISIONING_PROFILE_SPECIFIER = `"${provisioningProfileSpecifier}"`;
38
+ buildSettings.PROVISIONING_PROFILE_SPECIFIER = `"${provisioningProfileSpecifier}"`;
28
39
  }
29
- return commonBuildSettings;
40
+ return buildSettings;
30
41
  }
31
42
  /**
32
- * Adds the XCConfigurationList for the widget extension target.
43
+ * Adds a fresh XCConfigurationList for the widget extension target. Internal create-only fallback
44
+ * for {@link ensureXCConfigurationList}; not part of the public pipeline.
33
45
  */
34
- export function addXCConfigurationList(xcodeProject, options) {
46
+ function addXCConfigurationList(xcodeProject, options) {
35
47
  const { targetName } = options;
36
- const commonBuildSettings = createCommonBuildSettings(options);
37
48
  const buildConfigurationsList = [
38
49
  {
39
50
  name: 'Debug',
40
51
  isa: 'XCBuildConfiguration',
41
- buildSettings: {
42
- ...commonBuildSettings,
43
- },
52
+ buildSettings: createBuildSettings(options, 'Debug'),
44
53
  },
45
54
  {
46
55
  name: 'Release',
47
56
  isa: 'XCBuildConfiguration',
48
- buildSettings: {
49
- ...commonBuildSettings,
50
- },
57
+ buildSettings: createBuildSettings(options, 'Release'),
51
58
  },
52
59
  ];
53
60
  const xCConfigurationList = xcodeProject.addXCConfigurationList(buildConfigurationsList, 'Release', `Build configuration list for PBXNativeTarget "${targetName}"`);
54
61
  return xCConfigurationList;
55
62
  }
56
63
  /**
57
- * Ensures an existing XCConfigurationList is updated, or adds a new one if missing.
64
+ * Ensures an existing XCConfigurationList is updated, or adds a new one if missing. Each widget
65
+ * configuration receives the build settings derived for its own name, so Debug and Release signing
66
+ * stay in sync with the main app's respective configurations.
58
67
  */
59
68
  export function ensureXCConfigurationList(xcodeProject, options, existingConfigurationListId) {
60
69
  const configurationListId = typeof existingConfigurationListId === 'string'
@@ -65,7 +74,6 @@ export function ensureXCConfigurationList(xcodeProject, options, existingConfigu
65
74
  if (!configurationList || !configurationList.buildConfigurations) {
66
75
  return addXCConfigurationList(xcodeProject, options);
67
76
  }
68
- const commonBuildSettings = createCommonBuildSettings(options);
69
77
  const buildConfigurations = configurationList.buildConfigurations;
70
78
  const buildConfigurationSection = xcodeProject.pbxXCBuildConfigurationSection();
71
79
  for (const configRef of buildConfigurations) {
@@ -77,9 +85,10 @@ export function ensureXCConfigurationList(xcodeProject, options, existingConfigu
77
85
  if (!buildConfiguration) {
78
86
  continue;
79
87
  }
88
+ const configurationName = typeof buildConfiguration.name === 'string' ? buildConfiguration.name.replace(/^"|"$/g, '') : '';
80
89
  buildConfiguration.buildSettings = {
81
90
  ...(buildConfiguration.buildSettings ?? {}),
82
- ...commonBuildSettings,
91
+ ...createBuildSettings(options, configurationName),
83
92
  };
84
93
  }
85
94
  return { uuid: configurationListId };
@@ -1 +1 @@
1
- {"version":3,"file":"configurationList.js","sourceRoot":"","sources":["../../../../src/ios-widget/xcode/configurationList.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"configurationList.js","sourceRoot":"","sources":["../../../../src/ios-widget/xcode/configurationList.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ const pbxFile = require('xcode/lib/pbxFile');
2
+ /** Strips surrounding quotes from a pbx path/name value. */
3
+ export function normalizePath(value) {
4
+ if (!value) {
5
+ return '';
6
+ }
7
+ return value.replace(/^"|"$/g, '');
8
+ }
9
+ /** Strips a trailing `/* comment *\/` and whitespace, yielding the bare UUID of a pbx reference. */
10
+ export function normalizeRef(value) {
11
+ return String(value)
12
+ .replace(/\/\*.*?\*\//g, '')
13
+ .trim();
14
+ }
15
+ /**
16
+ * Resolves the PBXFileReference UUID for a widget file, scoped to the widget's own PBXGroup.
17
+ *
18
+ * pbxproj paths are group-relative, so a bare path like `Assets.xcassets` collides with any other
19
+ * extension's identically named file. Scoping the lookup to the children of the widget group
20
+ * (identified by `targetName`) keeps the widget's references distinct from those, which is what
21
+ * prevents the shared-fileRef corruption behind issues #87/#32. When the widget group does not
22
+ * exist yet, a fresh reference is created.
23
+ */
24
+ export function ensureWidgetFileReference(xcodeProject, filePath, targetName) {
25
+ const file = new pbxFile(filePath);
26
+ const fileReferenceSection = xcodeProject.pbxFileReferenceSection();
27
+ const group = xcodeProject.pbxGroupByName(targetName);
28
+ if (group?.children) {
29
+ for (const child of group.children) {
30
+ const refKey = normalizeRef(child.value);
31
+ const entry = fileReferenceSection[refKey];
32
+ if (!entry) {
33
+ continue;
34
+ }
35
+ const entryPath = normalizePath(entry.path);
36
+ if (entryPath === file.path || entryPath === normalizePath(filePath)) {
37
+ return refKey;
38
+ }
39
+ }
40
+ }
41
+ file.fileRef = xcodeProject.generateUuid();
42
+ xcodeProject.addToPbxFileReferenceSection(file);
43
+ return file.fileRef;
44
+ }
45
+ //# sourceMappingURL=fileReferences.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileReferences.js","sourceRoot":"","sources":["../../../../src/ios-widget/xcode/fileReferences.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAA;AAE5C,4DAA4D;AAC5D,MAAM,UAAU,aAAa,CAAC,KAAyB;IACrD,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,oGAAoG;AACpG,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,OAAO,MAAM,CAAC,KAAK,CAAC;SACjB,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;SAC3B,IAAI,EAAE,CAAA;AACX,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,yBAAyB,CAAC,YAA0B,EAAE,QAAgB,EAAE,UAAkB;IACxG,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAA;IAClC,MAAM,oBAAoB,GAAG,YAAY,CAAC,uBAAuB,EAAE,CAAA;IACnE,MAAM,KAAK,GAAG,YAAY,CAAC,cAAc,CAAC,UAAU,CAAC,CAAA;IAErD,IAAI,KAAK,EAAE,QAAQ,EAAE,CAAC;QACpB,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACnC,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;YACxC,MAAM,KAAK,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAA;YAC1C,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,SAAQ;YACV,CAAC;YACD,MAAM,SAAS,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;YAC3C,IAAI,SAAS,KAAK,IAAI,CAAC,IAAI,IAAI,SAAS,KAAK,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACrE,OAAO,MAAM,CAAA;YACf,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,CAAC,OAAO,GAAG,YAAY,CAAC,YAAY,EAAE,CAAA;IAC1C,YAAY,CAAC,4BAA4B,CAAC,IAAI,CAAC,CAAA;IAC/C,OAAO,IAAI,CAAC,OAAO,CAAA;AACrB,CAAC"}
@@ -1,43 +1,63 @@
1
+ import { ensureWidgetFileReference } from './fileReferences';
1
2
  const pbxFile = require('xcode/lib/pbxFile');
2
- /**
3
- * Adds a PBXGroup for the widget extension files.
4
- */
5
- export function addPbxGroup(xcodeProject, options) {
6
- const { targetName, widgetFiles } = options;
3
+ function collectGroupFiles(widgetFiles) {
7
4
  const { swiftFiles, intentFiles, assetDirectories, entitlementFiles, plistFiles, localizedStringResources } = widgetFiles;
8
- // Add PBX group with all widget files
9
- const { uuid: pbxGroupUuid } = xcodeProject.addPbxGroup([
5
+ return [
10
6
  ...swiftFiles,
11
7
  ...intentFiles,
12
8
  ...entitlementFiles,
13
9
  ...plistFiles,
14
10
  ...assetDirectories,
15
11
  ...localizedStringResources,
16
- ], targetName, targetName);
17
- // Add PBXGroup to top level group
12
+ ];
13
+ }
14
+ /**
15
+ * Adds a PBXGroup for the widget extension files.
16
+ *
17
+ * Constructs the PBXGroup and its PBXFileReference children by hand rather than delegating to
18
+ * `xcodeProject.addPbxGroup`, because that helper also creates a PBXBuildFile per file as a side
19
+ * effect. Those extra build files collide with the ones managed by the build-phase functions and
20
+ * produce the "no parent for object" consistency errors from issues #87/#32. File references are
21
+ * resolved through the widget-scoped {@link ensureWidgetFileReference} so they are shared with the
22
+ * build phases instead of duplicated.
23
+ *
24
+ * Internal create-only fallback for {@link ensurePbxGroup}; not part of the public pipeline.
25
+ */
26
+ function addPbxGroup(xcodeProject, options) {
27
+ const { targetName, widgetFiles } = options;
28
+ const allFiles = collectGroupFiles(widgetFiles);
29
+ const pbxGroupUuid = xcodeProject.generateUuid();
30
+ const pbxGroup = {
31
+ isa: 'PBXGroup',
32
+ children: [],
33
+ name: targetName,
34
+ path: targetName,
35
+ sourceTree: '"<group>"',
36
+ };
18
37
  const groups = xcodeProject.hash.project.objects['PBXGroup'];
19
- if (pbxGroupUuid) {
20
- Object.keys(groups).forEach(function (key) {
21
- if (groups[key].name === undefined && groups[key].path === undefined) {
22
- xcodeProject.addToPbxGroup(pbxGroupUuid, key);
23
- }
24
- });
38
+ groups[pbxGroupUuid] = pbxGroup;
39
+ groups[`${pbxGroupUuid}_comment`] = targetName;
40
+ for (const filePath of allFiles) {
41
+ const file = new pbxFile(filePath);
42
+ const fileRef = ensureWidgetFileReference(xcodeProject, filePath, targetName);
43
+ pbxGroup.children.push({ value: fileRef, comment: file.basename });
25
44
  }
45
+ // Attach the new group to the top-level (unnamed, path-less) group.
46
+ Object.keys(groups).forEach(function (key) {
47
+ if (/_comment$/.test(key)) {
48
+ return;
49
+ }
50
+ if (groups[key].name === undefined && groups[key].path === undefined) {
51
+ xcodeProject.addToPbxGroup(pbxGroupUuid, key);
52
+ }
53
+ });
26
54
  }
27
55
  /**
28
56
  * Ensures a PBXGroup exists for the widget extension files.
29
57
  */
30
58
  export function ensurePbxGroup(xcodeProject, options) {
31
59
  const { targetName, widgetFiles } = options;
32
- const { swiftFiles, intentFiles, assetDirectories, entitlementFiles, plistFiles, localizedStringResources } = widgetFiles;
33
- const allFiles = [
34
- ...swiftFiles,
35
- ...intentFiles,
36
- ...entitlementFiles,
37
- ...plistFiles,
38
- ...assetDirectories,
39
- ...localizedStringResources,
40
- ];
60
+ const allFiles = collectGroupFiles(widgetFiles);
41
61
  const existingGroup = xcodeProject.pbxGroupByName(targetName);
42
62
  if (!existingGroup) {
43
63
  addPbxGroup(xcodeProject, options);
@@ -48,28 +68,11 @@ export function ensurePbxGroup(xcodeProject, options) {
48
68
  }
49
69
  for (const filePath of allFiles) {
50
70
  const file = new pbxFile(filePath);
51
- const fileRef = ensureFileReference(xcodeProject, filePath);
71
+ const fileRef = ensureWidgetFileReference(xcodeProject, filePath, targetName);
52
72
  const alreadyInGroup = existingGroup.children.some((child) => child.value === fileRef || child.comment === file.basename);
53
73
  if (!alreadyInGroup) {
54
74
  existingGroup.children.push({ value: fileRef, comment: file.basename });
55
75
  }
56
76
  }
57
77
  }
58
- function ensureFileReference(xcodeProject, filePath) {
59
- const fileReferenceSection = xcodeProject.pbxFileReferenceSection();
60
- const file = new pbxFile(filePath);
61
- for (const key of Object.keys(fileReferenceSection)) {
62
- if (/_comment$/.test(key)) {
63
- continue;
64
- }
65
- const entry = fileReferenceSection[key];
66
- const entryPath = typeof entry?.path === 'string' ? entry.path.replace(/^"|"$/g, '') : '';
67
- if (entryPath === file.path || entryPath === filePath) {
68
- return key;
69
- }
70
- }
71
- file.fileRef = xcodeProject.generateUuid();
72
- xcodeProject.addToPbxFileReferenceSection(file);
73
- return file.fileRef;
74
- }
75
78
  //# sourceMappingURL=groups.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"groups.js","sourceRoot":"","sources":["../../../../src/ios-widget/xcode/groups.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"groups.js","sourceRoot":"","sources":["../../../../src/ios-widget/xcode/groups.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAA;AAE5D,MAAM,OAAO,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAA;AAO5C,SAAS,iBAAiB,CAAC,WAAoC;IAC7D,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,UAAU,EAAE,wBAAwB,EAAE,GACzG,WAAW,CAAA;IACb,OAAO;QACL,GAAG,UAAU;QACb,GAAG,WAAW;QACd,GAAG,gBAAgB;QACnB,GAAG,UAAU;QACb,GAAG,gBAAgB;QACnB,GAAG,wBAAwB;KAC5B,CAAA;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,WAAW,CAAC,YAA0B,EAAE,OAA2B;IAC1E,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,OAAO,CAAA;IAC3C,MAAM,QAAQ,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAA;IAE/C,MAAM,YAAY,GAAG,YAAY,CAAC,YAAY,EAAE,CAAA;IAChD,MAAM,QAAQ,GAAG;QACf,GAAG,EAAE,UAAU;QACf,QAAQ,EAAE,EAA0C;QACpD,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,UAAU;QAChB,UAAU,EAAE,WAAW;KACxB,CAAA;IAED,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IAC5D,MAAM,CAAC,YAAY,CAAC,GAAG,QAAQ,CAAA;IAC/B,MAAM,CAAC,GAAG,YAAY,UAAU,CAAC,GAAG,UAAU,CAAA;IAE9C,KAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAA;QAClC,MAAM,OAAO,GAAG,yBAAyB,CAAC,YAAY,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAA;QAC7E,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAA;IACpE,CAAC;IAED,oEAAoE;IACpE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,UAAU,GAAG;QACvC,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,OAAM;QACR,CAAC;QACD,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACrE,YAAY,CAAC,aAAa,CAAC,YAAY,EAAE,GAAG,CAAC,CAAA;QAC/C,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,YAA0B,EAAE,OAA2B;IACpF,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,OAAO,CAAA;IAC3C,MAAM,QAAQ,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAA;IAE/C,MAAM,aAAa,GAAG,YAAY,CAAC,cAAc,CAAC,UAAU,CAAC,CAAA;IAC7D,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,WAAW,CAAC,YAAY,EAAE,OAAO,CAAC,CAAA;QAClC,OAAM;IACR,CAAC;IAED,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC;QAC5B,aAAa,CAAC,QAAQ,GAAG,EAAE,CAAA;IAC7B,CAAC;IAED,KAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAA;QAClC,MAAM,OAAO,GAAG,yBAAyB,CAAC,YAAY,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAA;QAC7E,MAAM,cAAc,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,CAChD,CAAC,KAAU,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,OAAO,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC,QAAQ,CAC3E,CAAA;QACD,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAA;QACzE,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -2,12 +2,83 @@ import { withXcodeProject } from '@expo/config-plugins';
2
2
  import * as path from 'path';
3
3
  import { getIOSWidgetExtensionFiles } from '../../utils/fileDiscovery';
4
4
  import { detectClientRenderedWidgets } from '../clientRendered';
5
- import { addBuildPhases, ensureBuildPhases, ensureWidgetBundleScriptPhase } from './buildPhases';
6
- import { addXCConfigurationList, ensureXCConfigurationList } from './configurationList';
7
- import { addPbxGroup, ensurePbxGroup } from './groups';
5
+ import { ensureBuildPhases, ensureWidgetBundleScriptPhase } from './buildPhases';
6
+ import { ensureXCConfigurationList } from './configurationList';
7
+ import { ensurePbxGroup } from './groups';
8
8
  import { getMainAppTargetSettings } from './mainAppSettings';
9
- import { addProductFile, ensureProductFile } from './productFile';
10
- import { configureTarget, ensureTargetAttributes, ensureTargetDependency } from './target';
9
+ import { ensureProductFile } from './productFile';
10
+ import { createTargetSkeleton, ensureTargetAttributes, ensureTargetDependency } from './target';
11
+ /**
12
+ * Applies all widget-extension changes to an already-parsed Xcode project.
13
+ *
14
+ * This is the pure core of {@link configureXcodeProject}: it takes the parsed project, the plugin
15
+ * props, the discovered widget files, and whether any widget is client-rendered, then mutates the
16
+ * project in place. It performs no filesystem or `modRequest` access, which makes it directly
17
+ * testable against pbxproj fixtures.
18
+ *
19
+ * When the widget target does not exist yet, the minimal native-target skeleton is created first
20
+ * (targets cannot be "ensured" into existence); every other object is then reconciled by the same
21
+ * idempotent ensure pipeline that runs for an already-existing target.
22
+ */
23
+ export function applyXcodeChanges(xcodeProject, props, widgetFiles, hasClientRenderedWidgets = false) {
24
+ const { targetName, bundleIdentifier, deploymentTarget, version, buildNumber } = props;
25
+ const groupName = 'Embed Foundation Extensions';
26
+ // Read main app target settings to synchronize code signing (per configuration).
27
+ const mainAppSettings = getMainAppTargetSettings(xcodeProject);
28
+ // Use the deploymentTarget from plugin config (or default), ignore main app's deployment target.
29
+ // This allows the widget extension to have its own deployment target independent of the main app.
30
+ // Resolve (or create) the widget target. A target cannot be reconciled into existence, so the
31
+ // absent case creates the minimal skeleton; from here on both paths share one pipeline.
32
+ let targetUuid = xcodeProject.findTargetKey(targetName);
33
+ if (!targetUuid) {
34
+ targetUuid = xcodeProject.generateUuid();
35
+ createTargetSkeleton(xcodeProject, { targetName, targetUuid });
36
+ }
37
+ const target = xcodeProject.pbxNativeTargetSection()[targetUuid];
38
+ // Ensure the configuration list is present and its settings are in sync.
39
+ const xCConfigurationList = ensureXCConfigurationList(xcodeProject, {
40
+ targetName,
41
+ bundleIdentifier,
42
+ deploymentTarget,
43
+ version,
44
+ buildNumber,
45
+ mainAppSettings,
46
+ }, target.buildConfigurationList);
47
+ // Ensure the product file (.appex) exists.
48
+ const productFile = ensureProductFile(xcodeProject, {
49
+ targetName,
50
+ groupName,
51
+ });
52
+ // Point the target at the reconciled configuration list and product file.
53
+ target.productReference = productFile.fileRef;
54
+ target.buildConfigurationList = xCConfigurationList.uuid;
55
+ target.productType = `"com.apple.product-type.app-extension"`;
56
+ target.name = targetName;
57
+ target.productName = targetName;
58
+ if (!target.buildPhases) {
59
+ target.buildPhases = [];
60
+ }
61
+ // Ensure the group first so the widget's file references exist before the build phases
62
+ // reference them (the phases resolve files through the widget-scoped group).
63
+ ensurePbxGroup(xcodeProject, {
64
+ targetName,
65
+ widgetFiles,
66
+ });
67
+ // Ensure build phases and their files.
68
+ ensureBuildPhases(xcodeProject, {
69
+ targetUuid,
70
+ targetName,
71
+ groupName,
72
+ productFile,
73
+ widgetFiles,
74
+ mainTargetUuid: xcodeProject.getFirstTarget().uuid,
75
+ });
76
+ if (hasClientRenderedWidgets) {
77
+ ensureWidgetBundleScriptPhase(xcodeProject, targetUuid);
78
+ }
79
+ ensureTargetAttributes(xcodeProject, targetUuid);
80
+ ensureTargetDependency(xcodeProject, targetUuid);
81
+ }
11
82
  /**
12
83
  * Plugin step that configures the Xcode project for the widget extension.
13
84
  *
@@ -18,111 +89,25 @@ import { configureTarget, ensureTargetAttributes, ensureTargetDependency } from
18
89
  * - Adds build phases (Sources, CopyFiles, Frameworks, Resources)
19
90
  * - Adds PBXGroup for widget files
20
91
  *
21
- * This should run after generateWidgetExtensionFiles so the files exist.
92
+ * This should run after generateWidgetExtensionFiles so the files exist. The wrapper is kept thin:
93
+ * it discovers widget files and detects client-rendered widgets, then delegates the actual pbxproj
94
+ * mutation to {@link applyXcodeChanges}.
22
95
  */
23
96
  export const configureXcodeProject = (config, props) => {
24
- const { targetName, bundleIdentifier, deploymentTarget, widgets } = props;
97
+ const { targetName, widgets } = props;
25
98
  return withXcodeProject(config, (config) => {
26
99
  if (config.modRequest.introspect) {
27
100
  return config;
28
101
  }
29
102
  const xcodeProject = config.modResults;
30
- const groupName = 'Embed Foundation Extensions';
31
103
  // The release widget-bundling phase is only needed when a widget is a Dynamic Widget (server
32
104
  // widgets carry no JS bundle). Detect once so both the create and update paths agree.
33
105
  const hasClientRenderedWidgets = !!widgets &&
34
106
  detectClientRenderedWidgets(widgets, config.modRequest.projectRoot).some((widget) => widget.clientRendered);
35
- // Check if target already exists
36
- const nativeTargets = xcodeProject.pbxNativeTargetSection();
37
- const existingTargetKey = xcodeProject.findTargetKey(targetName);
38
- const existingTarget = existingTargetKey ? nativeTargets[existingTargetKey] : null;
39
107
  const { platformProjectRoot } = config.modRequest;
40
108
  const targetPath = path.join(platformProjectRoot, targetName);
41
109
  const widgetFiles = getIOSWidgetExtensionFiles(targetPath, targetName);
42
- // Read main app target settings to synchronize code signing
43
- const mainAppSettings = getMainAppTargetSettings(xcodeProject);
44
- // Use the deploymentTarget from plugin config (or default), ignore main app's deployment target
45
- // This allows the widget extension to have its own deployment target independent of the main app
46
- if (existingTarget && existingTargetKey) {
47
- // Ensure configuration list is up to date
48
- const xCConfigurationList = ensureXCConfigurationList(xcodeProject, {
49
- targetName,
50
- bundleIdentifier,
51
- deploymentTarget,
52
- codeSignStyle: mainAppSettings?.codeSignStyle,
53
- developmentTeam: mainAppSettings?.developmentTeam,
54
- provisioningProfileSpecifier: mainAppSettings?.provisioningProfileSpecifier,
55
- }, existingTarget.buildConfigurationList);
56
- // Ensure product file exists
57
- const productFile = ensureProductFile(xcodeProject, {
58
- targetName,
59
- groupName,
60
- });
61
- // Update target references
62
- existingTarget.productReference = productFile.fileRef;
63
- existingTarget.buildConfigurationList = xCConfigurationList.uuid;
64
- existingTarget.productType = `"com.apple.product-type.app-extension"`;
65
- existingTarget.name = targetName;
66
- existingTarget.productName = targetName;
67
- if (!existingTarget.buildPhases) {
68
- existingTarget.buildPhases = [];
69
- }
70
- // Ensure build phases and groups
71
- ensureBuildPhases(xcodeProject, {
72
- targetUuid: existingTargetKey,
73
- groupName,
74
- productFile,
75
- widgetFiles,
76
- mainTargetUuid: xcodeProject.getFirstTarget().uuid,
77
- });
78
- if (hasClientRenderedWidgets) {
79
- ensureWidgetBundleScriptPhase(xcodeProject, existingTargetKey);
80
- }
81
- ensurePbxGroup(xcodeProject, {
82
- targetName,
83
- widgetFiles,
84
- });
85
- ensureTargetAttributes(xcodeProject, existingTargetKey);
86
- ensureTargetDependency(xcodeProject, existingTargetKey);
87
- return config;
88
- }
89
- // Add configuration list
90
- const targetUuid = xcodeProject.generateUuid();
91
- const xCConfigurationList = addXCConfigurationList(xcodeProject, {
92
- targetName,
93
- bundleIdentifier,
94
- deploymentTarget,
95
- codeSignStyle: mainAppSettings?.codeSignStyle,
96
- developmentTeam: mainAppSettings?.developmentTeam,
97
- provisioningProfileSpecifier: mainAppSettings?.provisioningProfileSpecifier,
98
- });
99
- // Add product file
100
- const productFile = addProductFile(xcodeProject, {
101
- targetName,
102
- groupName,
103
- });
104
- // Configure target (native target, project section, dependency)
105
- configureTarget(xcodeProject, {
106
- targetName,
107
- targetUuid,
108
- productFile,
109
- xCConfigurationList,
110
- });
111
- // Add build phases
112
- addBuildPhases(xcodeProject, {
113
- targetUuid,
114
- groupName,
115
- productFile,
116
- widgetFiles,
117
- });
118
- if (hasClientRenderedWidgets) {
119
- ensureWidgetBundleScriptPhase(xcodeProject, targetUuid);
120
- }
121
- // Add PBX group
122
- addPbxGroup(xcodeProject, {
123
- targetName,
124
- widgetFiles,
125
- });
110
+ applyXcodeChanges(xcodeProject, props, widgetFiles, hasClientRenderedWidgets);
126
111
  return config;
127
112
  });
128
113
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/ios-widget/xcode/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/ios-widget/xcode/index.ts"],"names":[],"mappings":"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"}