create-cmp-cli 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +232 -0
  3. package/bin/create-cmp.mjs +91 -0
  4. package/options.schema.json +110 -0
  5. package/package.json +52 -0
  6. package/src/bootstrap/checks.mjs +283 -0
  7. package/src/bootstrap/exec.mjs +90 -0
  8. package/src/commands/clean.mjs +195 -0
  9. package/src/commands/create.mjs +223 -0
  10. package/src/commands/doctor.mjs +256 -0
  11. package/src/commands/upgrade.mjs +196 -0
  12. package/src/commands/verify.mjs +94 -0
  13. package/src/doctor.mjs +109 -0
  14. package/src/lib/args.mjs +38 -0
  15. package/src/lib/clean.mjs +72 -0
  16. package/src/lib/fsutil.mjs +90 -0
  17. package/src/lib/log.mjs +40 -0
  18. package/src/lib/project-doctor.mjs +329 -0
  19. package/src/lib/registry.mjs +102 -0
  20. package/src/lib/rename.mjs +116 -0
  21. package/src/lib/schema.mjs +123 -0
  22. package/src/lib/toggle.mjs +130 -0
  23. package/src/lib/tokens.mjs +96 -0
  24. package/src/lib/toml.mjs +137 -0
  25. package/src/lib/upgrade.mjs +159 -0
  26. package/src/lib/verify.mjs +97 -0
  27. package/src/scaffold.mjs +347 -0
  28. package/src/verify.mjs +4 -0
  29. package/src/versions/registry.json +42 -0
  30. package/template/.github/workflows/verify.yml +70 -0
  31. package/template/build.gradle.kts +17 -0
  32. package/template/composeApp/build.gradle.kts +257 -0
  33. package/template/composeApp/google-services.json +29 -0
  34. package/template/composeApp/proguard-rules.pro +34 -0
  35. package/template/composeApp/src/androidDebug/AndroidManifest.xml +13 -0
  36. package/template/composeApp/src/androidDebug/kotlin/com/example/app/inspector/ComposeRootRegistry.kt +40 -0
  37. package/template/composeApp/src/androidDebug/kotlin/com/example/app/inspector/InspectorCatalog.kt +80 -0
  38. package/template/composeApp/src/androidDebug/kotlin/com/example/app/inspector/InspectorHttpServer.kt +322 -0
  39. package/template/composeApp/src/androidDebug/kotlin/com/example/app/inspector/InspectorInit.kt +16 -0
  40. package/template/composeApp/src/androidDebug/kotlin/com/example/app/inspector/LiveSemanticsJson.kt +102 -0
  41. package/template/composeApp/src/androidDebug/kotlin/com/example/app/inspector/RemoteControlPage.kt +106 -0
  42. package/template/composeApp/src/androidDebug/res/xml/debug_network_security_config.xml +9 -0
  43. package/template/composeApp/src/androidMain/AndroidManifest.xml +28 -0
  44. package/template/composeApp/src/androidMain/kotlin/com/example/app/AppApplication.kt +72 -0
  45. package/template/composeApp/src/androidMain/kotlin/com/example/app/MainActivity.kt +24 -0
  46. package/template/composeApp/src/androidMain/kotlin/com/example/app/core/connectivity/NetworkMonitor.kt +42 -0
  47. package/template/composeApp/src/androidMain/kotlin/com/example/app/data/local/DatabaseBuilder.android.kt +13 -0
  48. package/template/composeApp/src/androidMain/kotlin/com/example/app/di/AndroidModule.kt +9 -0
  49. package/template/composeApp/src/androidMain/kotlin/com/example/app/presentation/components/TestTagAutomation.android.kt +11 -0
  50. package/template/composeApp/src/androidMain/res/drawable/ic_launcher_background.xml +9 -0
  51. package/template/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml +6 -0
  52. package/template/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml +6 -0
  53. package/template/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher.png +0 -0
  54. package/template/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_foreground.png +0 -0
  55. package/template/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png +0 -0
  56. package/template/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher.png +0 -0
  57. package/template/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_foreground.png +0 -0
  58. package/template/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png +0 -0
  59. package/template/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.png +0 -0
  60. package/template/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
  61. package/template/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
  62. package/template/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  63. package/template/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
  64. package/template/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  65. package/template/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  66. package/template/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
  67. package/template/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  68. package/template/composeApp/src/androidMain/res/values/colors.xml +6 -0
  69. package/template/composeApp/src/androidMain/res/values/themes.xml +9 -0
  70. package/template/composeApp/src/androidMain/res/values-v31/themes.xml +8 -0
  71. package/template/composeApp/src/androidRelease/kotlin/com/example/app/inspector/InspectorInit.kt +13 -0
  72. package/template/composeApp/src/commonMain/composeResources/font/DMSans_Bold.ttf +0 -0
  73. package/template/composeApp/src/commonMain/composeResources/font/DMSans_Medium.ttf +0 -0
  74. package/template/composeApp/src/commonMain/composeResources/font/DMSans_Regular.ttf +0 -0
  75. package/template/composeApp/src/commonMain/composeResources/font/DMSans_SemiBold.ttf +0 -0
  76. package/template/composeApp/src/commonMain/kotlin/com/example/app/App.kt +7 -0
  77. package/template/composeApp/src/commonMain/kotlin/com/example/app/core/connectivity/NetworkMonitor.kt +7 -0
  78. package/template/composeApp/src/commonMain/kotlin/com/example/app/data/local/AppDatabase.kt +28 -0
  79. package/template/composeApp/src/commonMain/kotlin/com/example/app/data/local/DatabaseBuilder.kt +14 -0
  80. package/template/composeApp/src/commonMain/kotlin/com/example/app/data/local/ItemDao.kt +18 -0
  81. package/template/composeApp/src/commonMain/kotlin/com/example/app/data/remote/FirebaseConfig.kt +5 -0
  82. package/template/composeApp/src/commonMain/kotlin/com/example/app/data/remote/ItemRepositoryImpl.kt +22 -0
  83. package/template/composeApp/src/commonMain/kotlin/com/example/app/di/AppModule.kt +23 -0
  84. package/template/composeApp/src/commonMain/kotlin/com/example/app/domain/model/Item.kt +8 -0
  85. package/template/composeApp/src/commonMain/kotlin/com/example/app/domain/repository/ItemRepository.kt +8 -0
  86. package/template/composeApp/src/commonMain/kotlin/com/example/app/domain/usecase/GetItemsUseCase.kt +12 -0
  87. package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/App.kt +13 -0
  88. package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/components/BaseScreen.kt +69 -0
  89. package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/components/TestTagAutomation.kt +18 -0
  90. package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/home/DetailScreen.kt +39 -0
  91. package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/home/HomeScreen.kt +87 -0
  92. package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/home/HomeViewModel.kt +35 -0
  93. package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/navigation/AppNavHost.kt +43 -0
  94. package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/navigation/AppShell.kt +144 -0
  95. package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/navigation/AppTab.kt +25 -0
  96. package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/navigation/Screen.kt +15 -0
  97. package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/profile/ProfileScreen.kt +43 -0
  98. package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/theme/DesignToken.kt +25 -0
  99. package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/theme/Shape.kt +12 -0
  100. package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/theme/Theme.kt +64 -0
  101. package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/theme/Tokens.kt +19 -0
  102. package/template/composeApp/src/commonMain/kotlin/com/example/app/presentation/theme/Typography.kt +36 -0
  103. package/template/composeApp/src/desktopMain/kotlin/com/example/app/core/connectivity/NetworkMonitor.desktop.kt +9 -0
  104. package/template/composeApp/src/desktopMain/kotlin/com/example/app/data/local/DatabaseBuilder.desktop.kt +13 -0
  105. package/template/composeApp/src/desktopMain/kotlin/com/example/app/di/DesktopModule.kt +32 -0
  106. package/template/composeApp/src/desktopMain/kotlin/com/example/app/main.kt +29 -0
  107. package/template/composeApp/src/desktopMain/kotlin/com/example/app/presentation/components/TestTagAutomation.desktop.kt +6 -0
  108. package/template/composeApp/src/iosMain/kotlin/com/example/app/KoinHelper.kt +50 -0
  109. package/template/composeApp/src/iosMain/kotlin/com/example/app/MainViewController.kt +10 -0
  110. package/template/composeApp/src/iosMain/kotlin/com/example/app/core/connectivity/NetworkMonitor.kt +32 -0
  111. package/template/composeApp/src/iosMain/kotlin/com/example/app/data/local/DatabaseBuilder.ios.kt +10 -0
  112. package/template/composeApp/src/iosMain/kotlin/com/example/app/presentation/components/TestTagAutomation.ios.kt +11 -0
  113. package/template/docs/dev-client.md +52 -0
  114. package/template/gitignore +21 -0
  115. package/template/gradle/libs.versions.toml +100 -0
  116. package/template/gradle/wrapper/gradle-wrapper.jar +0 -0
  117. package/template/gradle/wrapper/gradle-wrapper.properties +7 -0
  118. package/template/gradle.properties +9 -0
  119. package/template/gradlew +152 -0
  120. package/template/gradlew.bat +94 -0
  121. package/template/iosApp/Podfile +27 -0
  122. package/template/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png +0 -0
  123. package/template/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json +14 -0
  124. package/template/iosApp/iosApp/Assets.xcassets/Contents.json +6 -0
  125. package/template/iosApp/iosApp/ContentView.swift +17 -0
  126. package/template/iosApp/iosApp/GoogleService-Info.plist +34 -0
  127. package/template/iosApp/iosApp/Info.plist +43 -0
  128. package/template/iosApp/iosApp/PrivacyInfo.xcprivacy +42 -0
  129. package/template/iosApp/iosApp/iOSApp.swift +33 -0
  130. package/template/iosApp/project.yml +56 -0
  131. package/template/local.properties.example +2 -0
  132. package/template/manifest.json +125 -0
  133. package/template/qa/appium/README.md +23 -0
  134. package/template/qa/appium/lib/appium-client.mjs +225 -0
  135. package/template/qa/appium/package.json +8 -0
  136. package/template/qa/appium/run-android-smoke.mjs +39 -0
  137. package/template/settings.gradle.kts +34 -0
  138. package/template/tests/appium/cmp/conftest.py +96 -0
  139. package/template/tests/appium/cmp/test_smoke.py +17 -0
