pakstr 0.0.1 → 0.0.3

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 (59) hide show
  1. package/README.md +33 -0
  2. package/android-template/app/build.gradle.kts +2 -2
  3. package/android-template/app/src/androidTest/java/com/{nostrappshell → pakstr}/app/ExampleInstrumentedTest.kt +1 -1
  4. package/android-template/app/src/main/AndroidManifest.xml +2 -1
  5. package/android-template/app/src/main/assets/www/.gitkeep +0 -0
  6. package/android-template/app/src/main/java/com/{nostrappshell → pakstr}/app/ApplicationClass.kt +2 -2
  7. package/android-template/app/src/main/java/com/{nostrappshell → pakstr}/app/Config.kt +1 -1
  8. package/android-template/app/src/main/java/com/{nostrappshell → pakstr}/app/LocalServer.kt +3 -3
  9. package/android-template/app/src/main/java/com/{nostrappshell → pakstr}/app/MainActivity.kt +68 -20
  10. package/android-template/app/src/main/java/com/{nostrappshell → pakstr}/app/ShellRuntime.kt +7 -4
  11. package/android-template/app/src/main/java/com/{nostrappshell → pakstr}/app/WebViewController.kt +17 -8
  12. package/android-template/app/src/main/java/com/pakstr/app/permissions/PermissionManager.kt +78 -0
  13. package/android-template/app/src/main/java/com/pakstr/app/permissions/interfaces/PermissionHandler.kt +7 -0
  14. package/android-template/app/src/main/java/com/{nostrappshell → pakstr}/app/signer/AmberSigner.kt +2 -2
  15. package/android-template/app/src/main/java/com/{nostrappshell → pakstr}/app/signer/BunkerSigner.kt +2 -2
  16. package/android-template/app/src/main/java/com/{nostrappshell → pakstr}/app/signer/FakeSigner.kt +2 -2
  17. package/android-template/app/src/main/java/com/{nostrappshell → pakstr}/app/signer/NostrBridge.kt +1 -2
  18. package/android-template/app/src/main/java/com/{nostrappshell → pakstr}/app/signer/SignerManager.kt +2 -9
  19. package/android-template/app/src/main/java/com/{nostrappshell → pakstr}/app/signer/SignerType.kt +1 -1
  20. package/android-template/app/src/main/java/com/{nostrappshell → pakstr}/app/signer/interfaces/NostrSigner.kt +1 -1
  21. package/android-template/app/src/main/java/com/{nostrappshell → pakstr}/app/ui/theme/Color.kt +1 -1
  22. package/android-template/app/src/main/java/com/{nostrappshell → pakstr}/app/ui/theme/Theme.kt +1 -1
  23. package/android-template/app/src/main/java/com/{nostrappshell → pakstr}/app/ui/theme/Type.kt +1 -1
  24. package/android-template/app/src/main/java/com/{nostrappshell → pakstr}/app/utils/AppPreferences.kt +1 -1
  25. package/android-template/app/src/main/java/com/{nostrappshell → pakstr}/app/utils/SignerPickerBottomSheet.kt +3 -3
  26. package/android-template/app/src/test/java/com/{nostrappshell → pakstr}/app/ExampleUnitTest.kt +1 -1
  27. package/bin/cli.js +5 -2
  28. package/dist/android/branding.js +23 -0
  29. package/dist/android/gradle.js +17 -0
  30. package/dist/android/icon.js +105 -0
  31. package/dist/android/permissions.js +33 -0
  32. package/dist/android/splash.js +62 -0
  33. package/dist/android/template.js +142 -0
  34. package/dist/android/version.js +16 -0
  35. package/dist/cli.js +56 -0
  36. package/dist/commands/build.js +159 -0
  37. package/dist/config.js +4 -0
  38. package/dist/core/buildContext.js +100 -0
  39. package/dist/core/config.js +24 -0
  40. package/dist/core/copyFile.js +17 -0
  41. package/dist/core/manifest.js +28 -0
  42. package/dist/core/resolveProjectInputs.js +20 -0
  43. package/dist/core/validateProject.js +21 -0
  44. package/dist/core/zeroConfig.js +97 -0
  45. package/dist/index.js +5 -0
  46. package/dist/runners/BuildRunner.js +2 -0
  47. package/dist/runners/DockerGradleRunner.js +60 -0
  48. package/dist/runners/LocalGradleRunner.js +40 -0
  49. package/dist/runners/createRunner.js +15 -0
  50. package/package.json +28 -20
  51. package/android-template/app/src/main/assets/www/assets/hero-CLDdwZDr.png +0 -0
  52. package/android-template/app/src/main/assets/www/assets/index-CsUDhMuy.css +0 -1
  53. package/android-template/app/src/main/assets/www/assets/index-D-e3tQW5.js +0 -56
  54. package/android-template/app/src/main/assets/www/assets/vite-BF8QNONU.svg +0 -1
  55. package/android-template/app/src/main/assets/www/favicon.svg +0 -1
  56. package/android-template/app/src/main/assets/www/icons.svg +0 -24
  57. package/android-template/app/src/main/assets/www/index.html +0 -14
  58. package/android-template/app/src/main/assets/www/test.html +0 -17
  59. package/bin/cli.ts +0 -5
