@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.
Files changed (244) hide show
  1. package/README.md +34 -0
  2. package/build/cjs/android/files/assets.js +259 -0
  3. package/build/cjs/android/files/assets.js.map +1 -0
  4. package/build/cjs/android/files/fonts.js +69 -0
  5. package/build/cjs/android/files/fonts.js.map +1 -0
  6. package/build/cjs/android/files/index.js +81 -0
  7. package/build/cjs/android/files/index.js.map +1 -0
  8. package/build/cjs/android/files/initialStates.js +83 -0
  9. package/build/cjs/android/files/initialStates.js.map +1 -0
  10. package/build/cjs/android/files/kotlin.js +142 -0
  11. package/build/cjs/android/files/kotlin.js.map +1 -0
  12. package/build/cjs/android/files/xml.js +247 -0
  13. package/build/cjs/android/files/xml.js.map +1 -0
  14. package/build/cjs/android/index.js +33 -0
  15. package/build/cjs/android/index.js.map +1 -0
  16. package/build/cjs/android/manifest.js +63 -0
  17. package/build/cjs/android/manifest.js.map +1 -0
  18. package/build/cjs/constants.js +48 -0
  19. package/build/cjs/constants.js.map +1 -0
  20. package/build/cjs/index.js +71 -0
  21. package/build/cjs/index.js.map +1 -0
  22. package/build/cjs/ios/eas.js +28 -0
  23. package/build/cjs/ios/eas.js.map +1 -0
  24. package/build/cjs/ios/entitlements.js +46 -0
  25. package/build/cjs/ios/entitlements.js.map +1 -0
  26. package/build/cjs/ios/index.js +39 -0
  27. package/build/cjs/ios/index.js.map +1 -0
  28. package/build/cjs/ios/infoPlist.js +51 -0
  29. package/build/cjs/ios/infoPlist.js.map +1 -0
  30. package/build/cjs/ios/pushNotifications.js +22 -0
  31. package/build/cjs/ios/pushNotifications.js.map +1 -0
  32. package/build/cjs/ios-widget/eas.js +66 -0
  33. package/build/cjs/ios-widget/eas.js.map +1 -0
  34. package/build/cjs/ios-widget/files/assets.js +199 -0
  35. package/build/cjs/ios-widget/files/assets.js.map +1 -0
  36. package/build/cjs/ios-widget/files/entitlements.js +77 -0
  37. package/build/cjs/ios-widget/files/entitlements.js.map +1 -0
  38. package/build/cjs/ios-widget/files/index.js +92 -0
  39. package/build/cjs/ios-widget/files/index.js.map +1 -0
  40. package/build/cjs/ios-widget/files/infoPlist.js +91 -0
  41. package/build/cjs/ios-widget/files/infoPlist.js.map +1 -0
  42. package/build/cjs/ios-widget/files/swift.js +256 -0
  43. package/build/cjs/ios-widget/files/swift.js.map +1 -0
  44. package/build/cjs/ios-widget/fonts.js +151 -0
  45. package/build/cjs/ios-widget/fonts.js.map +1 -0
  46. package/build/cjs/ios-widget/index.js +46 -0
  47. package/build/cjs/ios-widget/index.js.map +1 -0
  48. package/build/cjs/ios-widget/podfile.js +43 -0
  49. package/build/cjs/ios-widget/podfile.js.map +1 -0
  50. package/build/cjs/ios-widget/widgetPlist.js +99 -0
  51. package/build/cjs/ios-widget/widgetPlist.js.map +1 -0
  52. package/build/cjs/ios-widget/xcode/buildPhases.js +245 -0
  53. package/build/cjs/ios-widget/xcode/buildPhases.js.map +1 -0
  54. package/build/cjs/ios-widget/xcode/configurationList.js +91 -0
  55. package/build/cjs/ios-widget/xcode/configurationList.js.map +1 -0
  56. package/build/cjs/ios-widget/xcode/groups.js +65 -0
  57. package/build/cjs/ios-widget/xcode/groups.js.map +1 -0
  58. package/build/cjs/ios-widget/xcode/index.js +155 -0
  59. package/build/cjs/ios-widget/xcode/index.js.map +1 -0
  60. package/build/cjs/ios-widget/xcode/mainAppSettings.js +71 -0
  61. package/build/cjs/ios-widget/xcode/mainAppSettings.js.map +1 -0
  62. package/build/cjs/ios-widget/xcode/productFile.js +74 -0
  63. package/build/cjs/ios-widget/xcode/productFile.js.map +1 -0
  64. package/build/cjs/ios-widget/xcode/target.js +113 -0
  65. package/build/cjs/ios-widget/xcode/target.js.map +1 -0
  66. package/build/cjs/package.json +3 -0
  67. package/build/cjs/types.js +3 -0
  68. package/build/cjs/types.js.map +1 -0
  69. package/build/cjs/utils/entitlements.js +21 -0
  70. package/build/cjs/utils/entitlements.js.map +1 -0
  71. package/build/cjs/utils/fileDiscovery.js +107 -0
  72. package/build/cjs/utils/fileDiscovery.js.map +1 -0
  73. package/build/cjs/utils/fonts.js +75 -0
  74. package/build/cjs/utils/fonts.js.map +1 -0
  75. package/build/cjs/utils/logger.js +51 -0
  76. package/build/cjs/utils/logger.js.map +1 -0
  77. package/build/cjs/utils/prerender.js +191 -0
  78. package/build/cjs/utils/prerender.js.map +1 -0
  79. package/build/cjs/utils/urlScheme.js +40 -0
  80. package/build/cjs/utils/urlScheme.js.map +1 -0
  81. package/build/cjs/validation.js +231 -0
  82. package/build/cjs/validation.js.map +1 -0
  83. package/build/esm/android/files/assets.js +223 -0
  84. package/build/esm/android/files/assets.js.map +1 -0
  85. package/build/esm/android/files/fonts.js +33 -0
  86. package/build/esm/android/files/fonts.js.map +1 -0
  87. package/build/esm/android/files/index.js +77 -0
  88. package/build/esm/android/files/index.js.map +1 -0
  89. package/build/esm/android/files/initialStates.js +44 -0
  90. package/build/esm/android/files/initialStates.js.map +1 -0
  91. package/build/esm/android/files/kotlin.js +103 -0
  92. package/build/esm/android/files/kotlin.js.map +1 -0
  93. package/build/esm/android/files/xml.js +206 -0
  94. package/build/esm/android/files/xml.js.map +1 -0
  95. package/build/esm/android/index.js +29 -0
  96. package/build/esm/android/index.js.map +1 -0
  97. package/build/esm/android/manifest.js +59 -0
  98. package/build/esm/android/manifest.js.map +1 -0
  99. package/build/esm/constants.js +45 -0
  100. package/build/esm/constants.js.map +1 -0
  101. package/build/esm/index.js +69 -0
  102. package/build/esm/index.js.map +1 -0
  103. package/build/esm/ios/eas.js +24 -0
  104. package/build/esm/ios/eas.js.map +1 -0
  105. package/build/esm/ios/entitlements.js +42 -0
  106. package/build/esm/ios/entitlements.js.map +1 -0
  107. package/build/esm/ios/index.js +34 -0
  108. package/build/esm/ios/index.js.map +1 -0
  109. package/build/esm/ios/infoPlist.js +47 -0
  110. package/build/esm/ios/infoPlist.js.map +1 -0
  111. package/build/esm/ios/pushNotifications.js +18 -0
  112. package/build/esm/ios/pushNotifications.js.map +1 -0
  113. package/build/esm/ios-widget/eas.js +62 -0
  114. package/build/esm/ios-widget/eas.js.map +1 -0
  115. package/build/esm/ios-widget/files/assets.js +163 -0
  116. package/build/esm/ios-widget/files/assets.js.map +1 -0
  117. package/build/esm/ios-widget/files/entitlements.js +37 -0
  118. package/build/esm/ios-widget/files/entitlements.js.map +1 -0
  119. package/build/esm/ios-widget/files/index.js +55 -0
  120. package/build/esm/ios-widget/files/index.js.map +1 -0
  121. package/build/esm/ios-widget/files/infoPlist.js +55 -0
  122. package/build/esm/ios-widget/files/infoPlist.js.map +1 -0
  123. package/build/esm/ios-widget/files/swift.js +217 -0
  124. package/build/esm/ios-widget/files/swift.js.map +1 -0
  125. package/build/esm/ios-widget/fonts.js +111 -0
  126. package/build/esm/ios-widget/fonts.js.map +1 -0
  127. package/build/esm/ios-widget/index.js +42 -0
  128. package/build/esm/ios-widget/index.js.map +1 -0
  129. package/build/esm/ios-widget/podfile.js +39 -0
  130. package/build/esm/ios-widget/podfile.js.map +1 -0
  131. package/build/esm/ios-widget/widgetPlist.js +92 -0
  132. package/build/esm/ios-widget/widgetPlist.js.map +1 -0
  133. package/build/esm/ios-widget/xcode/buildPhases.js +208 -0
  134. package/build/esm/ios-widget/xcode/buildPhases.js.map +1 -0
  135. package/build/esm/ios-widget/xcode/configurationList.js +87 -0
  136. package/build/esm/ios-widget/xcode/configurationList.js.map +1 -0
  137. package/build/esm/ios-widget/xcode/groups.js +61 -0
  138. package/build/esm/ios-widget/xcode/groups.js.map +1 -0
  139. package/build/esm/ios-widget/xcode/index.js +118 -0
  140. package/build/esm/ios-widget/xcode/index.js.map +1 -0
  141. package/build/esm/ios-widget/xcode/mainAppSettings.js +68 -0
  142. package/build/esm/ios-widget/xcode/mainAppSettings.js.map +1 -0
  143. package/build/esm/ios-widget/xcode/productFile.js +70 -0
  144. package/build/esm/ios-widget/xcode/productFile.js.map +1 -0
  145. package/build/esm/ios-widget/xcode/target.js +108 -0
  146. package/build/esm/ios-widget/xcode/target.js.map +1 -0
  147. package/build/esm/package.json +3 -0
  148. package/build/esm/types.js +2 -0
  149. package/build/esm/types.js.map +1 -0
  150. package/build/esm/utils/entitlements.js +18 -0
  151. package/build/esm/utils/entitlements.js.map +1 -0
  152. package/build/esm/utils/fileDiscovery.js +71 -0
  153. package/build/esm/utils/fileDiscovery.js.map +1 -0
  154. package/build/esm/utils/fonts.js +39 -0
  155. package/build/esm/utils/fonts.js.map +1 -0
  156. package/build/esm/utils/logger.js +48 -0
  157. package/build/esm/utils/logger.js.map +1 -0
  158. package/build/esm/utils/prerender.js +152 -0
  159. package/build/esm/utils/prerender.js.map +1 -0
  160. package/build/esm/utils/urlScheme.js +37 -0
  161. package/build/esm/utils/urlScheme.js.map +1 -0
  162. package/build/esm/validation.js +193 -0
  163. package/build/esm/validation.js.map +1 -0
  164. package/build/types/android/files/assets.d.ts +26 -0
  165. package/build/types/android/files/assets.d.ts.map +1 -0
  166. package/build/types/android/files/fonts.d.ts +19 -0
  167. package/build/types/android/files/fonts.d.ts.map +1 -0
  168. package/build/types/android/files/index.d.ts +21 -0
  169. package/build/types/android/files/index.d.ts.map +1 -0
  170. package/build/types/android/files/initialStates.d.ts +14 -0
  171. package/build/types/android/files/initialStates.d.ts.map +1 -0
  172. package/build/types/android/files/kotlin.d.ts +11 -0
  173. package/build/types/android/files/kotlin.d.ts.map +1 -0
  174. package/build/types/android/files/xml.d.ts +25 -0
  175. package/build/types/android/files/xml.d.ts.map +1 -0
  176. package/build/types/android/index.d.ts +12 -0
  177. package/build/types/android/index.d.ts.map +1 -0
  178. package/build/types/android/manifest.d.ts +15 -0
  179. package/build/types/android/manifest.d.ts.map +1 -0
  180. package/build/types/constants.d.ts +29 -0
  181. package/build/types/constants.d.ts.map +1 -0
  182. package/build/types/index.d.ts +13 -0
  183. package/build/types/index.d.ts.map +1 -0
  184. package/build/types/ios/eas.d.ts +12 -0
  185. package/build/types/ios/eas.d.ts.map +1 -0
  186. package/build/types/ios/entitlements.d.ts +14 -0
  187. package/build/types/ios/entitlements.d.ts.map +1 -0
  188. package/build/types/ios/index.d.ts +19 -0
  189. package/build/types/ios/index.d.ts.map +1 -0
  190. package/build/types/ios/infoPlist.d.ts +21 -0
  191. package/build/types/ios/infoPlist.d.ts.map +1 -0
  192. package/build/types/ios/pushNotifications.d.ts +10 -0
  193. package/build/types/ios/pushNotifications.d.ts.map +1 -0
  194. package/build/types/ios-widget/eas.d.ts +15 -0
  195. package/build/types/ios-widget/eas.d.ts.map +1 -0
  196. package/build/types/ios-widget/files/assets.d.ts +13 -0
  197. package/build/types/ios-widget/files/assets.d.ts.map +1 -0
  198. package/build/types/ios-widget/files/entitlements.d.ts +17 -0
  199. package/build/types/ios-widget/files/entitlements.d.ts.map +1 -0
  200. package/build/types/ios-widget/files/index.d.ts +24 -0
  201. package/build/types/ios-widget/files/index.d.ts.map +1 -0
  202. package/build/types/ios-widget/files/infoPlist.d.ts +10 -0
  203. package/build/types/ios-widget/files/infoPlist.d.ts.map +1 -0
  204. package/build/types/ios-widget/files/swift.d.ts +15 -0
  205. package/build/types/ios-widget/files/swift.d.ts.map +1 -0
  206. package/build/types/ios-widget/fonts.d.ts +22 -0
  207. package/build/types/ios-widget/fonts.d.ts.map +1 -0
  208. package/build/types/ios-widget/index.d.ts +31 -0
  209. package/build/types/ios-widget/index.d.ts.map +1 -0
  210. package/build/types/ios-widget/podfile.d.ts +9 -0
  211. package/build/types/ios-widget/podfile.d.ts.map +1 -0
  212. package/build/types/ios-widget/widgetPlist.d.ts +20 -0
  213. package/build/types/ios-widget/widgetPlist.d.ts.map +1 -0
  214. package/build/types/ios-widget/xcode/buildPhases.d.ts +25 -0
  215. package/build/types/ios-widget/xcode/buildPhases.d.ts.map +1 -0
  216. package/build/types/ios-widget/xcode/configurationList.d.ts +20 -0
  217. package/build/types/ios-widget/xcode/configurationList.d.ts.map +1 -0
  218. package/build/types/ios-widget/xcode/groups.d.ts +15 -0
  219. package/build/types/ios-widget/xcode/groups.d.ts.map +1 -0
  220. package/build/types/ios-widget/xcode/index.d.ts +20 -0
  221. package/build/types/ios-widget/xcode/index.d.ts.map +1 -0
  222. package/build/types/ios-widget/xcode/mainAppSettings.d.ts +15 -0
  223. package/build/types/ios-widget/xcode/mainAppSettings.d.ts.map +1 -0
  224. package/build/types/ios-widget/xcode/productFile.d.ts +14 -0
  225. package/build/types/ios-widget/xcode/productFile.d.ts.map +1 -0
  226. package/build/types/ios-widget/xcode/target.d.ts +42 -0
  227. package/build/types/ios-widget/xcode/target.d.ts.map +1 -0
  228. package/build/types/types.d.ts +261 -0
  229. package/build/types/types.d.ts.map +1 -0
  230. package/build/types/utils/entitlements.d.ts +9 -0
  231. package/build/types/utils/entitlements.d.ts.map +1 -0
  232. package/build/types/utils/fileDiscovery.d.ts +13 -0
  233. package/build/types/utils/fileDiscovery.d.ts.map +1 -0
  234. package/build/types/utils/fonts.d.ts +2 -0
  235. package/build/types/utils/fonts.d.ts.map +1 -0
  236. package/build/types/utils/logger.d.ts +30 -0
  237. package/build/types/utils/logger.d.ts.map +1 -0
  238. package/build/types/utils/prerender.d.ts +25 -0
  239. package/build/types/utils/prerender.d.ts.map +1 -0
  240. package/build/types/utils/urlScheme.d.ts +10 -0
  241. package/build/types/utils/urlScheme.d.ts.map +1 -0
  242. package/build/types/validation.d.ts +17 -0
  243. package/build/types/validation.d.ts.map +1 -0
  244. package/package.json +58 -0
