catalyst-core 0.0.3-canary.1 → 0.0.3-canary.11

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 (96) hide show
  1. package/README.md +2 -3
  2. package/babel.config.js +32 -0
  3. package/bin/catalyst.js +28 -15
  4. package/changelog.md +62 -23
  5. package/dist/native/androidProject/.idea/.name +1 -0
  6. package/dist/native/androidProject/.idea/AndroidProjectSystem.xml +6 -0
  7. package/dist/native/androidProject/.idea/compiler.xml +6 -0
  8. package/dist/native/androidProject/.idea/deploymentTargetSelector.xml +10 -0
  9. package/dist/native/androidProject/.idea/gradle.xml +19 -0
  10. package/dist/native/androidProject/.idea/migrations.xml +10 -0
  11. package/dist/native/androidProject/.idea/misc.xml +5 -0
  12. package/dist/native/androidProject/.idea/runConfigurations.xml +17 -0
  13. package/dist/native/androidProject/.idea/vcs.xml +6 -0
  14. package/dist/native/androidProject/app/build.gradle.kts +185 -31
  15. package/dist/native/androidProject/app/src/main/AndroidManifest.xml +22 -3
  16. package/dist/native/androidProject/app/src/main/assets/webview_config.properties +13 -0
  17. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/CustomWebview.kt +535 -0
  18. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/MainActivity.kt +197 -0
  19. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/NativeBridge.kt +356 -0
  20. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/Utils.kt +64 -0
  21. package/dist/native/androidProject/app/src/main/java/{com/example/myapplication → io/yourname/androidproject}/WebCacheManager.kt +91 -33
  22. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/BridgeUtils.kt +221 -0
  23. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/CameraUtils.kt +269 -0
  24. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/DeviceInfoUtils.kt +60 -0
  25. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/DownloadUtils.kt +251 -0
  26. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/FileSizeRouterUtils.kt +347 -0
  27. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/FileUtils.kt +334 -0
  28. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/FrameworkServerUtils.kt +362 -0
  29. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/IntentUtils.kt +274 -0
  30. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/KeyboardUtil.kt +49 -0
  31. package/dist/native/androidProject/app/src/main/res/drawable/splashscreen_fallback.png +0 -0
  32. package/dist/native/androidProject/app/src/main/res/layout/activity_main.xml +13 -6
  33. package/dist/native/androidProject/app/src/main/res/values/strings.xml +1 -1
  34. package/dist/native/androidProject/app/src/main/res/xml/file_paths.xml +18 -0
  35. package/dist/native/androidProject/gradle/libs.versions.toml +1 -1
  36. package/dist/native/androidProject/gradle/wrapper/gradle-wrapper.properties +1 -1
  37. package/dist/native/androidProject/keystore/Untitled +0 -0
  38. package/dist/native/androidProject/keystore/release-key.jks +0 -0
  39. package/dist/native/androidProject/settings.gradle.kts +1 -1
  40. package/dist/native/androidSetup.js +4 -3
  41. package/dist/native/bridge/WebBridge.js +47 -0
  42. package/dist/native/bridge/constants/NativeInterfaces.js +24 -0
  43. package/dist/native/bridge/errors.js +39 -0
  44. package/dist/native/bridge/hooks.js +77 -0
  45. package/dist/native/bridge/standardizedHooks.js +80 -0
  46. package/dist/native/bridge/useBaseHook.js +43 -0
  47. package/dist/native/bridge/utils/NativeBridge.js +60 -0
  48. package/dist/native/buildAppAndroid.js +94 -7
  49. package/dist/native/buildAppIos.js +23 -15
  50. package/dist/native/iosnativeWebView/iosnativeWebView/Assets.xcassets/AccentColor.colorset/Contents.json +8 -8
  51. package/dist/native/iosnativeWebView/iosnativeWebView/Assets.xcassets/AppIcon.appiconset/Contents.json +10 -10
  52. package/dist/native/iosnativeWebView/iosnativeWebView/Assets.xcassets/Contents.json +4 -4
  53. package/dist/native/iosnativeWebView/iosnativeWebView/ContentView.swift +15 -0
  54. package/dist/native/iosnativeWebView/iosnativeWebView/ImageHandler.swift +288 -0
  55. package/dist/native/iosnativeWebView/iosnativeWebView/Info.plist +2 -0
  56. package/dist/native/iosnativeWebView/iosnativeWebView/NativeBridge.swift +217 -0
  57. package/dist/native/iosnativeWebView/iosnativeWebView/Preview Content/Preview Assets.xcassets/Contents.json +4 -4
  58. package/dist/native/iosnativeWebView/iosnativeWebView/WebView.swift +17 -0
  59. package/dist/native/iosnativeWebView/iosnativeWebView.xcodeproj/project.pbxproj +8 -0
  60. package/dist/native/iosnativeWebView/iosnativeWebView.xcodeproj/project.xcworkspace/xcuserdata/mayansharma.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  61. package/dist/native/renameAndroidProject.js +79 -0
  62. package/dist/native/setupEmulatorIos.js +22 -5
  63. package/dist/native/setupServer.js +28 -0
  64. package/dist/native/terminalProgress.js +10 -10
  65. package/dist/native/utils.js +5 -6
  66. package/dist/otel.js +4 -0
  67. package/dist/scripts/build.js +2 -9
  68. package/dist/scripts/devBuild.js +2 -9
  69. package/dist/scripts/devServe.js +2 -4
  70. package/dist/scripts/loadEnvironmentVariables.js +2 -1
  71. package/dist/scripts/loadScriptsBeforeServerStarts.js +2 -2
  72. package/dist/scripts/registerAliases.js +1 -1
  73. package/dist/scripts/scriptUtils.js +2 -2
  74. package/dist/scripts/serve.js +2 -4
  75. package/dist/scripts/start.js +4 -4
  76. package/dist/sentry.js +2 -0
  77. package/dist/server/expressServer.js +1 -1
  78. package/dist/server/renderer/document/Body.js +3 -3
  79. package/dist/server/renderer/document/Head.js +2 -2
  80. package/dist/server/renderer/extract.js +4 -4
  81. package/dist/server/renderer/handler.js +13 -7
  82. package/dist/server/renderer/index.js +1 -1
  83. package/dist/server/startServer.js +4 -3
  84. package/dist/server/utils/userAgentUtil.js +1 -1
  85. package/dist/server/utils/validator.js +1 -1
  86. package/dist/webpack/babel.config.client.js +1 -1
  87. package/dist/webpack/babel.config.ssr.js +1 -1
  88. package/dist/webpack/base.babel.js +4 -4
  89. package/dist/webpack/development.client.babel.js +17 -2
  90. package/dist/webpack/production.client.babel.js +2 -2
  91. package/dist/webpack/production.ssr.babel.js +2 -2
  92. package/package.json +13 -4
  93. package/babel.config.json +0 -21
  94. package/dist/native/androidProject/app/src/androidTest/java/com/example/myapplication/ExampleInstrumentedTest.kt +0 -24
  95. package/dist/native/androidProject/app/src/main/java/com/example/myapplication/MainActivity.kt +0 -278
  96. package/dist/native/androidProject/app/src/test/java/com/example/myapplication/ExampleUnitTest.kt +0 -17
