@teardown/cli 1.2.39 → 2.0.41

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 (260) hide show
  1. package/bin/teardown.js +11 -1
  2. package/package.json +77 -57
  3. package/src/cli/commands/init.ts +254 -0
  4. package/src/cli/commands/plugins.ts +93 -0
  5. package/src/cli/commands/prebuild.ts +168 -0
  6. package/src/cli/commands/run.ts +727 -0
  7. package/src/cli/commands/start.ts +87 -0
  8. package/src/cli/commands/validate.ts +62 -0
  9. package/src/cli/index.ts +59 -0
  10. package/src/config/index.ts +45 -0
  11. package/src/config/loader.ts +366 -0
  12. package/src/config/schema.ts +235 -0
  13. package/src/config/types.ts +322 -0
  14. package/src/index.ts +177 -0
  15. package/src/pipeline/cache.ts +179 -0
  16. package/src/pipeline/index.ts +10 -0
  17. package/src/pipeline/stages.ts +692 -0
  18. package/src/plugins/base.ts +370 -0
  19. package/src/plugins/capabilities/biometrics.ts +64 -0
  20. package/src/plugins/capabilities/bluetooth.ts +86 -0
  21. package/src/plugins/capabilities/calendar.ts +57 -0
  22. package/src/plugins/capabilities/camera.ts +77 -0
  23. package/src/plugins/capabilities/contacts.ts +57 -0
  24. package/src/plugins/capabilities/deep-linking.ts +124 -0
  25. package/src/plugins/capabilities/firebase.ts +138 -0
  26. package/src/plugins/capabilities/index.ts +96 -0
  27. package/src/plugins/capabilities/location.ts +87 -0
  28. package/src/plugins/capabilities/photo-library.ts +80 -0
  29. package/src/plugins/capabilities/push-notifications.ts +98 -0
  30. package/src/plugins/capabilities/sign-in-with-apple.ts +53 -0
  31. package/src/plugins/context.ts +220 -0
  32. package/src/plugins/index.ts +26 -0
  33. package/src/plugins/resolver.ts +321 -0
  34. package/src/templates/generator.ts +507 -0
  35. package/src/templates/index.ts +9 -0
  36. package/src/templates/paths.ts +25 -0
  37. package/src/transformers/android/gradle.ts +400 -0
  38. package/src/transformers/android/index.ts +19 -0
  39. package/src/transformers/android/manifest.ts +506 -0
  40. package/src/transformers/index.ts +39 -0
  41. package/src/transformers/ios/entitlements.ts +283 -0
  42. package/src/transformers/ios/index.ts +10 -0
  43. package/src/transformers/ios/pbxproj.ts +267 -0
  44. package/src/transformers/ios/plist.ts +198 -0
  45. package/src/utils/fs.ts +429 -0
  46. package/src/utils/index.ts +21 -0
  47. package/src/utils/logger.ts +203 -0
  48. package/templates/.gitignore +63 -0
  49. package/templates/Gemfile +3 -0
  50. package/templates/android/app/build.gradle.kts +97 -0
  51. package/templates/android/app/proguard-rules.pro +10 -0
  52. package/templates/android/app/src/main/AndroidManifest.xml +26 -0
  53. package/templates/android/app/src/main/java/com/appname/MainActivity.kt +22 -0
  54. package/templates/android/app/src/main/java/com/appname/MainApplication.kt +44 -0
  55. package/templates/android/app/src/main/res/values/strings.xml +3 -0
  56. package/templates/android/app/src/main/res/values/styles.xml +7 -0
  57. package/templates/android/build.gradle.kts +44 -0
  58. package/templates/android/gradle.properties +39 -0
  59. package/templates/android/settings.gradle.kts +12 -0
  60. package/templates/babel.config.js +15 -0
  61. package/templates/index.js +7 -0
  62. package/templates/ios/.xcode.env +11 -0
  63. package/templates/ios/AppName/AppDelegate.swift +25 -0
  64. package/templates/ios/AppName/AppName-Bridging-Header.h +4 -0
  65. package/templates/ios/AppName/AppName.entitlements +6 -0
  66. package/templates/ios/AppName/Images.xcassets/AppIcon.appiconset/Contents.json +35 -0
  67. package/templates/ios/AppName/Images.xcassets/Contents.json +6 -0
  68. package/templates/ios/AppName/Info.plist +49 -0
  69. package/templates/ios/AppName/LaunchScreen.storyboard +38 -0
  70. package/templates/ios/AppName.xcodeproj/project.pbxproj +402 -0
  71. package/templates/ios/AppName.xcodeproj/xcshareddata/xcschemes/AppName.xcscheme +78 -0
  72. package/templates/ios/Podfile +35 -0
  73. package/templates/metro.config.js +41 -0
  74. package/templates/package.json +57 -0
  75. package/templates/react-native.config.js +8 -0
  76. package/templates/src/app/index.tsx +34 -0
  77. package/templates/src/assets/fonts/.gitkeep +1 -0
  78. package/templates/src/assets/images/.gitkeep +1 -0
  79. package/templates/src/components/ui/accordion.tsx +114 -0
  80. package/templates/src/components/ui/avatar.tsx +75 -0
  81. package/templates/src/components/ui/button.tsx +93 -0
  82. package/templates/src/components/ui/card.tsx +120 -0
  83. package/templates/src/components/ui/checkbox.tsx +133 -0
  84. package/templates/src/components/ui/chip.tsx +95 -0
  85. package/templates/src/components/ui/dialog.tsx +134 -0
  86. package/templates/src/components/ui/divider.tsx +67 -0
  87. package/templates/src/components/ui/error-view.tsx +82 -0
  88. package/templates/src/components/ui/form-field.tsx +101 -0
  89. package/templates/src/components/ui/index.ts +100 -0
  90. package/templates/src/components/ui/popover.tsx +92 -0
  91. package/templates/src/components/ui/pressable-feedback.tsx +88 -0
  92. package/templates/src/components/ui/radio-group.tsx +153 -0
  93. package/templates/src/components/ui/scroll-shadow.tsx +108 -0
  94. package/templates/src/components/ui/select.tsx +165 -0
  95. package/templates/src/components/ui/skeleton-group.tsx +97 -0
  96. package/templates/src/components/ui/skeleton.tsx +87 -0
  97. package/templates/src/components/ui/spinner.tsx +87 -0
  98. package/templates/src/components/ui/surface.tsx +95 -0
  99. package/templates/src/components/ui/switch.tsx +124 -0
  100. package/templates/src/components/ui/tabs.tsx +154 -0
  101. package/templates/src/components/ui/text-field.tsx +106 -0
  102. package/templates/src/components/ui/toast.tsx +129 -0
  103. package/templates/src/contexts/.gitkeep +2 -0
  104. package/templates/src/core/clients/api/api.client.ts +113 -0
  105. package/templates/src/core/clients/api/index.ts +1 -0
  106. package/templates/src/core/clients/storage/index.ts +1 -0
  107. package/templates/src/core/clients/storage/storage.client.ts +121 -0
  108. package/templates/src/core/constants/index.ts +19 -0
  109. package/templates/src/core/core.ts +40 -0
  110. package/templates/src/core/index.ts +10 -0
  111. package/templates/src/global.css +87 -0
  112. package/templates/src/hooks/index.ts +6 -0
  113. package/templates/src/hooks/use-debounce.ts +23 -0
  114. package/templates/src/hooks/use-mounted.ts +21 -0
  115. package/templates/src/index.ts +28 -0
  116. package/templates/src/lib/index.ts +5 -0
  117. package/templates/src/lib/utils.ts +115 -0
  118. package/templates/src/modules/.gitkeep +6 -0
  119. package/templates/src/navigation/index.ts +8 -0
  120. package/templates/src/navigation/navigation-provider.tsx +36 -0
  121. package/templates/src/navigation/router.tsx +137 -0
  122. package/templates/src/providers/app.provider.tsx +29 -0
  123. package/templates/src/providers/index.ts +5 -0
  124. package/templates/src/routes/(tabs)/_layout.tsx +42 -0
  125. package/templates/src/routes/(tabs)/explore.tsx +161 -0
  126. package/templates/src/routes/(tabs)/home.tsx +138 -0
  127. package/templates/src/routes/(tabs)/profile.tsx +151 -0
  128. package/templates/src/routes/_layout.tsx +18 -0
  129. package/templates/src/routes/settings.tsx +194 -0
  130. package/templates/src/screens/auth/index.ts +6 -0
  131. package/templates/src/screens/auth/login.tsx +165 -0
  132. package/templates/src/screens/auth/register.tsx +203 -0
  133. package/templates/src/screens/home.tsx +204 -0
  134. package/templates/src/screens/index.ts +17 -0
  135. package/templates/src/screens/profile.tsx +210 -0
  136. package/templates/src/screens/settings.tsx +216 -0
  137. package/templates/src/screens/welcome.tsx +101 -0
  138. package/templates/src/styles/index.ts +103 -0
  139. package/templates/src/types/common.ts +71 -0
  140. package/templates/src/types/index.ts +5 -0
  141. package/templates/tsconfig.json +14 -0
  142. package/README.md +0 -15
  143. package/assets/favicon.ico +0 -0
  144. package/dist/commands/dev/dev.d.ts +0 -22
  145. package/dist/commands/dev/dev.js +0 -56
  146. package/dist/commands/dev/dev.js.map +0 -1
  147. package/dist/commands/init/init-teardown.d.ts +0 -9
  148. package/dist/commands/init/init-teardown.js +0 -27
  149. package/dist/commands/init/init-teardown.js.map +0 -1
  150. package/dist/index.d.ts +0 -1
  151. package/dist/index.js +0 -21
  152. package/dist/index.js.map +0 -1
  153. package/dist/modules/dev/dev-menu/keyboard-handler.d.ts +0 -21
  154. package/dist/modules/dev/dev-menu/keyboard-handler.js +0 -139
  155. package/dist/modules/dev/dev-menu/keyboard-handler.js.map +0 -1
  156. package/dist/modules/dev/dev-menu/open-debugger-keyboard-handler.d.ts +0 -18
  157. package/dist/modules/dev/dev-menu/open-debugger-keyboard-handler.js +0 -106
  158. package/dist/modules/dev/dev-menu/open-debugger-keyboard-handler.js.map +0 -1
  159. package/dist/modules/dev/dev-server/cdp/cdp.adapter.d.ts +0 -6
  160. package/dist/modules/dev/dev-server/cdp/cdp.adapter.js +0 -13
  161. package/dist/modules/dev/dev-server/cdp/cdp.adapter.js.map +0 -1
  162. package/dist/modules/dev/dev-server/cdp/index.d.ts +0 -2
  163. package/dist/modules/dev/dev-server/cdp/index.js +0 -19
  164. package/dist/modules/dev/dev-server/cdp/index.js.map +0 -1
  165. package/dist/modules/dev/dev-server/cdp/types.d.ts +0 -107
  166. package/dist/modules/dev/dev-server/cdp/types.js +0 -3
  167. package/dist/modules/dev/dev-server/cdp/types.js.map +0 -1
  168. package/dist/modules/dev/dev-server/dev-server-checker.d.ts +0 -22
  169. package/dist/modules/dev/dev-server/dev-server-checker.js +0 -73
  170. package/dist/modules/dev/dev-server/dev-server-checker.js.map +0 -1
  171. package/dist/modules/dev/dev-server/dev-server.d.ts +0 -74
  172. package/dist/modules/dev/dev-server/dev-server.js +0 -272
  173. package/dist/modules/dev/dev-server/dev-server.js.map +0 -1
  174. package/dist/modules/dev/dev-server/inspector/device.d.ts +0 -46
  175. package/dist/modules/dev/dev-server/inspector/device.event-reporter.d.ts +0 -37
  176. package/dist/modules/dev/dev-server/inspector/device.event-reporter.js +0 -166
  177. package/dist/modules/dev/dev-server/inspector/device.event-reporter.js.map +0 -1
  178. package/dist/modules/dev/dev-server/inspector/device.js +0 -578
  179. package/dist/modules/dev/dev-server/inspector/device.js.map +0 -1
  180. package/dist/modules/dev/dev-server/inspector/inspector.d.ts +0 -27
  181. package/dist/modules/dev/dev-server/inspector/inspector.js +0 -225
  182. package/dist/modules/dev/dev-server/inspector/inspector.js.map +0 -1
  183. package/dist/modules/dev/dev-server/inspector/types.d.ts +0 -156
  184. package/dist/modules/dev/dev-server/inspector/types.js +0 -3
  185. package/dist/modules/dev/dev-server/inspector/types.js.map +0 -1
  186. package/dist/modules/dev/dev-server/inspector/wss/servers/debugger-connection.server.d.ts +0 -14
  187. package/dist/modules/dev/dev-server/inspector/wss/servers/debugger-connection.server.js +0 -63
  188. package/dist/modules/dev/dev-server/inspector/wss/servers/debugger-connection.server.js.map +0 -1
  189. package/dist/modules/dev/dev-server/inspector/wss/servers/device-connection.server.d.ts +0 -19
  190. package/dist/modules/dev/dev-server/inspector/wss/servers/device-connection.server.js +0 -66
  191. package/dist/modules/dev/dev-server/inspector/wss/servers/device-connection.server.js.map +0 -1
  192. package/dist/modules/dev/dev-server/plugins/devtools.plugin.d.ts +0 -1
  193. package/dist/modules/dev/dev-server/plugins/devtools.plugin.js +0 -51
  194. package/dist/modules/dev/dev-server/plugins/devtools.plugin.js.map +0 -1
  195. package/dist/modules/dev/dev-server/plugins/favicon.plugin.d.ts +0 -1
  196. package/dist/modules/dev/dev-server/plugins/favicon.plugin.js +0 -19
  197. package/dist/modules/dev/dev-server/plugins/favicon.plugin.js.map +0 -1
  198. package/dist/modules/dev/dev-server/plugins/multipart.plugin.d.ts +0 -1
  199. package/dist/modules/dev/dev-server/plugins/multipart.plugin.js +0 -63
  200. package/dist/modules/dev/dev-server/plugins/multipart.plugin.js.map +0 -1
  201. package/dist/modules/dev/dev-server/plugins/systrace.plugin.d.ts +0 -1
  202. package/dist/modules/dev/dev-server/plugins/systrace.plugin.js +0 -29
  203. package/dist/modules/dev/dev-server/plugins/systrace.plugin.js.map +0 -1
  204. package/dist/modules/dev/dev-server/plugins/types.d.ts +0 -11
  205. package/dist/modules/dev/dev-server/plugins/types.js +0 -3
  206. package/dist/modules/dev/dev-server/plugins/types.js.map +0 -1
  207. package/dist/modules/dev/dev-server/plugins/wss/index.d.ts +0 -3
  208. package/dist/modules/dev/dev-server/plugins/wss/index.js +0 -20
  209. package/dist/modules/dev/dev-server/plugins/wss/index.js.map +0 -1
  210. package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-api.server.d.ts +0 -37
  211. package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-api.server.js +0 -67
  212. package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-api.server.js.map +0 -1
  213. package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-debugger.server.d.ts +0 -63
  214. package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-debugger.server.js +0 -129
  215. package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-debugger.server.js.map +0 -1
  216. package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-dev-client.server.d.ts +0 -32
  217. package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-dev-client.server.js +0 -76
  218. package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-dev-client.server.js.map +0 -1
  219. package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-events.server.d.ts +0 -75
  220. package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-events.server.js +0 -199
  221. package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-events.server.js.map +0 -1
  222. package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-hmr.server.d.ts +0 -44
  223. package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-hmr.server.js +0 -121
  224. package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-hmr.server.js.map +0 -1
  225. package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-message.server.d.ts +0 -135
  226. package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-message.server.js +0 -364
  227. package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-message.server.js.map +0 -1
  228. package/dist/modules/dev/dev-server/plugins/wss/types.d.ts +0 -6
  229. package/dist/modules/dev/dev-server/plugins/wss/types.js +0 -3
  230. package/dist/modules/dev/dev-server/plugins/wss/types.js.map +0 -1
  231. package/dist/modules/dev/dev-server/plugins/wss/web-socket-router.d.ts +0 -32
  232. package/dist/modules/dev/dev-server/plugins/wss/web-socket-router.js +0 -58
  233. package/dist/modules/dev/dev-server/plugins/wss/web-socket-router.js.map +0 -1
  234. package/dist/modules/dev/dev-server/plugins/wss/web-socket-server-adapter.d.ts +0 -13
  235. package/dist/modules/dev/dev-server/plugins/wss/web-socket-server-adapter.js +0 -27
  236. package/dist/modules/dev/dev-server/plugins/wss/web-socket-server-adapter.js.map +0 -1
  237. package/dist/modules/dev/dev-server/plugins/wss/web-socket-server.d.ts +0 -39
  238. package/dist/modules/dev/dev-server/plugins/wss/web-socket-server.js +0 -47
  239. package/dist/modules/dev/dev-server/plugins/wss/web-socket-server.js.map +0 -1
  240. package/dist/modules/dev/dev-server/plugins/wss/wss.plugin.d.ts +0 -24
  241. package/dist/modules/dev/dev-server/plugins/wss/wss.plugin.js +0 -56
  242. package/dist/modules/dev/dev-server/plugins/wss/wss.plugin.js.map +0 -1
  243. package/dist/modules/dev/dev-server/sybmolicate/sybmolicate.plugin.d.ts +0 -7
  244. package/dist/modules/dev/dev-server/sybmolicate/sybmolicate.plugin.js +0 -41
  245. package/dist/modules/dev/dev-server/sybmolicate/sybmolicate.plugin.js.map +0 -1
  246. package/dist/modules/dev/dev-server/sybmolicate/types.d.ts +0 -64
  247. package/dist/modules/dev/dev-server/sybmolicate/types.js +0 -3
  248. package/dist/modules/dev/dev-server/sybmolicate/types.js.map +0 -1
  249. package/dist/modules/dev/terminal/base.terminal.reporter.d.ts +0 -25
  250. package/dist/modules/dev/terminal/base.terminal.reporter.js +0 -79
  251. package/dist/modules/dev/terminal/base.terminal.reporter.js.map +0 -1
  252. package/dist/modules/dev/terminal/terminal.reporter.d.ts +0 -13
  253. package/dist/modules/dev/terminal/terminal.reporter.js +0 -83
  254. package/dist/modules/dev/terminal/terminal.reporter.js.map +0 -1
  255. package/dist/modules/dev/types.d.ts +0 -20
  256. package/dist/modules/dev/types.js +0 -3
  257. package/dist/modules/dev/types.js.map +0 -1
  258. package/dist/modules/dev/utils/log.d.ts +0 -23
  259. package/dist/modules/dev/utils/log.js +0 -74
  260. package/dist/modules/dev/utils/log.js.map +0 -1