@@ -0,0 +1,10 @@
1
+ package __PACKAGE__.data.local
2
+
3
+ import androidx.room.Room
4
+ import androidx.room.RoomDatabase
5
+ import platform.Foundation.NSHomeDirectory
6
+
7
+ actual fun getDatabaseBuilder(): RoomDatabase.Builder<AppDatabase> {
8
+ val dbFilePath = NSHomeDirectory() + "/Documents/app.db"
9
+ return Room.databaseBuilder<AppDatabase>(name = dbFilePath)
10
+ }
@@ -0,0 +1,11 @@
1
+ package __PACKAGE__.presentation.components
2
+
3
+ import androidx.compose.ui.Modifier
4
+
5
+ /**
6
+ * iOS: no-op — `testTagsAsResourceId` is Android-only in the compose `ui` artifact at this
7
+ * version set. Compose Multiplatform on iOS already exposes `Modifier.testTag` through the
8
+ * accessibility tree (XCUITest/Appium can match it as the accessibility identifier), so no
9
+ * extra semantics flag is required here.
10
+ */
11
+ actual fun Modifier.exposeTestTagsForAutomation(): Modifier = this
@@ -0,0 +1,52 @@
1
+ # Desktop dev-client — the daily dev loop
2
+
3
+ Your app ships with a pre-wired **JVM desktop run target**: the shared `commonMain` UI in a live,
4
+ clickable window on your workstation, with **Compose Hot Reload** attached. Edit a composable,
5
+ save, and watch the window update — no emulator, no reinstall, no restart.
6
+
7
+ ## Run it
8
+
9
+ ```bash
10
+ # Hot reload (recommended): auto-reloads on every save
11
+ ./gradlew :composeApp:hotRunDesktop --auto
12
+
13
+ # Hot reload, explicit mode: reload only when you run the `reload` task
14
+ ./gradlew :composeApp:hotRunDesktop
15
+
16
+ # Plain run (no hot reload — works on any JDK 17+)
17
+ ./gradlew :composeApp:run
18
+ ```
19
+
20
+ The window is phone-sized (411×891 dp) and titled `__APP_NAME__ dev-client`.
21
+
22
+ ### How reload triggers
23
+
24
+ - With `--auto` (or `--autoReload`), Gradle's continuous build watches your sources; **saving a
25
+ file** recompiles and hot-swaps the running UI in place.
26
+ - Without it, trigger reloads explicitly with the IDE's **Reload UI** button (IntelliJ /
27
+ Android Studio with the Kotlin Multiplatform plugin) or `./gradlew reload`.
28
+ - Hot reload runs on the **JetBrains Runtime**. The scaffold wires the
29
+ `foojay-resolver-convention` settings plugin so Gradle auto-downloads a JBR the first time you
30
+ run `hotRunDesktop` if none is installed (one-time download). `:composeApp:run` needs no JBR.
31
+
32
+ ## What's real and what's faked on desktop
33
+
34
+ The desktop target reuses all of `commonMain` — screens, ViewModels, navigation, theme, DI. The
35
+ platform seams get JVM implementations in `composeApp/src/desktopMain`:
36
+
37
+ | Seam | Desktop implementation |
38
+ |---|---|
39
+ | `NetworkMonitor` | Always-online stub (`NetworkMonitor.desktop.kt`) |
40
+ | Room database | Real Room via `BundledSQLiteDriver`, stored in the OS temp dir (`DatabaseBuilder.desktop.kt`) |
41
+ | Firebase | **Not wired at all** — the dev-client never initializes or contacts Firebase |
42
+ | `ItemRepository` (example feature) | The same in-memory `ItemRepositoryImpl` every platform binds |
43
+
44
+ When you add a real remote-backed repository, bind a desktop fake for it in
45
+ `desktopMain/.../di/DesktopModule.kt` so the dev-client keeps running without a backend.
46
+
47
+ ## Limits
48
+
49
+ - Desktop is a **development client**, not a shipping target: platform-specific behavior
50
+ (permissions, push, deep links, insets) still needs the Android/iOS builds.
51
+ - Hot reload swaps UI and most code changes in place; structural changes (new `expect`/`actual`,
52
+ build-file edits) need a restart of the run task.
@@ -0,0 +1,21 @@
1
+ *.iml
2
+ .gradle
3
+ /local.properties
4
+ .DS_Store
5
+ /build
6
+ /captures
7
+ .externalNativeBuild
8
+ .cxx
9
+ *.log
10
+
11
+ # Kotlin
12
+ .kotlin/
13
+
14
+ # iOS / CocoaPods / XcodeGen
15
+ iosApp/Pods/
16
+ iosApp/Podfile.lock
17
+ iosApp/*.xcodeproj/
18
+ iosApp/*.xcworkspace/
19
+ iosApp/build/
20
+ xcuserdata/
21
+ *.xcuserstate
@@ -0,0 +1,100 @@
1
+ [versions]
2
+ # ── Frozen, CI-verified version set (the reproducibility moat). Do not bump in
3
+ # ── isolation — Kotlin / KSP / Compose / Room / AGP move as ONE set or the build dies.
4
+ kotlin = "2.2.20"
5
+ agp = "8.7.3"
6
+ google-services = "4.4.2"
7
+ compose-multiplatform = "1.10.3"
8
+ koin = "4.1.1"
9
+ ktor = "3.1.0"
10
+ room = "2.8.4"
11
+ sqlite = "2.6.2"
12
+ # KSP MUST be <kotlin>-<ksp>. With ksp.useKSP2=true this is the combo that links Room on iOS native.
13
+ ksp = "2.2.20-2.0.4"
14
+ kotlinx-serialization = "1.7.3"
15
+ kotlinx-datetime = "0.7.0"
16
+ lifecycle = "2.10.0"
17
+ navigation = "2.9.2"
18
+ firebase-gitlive = "2.1.0"
19
+ # Desktop dev-client. CHR 1.1.1 (latest stable) needs Kotlin >= 2.1.20 + CMP >= 1.8.2 — satisfied
20
+ # by this set. The 1.2.x line (beta) additionally requires CMP 1.10+; safe to move to when stable.
21
+ compose-hot-reload = "1.1.1"
22
+ coil = "3.1.0"
23
+ androidx-core = "1.15.0"
24
+ androidx-activity = "1.10.1"
25
+
26
+ [libraries]
27
+ # Compose Multiplatform
28
+ compose-ui = { module = "org.jetbrains.compose.ui:ui" }
29
+ compose-foundation = { module = "org.jetbrains.compose.foundation:foundation" }
30
+ compose-material3 = { module = "org.jetbrains.compose.material3:material3" }
31
+ compose-material-icons-extended = { module = "org.jetbrains.compose.material:material-icons-extended" }
32
+
33
+ # Lifecycle / ViewModel (JetBrains KMP)
34
+ lifecycle-viewmodel = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel", version.ref = "lifecycle" }
35
+ lifecycle-viewmodel-compose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycle" }
36
+ lifecycle-runtime-compose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-runtime-compose", version.ref = "lifecycle" }
37
+
38
+ # Navigation
39
+ navigation-compose = { module = "org.jetbrains.androidx.navigation:navigation-compose", version.ref = "navigation" }
40
+
41
+ # Koin
42
+ koin-core = { module = "io.insert-koin:koin-core", version.ref = "koin" }
43
+ koin-compose = { module = "io.insert-koin:koin-compose", version.ref = "koin" }
44
+ koin-compose-viewmodel = { module = "io.insert-koin:koin-compose-viewmodel", version.ref = "koin" }
45
+ koin-android = { module = "io.insert-koin:koin-android", version.ref = "koin" }
46
+
47
+ # Ktor
48
+ ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
49
+ ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" }
50
+ ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktor" }
51
+ ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" }
52
+ ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" }
53
+
54
+ # Firebase GitLive KMP SDK
55
+ firebase-auth = { module = "dev.gitlive:firebase-auth", version.ref = "firebase-gitlive" }
56
+ firebase-firestore = { module = "dev.gitlive:firebase-firestore", version.ref = "firebase-gitlive" }
57
+ firebase-functions = { module = "dev.gitlive:firebase-functions", version.ref = "firebase-gitlive" }
58
+ firebase-storage = { module = "dev.gitlive:firebase-storage", version.ref = "firebase-gitlive" }
59
+ firebase-messaging = { module = "dev.gitlive:firebase-messaging", version.ref = "firebase-gitlive" }
60
+ firebase-config = { module = "dev.gitlive:firebase-config", version.ref = "firebase-gitlive" }
61
+
62
+ # Room KMP
63
+ room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
64
+ room-runtime-android = { module = "androidx.room:room-runtime-android", version.ref = "room" }
65
+ room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
66
+ sqlite-bundled = { module = "androidx.sqlite:sqlite-bundled", version.ref = "sqlite" }
67
+
68
+ # Kotlinx
69
+ kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" }
70
+ kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-datetime" }
71
+ kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version = "1.9.0" }
72
+ kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version = "1.9.0" }
73
+ # Desktop dev-client: Dispatchers.Main for Compose on the JVM (Swing event loop).
74
+ kotlinx-coroutines-swing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version = "1.9.0" }
75
+
76
+ # Coil (image loading KMP)
77
+ coil-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil" }
78
+ coil-network-ktor = { module = "io.coil-kt.coil3:coil-network-ktor3", version.ref = "coil" }
79
+
80
+ # Android
81
+ androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidx-core" }
82
+ androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" }
83
+ android-desugar-jdk = { module = "com.android.tools:desugar_jdk_libs", version = "2.1.3" }
84
+
85
+ # Test
86
+ kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
87
+ koin-test = { module = "io.insert-koin:koin-test", version.ref = "koin" }
88
+ kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version = "1.9.0" }
89
+
90
+ [plugins]
91
+ kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
92
+ kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
93
+ compose-multiplatform = { id = "org.jetbrains.compose", version.ref = "compose-multiplatform" }
94
+ compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
95
+ android-application = { id = "com.android.application", version.ref = "agp" }
96
+ android-library = { id = "com.android.library", version.ref = "agp" }
97
+ google-services = { id = "com.google.gms.google-services", version.ref = "google-services" }
98
+ ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
99
+ room = { id = "androidx.room", version.ref = "room" }
100
+ compose-hot-reload = { id = "org.jetbrains.compose.hot-reload", version.ref = "compose-hot-reload" }
@@ -0,0 +1,7 @@
1
+ distributionBase=GRADLE_USER_HOME
2
+ distributionPath=wrapper/dists
3
+ distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
4
+ networkTimeout=10000
5
+ validateDistributionUrl=true
6
+ zipStoreBase=GRADLE_USER_HOME
7
+ zipStorePath=wrapper/dists
@@ -0,0 +1,9 @@
1
+ kotlin.code.style=official
2
+ android.useAndroidX=true
3
+ org.gradle.jvmargs=-Xmx4g -XX:+UseG1GC
4
+ org.gradle.parallel=true
5
+ org.gradle.caching=true
6
+ kotlin.incremental=true
7
+ # KSP2 — fixes "ClassNotFoundException: org.jetbrains.kotlin.cli.utilities.MainKt"
8
+ # on Kotlin/Native (iOS) targets with Room's KSP processor (the KSP1 native catch-22).
9
+ ksp.useKSP2=true
@@ -0,0 +1,152 @@
1
+ #!/bin/sh
2
+ #
3
+ # Copyright © 2015-2021 the original authors.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+ # SPDX-License-Identifier: Apache-2.0
18
+ #
19
+
20
+ ##############################################################################
21
+ #
22
+ # Gradle start up script for POSIX generated by "Gradle Wrapper".
23
+ #
24
+ # Important for running:
25
+ #
26
+ # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
27
+ # noncompliant, but you have some other POSIX-compliant shell such as ksh or
28
+ # bash, then to run this script, type that shell name before the whole
29
+ # command line, like:
30
+ #
31
+ # ksh Gradle
32
+ #
33
+ # Busybox and similar reduced shells will NOT work, because this script
34
+ # requires all of these POSIX shell features:
35
+ # * functions;
36
+ # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
37
+ # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
38
+ # * compound commands having a testable exit status, especially «case»;
39
+ # * various built-in commands including «command», «set», and «ulimit».
40
+ #
41
+ # Important for security:
42
+ #
43
+ # (2) This script relies on the fact that it is not setuid. Security audit
44
+ # tools (e.g. Sonartype) will complain about world-writable files in the
45
+ # Gradle user home, but that is just by design.
46
+ #
47
+ ##############################################################################
48
+
49
+ # Attempt to set APP_HOME
50
+ # Resolve links: $0 may be a link
51
+ app_path=$0
52
+
53
+ # Need this for daisy-chained symlinks.
54
+ while
55
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
56
+ [ -h "$app_path" ]
57
+ do
58
+ ls=$( ls -ld "$app_path" )
59
+ link=${ls#*' -> '}
60
+ case $link in #(
61
+ /*) app_path=$link ;; #( absolute
62
+ *) app_path=$APP_HOME$link ;; #( relative
63
+ esac
64
+ done
65
+
66
+ # This is reliable for both POSIX and GNU/Linux.
67
+ APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
68
+
69
+ APP_NAME="Gradle"
70
+ APP_BASE_NAME=${0##*/}
71
+
72
+ # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
73
+ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
74
+
75
+ # Use the maximum available, or set MAX_FD != -1 to use that value.
76
+ MAX_FD=maximum
77
+
78
+ warn () {
79
+ echo "$*"
80
+ } >&2
81
+
82
+ die () {
83
+ echo
84
+ echo "$*"
85
+ echo
86
+ exit 1
87
+ } >&2
88
+
89
+ # OS specific support (must be 'true' or 'false').
90
+ cygwin=false
91
+ msys=false
92
+ darwin=false
93
+ nonstop=false
94
+ case "$( uname )" in #(
95
+ CYGWIN* ) cygwin=true ;; #(
96
+ Darwin* ) darwin=true ;; #(
97
+ MSYS* | MINGW* ) msys=true ;; #(
98
+ NONSTOP* ) nonstop=true ;;
99
+ esac
100
+
101
+ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
102
+
103
+
104
+ # Determine the Java command to use to start the JVM.
105
+ if [ -n "$JAVA_HOME" ] ; then
106
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
107
+ # IBM's JDK on AIX uses strange locations for the executables
108
+ JAVACMD=$JAVA_HOME/jre/sh/java
109
+ else
110
+ JAVACMD=$JAVA_HOME/bin/java
111
+ fi
112
+ if [ ! -x "$JAVACMD" ] ; then
113
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
114
+
115
+ Please set the JAVA_HOME variable in your environment to match the
116
+ location of your Java installation."
117
+ fi
118
+ else
119
+ JAVACMD=java
120
+ if ! command -v java >/dev/null 2>&1
121
+ then
122
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
123
+
124
+ Please set the JAVA_HOME variable in your environment to match the
125
+ location of your Java installation."
126
+ fi
127
+ fi
128
+
129
+ # Increase the maximum file descriptors if we can.
130
+ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
131
+ case $MAX_FD in #(
132
+ max*)
133
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
134
+ # shellcheck disable=SC2039,SC3045
135
+ MAX_FD=$( ulimit -H -n ) ||
136
+ warn "Could not query maximum file descriptor limit"
137
+ ;;
138
+ esac
139
+ case $MAX_FD in #(
140
+ '' | soft) :;; #(
141
+ *)
142
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
143
+ # shellcheck disable=SC2039,SC3045
144
+ ulimit -n "$MAX_FD" ||
145
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
146
+ esac
147
+ fi
148
+
149
+ # Collect all arguments for the java command, following the shell quoting and substitution rules
150
+ eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$@"
151
+
152
+ exec "$JAVACMD" "$@"
@@ -0,0 +1,94 @@
1
+ @rem
2
+ @rem Copyright 2015 the original author or authors.
3
+ @rem
4
+ @rem Licensed under the Apache License, Version 2.0 (the "License");
5
+ @rem you may not use this file except in compliance with the License.
6
+ @rem You may obtain a copy of the License at
7
+ @rem
8
+ @rem https://www.apache.org/licenses/LICENSE-2.0
9
+ @rem
10
+ @rem Unless required by applicable law or agreed to in writing, software
11
+ @rem distributed under the License is distributed on an "AS IS" BASIS,
12
+ @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ @rem See the License for the specific language governing permissions and
14
+ @rem limitations under the License.
15
+ @rem
16
+ @rem SPDX-License-Identifier: Apache-2.0
17
+ @rem
18
+
19
+ @if "%DEBUG%"=="" @echo off
20
+ @rem ##########################################################################
21
+ @rem
22
+ @rem Gradle startup script for Windows
23
+ @rem
24
+ @rem ##########################################################################
25
+
26
+ @rem Set local scope for the variables with windows NT shell
27
+ if "%OS%"=="Windows_NT" setlocal
28
+
29
+ set DIRNAME=%~dp0
30
+ if "%DIRNAME%"=="" set DIRNAME=.
31
+ @rem This is normally unused
32
+ set APP_BASE_NAME=%~n0
33
+ set APP_HOME=%DIRNAME%
34
+
35
+ @rem Resolve any "." and ".." in APP_HOME to make it shorter.
36
+ for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
37
+
38
+ @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
39
+ set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
40
+
41
+ @rem Find java.exe
42
+ if defined JAVA_HOME goto findJavaFromJavaHome
43
+
44
+ set JAVA_EXE=java.exe
45
+ %JAVA_EXE% -version >NUL 2>&1
46
+ if %ERRORLEVEL% equ 0 goto execute
47
+
48
+ echo. 1>&2
49
+ echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
50
+ echo. 1>&2
51
+ echo Please set the JAVA_HOME variable in your environment to match the 1>&2
52
+ echo location of your Java installation. 1>&2
53
+
54
+ goto fail
55
+
56
+ :findJavaFromJavaHome
57
+ set JAVA_HOME=%JAVA_HOME:"=%
58
+ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
59
+
60
+ if exist "%JAVA_EXE%" goto execute
61
+
62
+ echo. 1>&2
63
+ echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
64
+ echo. 1>&2
65
+ echo Please set the JAVA_HOME variable in your environment to match the 1>&2
66
+ echo location of your Java installation. 1>&2
67
+
68
+ goto fail
69
+
70
+ :execute
71
+ @rem Setup the command line
72
+
73
+ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
74
+
75
+
76
+ @rem Execute Gradle
77
+ "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
78
+
79
+ :end
80
+ @rem End local scope for the variables with windows NT shell
81
+ if %ERRORLEVEL% equ 0 goto mainEnd
82
+
83
+ :fail
84
+ rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
85
+ rem the _cmd.exe /C_ return code!
86
+ set EXIT_CODE=%ERRORLEVEL%
87
+ if %EXIT_CODE% equ 0 set EXIT_CODE=1
88
+ if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
89
+ exit /b %EXIT_CODE%
90
+
91
+ :mainEnd
92
+ if "%OS%"=="Windows_NT" endlocal
93
+
94
+ :omega
@@ -0,0 +1,27 @@
1
+ # iOS native Firebase SDKs for the GitLive Firebase KMP bindings (v2.1.0 -> Firebase iOS 11.x).
2
+ # The ComposeApp KMP framework references these Obj-C symbols at link time; the app provides them.
3
+ platform :ios, '16.0'
4
+
5
+ # Static linkage pairs with the static ComposeApp.framework (isStatic = true).
6
+ use_frameworks! :linkage => :static
7
+
8
+ target 'iosApp' do
9
+ # >>> cmp:feature firebase
10
+ pod 'FirebaseCore', '~> 11.0'
11
+ pod 'FirebaseAuth', '~> 11.0'
12
+ pod 'FirebaseFirestore', '~> 11.0'
13
+ pod 'FirebaseFunctions', '~> 11.0'
14
+ pod 'FirebaseStorage', '~> 11.0'
15
+ pod 'FirebaseMessaging', '~> 11.0'
16
+ pod 'FirebaseRemoteConfig', '~> 11.0'
17
+ # <<< cmp:feature firebase
18
+ end
19
+
20
+ post_install do |installer|
21
+ installer.pods_project.targets.each do |target|
22
+ target.build_configurations.each do |config|
23
+ config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '16.0'
24
+ config.build_settings['ENABLE_USER_SCRIPT_SANDBOXING'] = 'NO'
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,14 @@
1
+ {
2
+ "images" : [
3
+ {
4
+ "filename" : "AppIcon-1024.png",
5
+ "idiom" : "universal",
6
+ "platform" : "ios",
7
+ "size" : "1024x1024"
8
+ }
9
+ ],
10
+ "info" : {
11
+ "author" : "xcode",
12
+ "version" : 1
13
+ }
14
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "info" : {
3
+ "author" : "xcode",
4
+ "version" : 1
5
+ }
6
+ }
@@ -0,0 +1,17 @@
1
+ import SwiftUI
2
+ import ComposeApp
3
+
4
+ struct ContentView: View {
5
+ var body: some View {
6
+ ComposeView()
7
+ .ignoresSafeArea(.keyboard)
8
+ }
9
+ }
10
+
11
+ // UIViewControllerRepresentable that hosts the Compose Multiplatform entry point.
12
+ struct ComposeView: UIViewControllerRepresentable {
13
+ func makeUIViewController(context: Context) -> UIViewController {
14
+ MainViewControllerKt.MainViewController()
15
+ }
16
+ func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
17
+ }
@@ -0,0 +1,34 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!--
3
+ PLACEHOLDER — replace with the real GoogleService-Info.plist for your iOS app from the
4
+ Firebase console (Project settings → your iOS app → download). Not templated on purpose.
5
+ -->
6
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
7
+ <plist version="1.0">
8
+ <dict>
9
+ <key>API_KEY</key>
10
+ <string>REPLACE_ME_IOS_API_KEY</string>
11
+ <key>GCM_SENDER_ID</key>
12
+ <string>000000000000</string>
13
+ <key>PLIST_VERSION</key>
14
+ <string>1</string>
15
+ <key>BUNDLE_ID</key>
16
+ <string>__IOS_BUNDLE_ID__</string>
17
+ <key>PROJECT_ID</key>
18
+ <string>REPLACE_ME_PROJECT_ID</string>
19
+ <key>STORAGE_BUCKET</key>
20
+ <string>REPLACE_ME_PROJECT_ID.appspot.com</string>
21
+ <key>IS_ADS_ENABLED</key>
22
+ <false/>
23
+ <key>IS_ANALYTICS_ENABLED</key>
24
+ <false/>
25
+ <key>IS_APPINVITE_ENABLED</key>
26
+ <true/>
27
+ <key>IS_GCM_ENABLED</key>
28
+ <true/>
29
+ <key>IS_SIGNIN_ENABLED</key>
30
+ <true/>
31
+ <key>GOOGLE_APP_ID</key>
32
+ <string>1:000000000000:ios:0000000000000000000000</string>
33
+ </dict>
34
+ </plist>
@@ -0,0 +1,43 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>CADisableMinimumFrameDurationOnPhone</key>
6
+ <true/>
7
+ <key>CFBundleDevelopmentRegion</key>
8
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
9
+ <key>CFBundleDisplayName</key>
10
+ <string>__APP_NAME__</string>
11
+ <key>CFBundleExecutable</key>
12
+ <string>$(EXECUTABLE_NAME)</string>
13
+ <key>CFBundleIdentifier</key>
14
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
15
+ <key>CFBundleInfoDictionaryVersion</key>
16
+ <string>6.0</string>
17
+ <key>CFBundleName</key>
18
+ <string>$(PRODUCT_NAME)</string>
19
+ <key>CFBundlePackageType</key>
20
+ <string>APPL</string>
21
+ <key>CFBundleShortVersionString</key>
22
+ <string>1.0</string>
23
+ <key>CFBundleVersion</key>
24
+ <string>1</string>
25
+ <key>NSCameraUsageDescription</key>
26
+ <string>__APP_NAME__ uses the camera to capture photos.</string>
27
+ <key>NSLocationWhenInUseUsageDescription</key>
28
+ <string>__APP_NAME__ uses your location to show nearby content.</string>
29
+ <key>NSPhotoLibraryUsageDescription</key>
30
+ <string>__APP_NAME__ lets you attach photos to your profile.</string>
31
+ <key>UIApplicationSceneManifest</key>
32
+ <dict>
33
+ <key>UIApplicationSupportsMultipleScenes</key>
34
+ <false/>
35
+ </dict>
36
+ <key>UILaunchScreen</key>
37
+ <dict/>
38
+ <key>UISupportedInterfaceOrientations</key>
39
+ <array>
40
+ <string>UIInterfaceOrientationPortrait</string>
41
+ </array>
42
+ </dict>
43
+ </plist>
@@ -0,0 +1,42 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <!--
4
+ PrivacyInfo.xcprivacy — Apple Privacy Manifest (required from May 2024).
5
+ Declare privacy-sensitive API usages used by the app and its SDKs. Extend as you add data
6
+ collection (Firebase Auth email/phone, location, etc.).
7
+ https://developer.apple.com/documentation/bundleresources/privacy_manifest_files
8
+ -->
9
+ <plist version="1.0">
10
+ <dict>
11
+ <key>NSPrivacyTracking</key>
12
+ <false/>
13
+
14
+ <key>NSPrivacyTrackingDomains</key>
15
+ <array/>
16
+
17
+ <key>NSPrivacyCollectedDataTypes</key>
18
+ <array/>
19
+
20
+ <key>NSPrivacyAccessedAPITypes</key>
21
+ <array>
22
+ <!-- UserDefaults: required by Firebase, Koin, and local cache -->
23
+ <dict>
24
+ <key>NSPrivacyAccessedAPIType</key>
25
+ <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
26
+ <key>NSPrivacyAccessedAPITypeReasons</key>
27
+ <array>
28
+ <string>CA92.1</string>
29
+ </array>
30
+ </dict>
31
+ <!-- File timestamp APIs: SQLite (Room) -->
32
+ <dict>
33
+ <key>NSPrivacyAccessedAPIType</key>
34
+ <string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
35
+ <key>NSPrivacyAccessedAPITypeReasons</key>
36
+ <array>
37
+ <string>C617.1</string>
38
+ </array>
39
+ </dict>
40
+ </array>
41
+ </dict>
42
+ </plist>