@@ -0,0 +1,206 @@
1
+ import dedent from 'dedent';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+ import { logger } from '../../utils/logger';
5
+ // ============================================================================
6
+ // Main Functions
7
+ // ============================================================================
8
+ /**
9
+ * Generates widget info XML files for all widgets
10
+ */
11
+ export async function generateWidgetInfoFiles(props) {
12
+ const { platformProjectRoot, widgets } = props;
13
+ const xmlPath = path.join(platformProjectRoot, 'app', 'src', 'main', 'res', 'xml');
14
+ const valuesPath = path.join(platformProjectRoot, 'app', 'src', 'main', 'res', 'values');
15
+ // Ensure directories exist
16
+ if (!fs.existsSync(xmlPath)) {
17
+ fs.mkdirSync(xmlPath, { recursive: true });
18
+ }
19
+ if (!fs.existsSync(valuesPath)) {
20
+ fs.mkdirSync(valuesPath, { recursive: true });
21
+ }
22
+ // Generate string resources for all widgets
23
+ const stringsPath = path.join(valuesPath, 'voltra_widgets.xml');
24
+ const stringsContent = generateStringResourcesXml(widgets);
25
+ fs.writeFileSync(stringsPath, stringsContent, 'utf8');
26
+ }
27
+ /**
28
+ * Generates placeholder layout XML
29
+ */
30
+ export async function generateWidgetPlaceholderLayouts(props) {
31
+ const layoutPath = path.join(props.platformProjectRoot, 'app', 'src', 'main', 'res', 'layout');
32
+ if (!fs.existsSync(layoutPath)) {
33
+ fs.mkdirSync(layoutPath, { recursive: true });
34
+ }
35
+ const placeholderLayoutPath = path.join(layoutPath, 'voltra_widget_placeholder.xml');
36
+ const placeholderLayoutContent = generatePlaceholderLayoutXml();
37
+ fs.writeFileSync(placeholderLayoutPath, placeholderLayoutContent, 'utf8');
38
+ }
39
+ /**
40
+ * Generates preview layouts for widgets
41
+ */
42
+ export async function generateWidgetPreviewLayouts(props) {
43
+ const { platformProjectRoot, projectRoot, widgets, previewImageMap } = props;
44
+ const layoutPath = path.join(platformProjectRoot, 'app', 'src', 'main', 'res', 'layout');
45
+ const xmlPath = path.join(platformProjectRoot, 'app', 'src', 'main', 'res', 'xml');
46
+ if (!fs.existsSync(layoutPath)) {
47
+ fs.mkdirSync(layoutPath, { recursive: true });
48
+ }
49
+ // Generate preview layouts and get the map
50
+ const previewLayoutMap = await generatePreviewLayouts(widgets, projectRoot, layoutPath, previewImageMap);
51
+ // Write widget info XML for all widgets, including preview references where available
52
+ for (const widget of widgets) {
53
+ const widgetInfoPath = path.join(xmlPath, `voltra_widget_${widget.id}_info.xml`);
54
+ const previewImageResourceName = previewImageMap.get(widget.id);
55
+ const previewLayoutResourceName = previewLayoutMap.get(widget.id);
56
+ const widgetInfoContent = generateWidgetInfoXml(widget, previewImageResourceName, previewLayoutResourceName);
57
+ fs.writeFileSync(widgetInfoPath, widgetInfoContent, 'utf8');
58
+ }
59
+ }
60
+ // ============================================================================
61
+ // Widget Info XML
62
+ // ============================================================================
63
+ /**
64
+ * Generates widget provider info XML for a single widget
65
+ */
66
+ function generateWidgetInfoXml(widget, previewImageResourceName, previewLayoutResourceName) {
67
+ const { targetCellWidth, targetCellHeight } = widget;
68
+ const resizeMode = widget.resizeMode || 'horizontal|vertical';
69
+ const widgetCategory = widget.widgetCategory || 'home_screen';
70
+ let minWidth = widget.minWidth;
71
+ if (minWidth === undefined && widget.minCellWidth !== undefined) {
72
+ minWidth = widget.minCellWidth * 70 - 30;
73
+ }
74
+ let minHeight = widget.minHeight;
75
+ if (minHeight === undefined && widget.minCellHeight !== undefined) {
76
+ minHeight = widget.minCellHeight * 70 - 30;
77
+ }
78
+ const minWidthAttr = minWidth !== undefined ? `\n android:minWidth="${minWidth}dp"` : '';
79
+ const minHeightAttr = minHeight !== undefined ? `\n android:minHeight="${minHeight}dp"` : '';
80
+ const previewImageAttr = previewImageResourceName
81
+ ? `\n android:previewImage="@drawable/${previewImageResourceName}"`
82
+ : '';
83
+ const previewLayoutAttr = previewLayoutResourceName
84
+ ? `\n android:previewLayout="@layout/${previewLayoutResourceName}"`
85
+ : '';
86
+ return dedent `
87
+ <?xml version="1.0" encoding="utf-8"?>
88
+ <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"${minWidthAttr}${minHeightAttr}
89
+ android:targetCellWidth="${targetCellWidth}"
90
+ android:targetCellHeight="${targetCellHeight}"
91
+ android:updatePeriodMillis="0"
92
+ android:initialLayout="@layout/voltra_widget_placeholder"
93
+ android:resizeMode="${resizeMode}"
94
+ android:widgetCategory="${widgetCategory}"
95
+ android:description="@string/voltra_widget_${widget.id}_description"${previewImageAttr}${previewLayoutAttr}>
96
+ </appwidget-provider>
97
+ `;
98
+ }
99
+ // ============================================================================
100
+ // String Resources XML
101
+ // ============================================================================
102
+ /**
103
+ * Generates string resources for widget display names and descriptions
104
+ */
105
+ function generateStringResourcesXml(widgets) {
106
+ const stringEntries = widgets
107
+ .map((widget) => `<string name="voltra_widget_${widget.id}_label">${widget.displayName}</string>\n <string name="voltra_widget_${widget.id}_description">${widget.description}</string>`)
108
+ .join('\n ');
109
+ return dedent `
110
+ <?xml version="1.0" encoding="utf-8"?>
111
+ <resources>
112
+ <!-- Voltra Widget Labels and Descriptions (Auto-generated) -->
113
+ ${stringEntries}
114
+ </resources>
115
+ `;
116
+ }
117
+ // ============================================================================
118
+ // Placeholder Layout XML
119
+ // ============================================================================
120
+ /**
121
+ * Generates placeholder layout XML for widgets
122
+ * This will be replaced by Glance at runtime
123
+ */
124
+ function generatePlaceholderLayoutXml() {
125
+ return dedent `
126
+ <?xml version="1.0" encoding="utf-8"?>
127
+ <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
128
+ android:layout_width="match_parent"
129
+ android:layout_height="match_parent"
130
+ android:background="?android:attr/colorBackground">
131
+ <TextView
132
+ android:layout_width="wrap_content"
133
+ android:layout_height="wrap_content"
134
+ android:layout_gravity="center"
135
+ android:text="Loading..."
136
+ android:textColor="?android:attr/textColorPrimary" />
137
+ </FrameLayout>
138
+ `;
139
+ }
140
+ // ============================================================================
141
+ // Preview Layout
142
+ // ============================================================================
143
+ /**
144
+ * Generates an auto-layout XML for image-based preview.
145
+ * This is used when previewImage is provided but no custom previewLayout.
146
+ */
147
+ function generateAutoImagePreviewLayout(widgetId, drawableResourceName) {
148
+ return dedent `
149
+ <?xml version="1.0" encoding="utf-8"?>
150
+ <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
151
+ android:layout_width="match_parent"
152
+ android:layout_height="match_parent">
153
+ <ImageView
154
+ android:layout_width="match_parent"
155
+ android:layout_height="match_parent"
156
+ android:src="@drawable/${drawableResourceName}"
157
+ android:scaleType="centerCrop"
158
+ android:contentDescription="@string/voltra_widget_${widgetId}_description" />
159
+ </FrameLayout>
160
+ `;
161
+ }
162
+ /**
163
+ * Generates preview layout XML files for all widgets.
164
+ * Returns a map of widgetId to layout resource name.
165
+ *
166
+ * Strategy:
167
+ * - If previewLayout is provided: copy user's custom XML
168
+ * - Else if previewImage is provided: generate auto-layout with ImageView
169
+ * - Otherwise: no preview layout generated
170
+ */
171
+ async function generatePreviewLayouts(widgets, projectRoot, layoutPath, previewImageMap) {
172
+ const previewLayoutMap = new Map();
173
+ // Ensure layout directory exists
174
+ if (!fs.existsSync(layoutPath)) {
175
+ fs.mkdirSync(layoutPath, { recursive: true });
176
+ }
177
+ for (const widget of widgets) {
178
+ let layoutContent = null;
179
+ const layoutResourceName = `voltra_widget_${widget.id}_preview`;
180
+ const layoutFilePath = path.join(layoutPath, `${layoutResourceName}.xml`);
181
+ // Strategy 1: User provided custom preview layout
182
+ if (widget.previewLayout) {
183
+ const sourcePath = path.join(projectRoot, widget.previewLayout);
184
+ if (!fs.existsSync(sourcePath)) {
185
+ logger.warn(`Preview layout not found for widget '${widget.id}' at ${widget.previewLayout}`);
186
+ continue;
187
+ }
188
+ // Copy user's custom XML
189
+ layoutContent = fs.readFileSync(sourcePath, 'utf8');
190
+ logger.info(`Using custom preview layout for widget '${widget.id}'`);
191
+ }
192
+ // Strategy 2: Auto-generate layout from preview image
193
+ else if (widget.previewImage && previewImageMap.has(widget.id)) {
194
+ const drawableResourceName = previewImageMap.get(widget.id);
195
+ layoutContent = generateAutoImagePreviewLayout(widget.id, drawableResourceName);
196
+ logger.info(`Generated auto preview layout for widget '${widget.id}' from preview image`);
197
+ }
198
+ // Write layout file if we have content
199
+ if (layoutContent) {
200
+ fs.writeFileSync(layoutFilePath, layoutContent, 'utf8');
201
+ previewLayoutMap.set(widget.id, layoutResourceName);
202
+ }
203
+ }
204
+ return previewLayoutMap;
205
+ }
206
+ //# sourceMappingURL=xml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xml.js","sourceRoot":"","sources":["../../../../src/android/files/xml.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { withPlugins } from '@expo/config-plugins';
2
+ import { validateAndroidWidgetConfig } from '../validation';
3
+ import { generateAndroidWidgetFiles } from './files';
4
+ import { configureAndroidManifest } from './manifest';
5
+ /**
6
+ * Main Android configuration plugin.
7
+ *
8
+ * This orchestrates all Android-related configuration in the correct order:
9
+ * 1. Validate widget configurations with file existence checks
10
+ * 2. Generate widget files (Kotlin receivers, XML metadata, resources)
11
+ * 3. Configure AndroidManifest (receiver entries)
12
+ */
13
+ export const withAndroid = (config, props) => {
14
+ const { widgets, userImagesPath, fonts } = props;
15
+ if (!config.android?.package) {
16
+ throw new Error('Voltra config plugin requires expo.android.package to be set in app.json/app.config.* to configure Android widgets.');
17
+ }
18
+ // Get project root from modRequest if available, otherwise validation will skip file checks
19
+ const projectRoot = config.modRequest?.projectRoot;
20
+ // Validate Android widgets with file existence checks
21
+ widgets.forEach((widget) => validateAndroidWidgetConfig(widget, projectRoot));
22
+ return withPlugins(config, [
23
+ // 1. Generate widget files (must run first so files exist)
24
+ [generateAndroidWidgetFiles, { widgets, userImagesPath, fonts }],
25
+ // 2. Configure AndroidManifest (must run after files are generated)
26
+ [configureAndroidManifest, { widgets }],
27
+ ]);
28
+ };
29
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/android/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAGhE,OAAO,EAAE,2BAA2B,EAAE,MAAM,eAAe,CAAA;AAC3D,OAAO,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAA;AACpD,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAA;AAErD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,WAAW,GAAqC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;IAC7E,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,GAAG,KAAK,CAAA;IAEhD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CACb,qHAAqH,CACtH,CAAA;IACH,CAAC;IAED,4FAA4F;IAC5F,MAAM,WAAW,GAAI,MAAc,CAAC,UAAU,EAAE,WAAW,CAAA;IAE3D,sDAAsD;IACtD,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,2BAA2B,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAA;IAE7E,OAAO,WAAW,CAAC,MAAM,EAAE;QACzB,2DAA2D;QAC3D,CAAC,0BAA0B,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC;QAEhE,oEAAoE;QACpE,CAAC,wBAAwB,EAAE,EAAE,OAAO,EAAE,CAAC;KACxC,CAAC,CAAA;AACJ,CAAC,CAAA"}
@@ -0,0 +1,59 @@
1
+ import { withAndroidManifest } from '@expo/config-plugins';
2
+ import { AndroidConfig } from 'expo/config-plugins';
3
+ /**
4
+ * Plugin step that adds widget receiver entries to AndroidManifest.xml
5
+ *
6
+ * This adds a <receiver> entry for each widget with:
7
+ * - The generated receiver class name
8
+ * - APPWIDGET_UPDATE intent filter
9
+ * - Widget provider metadata reference
10
+ */
11
+ export const configureAndroidManifest = (config, props) => {
12
+ const { widgets } = props;
13
+ return withAndroidManifest(config, (config) => {
14
+ const mainApplication = AndroidConfig.Manifest.getMainApplicationOrThrow(config.modResults);
15
+ // Add a receiver for each widget
16
+ for (const widget of widgets) {
17
+ const receiverClassName = `.widget.VoltraWidget_${widget.id}Receiver`;
18
+ // Check if receiver already exists
19
+ const existingReceivers = (mainApplication.receiver || []);
20
+ const alreadyExists = existingReceivers.some((receiver) => receiver.$?.['android:name'] === receiverClassName);
21
+ if (!alreadyExists) {
22
+ // Create the receiver entry
23
+ const receiver = {
24
+ $: {
25
+ 'android:name': receiverClassName,
26
+ 'android:exported': 'true',
27
+ 'android:label': `@string/voltra_widget_${widget.id}_label`,
28
+ },
29
+ 'intent-filter': [
30
+ {
31
+ action: [
32
+ {
33
+ $: {
34
+ 'android:name': 'android.appwidget.action.APPWIDGET_UPDATE',
35
+ },
36
+ },
37
+ ],
38
+ },
39
+ ],
40
+ 'meta-data': [
41
+ {
42
+ $: {
43
+ 'android:name': 'android.appwidget.provider',
44
+ 'android:resource': `@xml/voltra_widget_${widget.id}_info`,
45
+ },
46
+ },
47
+ ],
48
+ };
49
+ // Add the receiver to the application
50
+ if (!mainApplication.receiver) {
51
+ mainApplication.receiver = [];
52
+ }
53
+ mainApplication.receiver.push(receiver);
54
+ }
55
+ }
56
+ return config;
57
+ });
58
+ };
59
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../../src/android/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAQnD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAgD,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;IACrG,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAA;IAEzB,OAAO,mBAAmB,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;QAC5C,MAAM,eAAe,GAAG,aAAa,CAAC,QAAQ,CAAC,yBAAyB,CAAC,MAAM,CAAC,UAAU,CAAQ,CAAA;QAClG,iCAAiC;QACjC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,iBAAiB,GAAG,wBAAwB,MAAM,CAAC,EAAE,UAAU,CAAA;YAErE,mCAAmC;YACnC,MAAM,iBAAiB,GAAG,CAAC,eAAe,CAAC,QAAQ,IAAI,EAAE,CAAU,CAAA;YACnE,MAAM,aAAa,GAAG,iBAAiB,CAAC,IAAI,CAC1C,CAAC,QAAa,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,cAAc,CAAC,KAAK,iBAAiB,CACtE,CAAA;YAED,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnB,4BAA4B;gBAC5B,MAAM,QAAQ,GAAG;oBACf,CAAC,EAAE;wBACD,cAAc,EAAE,iBAAiB;wBACjC,kBAAkB,EAAE,MAAe;wBACnC,eAAe,EAAE,yBAAyB,MAAM,CAAC,EAAE,QAAQ;qBAC5D;oBACD,eAAe,EAAE;wBACf;4BACE,MAAM,EAAE;gCACN;oCACE,CAAC,EAAE;wCACD,cAAc,EAAE,2CAA2C;qCAC5D;iCACF;6BACF;yBACF;qBACF;oBACD,WAAW,EAAE;wBACX;4BACE,CAAC,EAAE;gCACD,cAAc,EAAE,4BAA4B;gCAC5C,kBAAkB,EAAE,sBAAsB,MAAM,CAAC,EAAE,OAAO;6BAC3D;yBACF;qBACF;iBACF,CAAA;gBAED,sCAAsC;gBACtC,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,CAAC;oBAC9B,eAAe,CAAC,QAAQ,GAAG,EAAE,CAAA;gBAC/B,CAAC;gBACD,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YACzC,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAA;IACf,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Constants for the Voltra plugin
3
+ */
4
+ // ============================================================================
5
+ // iOS Constants
6
+ // ============================================================================
7
+ export const IOS = {
8
+ /** Minimum iOS deployment target version */
9
+ DEPLOYMENT_TARGET: '17.0',
10
+ /** Swift language version */
11
+ SWIFT_VERSION: '5.0',
12
+ /** Target device families (1 = iPhone, 2 = iPad) */
13
+ DEVICE_FAMILY: '1,2',
14
+ /** Last Swift migration version for Xcode */
15
+ LAST_SWIFT_MIGRATION: 1250,
16
+ };
17
+ // ============================================================================
18
+ // Path Constants
19
+ // ============================================================================
20
+ /** Default path for user-provided widget images */
21
+ export const DEFAULT_USER_IMAGES_PATH = './assets/voltra';
22
+ /** Default path for user-provided Android widget images */
23
+ export const DEFAULT_ANDROID_USER_IMAGES_PATH = './assets/voltra-android';
24
+ // ============================================================================
25
+ // Widget Constants
26
+ // ============================================================================
27
+ /** Maximum image size in bytes for Live Activities (4KB limit) */
28
+ export const MAX_IMAGE_SIZE_BYTES = 4096;
29
+ /** Supported image extensions for widget assets */
30
+ export const SUPPORTED_IMAGE_EXTENSIONS = /\.(png|jpg|jpeg)$/i;
31
+ /** Default widget families when not specified */
32
+ export const DEFAULT_WIDGET_FAMILIES = ['systemSmall', 'systemMedium', 'systemLarge'];
33
+ /** Maps JS widget family names to SwiftUI WidgetFamily enum cases */
34
+ export const WIDGET_FAMILY_MAP = {
35
+ systemSmall: '.systemSmall',
36
+ systemMedium: '.systemMedium',
37
+ systemLarge: '.systemLarge',
38
+ systemExtraLarge: '.systemExtraLarge',
39
+ accessoryCircular: '.accessoryCircular',
40
+ accessoryRectangular: '.accessoryRectangular',
41
+ accessoryInline: '.accessoryInline',
42
+ };
43
+ /** Extensions to try when resolving module paths for pre-rendering */
44
+ export const MODULE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', ''];
45
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAEA;;GAEG;AAEH,+EAA+E;AAC/E,gBAAgB;AAChB,+EAA+E;AAE/E,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,4CAA4C;IAC5C,iBAAiB,EAAE,MAAM;IAEzB,6BAA6B;IAC7B,aAAa,EAAE,KAAK;IAEpB,oDAAoD;IACpD,aAAa,EAAE,KAAK;IAEpB,6CAA6C;IAC7C,oBAAoB,EAAE,IAAI;CAClB,CAAA;AAEV,+EAA+E;AAC/E,iBAAiB;AACjB,+EAA+E;AAE/E,mDAAmD;AACnD,MAAM,CAAC,MAAM,wBAAwB,GAAG,iBAAiB,CAAA;AAEzD,2DAA2D;AAC3D,MAAM,CAAC,MAAM,gCAAgC,GAAG,yBAAyB,CAAA;AAEzE,+EAA+E;AAC/E,mBAAmB;AACnB,+EAA+E;AAE/E,kEAAkE;AAClE,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAAA;AAExC,mDAAmD;AACnD,MAAM,CAAC,MAAM,0BAA0B,GAAG,oBAAoB,CAAA;AAE9D,iDAAiD;AACjD,MAAM,CAAC,MAAM,uBAAuB,GAAmB,CAAC,aAAa,EAAE,cAAc,EAAE,aAAa,CAAC,CAAA;AAErG,qEAAqE;AACrE,MAAM,CAAC,MAAM,iBAAiB,GAAiC;IAC7D,WAAW,EAAE,cAAc;IAC3B,YAAY,EAAE,eAAe;IAC7B,WAAW,EAAE,cAAc;IAC3B,gBAAgB,EAAE,mBAAmB;IACrC,iBAAiB,EAAE,oBAAoB;IACvC,oBAAoB,EAAE,uBAAuB;IAC7C,eAAe,EAAE,kBAAkB;CACpC,CAAA;AAED,sEAAsE;AACtE,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,CAAA"}
@@ -0,0 +1,69 @@
1
+ import { IOSConfig } from 'expo/config-plugins';
2
+ import { withAndroid } from './android';
3
+ import { IOS } from './constants';
4
+ import { withIOS, withPushNotifications } from './ios';
5
+ import { withIOS as withIOSWidget } from './ios-widget';
6
+ import { ensureURLScheme } from './utils/urlScheme';
7
+ import { validateProps } from './validation';
8
+ /**
9
+ * Main Voltra config plugin.
10
+ *
11
+ * This plugin configures your Expo app for:
12
+ * - Live Activities (Dynamic Island + Lock Screen)
13
+ * - Home Screen Widgets (iOS and Android)
14
+ * - Push Notifications for Live Activities (optional)
15
+ */
16
+ const withVoltra = (config, props = {}) => {
17
+ // Validate props at entry point
18
+ validateProps(props);
19
+ // Configure iOS if bundleIdentifier is available
20
+ if (config.ios?.bundleIdentifier) {
21
+ // Use deploymentTarget from props if provided, otherwise fall back to default
22
+ const deploymentTarget = props.deploymentTarget || IOS.DEPLOYMENT_TARGET;
23
+ // Use custom targetName if provided, otherwise fall back to default "{AppName}LiveActivity"
24
+ const targetName = props.targetName || `${IOSConfig.XcodeUtils.sanitizedName(config.name)}LiveActivity`;
25
+ const bundleIdentifier = `${config.ios.bundleIdentifier}.${targetName}`;
26
+ // Extract version and buildNumber from config, defaulting to Expo defaults
27
+ const version = config.version || '1.0.0';
28
+ const buildNumber = config.ios?.buildNumber || '1';
29
+ // Ensure URL scheme is set for widget deep linking
30
+ config = ensureURLScheme(config);
31
+ // Derive a default keychainGroup from bundle identifier when any widget uses server-driven updates
32
+ const hasServerDrivenWidgets = props?.widgets?.some((w) => w.serverUpdate) ?? false;
33
+ const keychainGroup = props?.keychainGroup ??
34
+ (hasServerDrivenWidgets ? `$(AppIdentifierPrefix)${config.ios?.bundleIdentifier}` : undefined);
35
+ // Configure iOS main app (Info.plist, entitlements, EAS)
36
+ config = withIOS(config, {
37
+ groupIdentifier: props?.groupIdentifier,
38
+ widgetIds: props?.widgets && props.widgets.length > 0 ? props.widgets.map((w) => w.id) : undefined,
39
+ widgets: props?.widgets,
40
+ keychainGroup,
41
+ });
42
+ // Configure iOS widget extension (files, xcode, podfile, plist, eas)
43
+ config = withIOSWidget(config, {
44
+ targetName,
45
+ bundleIdentifier,
46
+ deploymentTarget,
47
+ widgets: props?.widgets,
48
+ version,
49
+ buildNumber,
50
+ ...(props?.groupIdentifier ? { groupIdentifier: props.groupIdentifier } : {}),
51
+ ...(keychainGroup ? { keychainGroup } : {}),
52
+ ...(props?.fonts ? { fonts: props.fonts } : {}),
53
+ });
54
+ }
55
+ // Apply Android configuration (files, manifest)
56
+ if (props.android) {
57
+ config = withAndroid(config, {
58
+ widgets: props.android.widgets ?? [],
59
+ ...(props?.fonts ? { fonts: props.fonts } : {}),
60
+ });
61
+ }
62
+ // Optionally enable push notifications
63
+ if (props.enablePushNotifications) {
64
+ config = withPushNotifications(config);
65
+ }
66
+ return config;
67
+ };
68
+ export default withVoltra;
69
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { addApplicationGroupsEntitlement } from '../utils/entitlements';
2
+ /**
3
+ * Configures main app for EAS builds.
4
+ *
5
+ * This adds the app group entitlement to the main app's entitlements
6
+ * so that EAS can properly configure provisioning profiles.
7
+ */
8
+ export const configureEas = (config, props = {}) => {
9
+ if (!props.groupIdentifier) {
10
+ // No group identifier provided, skip EAS configuration
11
+ return config;
12
+ }
13
+ // Ensure ios.entitlements exists in config for EAS to detect
14
+ if (!config.ios) {
15
+ config.ios = {};
16
+ }
17
+ if (!config.ios.entitlements) {
18
+ config.ios.entitlements = {};
19
+ }
20
+ // Add app groups entitlement for EAS
21
+ addApplicationGroupsEntitlement(config.ios.entitlements, props.groupIdentifier);
22
+ return config;
23
+ };
24
+ //# sourceMappingURL=eas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eas.js","sourceRoot":"","sources":["../../../src/ios/eas.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,+BAA+B,EAAE,MAAM,uBAAuB,CAAA;AAMvE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAoC,CAAC,MAAM,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE;IAClF,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC;QAC3B,uDAAuD;QACvD,OAAO,MAAM,CAAA;IACf,CAAC;IAED,6DAA6D;IAC7D,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QAChB,MAAM,CAAC,GAAG,GAAG,EAAE,CAAA;IACjB,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC7B,MAAM,CAAC,GAAG,CAAC,YAAY,GAAG,EAAE,CAAA;IAC9B,CAAC;IAED,qCAAqC;IACrC,+BAA+B,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,KAAK,CAAC,eAAe,CAAC,CAAA;IAE/E,OAAO,MAAM,CAAA;AACf,CAAC,CAAA"}
@@ -0,0 +1,42 @@
1
+ import { addApplicationGroupsEntitlement } from '../utils/entitlements';
2
+ /**
3
+ * Configures main app entitlements for app groups and keychain sharing.
4
+ *
5
+ * This adds:
6
+ * - com.apple.security.application-groups entitlement for data sharing
7
+ * - keychain-access-groups entitlement for shared credential access (if keychainGroup provided)
8
+ */
9
+ export const configureEntitlements = (config, props = {}) => {
10
+ if (!props.groupIdentifier && !props.keychainGroup) {
11
+ // Nothing to configure
12
+ return config;
13
+ }
14
+ if (!config.ios) {
15
+ config.ios = {};
16
+ }
17
+ if (!config.ios.entitlements) {
18
+ config.ios.entitlements = {};
19
+ }
20
+ if (props.groupIdentifier) {
21
+ addApplicationGroupsEntitlement(config.ios.entitlements, props.groupIdentifier);
22
+ }
23
+ if (props.keychainGroup) {
24
+ addKeychainAccessGroupEntitlement(config.ios.entitlements, props.keychainGroup);
25
+ }
26
+ return config;
27
+ };
28
+ /**
29
+ * Adds keychain-access-groups entitlement to an entitlements object.
30
+ * Ensures the group list is deduped and preserves existing order.
31
+ */
32
+ function addKeychainAccessGroupEntitlement(entitlements, keychainGroup) {
33
+ const existingGroups = (entitlements['keychain-access-groups'] ?? []).filter(Boolean);
34
+ const deduped = Array.from(new Set(existingGroups));
35
+ if (deduped.includes(keychainGroup)) {
36
+ entitlements['keychain-access-groups'] = deduped;
37
+ return entitlements;
38
+ }
39
+ entitlements['keychain-access-groups'] = [...deduped, keychainGroup];
40
+ return entitlements;
41
+ }
42
+ //# sourceMappingURL=entitlements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entitlements.js","sourceRoot":"","sources":["../../../src/ios/entitlements.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,+BAA+B,EAAE,MAAM,uBAAuB,CAAA;AAOvE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAA6C,CAAC,MAAM,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE;IACpG,IAAI,CAAC,KAAK,CAAC,eAAe,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;QACnD,uBAAuB;QACvB,OAAO,MAAM,CAAA;IACf,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QAChB,MAAM,CAAC,GAAG,GAAG,EAAE,CAAA;IACjB,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC7B,MAAM,CAAC,GAAG,CAAC,YAAY,GAAG,EAAE,CAAA;IAC9B,CAAC;IAED,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC;QAC1B,+BAA+B,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,KAAK,CAAC,eAAe,CAAC,CAAA;IACjF,CAAC;IAED,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;QACxB,iCAAiC,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,KAAK,CAAC,aAAa,CAAC,CAAA;IACjF,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAED;;;GAGG;AACH,SAAS,iCAAiC,CACxC,YAAiC,EACjC,aAAqB;IAErB,MAAM,cAAc,GAAG,CAAE,YAAY,CAAC,wBAAwB,CAAc,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACnG,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,cAAc,CAAC,CAAC,CAAA;IAEnD,IAAI,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QACpC,YAAY,CAAC,wBAAwB,CAAC,GAAG,OAAO,CAAA;QAChD,OAAO,YAAY,CAAA;IACrB,CAAC;IAED,YAAY,CAAC,wBAAwB,CAAC,GAAG,CAAC,GAAG,OAAO,EAAE,aAAa,CAAC,CAAA;IACpE,OAAO,YAAY,CAAA;AACrB,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { configureEas } from './eas';
2
+ import { configureEntitlements } from './entitlements';
3
+ import { configureInfoPlist } from './infoPlist';
4
+ /**
5
+ * Main iOS app configuration.
6
+ *
7
+ * This configures the main app (not the widget extension) for:
8
+ * - Live Activities support (Info.plist)
9
+ * - App groups for widget communication (entitlements)
10
+ * - Keychain sharing for widget server credentials (entitlements)
11
+ * - EAS build configuration
12
+ */
13
+ export function withIOS(config, props) {
14
+ // Configure Info.plist
15
+ config = configureInfoPlist(config, {
16
+ groupIdentifier: props.groupIdentifier,
17
+ widgetIds: props.widgetIds,
18
+ widgets: props.widgets,
19
+ keychainGroup: props.keychainGroup,
20
+ });
21
+ // Configure entitlements
22
+ config = configureEntitlements(config, {
23
+ groupIdentifier: props.groupIdentifier,
24
+ keychainGroup: props.keychainGroup,
25
+ });
26
+ // Configure EAS
27
+ config = configureEas(config, {
28
+ groupIdentifier: props.groupIdentifier,
29
+ });
30
+ return config;
31
+ }
32
+ // Re-export for convenience
33
+ export { withPushNotifications } from './pushNotifications';
34
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ios/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AACpC,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAShD;;;;;;;;GAQG;AACH,MAAM,UAAU,OAAO,CAAC,MAAkB,EAAE,KAAqB;IAC/D,uBAAuB;IACvB,MAAM,GAAG,kBAAkB,CAAC,MAAM,EAAE;QAClC,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,aAAa,EAAE,KAAK,CAAC,aAAa;KACnC,CAAC,CAAA;IAEF,yBAAyB;IACzB,MAAM,GAAG,qBAAqB,CAAC,MAAM,EAAE;QACrC,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,aAAa,EAAE,KAAK,CAAC,aAAa;KACnC,CAAC,CAAA;IAEF,gBAAgB;IAChB,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE;QAC5B,eAAe,EAAE,KAAK,CAAC,eAAe;KACvC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACf,CAAC;AAED,4BAA4B;AAC5B,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA"}
@@ -0,0 +1,47 @@
1
+ import { withInfoPlist } from '@expo/config-plugins';
2
+ /**
3
+ * Configures main app Info.plist for Live Activities and widgets.
4
+ *
5
+ * This adds:
6
+ * - NSSupportsLiveActivities: Enables Live Activities support
7
+ * - Voltra_AppGroupIdentifier: App group ID for widget communication (if provided)
8
+ * - Voltra_WidgetIds: Array of widget IDs for native module access (if provided)
9
+ * - Voltra_WidgetServerUrls: Map of widget IDs to server URLs (if any widgets have serverUpdate)
10
+ * - Voltra_WidgetServerIntervals: Map of widget IDs to update intervals (if any widgets have serverUpdate)
11
+ * - Voltra_KeychainGroup: Keychain access group for shared credentials (if provided)
12
+ */
13
+ export const configureInfoPlist = (config, props = {}) => {
14
+ return withInfoPlist(config, (mod) => {
15
+ mod.modResults.NSSupportsLiveActivities = true;
16
+ mod.modResults.NSSupportsLiveActivitiesFrequentUpdates = false;
17
+ // Only add group identifier if provided
18
+ if (props.groupIdentifier) {
19
+ mod.modResults.Voltra_AppGroupIdentifier = props.groupIdentifier;
20
+ }
21
+ // Store widget IDs in Info.plist for native module to access
22
+ if (props.widgetIds && props.widgetIds.length > 0) {
23
+ mod.modResults.Voltra_WidgetIds = props.widgetIds;
24
+ }
25
+ // Configure server update URLs and intervals for widgets
26
+ if (props.widgets && props.widgets.length > 0) {
27
+ const serverUrls = {};
28
+ const serverIntervals = {};
29
+ for (const widget of props.widgets) {
30
+ if (widget.serverUpdate) {
31
+ serverUrls[widget.id] = widget.serverUpdate.url;
32
+ serverIntervals[widget.id] = widget.serverUpdate.intervalMinutes ?? 15;
33
+ }
34
+ }
35
+ if (Object.keys(serverUrls).length > 0) {
36
+ mod.modResults.Voltra_WidgetServerUrls = serverUrls;
37
+ mod.modResults.Voltra_WidgetServerIntervals = serverIntervals;
38
+ }
39
+ }
40
+ // Store Keychain group identifier for shared credential access
41
+ if (props.keychainGroup) {
42
+ mod.modResults.Voltra_KeychainGroup = props.keychainGroup;
43
+ }
44
+ return mod;
45
+ });
46
+ };
47
+ //# sourceMappingURL=infoPlist.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"infoPlist.js","sourceRoot":"","sources":["../../../src/ios/infoPlist.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAWlE;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAA0C,CAAC,MAAM,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE;IAC9F,OAAO,aAAa,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE;QACnC,GAAG,CAAC,UAAU,CAAC,wBAAwB,GAAG,IAAI,CAAA;QAC9C,GAAG,CAAC,UAAU,CAAC,uCAAuC,GAAG,KAAK,CAAA;QAE9D,wCAAwC;QACxC,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC;YAC1B,GAAG,CAAC,UAAU,CAAC,yBAAyB,GAAG,KAAK,CAAC,eAAe,CAAA;QAClE,CAAC;QAED,6DAA6D;QAC7D,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClD,GAAG,CAAC,UAAU,CAAC,gBAAgB,GAAG,KAAK,CAAC,SAAS,CAAA;QACnD,CAAC;QAED,yDAAyD;QACzD,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9C,MAAM,UAAU,GAA2B,EAAE,CAAA;YAC7C,MAAM,eAAe,GAA2B,EAAE,CAAA;YAElD,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBACnC,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;oBACxB,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAA;oBAC/C,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,eAAe,IAAI,EAAE,CAAA;gBACxE,CAAC;YACH,CAAC;YAED,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvC,GAAG,CAAC,UAAU,CAAC,uBAAuB,GAAG,UAAU,CAAA;gBACnD,GAAG,CAAC,UAAU,CAAC,4BAA4B,GAAG,eAAe,CAAA;YAC/D,CAAC;QACH,CAAC;QAED,+DAA+D;QAC/D,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;YACxB,GAAG,CAAC,UAAU,CAAC,oBAAoB,GAAG,KAAK,CAAC,aAAa,CAAA;QAC3D,CAAC;QAED,OAAO,GAAG,CAAA;IACZ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA"}
@@ -0,0 +1,18 @@
1
+ import { withEntitlementsPlist, withInfoPlist } from '@expo/config-plugins';
2
+ /**
3
+ * Plugin that enables push notification support for Live Activities.
4
+ *
5
+ * This:
6
+ * - Adds the aps-environment entitlement for push notifications
7
+ * - Adds Voltra_EnablePushNotifications flag to Info.plist
8
+ */
9
+ export const withPushNotifications = (config) => withInfoPlist(withEntitlementsPlist(config, (mod) => {
10
+ // NOTE: For App Store builds, provisioning profiles typically inject 'production'.
11
+ // This sets a default for debug/dev builds.
12
+ mod.modResults['aps-environment'] = 'development';
13
+ return mod;
14
+ }), (mod) => {
15
+ mod.modResults['Voltra_EnablePushNotifications'] = true;
16
+ return mod;
17
+ });
18
+ //# sourceMappingURL=pushNotifications.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pushNotifications.js","sourceRoot":"","sources":["../../../src/ios/pushNotifications.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,qBAAqB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEzF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAiB,CAAC,MAAM,EAAE,EAAE,CAC5D,aAAa,CACX,qBAAqB,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE;IACpC,mFAAmF;IACnF,4CAA4C;IAC5C,GAAG,CAAC,UAAU,CAAC,iBAAiB,CAAC,GAAG,aAAa,CAAA;IACjD,OAAO,GAAG,CAAA;AACZ,CAAC,CAAC,EACF,CAAC,GAAG,EAAE,EAAE;IACN,GAAG,CAAC,UAAU,CAAC,gCAAgC,CAAC,GAAG,IAAI,CAAA;IACvD,OAAO,GAAG,CAAA;AACZ,CAAC,CACF,CAAA"}