package/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # Pakstr
2
+
3
+ CLI for packaging Nostr web apps into Android APKs.
4
+
5
+ ## Status
6
+
7
+ Pakstr is currently in early development (0.x).
8
+
9
+ The CLI API and manifest format may change before 1.0.0.
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ npm install -g pakstr
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ```bash
20
+ pakstr build apk \
21
+ --manifest app.manifest.json \
22
+ --web ./dist \
23
+ --out ./build/app.apk
24
+ ```
25
+
26
+ ## Requirements
27
+
28
+ - Node.js 20+
29
+ - Docker Desktop (for Docker builds)
30
+
31
+ ## License
32
+
33
+ ISC
@@ -4,11 +4,11 @@ plugins {
4
4
  }
5
5
 
6
6
  android {
7
- namespace = "com.nostrappshell.app"
7
+ namespace = "com.pakstr.app"
8
8
  compileSdk = 36
9
9
 
10
10
  defaultConfig {
11
- applicationId = "com.nostrappshell.app"
11
+ applicationId = "com.pakstr.app"
12
12
  minSdk = 28
13
13
  targetSdk = 36
14
14
  versionCode = 1
@@ -1,4 +1,4 @@
1
- package com.nostrappshell.app
1
+ package com.pakstr.app
2
2
 
3
3
  import androidx.test.platform.app.InstrumentationRegistry
4
4
  import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -1,7 +1,8 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
2
  <manifest xmlns:android="http://schemas.android.com/apk/res/android">
3
3
 
4
- <uses-permission android:name="android.permission.INTERNET" />
4
+ <uses-permission android:name="android.permission.INTERNET"/>
5
+ <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
5
6
 
6
7
  <application
7
8
  android:name=".ApplicationClass"
@@ -1,7 +1,7 @@
1
- package com.nostrappshell.app
1
+ package com.pakstr.app
2
2
 
3
3
  import android.app.Application
4
- import com.nostrappshell.app.utils.AppPreferences
4
+ import com.pakstr.app.utils.AppPreferences
5
5
 
6
6
  class ApplicationClass : Application() {
7
7
  override fun onCreate() {
@@ -1,4 +1,4 @@
1
- package com.nostrappshell.app
1
+ package com.pakstr.app
2
2
 
3
3
  object Config {
4
4
 
@@ -1,4 +1,4 @@
1
- package com.nostrappshell.app
1
+ package com.pakstr.app
2
2
 
3
3
  import android.content.Context
4
4
  import android.webkit.MimeTypeMap
@@ -15,11 +15,11 @@ class LocalServer(private val context: Context, port: Int) : NanoHTTPD(port) {
15
15
  // Map the root URL to index.html, otherwise target the requested file in the assets folder
16
16
  val filePath = when {
17
17
 
18
- uri == "/" -> "www/test.html"
18
+ uri == "/" -> "www/index.html"
19
19
 
20
20
  uri.contains(".") -> "www$uri" // css, js, images
21
21
 
22
- else -> "www/test.html" // SPA ROUTES FALLBACK
22
+ else -> "www/index.html" // SPA ROUTES FALLBACK
23
23
 
24
24
  }
25
25
 
@@ -1,11 +1,12 @@
1
- package com.nostrappshell.app
1
+ package com.pakstr.app
2
2
 
3
- import android.content.Context
3
+ import android.Manifest
4
4
  import android.os.Bundle
5
+ import android.util.Log
5
6
  import android.view.View
7
+ import android.webkit.PermissionRequest
6
8
  import android.webkit.WebView
7
9
  import android.widget.FrameLayout
8
- import androidx.activity.ComponentActivity
9
10
  import androidx.activity.OnBackPressedCallback
10
11
  import androidx.activity.enableEdgeToEdge
11
12
  import androidx.activity.result.contract.ActivityResultContracts
@@ -14,14 +15,14 @@ import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
14
15
  import androidx.core.view.ViewCompat
15
16
  import androidx.core.view.WindowInsetsCompat
16
17
  import androidx.core.view.updatePadding
17
- import androidx.lifecycle.lifecycleScope
18
- import com.nostrappshell.app.signer.SignerManager
19
- import com.nostrappshell.app.signer.interfaces.NostrSigner
20
- import com.nostrappshell.app.utils.AppPreferences
21
- import com.nostrappshell.app.utils.SignerPickerBottomSheet
22
- import kotlinx.coroutines.launch
18
+ import com.pakstr.app.permissions.PermissionManager
19
+ import com.pakstr.app.permissions.interfaces.PermissionHandler
20
+ import com.pakstr.app.signer.SignerManager
21
+ import com.pakstr.app.signer.interfaces.NostrSigner
22
+ import com.pakstr.app.utils.AppPreferences
23
+ import com.pakstr.app.utils.SignerPickerBottomSheet
23
24
 
24
- class MainActivity : AppCompatActivity() {
25
+ class MainActivity : AppCompatActivity(), PermissionHandler {
25
26
 
26
27
  private lateinit var runtime: ShellRuntime
27
28
  private lateinit var container: FrameLayout
@@ -33,6 +34,9 @@ class MainActivity : AppCompatActivity() {
33
34
 
34
35
  private var activeSigner: NostrSigner? = null
35
36
 
37
+ private var pendingPermissionRequest: PermissionRequest? = null
38
+
39
+ private lateinit var permissionManager: PermissionManager
36
40
 
37
41
  private val amberLauncher =
38
42
 
@@ -53,6 +57,7 @@ class MainActivity : AppCompatActivity() {
53
57
  super.onCreate(savedInstanceState)
54
58
  setContentView(R.layout.activity_layout)
55
59
 
60
+ permissionManager = PermissionManager(this)
56
61
 
57
62
  signerManager = SignerManager(
58
63
 
@@ -66,10 +71,11 @@ class MainActivity : AppCompatActivity() {
66
71
 
67
72
  val isFirstRun = AppPreferences.getBoolean("isFirstRun", true)
68
73
 
69
- // if (isFirstRun) {
74
+ if (isFirstRun) {
70
75
  //showTwoOptionsPicker(prefs)
71
76
  showSignerPicker()
72
- // }
77
+ //testPush()
78
+ }
73
79
 
74
80
  initViews()
75
81
 
@@ -77,8 +83,7 @@ class MainActivity : AppCompatActivity() {
77
83
  val bars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
78
84
 
79
85
  view.updatePadding(
80
- top = bars.top,
81
- bottom = bars.bottom
86
+ top = bars.top, bottom = bars.bottom
82
87
  )
83
88
 
84
89
  insets
@@ -87,10 +92,9 @@ class MainActivity : AppCompatActivity() {
87
92
  runtime = ShellRuntime(
88
93
 
89
94
  this,
90
-
91
95
  webView,
92
-
93
- signerManager
96
+ signerManager,
97
+ permissionHandler = this
94
98
 
95
99
  )
96
100
 
@@ -147,14 +151,58 @@ class MainActivity : AppCompatActivity() {
147
151
  }
148
152
 
149
153
  private fun handleSignerSetup() {
150
-
151
154
  AppPreferences.saveBoolean(
152
-
153
155
  "isFirstRun",
154
-
155
156
  false
157
+ )
158
+ }
156
159
 
160
+ override fun onRequestPermissionsResult(
161
+ requestCode: Int,
162
+ permissions: Array<out String>,
163
+ grantResults: IntArray
164
+ ) {
165
+ super.onRequestPermissionsResult(
166
+ requestCode,
167
+ permissions,
168
+ grantResults
169
+ )
170
+ permissionManager.onRequestPermissionsResult(
171
+ requestCode,
172
+ grantResults
157
173
  )
174
+ }
175
+
176
+ override fun onPermissionRequest(
177
+ request: PermissionRequest
178
+ ) {
179
+ permissionManager.request(
180
+ Manifest.permission.CAMERA
181
+ ) { granted ->
182
+ if (granted) {
183
+ request.grant(request.resources)
184
+ } else {
185
+ request.deny()
186
+ }
187
+ }
188
+ }
189
+
190
+ private fun testPush() {
191
+ permissionManager.requestNotificationPermission { granted ->
192
+
193
+ if (granted) {
194
+ Log.d(
195
+ "PERMISSION",
196
+ "Notifications granted"
197
+ )
198
+ } else {
199
+ Log.d(
200
+ "PERMISSION",
201
+ "Notifications denied"
202
+ )
203
+ }
204
+
205
+ }
158
206
 
159
207
  }
160
208
  }
@@ -1,9 +1,10 @@
1
- package com.nostrappshell.app
1
+ package com.pakstr.app
2
2
 
3
3
  import android.content.Context
4
4
  import android.util.Log
5
5
  import android.webkit.WebView
6
- import com.nostrappshell.app.signer.SignerManager
6
+ import com.pakstr.app.permissions.interfaces.PermissionHandler
7
+ import com.pakstr.app.signer.SignerManager
7
8
  import fi.iki.elonen.NanoHTTPD
8
9
  import kotlinx.coroutines.CoroutineScope
9
10
  import kotlinx.coroutines.Dispatchers
@@ -13,7 +14,8 @@ import kotlinx.coroutines.withContext
13
14
  class ShellRuntime(
14
15
  private val context: Context,
15
16
  private val webView: WebView,
16
- private val signerManager: SignerManager
17
+ private val signerManager: SignerManager,
18
+ private val permissionHandler: PermissionHandler
17
19
  ) {
18
20
 
19
21
  private val port = Config.PORT
@@ -29,7 +31,8 @@ class ShellRuntime(
29
31
  context,
30
32
  webView,
31
33
  port,
32
- signerManager
34
+ signerManager,
35
+ permissionHandler
33
36
  )
34
37
 
35
38
 
@@ -1,20 +1,20 @@
1
- package com.nostrappshell.app
1
+ package com.pakstr.app
2
2
 
3
3
  import android.app.Activity
4
4
  import android.content.Context
5
5
  import android.util.Log
6
6
  import android.view.View
7
7
  import android.webkit.CookieManager
8
+ import android.webkit.PermissionRequest
8
9
  import android.webkit.WebChromeClient
9
10
  import android.webkit.WebResourceRequest
10
11
  import android.webkit.WebResourceResponse
11
12
  import android.webkit.WebView
12
13
  import android.webkit.WebViewClient
13
- import com.nostrappshell.app.R
14
- import com.nostrappshell.app.signer.FakeSigner
15
- import com.nostrappshell.app.signer.NostrBridge
16
- import com.nostrappshell.app.signer.SignerManager
17
- import com.nostrappshell.app.signer.interfaces.NostrSigner
14
+ import com.pakstr.app.R
15
+ import com.pakstr.app.permissions.interfaces.PermissionHandler
16
+ import com.pakstr.app.signer.NostrBridge
17
+ import com.pakstr.app.signer.SignerManager
18
18
 
19
19
  class WebViewController(
20
20
 
@@ -24,7 +24,9 @@ class WebViewController(
24
24
 
25
25
  private val port: Int,
26
26
 
27
- private val signerManager: SignerManager
27
+ private val signerManager: SignerManager,
28
+
29
+ private val permissionHandler: PermissionHandler
28
30
 
29
31
  ) {
30
32
  // Keeps a reference to the runnable to prevent memory leaks if destroyed early
@@ -84,7 +86,14 @@ class WebViewController(
84
86
  return super.shouldInterceptRequest(view, request)
85
87
  }
86
88
  }
87
- webChromeClient = WebChromeClient()
89
+ webChromeClient = object : WebChromeClient() {
90
+
91
+ override fun onPermissionRequest(request: PermissionRequest) {
92
+
93
+ permissionHandler.onPermissionRequest(request)
94
+
95
+ }
96
+ }
88
97
  }
89
98
 
90
99
  webView.addJavascriptInterface(
@@ -0,0 +1,78 @@
1
+ package com.pakstr.app.permissions
2
+
3
+ import android.app.Activity
4
+ import android.content.pm.PackageManager
5
+ import androidx.core.app.ActivityCompat
6
+ import androidx.core.content.ContextCompat
7
+
8
+ class PermissionManager(
9
+ private val activity: Activity
10
+ ) {
11
+
12
+ private var callback: ((Boolean) -> Unit)? = null
13
+
14
+ fun request(
15
+ permission: String,
16
+ callback: (Boolean) -> Unit
17
+ ) {
18
+
19
+ if (
20
+ ContextCompat.checkSelfPermission(
21
+ activity,
22
+ permission
23
+ ) == PackageManager.PERMISSION_GRANTED
24
+ ) {
25
+ callback(true)
26
+ return
27
+ }
28
+
29
+
30
+ this.callback = callback
31
+
32
+
33
+ ActivityCompat.requestPermissions(
34
+ activity,
35
+ arrayOf(permission),
36
+ REQUEST_CODE
37
+ )
38
+ }
39
+
40
+
41
+ fun onRequestPermissionsResult(
42
+ requestCode: Int,
43
+ grantResults: IntArray
44
+ ) {
45
+
46
+ if (requestCode != REQUEST_CODE)
47
+ return
48
+
49
+
50
+ val granted =
51
+ grantResults.isNotEmpty() &&
52
+ grantResults[0] == PackageManager.PERMISSION_GRANTED
53
+
54
+
55
+ callback?.invoke(granted)
56
+
57
+ callback = null
58
+ }
59
+
60
+
61
+ companion object {
62
+ private const val REQUEST_CODE = 100
63
+ }
64
+
65
+
66
+ fun requestNotificationPermission(
67
+ callback: (Boolean) -> Unit
68
+ ) {
69
+ if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.TIRAMISU) {
70
+ callback(true)
71
+ return
72
+ }
73
+ request(
74
+ android.Manifest.permission.POST_NOTIFICATIONS,
75
+ callback
76
+ )
77
+ }
78
+ }
@@ -0,0 +1,7 @@
1
+ package com.pakstr.app.permissions.interfaces
2
+
3
+ import android.webkit.PermissionRequest
4
+
5
+ interface PermissionHandler {
6
+ fun onPermissionRequest(request: PermissionRequest)
7
+ }
@@ -1,10 +1,10 @@
1
- package com.nostrappshell.app.signer
1
+ package com.pakstr.app.signer
2
2
 
3
3
  import android.app.Activity
4
4
  import android.content.Context
5
5
  import android.content.Intent
6
6
  import androidx.activity.result.ActivityResult
7
- import com.nostrappshell.app.signer.interfaces.NostrSigner
7
+ import com.pakstr.app.signer.interfaces.NostrSigner
8
8
  import kotlinx.coroutines.CancellableContinuation
9
9
  import kotlinx.coroutines.suspendCancellableCoroutine
10
10
  import kotlin.coroutines.resume
@@ -1,7 +1,7 @@
1
- package com.nostrappshell.app.signer
1
+ package com.pakstr.app.signer
2
2
 
3
3
  import android.content.Context
4
- import com.nostrappshell.app.signer.interfaces.NostrSigner
4
+ import com.pakstr.app.signer.interfaces.NostrSigner
5
5
 
6
6
  class BunkerSigner(context: Context) : NostrSigner {
7
7
  override suspend fun getPublicKey(): String {
@@ -1,6 +1,6 @@
1
- package com.nostrappshell.app.signer
1
+ package com.pakstr.app.signer
2
2
 
3
- import com.nostrappshell.app.signer.interfaces.NostrSigner
3
+ import com.pakstr.app.signer.interfaces.NostrSigner
4
4
 
5
5
  class FakeSigner : NostrSigner {
6
6
 
@@ -1,11 +1,10 @@
1
- package com.nostrappshell.app.signer
1
+ package com.pakstr.app.signer
2
2
 
3
3
  import android.os.Handler
4
4
  import android.os.Looper
5
5
  import android.webkit.JavascriptInterface
6
6
  import android.webkit.WebView
7
7
  import android.widget.Toast
8
- import com.nostrappshell.app.signer.interfaces.NostrSigner
9
8
  import kotlinx.coroutines.CoroutineScope
10
9
  import kotlinx.coroutines.Dispatchers
11
10
  import kotlinx.coroutines.launch
@@ -1,9 +1,8 @@
1
- package com.nostrappshell.app.signer
1
+ package com.pakstr.app.signer
2
2
 
3
- import android.app.Activity
4
3
  import android.content.Context
5
4
  import androidx.activity.result.ActivityResult
6
- import com.nostrappshell.app.signer.interfaces.NostrSigner
5
+ import com.pakstr.app.signer.interfaces.NostrSigner
7
6
 
8
7
  class SignerManager(
9
8
  private val context: Context,
@@ -65,12 +64,6 @@ class SignerManager(
65
64
 
66
65
  if (!isAmberInstalled()) {
67
66
 
68
- throw IllegalStateException(
69
-
70
- "Amber signer is not installed. Please install Amber."
71
-
72
- )
73
-
74
67
  }
75
68
 
76
69
  AmberSigner(
@@ -1,4 +1,4 @@
1
- package com.nostrappshell.app.signer
1
+ package com.pakstr.app.signer
2
2
 
3
3
  enum class SignerType {
4
4
  AMBER,
@@ -1,4 +1,4 @@
1
- package com.nostrappshell.app.signer.interfaces
1
+ package com.pakstr.app.signer.interfaces
2
2
 
3
3
  interface NostrSigner {
4
4
 
@@ -1,4 +1,4 @@
1
- package com.nostrappshell.app.ui.theme
1
+ package com.pakstr.app.ui.theme
2
2
 
3
3
  import androidx.compose.ui.graphics.Color
4
4
 
@@ -1,4 +1,4 @@
1
- package com.nostrappshell.app.ui.theme
1
+ package com.pakstr.app.ui.theme
2
2
 
3
3
  import android.os.Build
4
4
  import androidx.compose.foundation.isSystemInDarkTheme
@@ -1,4 +1,4 @@
1
- package com.nostrappshell.app.ui.theme
1
+ package com.pakstr.app.ui.theme
2
2
 
3
3
  import androidx.compose.material3.Typography
4
4
  import androidx.compose.ui.text.TextStyle
@@ -1,4 +1,4 @@
1
- package com.nostrappshell.app.utils
1
+ package com.pakstr.app.utils
2
2
 
3
3
  import android.content.Context
4
4
  import android.content.SharedPreferences
@@ -1,6 +1,6 @@
1
- package com.nostrappshell.app.utils
1
+ package com.pakstr.app.utils
2
2
 
3
- import com.nostrappshell.app.R
3
+ import com.pakstr.app.R
4
4
 
5
5
  import android.os.Bundle
6
6
  import android.view.LayoutInflater
@@ -9,7 +9,7 @@ import android.view.ViewGroup
9
9
  import android.widget.Button
10
10
  import android.widget.RadioGroup
11
11
  import com.google.android.material.bottomsheet.BottomSheetDialogFragment
12
- import com.nostrappshell.app.signer.SignerType
12
+ import com.pakstr.app.signer.SignerType
13
13
 
14
14
  class SignerPickerBottomSheet (
15
15
  private val onSignerSelected: (SignerType) -> Unit
@@ -1,4 +1,4 @@
1
- package com.nostrappshell.app
1
+ package com.pakstr.app
2
2
 
3
3
  import org.junit.Test
4
4
 
package/bin/cli.js CHANGED
@@ -1,10 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const { runCLI } = require("../dist/cli");
3
+ const { runCLI } = require("../dist/cli.js");
4
4
 
5
5
  runCLI(process.argv.slice(2))
6
+
6
7
  .catch((err) => {
8
+
7
9
  console.error("❌ CLI crashed:", err);
10
+
8
11
  process.exit(1);
9
- });
10
12
 
13
+ });
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.patchAppName = patchAppName;
7
+ exports.patchPackageName = patchPackageName;
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const path_1 = __importDefault(require("path"));
10
+ function patchAppName(androidRoot, appName) {
11
+ const stringsPath = path_1.default.join(androidRoot, "app", "src", "main", "res", "values", "strings.xml");
12
+ let xml = fs_1.default.readFileSync(stringsPath, "utf8");
13
+ xml = xml.replace(/<string name="app_name">.*?<\/string>/, `<string name="app_name">${appName}</string>`);
14
+ fs_1.default.writeFileSync(stringsPath, xml);
15
+ console.log("✅ App name:", appName);
16
+ }
17
+ function patchPackageName(androidRoot, packageName) {
18
+ const gradlePath = path_1.default.join(androidRoot, "app", "build.gradle.kts");
19
+ let gradle = fs_1.default.readFileSync(gradlePath, "utf8");
20
+ gradle = gradle.replace(/applicationId\s*=\s*"[^"]+"/, `applicationId = "${packageName}"`);
21
+ fs_1.default.writeFileSync(gradlePath, gradle);
22
+ console.log("✅ ApplicationId:", packageName);
23
+ }
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.patchGradle = patchGradle;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ function patchGradle(androidRoot, manifest) {
10
+ const gradlePath = path_1.default.join(androidRoot, "app/build.gradle.kts");
11
+ let content = fs_1.default.readFileSync(gradlePath, "utf-8");
12
+ content = content.replace(/applicationId\s+".*"/, `applicationId "${manifest.appId}"`);
13
+ content = content.replace(/versionCode\s+\d+/, `versionCode ${manifest.versionCode}`);
14
+ content = content.replace(/versionName\s+".*"/, `versionName "${manifest.versionName}"`);
15
+ fs_1.default.writeFileSync(gradlePath, content);
16
+ console.log("⚙️ Gradle patched");
17
+ }