package/README.md CHANGED
@@ -9,14 +9,13 @@
9
9
 
10
10
  - Overview
11
11
  - Installation
12
-
12
+
13
13
  ## Overview
14
14
 
15
15
  Catalyst offers a comprehensive suite of features designed for modern web development. It includes isomorphic rendering for optimal performance, an extendable server with full-stack capabilities, and configurable state management. The framework employs smart prefetching of data and chunks, allows easy configuration of global styles and layouts, and provides SEO optimization at both global and page levels.
16
16
 
17
17
  This version adds support for Universal app for both Android and iOS. Please checkout [Universal App Documentaion](https://catalyst.1mg.com/public_docs/content/Universal%20App/RunUniversalApp)
18
18
 
19
-
20
19
  ## Installation
21
20
 
22
21
  **System Requirements**
@@ -38,7 +37,7 @@ You will see some prompts to configure your application.
38
37
  cd <name-of-your-project> && npm run start
39
38
  ```
40
39
 
41
- The development server will start at ```http://localhost:3005```
40
+ The development server will start at `http://localhost:3005`
42
41
 
43
42
  ## Documentation
44
43
 
@@ -0,0 +1,32 @@
1
+ module.exports = (api) => {
2
+ api.cache(true)
3
+
4
+ return {
5
+ presets: [
6
+ [
7
+ "@babel/preset-typescript",
8
+ {
9
+ isTSX: true,
10
+ allExtensions: true,
11
+ },
12
+ ],
13
+ [
14
+ "@babel/preset-env",
15
+ {
16
+ targets: {
17
+ node: "current",
18
+ },
19
+ },
20
+ ],
21
+ ["@babel/preset-react", { runtime: "automatic" }],
22
+ ],
23
+ compact: true,
24
+ plugins: ["@loadable/babel-plugin"],
25
+ env: {
26
+ test: {
27
+ presets: ["@babel/preset-react"],
28
+ },
29
+ },
30
+ ignore: ["__TEST__"],
31
+ }
32
+ }
package/bin/catalyst.js CHANGED
@@ -8,9 +8,17 @@ const args = process.argv.slice(2)
8
8
 
9
9
  // Array of valid commands
10
10
  const validCommands = [
11
- "build", "start", "serve", "devBuild", "devServe",
12
- "buildApp", "buildApp:ios", "buildApp:android",
13
- "setupEmulator", "setupEmulator:ios", "setupEmulator:android"
11
+ "build",
12
+ "start",
13
+ "serve",
14
+ "devBuild",
15
+ "devServe",
16
+ "buildApp",
17
+ "buildApp:ios",
18
+ "buildApp:android",
19
+ "setupEmulator",
20
+ "setupEmulator:ios",
21
+ "setupEmulator:android",
14
22
  ]
15
23
 
16
24
  // Map of platform-specific commands to their script paths
@@ -18,17 +26,16 @@ const platformScripts = {
18
26
  "setupEmulator:ios": "../dist/native/setupEmulatorIos.js",
19
27
  "setupEmulator:android": "../dist/native/androidSetup.js",
20
28
  "buildApp:ios": "../dist/native/buildAppIos.js",
21
- "buildApp:android": "../dist/native/buildAppAndroid.js"
29
+ "buildApp:android": "../dist/native/buildAppAndroid.js",
22
30
  }
23
31
 
24
32
  // Helper to check if arg is a platform command
25
33
  const isPlatformCommand = (arg, prefix) => {
26
34
  if (!arg.startsWith(`${prefix}:`)) return false
27
- const platform = arg.split(':')[1]
28
- return ['ios', 'android'].includes(platform) || platform === undefined
35
+ const platform = arg.split(":")[1]
36
+ return ["ios", "android"].includes(platform) || platform === undefined
29
37
  }
30
38
 
31
-
32
39
  // Helper function to run a platform command
33
40
  const runPlatformCommand = (baseCommand, platform) => {
34
41
  const command = `${baseCommand}:${platform}`
@@ -42,7 +49,7 @@ const runPlatformCommand = (baseCommand, platform) => {
42
49
 
43
50
  // Helper function to run commands for all platforms
44
51
  const runAllPlatforms = (baseCommand) => {
45
- const platforms = ['ios', 'android']
52
+ const platforms = ["ios", "android"]
46
53
  for (const platform of platforms) {
47
54
  const result = runPlatformCommand(baseCommand, platform)
48
55
  if (result.status !== 0) {
@@ -54,8 +61,14 @@ const runAllPlatforms = (baseCommand) => {
54
61
  }
55
62
 
56
63
  const scriptIndex = args.findIndex(
57
- (x) => x === "build" || x === "start" || x === "serve" || x === "devBuild" || x === "devServe" ||
58
- isPlatformCommand(x, 'buildApp') || isPlatformCommand(x, 'setupEmulator')
64
+ (x) =>
65
+ x === "build" ||
66
+ x === "start" ||
67
+ x === "serve" ||
68
+ x === "devBuild" ||
69
+ x === "devServe" ||
70
+ isPlatformCommand(x, "buildApp") ||
71
+ isPlatformCommand(x, "setupEmulator")
59
72
  )
60
73
  const script = scriptIndex === -1 ? args[0] : args[scriptIndex]
61
74
  const nodeArgs = scriptIndex > 0 ? args.slice(0, scriptIndex) : []
@@ -92,17 +105,17 @@ function handleProcessResult(result) {
92
105
  if (result.signal === "SIGKILL") {
93
106
  console.log(
94
107
  "The build failed because the process exited too early. " +
95
- "This probably means the system ran out of memory or someone called " +
96
- "`kill -9` on the process."
108
+ "This probably means the system ran out of memory or someone called " +
109
+ "`kill -9` on the process."
97
110
  )
98
111
  } else if (result.signal === "SIGTERM") {
99
112
  console.log(
100
113
  "The build failed because the process exited too early. " +
101
- "Someone might have called `kill` or `killall`, or the system could " +
102
- "be shutting down."
114
+ "Someone might have called `kill` or `killall`, or the system could " +
115
+ "be shutting down."
103
116
  )
104
117
  }
105
118
  process.exit(1)
106
119
  }
107
120
  process.exit(result.status)
108
- }
121
+ }
package/changelog.md CHANGED
@@ -1,36 +1,75 @@
1
1
  # Changelog
2
2
 
3
- ## [0.0.3-canary.1] - 31-01-2025
3
+ ## [0.0.3-canary.11] - 2025-09-26
4
4
 
5
- ### Changes
5
+ - **Build organization**: Store APKs and iOS builds organized by generation date and time for better tracking and management
6
+ - **Enhanced Android native support**: Add support for native keyboard and webview resizing in Android
7
+ - **Device info API web support**: Web support in device info API
6
8
 
7
- # Native WebView Implementation and Cache Management Updates
9
+ ## [0.0.3-canary.10] - 2025-09-11
8
10
 
9
- ## Overview
10
- This PR introduces native WebView implementations for both Android and iOS platforms, along with significant cache management improvements and bug fixes.
11
+ - **Sentry import bug fix**
12
+ - **Open telemetry SDK**
11
13
 
12
- ## Changes
14
+ ## [0.0.3-canary.9] - 2025-09-11
13
15
 
14
- ### New Features
15
- - Implemented native Android WebView with cache management functionality
16
- - Added iOS native WebView implementation with custom cache handling
17
- - Introduced new cache pattern management system
16
+ - **App name configuration**
17
+ - **Device Info API**
18
+ - **Access control configuration**
18
19
 
19
- ### Technical Implementation Details
20
- - Android:
21
- - Added complete Android project structure with WebView implementation
22
- - Implemented `WebCacheManager.kt` for handling cache operations
23
- - Set up Gradle configuration and project dependencies
20
+ ## [0.0.3-canary.8] - 2025-01-06
24
21
 
25
- - iOS:
26
- - Created iOS native WebView project with Swift
27
- - Implemented `CacheManager.swift` and `ResourceURLProtocol.swift` for cache handling
28
- - Added WebView navigation and view model components
22
+ - **App icon configuration**
23
+ - **Splash screen integration**
24
+ - **Url Whitelisting**
29
25
 
26
+ ## [0.0.3-canary.7] - 2025-01-06
30
27
 
31
- ### Other Changes
32
- - Enhanced terminal progress reporting
33
- - Updated documentation and README
28
+ ### 🚀 Features
29
+
30
+ - **Native API Integration**: Enhanced native module integration for better performance
31
+ - **Automated IP Resolution**: Intelligent network detection eliminates manual IP configuration
32
+ - **Universal Build System**: Streamlined one-command builds for both Android and iOS platforms
33
+ - **Enhanced CLI Interface**: Improved command-line tools for better developer experience
34
+
35
+ ### 🐛 Bug Fixes
36
+
37
+ - Fixed IP address detection issues on development environments
38
+ - Resolved build configuration conflicts between platforms
39
+ - Improved error handling and recovery mechanisms
40
+
41
+ ### 🔧 Improvements
42
+
43
+ - **Performance**: Optimized native module loading and execution
44
+ - **Developer Experience**: Enhanced CLI with better error messages and debugging info
45
+ - **Configuration**: Dynamic config updates without requiring restarts
46
+ - **Build Process**: Faster and more reliable build pipeline
47
+
48
+ ### 🧪 Testing & Validation
49
+
50
+ - ✅ **Android Build**: Verified APK generation, installation, and runtime behavior
51
+ - ✅ **iOS Build**: Tested build process and device compatibility
52
+ - ✅ **IP Detection**: Validated automatic network resolution across platforms
53
+ - ✅ **Native Modules**: Confirmed API integration and performance benchmarks
54
+ - ✅ **CLI Operations**: Tested enhanced command-line workflows and error handling
55
+
56
+ ### 🔄 Breaking Changes
57
+
58
+ **None** - All changes maintain backward compatibility while enhancing existing functionality
59
+
60
+ ### 📝 Technical Details
61
+
62
+ - Improved native API bridge for better cross-platform communication
63
+ - Enhanced error reporting with detailed stack traces and suggestions
64
+ - Optimized build configuration for faster development cycles
65
+ - Added comprehensive logging for debugging and monitoring
66
+
67
+ ### 🔗 Migration Notes
68
+
69
+ - No migration steps required
70
+ - Existing projects will automatically benefit from improvements
71
+ - Optional: Update CLI usage to leverage new enhanced features
34
72
 
35
73
  ## Version
36
- - Target version: 0.0.3-canary.1
74
+
75
+ - Target version: 0.0.3-canary.7
@@ -0,0 +1 @@
1
+ Catalyst Application
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="AndroidProjectSystem">
4
+ <option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="CompilerConfiguration">
4
+ <bytecodeTargetLevel target="21" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="deploymentTargetSelector">
4
+ <selectionStates>
5
+ <SelectionState runConfigName="app">
6
+ <option name="selectionMode" value="DROPDOWN" />
7
+ </SelectionState>
8
+ </selectionStates>
9
+ </component>
10
+ </project>
@@ -0,0 +1,19 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="GradleMigrationSettings" migrationVersion="1" />
4
+ <component name="GradleSettings">
5
+ <option name="linkedExternalProjectsSettings">
6
+ <GradleProjectSettings>
7
+ <option name="testRunner" value="CHOOSE_PER_TEST" />
8
+ <option name="externalProjectPath" value="$PROJECT_DIR$" />
9
+ <option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
10
+ <option name="modules">
11
+ <set>
12
+ <option value="$PROJECT_DIR$" />
13
+ <option value="$PROJECT_DIR$/app" />
14
+ </set>
15
+ </option>
16
+ </GradleProjectSettings>
17
+ </option>
18
+ </component>
19
+ </project>
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectMigrations">
4
+ <option name="MigrateToGradleLocalJavaHome">
5
+ <set>
6
+ <option value="$PROJECT_DIR$" />
7
+ </set>
8
+ </option>
9
+ </component>
10
+ </project>
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ExternalStorageConfigurationManager" enabled="true" />
4
+ <component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK" />
5
+ </project>
@@ -0,0 +1,17 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="RunConfigurationProducerService">
4
+ <option name="ignoredProducers">
5
+ <set>
6
+ <option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
7
+ <option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
8
+ <option value="com.intellij.execution.junit.PatternConfigurationProducer" />
9
+ <option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
10
+ <option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
11
+ <option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
12
+ <option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
13
+ <option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
14
+ </set>
15
+ </option>
16
+ </component>
17
+ </project>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="$PROJECT_DIR$/../../.." vcs="Git" />
5
+ </component>
6
+ </project>
@@ -1,8 +1,19 @@
1
1
  import java.net.NetworkInterface
2
2
  import java.io.File
3
3
  import java.util.Properties
4
+ import org.json.JSONObject
5
+ import org.json.JSONArray
6
+
7
+ buildscript {
8
+ dependencies {
9
+ classpath("org.json:json:20231013")
10
+ }
11
+ }
4
12
 
5
13
  val configPath: String? by project.properties
14
+ val keystorePassword: String? by project.properties // Changed from keyStorePassword to keystorePassword
15
+ val keyAlias: String? by project.properties
16
+ val keyPassword: String? by project.properties
6
17
 
7
18
  fun getLocalIpAddress(): String {
8
19
  return NetworkInterface.getNetworkInterfaces().toList()
@@ -18,35 +29,73 @@ plugins {
18
29
  }
19
30
 
20
31
  android {
21
- namespace = "com.example.androidProject"
32
+ namespace = "io.yourname.androidproject"
22
33
  compileSdk = 34
23
34
 
24
35
  defaultConfig {
25
- applicationId = "com.example.androidProject"
36
+ applicationId = "io.yourname.androidproject"
26
37
  minSdk = 24
27
38
  targetSdk = 34
28
39
  versionCode = 1
29
- versionName = "1.0"
40
+ versionName = "1.1"
30
41
  testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
31
42
  buildConfigField("String", "LOCAL_IP", "\"${getLocalIpAddress()}\"")
32
43
  }
33
44
 
45
+ // Add signing configuration for app bundle
46
+ signingConfigs {
47
+ create("release") {
48
+ // Make sure the keystore file exists before referencing it
49
+ val keystoreFile = file("../keystore/release-key.jks")
50
+ if (keystoreFile.exists()) {
51
+ storeFile = file("../keystore/release-key.jks")
52
+ storePassword = "test@123"
53
+ keyAlias = "release"
54
+ keyPassword = "test@123"
55
+ } else {
56
+ // Log a warning if the keystore doesn't exist yet
57
+ logger.warn("Keystore file not found at ${keystoreFile.absolutePath}. Run the generateKeystore task first.")
58
+ }
59
+ }
60
+ }
61
+
34
62
  buildTypes {
35
63
  debug {
36
64
  manifestPlaceholders += mapOf("allowCleartextTraffic" to true)
65
+ applicationIdSuffix = ".debug"
66
+ versionNameSuffix = "-debug"
37
67
  isMinifyEnabled = false
38
68
  buildConfigField("Boolean", "ALLOW_MIXED_CONTENT", "true")
39
69
  buildConfigField("String", "LOCAL_IP", "\"${getLocalIpAddress()}\"")
40
70
  }
41
71
  release {
42
72
  manifestPlaceholders += mapOf("allowCleartextTraffic" to false)
43
- isMinifyEnabled = false
73
+ isMinifyEnabled = true
74
+ isShrinkResources = true
44
75
  proguardFiles(
45
76
  getDefaultProguardFile("proguard-android-optimize.txt"),
46
77
  "proguard-rules.pro"
47
78
  )
48
79
  buildConfigField("Boolean", "ALLOW_MIXED_CONTENT", "false")
49
80
  buildConfigField("String", "LOCAL_IP", "\"127.0.0.1\"")
81
+
82
+ // Only apply signing config if the keystore exists
83
+ if (file("../keystore/release-key.jks").exists()) {
84
+ signingConfig = signingConfigs.getByName("release")
85
+ }
86
+ }
87
+ }
88
+
89
+ // Configure App Bundle settings
90
+ bundle {
91
+ language {
92
+ enableSplit = true
93
+ }
94
+ density {
95
+ enableSplit = true
96
+ }
97
+ abi {
98
+ enableSplit = true
50
99
  }
51
100
  }
52
101
 
@@ -63,6 +112,23 @@ android {
63
112
  viewBinding = true
64
113
  buildConfig = true
65
114
  }
115
+
116
+ packaging {
117
+ resources {
118
+ excludes.add("**/route-manifest.json.gz")
119
+ excludes.add("**/route-manifest.json.br")
120
+ excludes.add("META-INF/LICENSE")
121
+ excludes.add("META-INF/NOTICE")
122
+ excludes.add("META-INF/INDEX.LIST")
123
+ excludes.add("META-INF/io.netty.versions.properties")
124
+ }
125
+ }
126
+
127
+ // Configure lint options
128
+ lint {
129
+ checkReleaseBuilds = true
130
+ abortOnError = true
131
+ }
66
132
  }
67
133
 
68
134
  dependencies {
@@ -75,6 +141,16 @@ dependencies {
75
141
  androidTestImplementation(libs.androidx.espresso.core)
76
142
  implementation("androidx.webkit:webkit:1.12.1")
77
143
  implementation("org.json:json:20231013")
144
+ implementation("androidx.core:core-splashscreen:1.0.1")
145
+
146
+ // Ktor Server dependencies for FrameworkServer (~200KB total)
147
+ implementation("io.ktor:ktor-server-core:2.3.7")
148
+ implementation("io.ktor:ktor-server-netty:2.3.7")
149
+ implementation("io.ktor:ktor-server-content-negotiation:2.3.7")
150
+ implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
151
+
152
+ // SLF4J simple logger for Ktor (optional, can be excluded if needed)
153
+ implementation("org.slf4j:slf4j-simple:2.0.9")
78
154
  }
79
155
 
80
156
  // Task to verify local IP
@@ -129,52 +205,130 @@ tasks.register("generateWebViewConfig") {
129
205
  }
130
206
 
131
207
  val configContent = configJsonFile.readText()
208
+
209
+ val jsonObject = JSONObject(configContent)
210
+
211
+ if (!jsonObject.has("WEBVIEW_CONFIG")) {
212
+ throw GradleException("WEBVIEW_CONFIG not found in config file")
213
+ }
214
+
215
+ val webviewConfig = jsonObject.getJSONObject("WEBVIEW_CONFIG")
216
+
217
+ val properties = Properties()
132
218
 
133
- // Extract WEBVIEW_CONFIG section
134
- val webviewConfigRegex = """"WEBVIEW_CONFIG"\s*:\s*\{([^}]*)\}""".toRegex()
135
- val webviewConfigMatch = webviewConfigRegex.find(configContent)
136
- val webviewConfigContent = webviewConfigMatch?.groupValues?.get(1)
219
+ // Set different IP based on build type
220
+ if (gradle.startParameter.taskNames.any { it.contains("Release") || it.contains("release") }) {
221
+ properties.setProperty("LOCAL_IP", "127.0.0.1") // Production
222
+ properties.setProperty("buildType", "release")
223
+ properties.setProperty("buildOptimisation", "true")
224
+ } else {
225
+ properties.setProperty("LOCAL_IP", getLocalIpAddress()) // Debug
226
+ properties.setProperty("buildType", "debug")
227
+ properties.setProperty("buildOptimisation", "false")
228
+ }
137
229
 
138
- val properties = Properties()
139
- properties.setProperty("LOCAL_IP", getLocalIpAddress())
140
-
141
- // Parse top-level properties
142
- val topLevelRegex = """"([^"]+)"\s*:\s*"([^"]+)"""".toRegex()
143
- webviewConfigContent?.let {
144
- topLevelRegex.findAll(it).forEach { matchResult ->
145
- val (key, value) = matchResult.destructured
146
- if (key != "android") {
147
- properties.setProperty(key, value)
230
+ fun extractProperties(jsonObj: org.json.JSONObject, prefix: String = "") {
231
+ try {
232
+ val keys = jsonObj.keys()
233
+
234
+ while (keys.hasNext()) {
235
+ val key = keys.next()
236
+ val value = jsonObj.opt(key)
237
+ val fullKey = if (prefix.isEmpty()) key else "$prefix.$key"
238
+
239
+ when (value) {
240
+ is org.json.JSONObject -> {
241
+ extractProperties(value, fullKey)
242
+ }
243
+ is org.json.JSONArray -> {
244
+ val arrayValues = (0 until value.length()).map { i ->
245
+ value.opt(i).toString()
246
+ }.joinToString(",")
247
+ properties.setProperty(fullKey, arrayValues)
248
+ }
249
+ else -> {
250
+ properties.setProperty(fullKey, value.toString())
251
+ }
252
+ }
148
253
  }
254
+ } catch (e: Exception) {
255
+ throw RuntimeException("Failed to extract properties from JSON at prefix: $prefix", e)
149
256
  }
150
257
  }
151
258
 
152
- // Parse android object specifically
153
- val androidRegex = """"android"\s*:\s*\{([^}]*)\}""".toRegex()
154
- val androidMatch = androidRegex.find(webviewConfigContent ?: "")
155
- val androidContent = androidMatch?.groupValues?.get(1)
259
+ extractProperties(webviewConfig)
156
260
 
157
- // Parse android object properties
158
- val androidPropsRegex = """"([^"]+)"\s*:\s*"([^"]+)"""".toRegex()
159
- androidContent?.let {
160
- androidPropsRegex.findAll(it).forEach { matchResult ->
161
- val (key, value) = matchResult.destructured
162
- properties.setProperty("android.$key", value)
163
- }
261
+ // Set production-specific properties for release builds
262
+ if (gradle.startParameter.taskNames.any { it.contains("Release") || it.contains("release") }) {
263
+ properties.setProperty("PRODUCTION_URL", "https://yourwebapp.com") // Replace with your domain
264
+ properties.setProperty("apiBaseUrl", "https://api.yourdomain.com/") // Replace with your API URL
164
265
  }
165
266
 
166
267
  // Create the assets directory if it doesn't exist
167
268
  val assetsDir = File("${project.projectDir}/src/main/assets")
168
269
  if (!assetsDir.exists()) {
169
270
  assetsDir.mkdirs()
170
- println("Created assets directory at ${assetsDir.absolutePath}")
171
271
  }
172
272
 
173
273
  // Write to properties file
174
274
  File(assetsDir, "webview_config.properties").outputStream().use {
175
275
  properties.store(it, "WebView Configuration")
176
276
  }
277
+ }
278
+ }
279
+
280
+ // Task to create key store if it doesn't exist
281
+ // Add this task to your build.gradle.kts
282
+ tasks.register("generateKeystore") {
283
+ doLast {
284
+ val keystoreDir = File(project.rootDir, "keystore")
285
+ if (!keystoreDir.exists()) {
286
+ keystoreDir.mkdirs()
287
+ }
177
288
 
178
- println("WebView config generated at ${assetsDir.absolutePath}/webview_config.properties")
289
+ val keystoreFile = File(keystoreDir, "release-key.jks")
290
+ if (!keystoreFile.exists()) {
291
+ val storePass = project.properties["keystorePassword"] as? String ?: System.getenv("KEYSTORE_PASSWORD") ?: "android"
292
+ val keyPass = project.properties["keyPassword"] as? String ?: System.getenv("KEY_PASSWORD") ?: "android"
293
+ val alias = project.properties["keyAlias"] as? String ?: System.getenv("KEY_ALIAS") ?: "release"
294
+
295
+ exec {
296
+ commandLine = listOf(
297
+ "keytool",
298
+ "-genkey",
299
+ "-v",
300
+ "-keystore", keystoreFile.absolutePath,
301
+ "-alias", alias,
302
+ "-keyalg", "RSA",
303
+ "-keysize", "2048",
304
+ "-validity", "10000",
305
+ "-storepass", storePass,
306
+ "-keypass", keyPass,
307
+ "-dname", "CN=YourCompany, OU=YourDepartment, O=YourOrganization, L=YourCity, ST=YourState, C=US"
308
+ )
309
+ }
310
+ println("Generated keystore at: ${keystoreFile.absolutePath}")
311
+ } else {
312
+ println("Keystore already exists at: ${keystoreFile.absolutePath}")
313
+ }
314
+ }
315
+ }
316
+ // Task to build app bundle
317
+ tasks.register("createAppBundle") {
318
+ dependsOn("generateKeystore", "bundleRelease")
319
+ doLast {
320
+ println("""
321
+ =======================================================
322
+ App Bundle created successfully!
323
+
324
+ Location: ${project.buildDir}/outputs/bundle/release/app-release.aab
325
+
326
+ Next steps:
327
+ 1. Test your bundle with:
328
+ bundletool build-apks --bundle=app/build/outputs/bundle/release/app-release.aab --output=test.apks
329
+
330
+ 2. Upload to Play Console: https://play.google.com/console
331
+ =======================================================
332
+ """.trimIndent())
179
333
  }
180
334
  }