@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,400 @@
1
+ import type { ProcessedAppConfig } from "../../config/types";
2
+ import type { PluginContext } from "../../plugins/context";
3
+
4
+ /**
5
+ * Gradle transformer for Android build.gradle.kts files
6
+ *
7
+ * Uses regex-based string manipulation since Gradle DSL is complex
8
+ * and AST parsing from JavaScript is unreliable.
9
+ */
10
+ export class GradleTransformer {
11
+ /**
12
+ * Transform the build.gradle files with configuration
13
+ */
14
+ async transform(context: PluginContext, config: ProcessedAppConfig): Promise<void> {
15
+ const { log } = context;
16
+
17
+ log.debug("Transforming build.gradle files...");
18
+
19
+ // Transform app/build.gradle.kts
20
+ await this.transformAppBuildGradle(context, config);
21
+
22
+ // Transform root build.gradle.kts if needed
23
+ await this.transformRootBuildGradle(context, config);
24
+
25
+ log.debug("Gradle transformation complete");
26
+ }
27
+
28
+ /**
29
+ * Transform app/build.gradle.kts
30
+ */
31
+ private async transformAppBuildGradle(context: PluginContext, config: ProcessedAppConfig): Promise<void> {
32
+ const { fs, log, androidPaths } = context;
33
+
34
+ let content: string;
35
+
36
+ try {
37
+ content = await fs.readFile(androidPaths.appBuildGradle);
38
+ } catch {
39
+ log.warn("app/build.gradle.kts not found, creating default");
40
+ content = this.createDefaultAppBuildGradle(config);
41
+ }
42
+
43
+ // Apply transformations
44
+ content = this.applyNamespace(content, config);
45
+ content = this.applyVersionCode(content, config);
46
+ content = this.applyVersionName(content, config);
47
+ content = this.applySdkVersions(content, config);
48
+ content = this.applyDependencies(content, config);
49
+
50
+ await fs.writeFile(androidPaths.appBuildGradle, content);
51
+ }
52
+
53
+ /**
54
+ * Transform root build.gradle.kts
55
+ */
56
+ private async transformRootBuildGradle(context: PluginContext, _config: ProcessedAppConfig): Promise<void> {
57
+ const { fs, androidPaths } = context;
58
+
59
+ let content: string;
60
+
61
+ try {
62
+ content = await fs.readFile(androidPaths.buildGradle);
63
+ } catch {
64
+ // Root build.gradle is optional
65
+ return;
66
+ }
67
+
68
+ // Apply any root-level transformations if needed
69
+ // (e.g., adding classpath dependencies for plugins)
70
+
71
+ await fs.writeFile(androidPaths.buildGradle, content);
72
+ }
73
+
74
+ /**
75
+ * Create default app/build.gradle.kts
76
+ */
77
+ private createDefaultAppBuildGradle(config: ProcessedAppConfig): string {
78
+ const packageName = config.android?.packageName ?? "com.example.app";
79
+ const minSdk = config.android?.minSdkVersion ?? 23;
80
+ const targetSdk = config.android?.targetSdkVersion ?? 34;
81
+ const compileSdk = config.android?.compileSdkVersion ?? 34;
82
+ const versionCode = config.android?.versionCode ?? 1;
83
+ const versionName = config.version;
84
+
85
+ return `plugins {
86
+ alias(libs.plugins.android.application)
87
+ alias(libs.plugins.kotlin.android)
88
+ }
89
+
90
+ android {
91
+ namespace = "${packageName}"
92
+ compileSdk = ${compileSdk}
93
+
94
+ defaultConfig {
95
+ applicationId = "${packageName}"
96
+ minSdk = ${minSdk}
97
+ targetSdk = ${targetSdk}
98
+ versionCode = ${versionCode}
99
+ versionName = "${versionName}"
100
+ }
101
+
102
+ buildTypes {
103
+ release {
104
+ isMinifyEnabled = false
105
+ proguardFiles(
106
+ getDefaultProguardFile("proguard-android-optimize.txt"),
107
+ "proguard-rules.pro"
108
+ )
109
+ }
110
+ }
111
+
112
+ compileOptions {
113
+ sourceCompatibility = JavaVersion.VERSION_17
114
+ targetCompatibility = JavaVersion.VERSION_17
115
+ }
116
+
117
+ kotlinOptions {
118
+ jvmTarget = "17"
119
+ }
120
+ }
121
+
122
+ dependencies {
123
+ implementation(libs.react.native)
124
+ }
125
+ `;
126
+ }
127
+
128
+ /**
129
+ * Apply namespace (package name)
130
+ */
131
+ private applyNamespace(content: string, config: ProcessedAppConfig): string {
132
+ if (!config.android?.packageName) {
133
+ return content;
134
+ }
135
+
136
+ let result = content;
137
+
138
+ // Update namespace
139
+ result = result.replace(/namespace\s*=\s*"[^"]*"/, `namespace = "${config.android.packageName}"`);
140
+
141
+ // Update applicationId
142
+ result = result.replace(/applicationId\s*=\s*"[^"]*"/, `applicationId = "${config.android.packageName}"`);
143
+
144
+ return result;
145
+ }
146
+
147
+ /**
148
+ * Apply version code
149
+ */
150
+ private applyVersionCode(content: string, config: ProcessedAppConfig): string {
151
+ const versionCode = config.android?.versionCode ?? 1;
152
+
153
+ return content.replace(/versionCode\s*=\s*\d+/, `versionCode = ${versionCode}`);
154
+ }
155
+
156
+ /**
157
+ * Apply version name
158
+ */
159
+ private applyVersionName(content: string, config: ProcessedAppConfig): string {
160
+ return content.replace(/versionName\s*=\s*"[^"]*"/, `versionName = "${config.version}"`);
161
+ }
162
+
163
+ /**
164
+ * Apply SDK versions
165
+ */
166
+ private applySdkVersions(content: string, config: ProcessedAppConfig): string {
167
+ let result = content;
168
+
169
+ if (config.android?.compileSdkVersion) {
170
+ result = result.replace(/compileSdk\s*=\s*\d+/, `compileSdk = ${config.android.compileSdkVersion}`);
171
+ }
172
+
173
+ if (config.android?.minSdkVersion) {
174
+ result = result.replace(/minSdk\s*=\s*\d+/, `minSdk = ${config.android.minSdkVersion}`);
175
+ }
176
+
177
+ if (config.android?.targetSdkVersion) {
178
+ result = result.replace(/targetSdk\s*=\s*\d+/, `targetSdk = ${config.android.targetSdkVersion}`);
179
+ }
180
+
181
+ return result;
182
+ }
183
+
184
+ /**
185
+ * Apply dependencies
186
+ */
187
+ private applyDependencies(content: string, config: ProcessedAppConfig): string {
188
+ if (config.resolvedGradleDependencies.length === 0) {
189
+ return content;
190
+ }
191
+
192
+ // Find the dependencies block
193
+ const dependenciesMatch = content.match(/dependencies\s*\{([^}]*)\}/s);
194
+
195
+ if (!dependenciesMatch) {
196
+ // Add dependencies block if it doesn't exist
197
+ const depsContent = config.resolvedGradleDependencies.map((dep) => ` implementation("${dep}")`).join("\n");
198
+
199
+ return `${content}\ndependencies {\n${depsContent}\n}\n`;
200
+ }
201
+
202
+ // Check which dependencies need to be added
203
+ const existingDeps = dependenciesMatch[1];
204
+ const depsToAdd: string[] = [];
205
+
206
+ for (const dep of config.resolvedGradleDependencies) {
207
+ // Extract artifact ID for comparison
208
+ const artifactMatch = dep.match(/:([^:]+):/);
209
+ const artifactId = artifactMatch ? artifactMatch[1] : dep;
210
+
211
+ if (!existingDeps.includes(artifactId)) {
212
+ depsToAdd.push(dep);
213
+ }
214
+ }
215
+
216
+ if (depsToAdd.length === 0) {
217
+ return content;
218
+ }
219
+
220
+ // Insert new dependencies
221
+ const newDeps = depsToAdd.map((dep) => ` implementation("${dep}")`).join("\n");
222
+
223
+ return content.replace(/dependencies\s*\{/, `dependencies {\n${newDeps}`);
224
+ }
225
+
226
+ /**
227
+ * Add a dependency to build.gradle content
228
+ */
229
+ static addDependency(content: string, dependency: string, type = "implementation"): string {
230
+ // Check if dependency already exists
231
+ const artifactMatch = dependency.match(/:([^:]+):/);
232
+ const artifactId = artifactMatch ? artifactMatch[1] : dependency;
233
+
234
+ if (content.includes(artifactId)) {
235
+ return content;
236
+ }
237
+
238
+ // Add to dependencies block
239
+ return content.replace(/dependencies\s*\{/, `dependencies {\n ${type}("${dependency}")`);
240
+ }
241
+
242
+ /**
243
+ * Add a plugin to build.gradle content
244
+ */
245
+ static addPlugin(content: string, plugin: string): string {
246
+ // Check if plugin already exists
247
+ if (content.includes(plugin)) {
248
+ return content;
249
+ }
250
+
251
+ // Add to plugins block
252
+ return content.replace(/plugins\s*\{/, `plugins {\n id("${plugin}")`);
253
+ }
254
+
255
+ /**
256
+ * Set a property in build.gradle content
257
+ */
258
+ static setProperty(content: string, property: string, value: string | number | boolean): string {
259
+ const valueStr = typeof value === "string" ? `"${value}"` : String(value);
260
+ const regex = new RegExp(`${property}\\s*=\\s*[^\\n]+`);
261
+
262
+ if (content.match(regex)) {
263
+ return content.replace(regex, `${property} = ${valueStr}`);
264
+ }
265
+
266
+ // Property doesn't exist, would need context to know where to add it
267
+ return content;
268
+ }
269
+
270
+ /**
271
+ * Add manifest placeholder
272
+ */
273
+ static addManifestPlaceholder(content: string, key: string, value: string): string {
274
+ // Check if manifestPlaceholders block exists
275
+ if (content.includes("manifestPlaceholders")) {
276
+ // Add to existing block
277
+ return content.replace(
278
+ /manifestPlaceholders\s*\+?=\s*mapOf\(/,
279
+ `manifestPlaceholders += mapOf(\n "${key}" to "${value}",`
280
+ );
281
+ }
282
+
283
+ // Add manifestPlaceholders to defaultConfig
284
+ return content.replace(
285
+ /defaultConfig\s*\{/,
286
+ `defaultConfig {\n manifestPlaceholders += mapOf("${key}" to "${value}")`
287
+ );
288
+ }
289
+
290
+ /**
291
+ * Add signing config
292
+ */
293
+ static addSigningConfig(
294
+ content: string,
295
+ name: string,
296
+ config: {
297
+ storeFile: string;
298
+ storePassword?: string;
299
+ keyAlias: string;
300
+ keyPassword?: string;
301
+ }
302
+ ): string {
303
+ const signingBlock = `
304
+ signingConfigs {
305
+ create("${name}") {
306
+ storeFile = file("${config.storeFile}")
307
+ storePassword = ${config.storePassword ? `"${config.storePassword}"` : 'System.getenv("KEYSTORE_PASSWORD")'}
308
+ keyAlias = "${config.keyAlias}"
309
+ keyPassword = ${config.keyPassword ? `"${config.keyPassword}"` : 'System.getenv("KEY_PASSWORD")'}
310
+ }
311
+ }
312
+ `;
313
+
314
+ // Add before buildTypes
315
+ return content.replace(/buildTypes\s*\{/, `${signingBlock}\n buildTypes {`);
316
+ }
317
+
318
+ /**
319
+ * Enable build feature
320
+ */
321
+ static enableBuildFeature(content: string, feature: string): string {
322
+ // Check if buildFeatures block exists
323
+ if (content.includes("buildFeatures")) {
324
+ return content.replace(/buildFeatures\s*\{/, `buildFeatures {\n ${feature} = true`);
325
+ }
326
+
327
+ // Add buildFeatures block after android {
328
+ return content.replace(/android\s*\{/, `android {\n buildFeatures {\n ${feature} = true\n }`);
329
+ }
330
+ }
331
+
332
+ /**
333
+ * Strings.xml transformer for Android
334
+ */
335
+ export class StringsTransformer {
336
+ /**
337
+ * Transform strings.xml with configuration
338
+ */
339
+ async transform(context: PluginContext, config: ProcessedAppConfig): Promise<void> {
340
+ const { fs, log, androidPaths } = context;
341
+
342
+ log.debug("Transforming strings.xml...");
343
+
344
+ let content: string;
345
+
346
+ try {
347
+ content = await fs.readFile(androidPaths.stringsXml);
348
+ } catch {
349
+ content = this.createDefaultStringsXml(config);
350
+ }
351
+
352
+ // Update app_name
353
+ content = content.replace(
354
+ /<string name="app_name">[^<]*<\/string>/,
355
+ `<string name="app_name">${this.escapeXml(config.name)}</string>`
356
+ );
357
+
358
+ await fs.writeFile(androidPaths.stringsXml, content);
359
+
360
+ log.debug("strings.xml transformation complete");
361
+ }
362
+
363
+ /**
364
+ * Create default strings.xml
365
+ */
366
+ private createDefaultStringsXml(config: ProcessedAppConfig): string {
367
+ return `<?xml version="1.0" encoding="utf-8"?>
368
+ <resources>
369
+ <string name="app_name">${this.escapeXml(config.name)}</string>
370
+ </resources>`;
371
+ }
372
+
373
+ /**
374
+ * Escape XML special characters
375
+ */
376
+ private escapeXml(text: string): string {
377
+ return text
378
+ .replace(/&/g, "&amp;")
379
+ .replace(/</g, "&lt;")
380
+ .replace(/>/g, "&gt;")
381
+ .replace(/"/g, "&quot;")
382
+ .replace(/'/g, "&apos;");
383
+ }
384
+
385
+ /**
386
+ * Add a string resource
387
+ */
388
+ static addString(content: string, name: string, value: string): string {
389
+ // Check if string already exists
390
+ if (content.includes(`name="${name}"`)) {
391
+ return content.replace(
392
+ new RegExp(`<string name="${name}">[^<]*</string>`),
393
+ `<string name="${name}">${value}</string>`
394
+ );
395
+ }
396
+
397
+ // Add new string before </resources>
398
+ return content.replace("</resources>", ` <string name="${name}">${value}</string>\n</resources>`);
399
+ }
400
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Android file transformers for Teardown Launchpad
3
+ */
4
+
5
+ export { GradleTransformer, StringsTransformer } from "./gradle";
6
+ export type {
7
+ AndroidActivityXml,
8
+ AndroidApplication,
9
+ AndroidFeature,
10
+ AndroidIntentFilterXml,
11
+ AndroidManifestXml,
12
+ AndroidMetaData,
13
+ AndroidPermission,
14
+ AndroidProviderXml,
15
+ AndroidQueries,
16
+ AndroidReceiverXml,
17
+ AndroidServiceXml,
18
+ } from "./manifest";
19
+ export { AndroidManifestTransformer } from "./manifest";