@@ -0,0 +1,283 @@
1
+ import * as plist from "simple-plist";
2
+ import type { ProcessedAppConfig } from "../../config/types";
3
+ import type { PluginContext } from "../../plugins/context";
4
+
5
+ /**
6
+ * iOS Entitlements structure
7
+ */
8
+ export interface EntitlementsContent {
9
+ /** Push notification environment */
10
+ "aps-environment"?: "development" | "production";
11
+
12
+ /** Sign in with Apple */
13
+ "com.apple.developer.applesignin"?: string[];
14
+
15
+ /** App Groups for data sharing */
16
+ "com.apple.security.application-groups"?: string[];
17
+
18
+ /** Associated Domains (Universal Links) */
19
+ "com.apple.developer.associated-domains"?: string[];
20
+
21
+ /** HealthKit */
22
+ "com.apple.developer.healthkit"?: boolean;
23
+ "com.apple.developer.healthkit.background-delivery"?: boolean;
24
+ "com.apple.developer.healthkit.access"?: string[];
25
+
26
+ /** HomeKit */
27
+ "com.apple.developer.homekit"?: boolean;
28
+
29
+ /** Siri */
30
+ "com.apple.developer.siri"?: boolean;
31
+
32
+ /** NFC */
33
+ "com.apple.developer.nfc.readersession.formats"?: string[];
34
+
35
+ /** Apple Pay */
36
+ "com.apple.developer.in-app-payments"?: string[];
37
+
38
+ /** iCloud */
39
+ "com.apple.developer.icloud-container-identifiers"?: string[];
40
+ "com.apple.developer.icloud-services"?: string[];
41
+ "com.apple.developer.ubiquity-container-identifiers"?: string[];
42
+
43
+ /** WiFi */
44
+ "com.apple.developer.networking.wifi-info"?: boolean;
45
+
46
+ /** Background Modes */
47
+ "com.apple.developer.kernel.extended-virtual-addressing"?: boolean;
48
+
49
+ /** Keychain Sharing */
50
+ "keychain-access-groups"?: string[];
51
+
52
+ /** Additional entitlements */
53
+ [key: string]: unknown;
54
+ }
55
+
56
+ /**
57
+ * Entitlements transformer for iOS entitlements files
58
+ */
59
+ export class EntitlementsTransformer {
60
+ /**
61
+ * Transform the entitlements file with configuration
62
+ */
63
+ async transform(context: PluginContext, config: ProcessedAppConfig): Promise<void> {
64
+ const { fs, log, iosPaths } = context;
65
+
66
+ log.debug("Transforming entitlements...");
67
+
68
+ let existingEntitlements: EntitlementsContent;
69
+
70
+ try {
71
+ const content = await fs.readFile(iosPaths.entitlements);
72
+ existingEntitlements = plist.parse(content) as EntitlementsContent;
73
+ } catch {
74
+ // Create default entitlements if doesn't exist
75
+ existingEntitlements = this.createDefaultEntitlements();
76
+ }
77
+
78
+ // Apply configuration
79
+ const updatedEntitlements = this.applyConfig(existingEntitlements, config);
80
+
81
+ // Write back
82
+ const entitlementsContent = plist.stringify(updatedEntitlements);
83
+ await fs.writeFile(iosPaths.entitlements, entitlementsContent);
84
+
85
+ log.debug("Entitlements transformation complete");
86
+ }
87
+
88
+ /**
89
+ * Create default entitlements content
90
+ */
91
+ private createDefaultEntitlements(): EntitlementsContent {
92
+ return {};
93
+ }
94
+
95
+ /**
96
+ * Apply configuration to existing entitlements
97
+ */
98
+ private applyConfig(entitlements: EntitlementsContent, config: ProcessedAppConfig): EntitlementsContent {
99
+ // Apply plugin-resolved entitlements
100
+ for (const [key, value] of Object.entries(config.resolvedEntitlements)) {
101
+ // Handle array entitlements by merging
102
+ if (Array.isArray(value) && Array.isArray(entitlements[key])) {
103
+ const existing = entitlements[key] as unknown[];
104
+ const merged = [...new Set([...existing, ...value])];
105
+ entitlements[key] = merged;
106
+ } else {
107
+ entitlements[key] = value;
108
+ }
109
+ }
110
+
111
+ // Apply custom entitlements from config
112
+ if (config.ios?.entitlements) {
113
+ for (const [key, value] of Object.entries(config.ios.entitlements)) {
114
+ if (Array.isArray(value) && Array.isArray(entitlements[key])) {
115
+ const existing = entitlements[key] as unknown[];
116
+ const merged = [...new Set([...existing, ...value])];
117
+ entitlements[key] = merged;
118
+ } else {
119
+ entitlements[key] = value;
120
+ }
121
+ }
122
+ }
123
+
124
+ return entitlements;
125
+ }
126
+
127
+ /**
128
+ * Add associated domain entitlement
129
+ */
130
+ static addAssociatedDomain(
131
+ entitlements: EntitlementsContent,
132
+ domain: string,
133
+ type: "applinks" | "webcredentials" | "activitycontinuation" = "applinks"
134
+ ): EntitlementsContent {
135
+ const key = "com.apple.developer.associated-domains";
136
+ const domainEntry = `${type}:${domain}`;
137
+
138
+ if (!entitlements[key]) {
139
+ entitlements[key] = [];
140
+ }
141
+
142
+ if (!entitlements[key]?.includes(domainEntry)) {
143
+ entitlements[key]?.push(domainEntry);
144
+ }
145
+
146
+ return entitlements;
147
+ }
148
+
149
+ /**
150
+ * Add app group entitlement
151
+ */
152
+ static addAppGroup(entitlements: EntitlementsContent, groupId: string): EntitlementsContent {
153
+ const key = "com.apple.security.application-groups";
154
+
155
+ if (!entitlements[key]) {
156
+ entitlements[key] = [];
157
+ }
158
+
159
+ if (!entitlements[key]?.includes(groupId)) {
160
+ entitlements[key]?.push(groupId);
161
+ }
162
+
163
+ return entitlements;
164
+ }
165
+
166
+ /**
167
+ * Enable push notifications
168
+ */
169
+ static enablePushNotifications(
170
+ entitlements: EntitlementsContent,
171
+ environment: "development" | "production"
172
+ ): EntitlementsContent {
173
+ entitlements["aps-environment"] = environment;
174
+ return entitlements;
175
+ }
176
+
177
+ /**
178
+ * Enable Sign in with Apple
179
+ */
180
+ static enableSignInWithApple(entitlements: EntitlementsContent): EntitlementsContent {
181
+ entitlements["com.apple.developer.applesignin"] = ["Default"];
182
+ return entitlements;
183
+ }
184
+
185
+ /**
186
+ * Enable HealthKit
187
+ */
188
+ static enableHealthKit(
189
+ entitlements: EntitlementsContent,
190
+ options: { backgroundDelivery?: boolean; clinicalRecords?: boolean } = {}
191
+ ): EntitlementsContent {
192
+ entitlements["com.apple.developer.healthkit"] = true;
193
+
194
+ if (options.backgroundDelivery) {
195
+ entitlements["com.apple.developer.healthkit.background-delivery"] = true;
196
+ }
197
+
198
+ if (options.clinicalRecords) {
199
+ const access = entitlements["com.apple.developer.healthkit.access"] ?? [];
200
+ if (!access.includes("health-records")) {
201
+ access.push("health-records");
202
+ }
203
+ entitlements["com.apple.developer.healthkit.access"] = access;
204
+ }
205
+
206
+ return entitlements;
207
+ }
208
+
209
+ /**
210
+ * Enable HomeKit
211
+ */
212
+ static enableHomeKit(entitlements: EntitlementsContent): EntitlementsContent {
213
+ entitlements["com.apple.developer.homekit"] = true;
214
+ return entitlements;
215
+ }
216
+
217
+ /**
218
+ * Enable Siri
219
+ */
220
+ static enableSiri(entitlements: EntitlementsContent): EntitlementsContent {
221
+ entitlements["com.apple.developer.siri"] = true;
222
+ return entitlements;
223
+ }
224
+
225
+ /**
226
+ * Enable NFC
227
+ */
228
+ static enableNFC(entitlements: EntitlementsContent, formats: ("NDEF" | "TAG")[] = ["NDEF"]): EntitlementsContent {
229
+ entitlements["com.apple.developer.nfc.readersession.formats"] = formats;
230
+ return entitlements;
231
+ }
232
+
233
+ /**
234
+ * Add Apple Pay merchant IDs
235
+ */
236
+ static addApplePayMerchants(entitlements: EntitlementsContent, merchantIds: string[]): EntitlementsContent {
237
+ entitlements["com.apple.developer.in-app-payments"] = merchantIds;
238
+ return entitlements;
239
+ }
240
+
241
+ /**
242
+ * Enable WiFi info access
243
+ */
244
+ static enableWiFiInfo(entitlements: EntitlementsContent): EntitlementsContent {
245
+ entitlements["com.apple.developer.networking.wifi-info"] = true;
246
+ return entitlements;
247
+ }
248
+
249
+ /**
250
+ * Add keychain access group
251
+ */
252
+ static addKeychainAccessGroup(entitlements: EntitlementsContent, groupId: string): EntitlementsContent {
253
+ const key = "keychain-access-groups";
254
+
255
+ if (!entitlements[key]) {
256
+ entitlements[key] = [];
257
+ }
258
+
259
+ if (!entitlements[key]?.includes(groupId)) {
260
+ entitlements[key]?.push(groupId);
261
+ }
262
+
263
+ return entitlements;
264
+ }
265
+
266
+ /**
267
+ * Read and parse an existing entitlements file
268
+ */
269
+ static async readEntitlements(filePath: string): Promise<EntitlementsContent> {
270
+ const fs = await import("node:fs/promises");
271
+ const content = await fs.readFile(filePath, "utf-8");
272
+ return plist.parse(content) as EntitlementsContent;
273
+ }
274
+
275
+ /**
276
+ * Write entitlements content to file
277
+ */
278
+ static async writeEntitlements(filePath: string, content: EntitlementsContent): Promise<void> {
279
+ const fs = await import("node:fs/promises");
280
+ const entitlementsContent = plist.stringify(content);
281
+ await fs.writeFile(filePath, entitlementsContent, "utf-8");
282
+ }
283
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * iOS file transformers for Teardown Launchpad
3
+ */
4
+
5
+ export type { EntitlementsContent } from "./entitlements";
6
+ export { EntitlementsTransformer } from "./entitlements";
7
+ export type { BuildSettings } from "./pbxproj";
8
+ export { PbxprojTransformer, XcodeProjectManipulator } from "./pbxproj";
9
+ export type { CFBundleURLType, InfoPlistContent } from "./plist";
10
+ export { PlistTransformer } from "./plist";
@@ -0,0 +1,267 @@
1
+ import type { ProcessedAppConfig } from "../../config/types";
2
+ import type { PluginContext } from "../../plugins/context";
3
+
4
+ /**
5
+ * Build configuration settings
6
+ */
7
+ export interface BuildSettings {
8
+ PRODUCT_BUNDLE_IDENTIFIER?: string;
9
+ INFOPLIST_FILE?: string;
10
+ CODE_SIGN_ENTITLEMENTS?: string;
11
+ CODE_SIGN_STYLE?: string;
12
+ DEVELOPMENT_TEAM?: string;
13
+ PROVISIONING_PROFILE_SPECIFIER?: string;
14
+ SWIFT_VERSION?: string;
15
+ IPHONEOS_DEPLOYMENT_TARGET?: string;
16
+ TARGETED_DEVICE_FAMILY?: string;
17
+ ASSETCATALOG_COMPILER_APPICON_NAME?: string;
18
+ [key: string]: string | undefined;
19
+ }
20
+
21
+ /**
22
+ * Xcode project file transformer
23
+ *
24
+ * Note: For full AST manipulation, we would use @bacons/xcode.
25
+ * This implementation provides basic string-based transformations
26
+ * for common modifications without requiring the full library.
27
+ */
28
+ export class PbxprojTransformer {
29
+ /**
30
+ * Transform the Xcode project file with configuration
31
+ */
32
+ async transform(context: PluginContext, config: ProcessedAppConfig): Promise<void> {
33
+ const { fs, log, iosPaths } = context;
34
+
35
+ log.debug("Transforming Xcode project...");
36
+
37
+ let content: string;
38
+
39
+ try {
40
+ content = await fs.readFile(iosPaths.pbxproj);
41
+ } catch {
42
+ log.warn("Xcode project file not found, skipping pbxproj transformation");
43
+ return;
44
+ }
45
+
46
+ // Apply transformations
47
+ content = this.applyBundleIdentifier(content, config);
48
+ content = this.applyBuildNumber(content, config);
49
+ content = this.applyDeploymentTarget(content, config);
50
+ content = this.applyDevelopmentTeam(content, config);
51
+ content = this.applyCodeSigningStyle(content, config);
52
+ content = this.applyFrameworks(content, config);
53
+
54
+ // Write back
55
+ await fs.writeFile(iosPaths.pbxproj, content);
56
+
57
+ log.debug("Xcode project transformation complete");
58
+ }
59
+
60
+ /**
61
+ * Update bundle identifier in project
62
+ */
63
+ private applyBundleIdentifier(content: string, config: ProcessedAppConfig): string {
64
+ if (!config.ios?.bundleIdentifier) {
65
+ return content;
66
+ }
67
+
68
+ // Replace PRODUCT_BUNDLE_IDENTIFIER in build settings
69
+ return content.replace(
70
+ /PRODUCT_BUNDLE_IDENTIFIER\s*=\s*"[^"]*"/g,
71
+ `PRODUCT_BUNDLE_IDENTIFIER = "${config.ios.bundleIdentifier}"`
72
+ );
73
+ }
74
+
75
+ /**
76
+ * Update build number in project
77
+ */
78
+ private applyBuildNumber(content: string, config: ProcessedAppConfig): string {
79
+ const buildNumber = config.ios?.buildNumber ?? 1;
80
+
81
+ return content.replace(/CURRENT_PROJECT_VERSION\s*=\s*\d+/g, `CURRENT_PROJECT_VERSION = ${buildNumber}`);
82
+ }
83
+
84
+ /**
85
+ * Update deployment target
86
+ */
87
+ private applyDeploymentTarget(content: string, config: ProcessedAppConfig): string {
88
+ const target = config.ios?.deploymentTarget ?? "15.0";
89
+
90
+ return content.replace(/IPHONEOS_DEPLOYMENT_TARGET\s*=\s*[\d.]+/g, `IPHONEOS_DEPLOYMENT_TARGET = ${target}`);
91
+ }
92
+
93
+ /**
94
+ * Update development team
95
+ */
96
+ private applyDevelopmentTeam(content: string, config: ProcessedAppConfig): string {
97
+ if (!config.ios?.developmentTeamId) {
98
+ return content;
99
+ }
100
+
101
+ // Add or update DEVELOPMENT_TEAM
102
+ if (content.includes("DEVELOPMENT_TEAM")) {
103
+ return content.replace(
104
+ /DEVELOPMENT_TEAM\s*=\s*"?[^";]*"?/g,
105
+ `DEVELOPMENT_TEAM = ${config.ios.developmentTeamId}`
106
+ );
107
+ }
108
+
109
+ // Add DEVELOPMENT_TEAM to build settings (simplified - adds to first occurrence)
110
+ return content.replace(
111
+ /(buildSettings\s*=\s*\{)/,
112
+ `$1\n\t\t\t\tDEVELOPMENT_TEAM = ${config.ios.developmentTeamId};`
113
+ );
114
+ }
115
+
116
+ /**
117
+ * Update code signing style
118
+ */
119
+ private applyCodeSigningStyle(content: string, config: ProcessedAppConfig): string {
120
+ const style = config.ios?.codeSigningStyle ?? "Automatic";
121
+
122
+ if (content.includes("CODE_SIGN_STYLE")) {
123
+ return content.replace(/CODE_SIGN_STYLE\s*=\s*\w+/g, `CODE_SIGN_STYLE = ${style}`);
124
+ }
125
+
126
+ return content;
127
+ }
128
+
129
+ /**
130
+ * Add frameworks to the project
131
+ */
132
+ private applyFrameworks(content: string, config: ProcessedAppConfig): string {
133
+ // This is a simplified implementation
134
+ // Full implementation would use @bacons/xcode for proper AST manipulation
135
+
136
+ const frameworksToAdd = config.resolvedFrameworks;
137
+
138
+ if (frameworksToAdd.length === 0) {
139
+ return content;
140
+ }
141
+
142
+ // Log frameworks that need to be added (for now, just informational)
143
+ // Real implementation would parse the pbxproj and add PBXBuildFile entries
144
+ for (const framework of frameworksToAdd) {
145
+ if (!content.includes(`${framework}.framework`)) {
146
+ // Framework not in project - would need to add it
147
+ // This requires full pbxproj parsing which is complex
148
+ }
149
+ }
150
+
151
+ return content;
152
+ }
153
+
154
+ /**
155
+ * Add a source file to the project
156
+ * Note: Simplified implementation - full version would use @bacons/xcode
157
+ */
158
+ static addSourceFile(_projectPath: string, _filePath: string): void {
159
+ // This would use @bacons/xcode to properly add the file
160
+ // For now, this is a placeholder
161
+ throw new Error("addSourceFile requires @bacons/xcode library integration");
162
+ }
163
+
164
+ /**
165
+ * Add a framework to the project
166
+ * Note: Simplified implementation - full version would use @bacons/xcode
167
+ */
168
+ static addFramework(_projectPath: string, _frameworkName: string): void {
169
+ // This would use @bacons/xcode to properly add the framework
170
+ throw new Error("addFramework requires @bacons/xcode library integration");
171
+ }
172
+
173
+ /**
174
+ * Update a build setting for all configurations
175
+ */
176
+ static updateBuildSetting(content: string, setting: string, value: string): string {
177
+ const regex = new RegExp(`${setting}\\s*=\\s*"?[^";]*"?`, "g");
178
+
179
+ if (content.match(regex)) {
180
+ // Update existing setting
181
+ return content.replace(regex, `${setting} = "${value}"`);
182
+ }
183
+
184
+ // Setting doesn't exist - would need to add it
185
+ return content;
186
+ }
187
+
188
+ /**
189
+ * Get the current value of a build setting
190
+ */
191
+ static getBuildSetting(content: string, setting: string): string | null {
192
+ const regex = new RegExp(`${setting}\\s*=\\s*"?([^";]*)"?`);
193
+ const match = content.match(regex);
194
+ return match ? match[1] : null;
195
+ }
196
+ }
197
+
198
+ /**
199
+ * Xcode project manipulation using @bacons/xcode
200
+ * This class provides full AST-based manipulation
201
+ */
202
+ export class XcodeProjectManipulator {
203
+ private projectPath: string;
204
+
205
+ constructor(projectPath: string) {
206
+ this.projectPath = projectPath;
207
+ }
208
+
209
+ /**
210
+ * Get the project path
211
+ */
212
+ getProjectPath(): string {
213
+ return this.projectPath;
214
+ }
215
+
216
+ /**
217
+ * Open and parse the project
218
+ * Requires @bacons/xcode to be properly integrated
219
+ */
220
+ async open(): Promise<void> {
221
+ // This would use:
222
+ // import { XcodeProject } from '@bacons/xcode';
223
+ // this.project = XcodeProject.open(this.projectPath);
224
+ }
225
+
226
+ /**
227
+ * Add a source file to a target
228
+ */
229
+ async addSourceFile(_targetName: string, _filePath: string): Promise<void> {
230
+ // project.addSourceFile(filePath);
231
+ }
232
+
233
+ /**
234
+ * Add a framework to a target
235
+ */
236
+ async addFramework(_targetName: string, _frameworkName: string): Promise<void> {
237
+ // project.addFramework(frameworkName);
238
+ }
239
+
240
+ /**
241
+ * Add a build phase script
242
+ */
243
+ async addBuildPhaseScript(_targetName: string, _scriptName: string, _script: string): Promise<void> {
244
+ // const target = project.getTarget(targetName);
245
+ // target.addBuildPhase('PBXShellScriptBuildPhase', scriptName, script);
246
+ }
247
+
248
+ /**
249
+ * Update build settings for a configuration
250
+ */
251
+ async updateBuildSettings(
252
+ _targetName: string,
253
+ _configuration: "Debug" | "Release",
254
+ _settings: BuildSettings
255
+ ): Promise<void> {
256
+ // const target = project.getTarget(targetName);
257
+ // const config = target.getBuildConfiguration(configuration);
258
+ // Object.assign(config.buildSettings, settings);
259
+ }
260
+
261
+ /**
262
+ * Save the project
263
+ */
264
+ async save(): Promise<void> {
265
+ // project.save();
266
+ }
267
+ }