catalyst-core 0.0.3-canary.1 → 0.0.3-canary.10
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.
- package/README.md +2 -3
- package/babel.config.js +32 -0
- package/bin/catalyst.js +28 -15
- package/changelog.md +56 -23
- package/dist/native/androidProject/app/build.gradle.kts +185 -31
- package/dist/native/androidProject/app/src/main/AndroidManifest.xml +22 -3
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/CustomWebview.kt +535 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/MainActivity.kt +188 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/NativeBridge.kt +356 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/Utils.kt +64 -0
- package/dist/native/androidProject/app/src/main/java/{com/example/myapplication → io/yourname/androidproject}/WebCacheManager.kt +91 -33
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/BridgeUtils.kt +221 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/CameraUtils.kt +269 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/DeviceInfoUtils.kt +60 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/DownloadUtils.kt +251 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/FileSizeRouterUtils.kt +347 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/FileUtils.kt +334 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/FrameworkServerUtils.kt +362 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/IntentUtils.kt +274 -0
- package/dist/native/androidProject/app/src/main/res/drawable/splashscreen_fallback.png +0 -0
- package/dist/native/androidProject/app/src/main/res/layout/activity_main.xml +12 -6
- package/dist/native/androidProject/app/src/main/res/values/strings.xml +1 -1
- package/dist/native/androidProject/app/src/main/res/xml/file_paths.xml +18 -0
- package/dist/native/androidProject/gradle/libs.versions.toml +1 -1
- package/dist/native/androidProject/gradle/wrapper/gradle-wrapper.properties +1 -1
- package/dist/native/androidProject/keystore/Untitled +0 -0
- package/dist/native/androidProject/keystore/release-key.jks +0 -0
- package/dist/native/androidProject/settings.gradle.kts +1 -1
- package/dist/native/androidSetup.js +4 -3
- package/dist/native/bridge/WebBridge.js +46 -0
- package/dist/native/bridge/constants/NativeInterfaces.js +24 -0
- package/dist/native/bridge/errors.js +39 -0
- package/dist/native/bridge/hooks.js +77 -0
- package/dist/native/bridge/standardizedHooks.js +80 -0
- package/dist/native/bridge/useBaseHook.js +43 -0
- package/dist/native/bridge/utils/NativeBridge.js +60 -0
- package/dist/native/buildAppAndroid.js +81 -7
- package/dist/native/buildAppIos.js +18 -14
- package/dist/native/iosnativeWebView/iosnativeWebView/Assets.xcassets/AccentColor.colorset/Contents.json +8 -8
- package/dist/native/iosnativeWebView/iosnativeWebView/Assets.xcassets/AppIcon.appiconset/Contents.json +10 -10
- package/dist/native/iosnativeWebView/iosnativeWebView/Assets.xcassets/Contents.json +4 -4
- package/dist/native/iosnativeWebView/iosnativeWebView/ContentView.swift +15 -0
- package/dist/native/iosnativeWebView/iosnativeWebView/ImageHandler.swift +288 -0
- package/dist/native/iosnativeWebView/iosnativeWebView/Info.plist +2 -0
- package/dist/native/iosnativeWebView/iosnativeWebView/NativeBridge.swift +217 -0
- package/dist/native/iosnativeWebView/iosnativeWebView/Preview Content/Preview Assets.xcassets/Contents.json +4 -4
- package/dist/native/iosnativeWebView/iosnativeWebView/WebView.swift +17 -0
- package/dist/native/iosnativeWebView/iosnativeWebView.xcodeproj/project.pbxproj +8 -0
- package/dist/native/renameAndroidProject.js +79 -0
- package/dist/native/setupEmulatorIos.js +22 -5
- package/dist/native/setupServer.js +28 -0
- package/dist/native/terminalProgress.js +10 -10
- package/dist/native/utils.js +5 -6
- package/dist/otel.js +4 -0
- package/dist/scripts/build.js +2 -9
- package/dist/scripts/devBuild.js +2 -9
- package/dist/scripts/devServe.js +2 -4
- package/dist/scripts/loadEnvironmentVariables.js +2 -1
- package/dist/scripts/loadScriptsBeforeServerStarts.js +2 -2
- package/dist/scripts/registerAliases.js +1 -1
- package/dist/scripts/scriptUtils.js +2 -2
- package/dist/scripts/serve.js +2 -4
- package/dist/scripts/start.js +4 -4
- package/dist/sentry.js +2 -0
- package/dist/server/expressServer.js +1 -1
- package/dist/server/renderer/document/Body.js +3 -3
- package/dist/server/renderer/document/Head.js +2 -2
- package/dist/server/renderer/extract.js +4 -4
- package/dist/server/renderer/handler.js +13 -7
- package/dist/server/renderer/index.js +1 -1
- package/dist/server/startServer.js +4 -3
- package/dist/server/utils/userAgentUtil.js +1 -1
- package/dist/server/utils/validator.js +1 -1
- package/dist/webpack/babel.config.client.js +1 -1
- package/dist/webpack/babel.config.ssr.js +1 -1
- package/dist/webpack/base.babel.js +4 -4
- package/dist/webpack/development.client.babel.js +17 -2
- package/dist/webpack/production.client.babel.js +2 -2
- package/dist/webpack/production.ssr.babel.js +2 -2
- package/package.json +13 -4
- package/babel.config.json +0 -21
- package/dist/native/androidProject/app/src/androidTest/java/com/example/myapplication/ExampleInstrumentedTest.kt +0 -24
- package/dist/native/androidProject/app/src/main/java/com/example/myapplication/MainActivity.kt +0 -278
- 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
|
|
40
|
+
The development server will start at `http://localhost:3005`
|
|
42
41
|
|
|
43
42
|
## Documentation
|
|
44
43
|
|
package/babel.config.js
ADDED
|
@@ -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",
|
|
12
|
-
"
|
|
13
|
-
"
|
|
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(
|
|
28
|
-
return [
|
|
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 = [
|
|
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) =>
|
|
58
|
-
|
|
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
|
-
|
|
96
|
-
|
|
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
|
-
|
|
102
|
-
|
|
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,69 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [0.0.3-canary.
|
|
3
|
+
## [0.0.3-canary.10] - 2025-09-11
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
- **Sentry import bug fix**
|
|
6
|
+
- **Open telemetry SDK**
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
## [0.0.3-canary.9] - 2025-09-11
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
- **App name configuration**
|
|
11
|
+
- **Device Info API**
|
|
12
|
+
- **Access control configuration**
|
|
11
13
|
|
|
12
|
-
##
|
|
14
|
+
## [0.0.3-canary.8] - 2025-01-06
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
- Introduced new cache pattern management system
|
|
16
|
+
- **App icon configuration**
|
|
17
|
+
- **Splash screen integration**
|
|
18
|
+
- **Url Whitelisting**
|
|
18
19
|
|
|
19
|
-
|
|
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.7] - 2025-01-06
|
|
24
21
|
|
|
25
|
-
|
|
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
|
+
### 🚀 Features
|
|
29
23
|
|
|
24
|
+
- **Native API Integration**: Enhanced native module integration for better performance
|
|
25
|
+
- **Automated IP Resolution**: Intelligent network detection eliminates manual IP configuration
|
|
26
|
+
- **Universal Build System**: Streamlined one-command builds for both Android and iOS platforms
|
|
27
|
+
- **Enhanced CLI Interface**: Improved command-line tools for better developer experience
|
|
30
28
|
|
|
31
|
-
###
|
|
32
|
-
|
|
33
|
-
-
|
|
29
|
+
### 🐛 Bug Fixes
|
|
30
|
+
|
|
31
|
+
- Fixed IP address detection issues on development environments
|
|
32
|
+
- Resolved build configuration conflicts between platforms
|
|
33
|
+
- Improved error handling and recovery mechanisms
|
|
34
|
+
|
|
35
|
+
### 🔧 Improvements
|
|
36
|
+
|
|
37
|
+
- **Performance**: Optimized native module loading and execution
|
|
38
|
+
- **Developer Experience**: Enhanced CLI with better error messages and debugging info
|
|
39
|
+
- **Configuration**: Dynamic config updates without requiring restarts
|
|
40
|
+
- **Build Process**: Faster and more reliable build pipeline
|
|
41
|
+
|
|
42
|
+
### 🧪 Testing & Validation
|
|
43
|
+
|
|
44
|
+
- ✅ **Android Build**: Verified APK generation, installation, and runtime behavior
|
|
45
|
+
- ✅ **iOS Build**: Tested build process and device compatibility
|
|
46
|
+
- ✅ **IP Detection**: Validated automatic network resolution across platforms
|
|
47
|
+
- ✅ **Native Modules**: Confirmed API integration and performance benchmarks
|
|
48
|
+
- ✅ **CLI Operations**: Tested enhanced command-line workflows and error handling
|
|
49
|
+
|
|
50
|
+
### 🔄 Breaking Changes
|
|
51
|
+
|
|
52
|
+
**None** - All changes maintain backward compatibility while enhancing existing functionality
|
|
53
|
+
|
|
54
|
+
### 📝 Technical Details
|
|
55
|
+
|
|
56
|
+
- Improved native API bridge for better cross-platform communication
|
|
57
|
+
- Enhanced error reporting with detailed stack traces and suggestions
|
|
58
|
+
- Optimized build configuration for faster development cycles
|
|
59
|
+
- Added comprehensive logging for debugging and monitoring
|
|
60
|
+
|
|
61
|
+
### 🔗 Migration Notes
|
|
62
|
+
|
|
63
|
+
- No migration steps required
|
|
64
|
+
- Existing projects will automatically benefit from improvements
|
|
65
|
+
- Optional: Update CLI usage to leverage new enhanced features
|
|
34
66
|
|
|
35
67
|
## Version
|
|
36
|
-
|
|
68
|
+
|
|
69
|
+
- Target version: 0.0.3-canary.7
|
|
@@ -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 = "
|
|
32
|
+
namespace = "io.yourname.androidproject"
|
|
22
33
|
compileSdk = 34
|
|
23
34
|
|
|
24
35
|
defaultConfig {
|
|
25
|
-
applicationId = "
|
|
36
|
+
applicationId = "io.yourname.androidproject"
|
|
26
37
|
minSdk = 24
|
|
27
38
|
targetSdk = 34
|
|
28
39
|
versionCode = 1
|
|
29
|
-
versionName = "1.
|
|
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 =
|
|
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
|
-
//
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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
|
-
|
|
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
|
}
|
|
@@ -3,26 +3,45 @@
|
|
|
3
3
|
xmlns:tools="http://schemas.android.com/tools">
|
|
4
4
|
<uses-permission android:name="android.permission.INTERNET" />
|
|
5
5
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
|
6
|
+
<uses-permission android:name="android.permission.CAMERA" />
|
|
7
|
+
<uses-permission android:name="android.permission.VIBRATE" />
|
|
8
|
+
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
|
9
|
+
<queries>
|
|
10
|
+
<intent>
|
|
11
|
+
<action android:name="android.media.action.IMAGE_CAPTURE" />
|
|
12
|
+
</intent>
|
|
13
|
+
</queries>
|
|
6
14
|
<application
|
|
7
|
-
android:usesCleartextTraffic="${allowCleartextTraffic}"
|
|
8
15
|
android:allowBackup="true"
|
|
9
16
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
|
10
17
|
android:fullBackupContent="@xml/backup_rules"
|
|
18
|
+
android:hardwareAccelerated="true"
|
|
11
19
|
android:icon="@mipmap/ic_launcher"
|
|
12
20
|
android:label="@string/app_name"
|
|
13
21
|
android:roundIcon="@mipmap/ic_launcher_round"
|
|
14
22
|
android:supportsRtl="true"
|
|
15
23
|
android:theme="@style/Theme.AndroidProject"
|
|
24
|
+
android:usesCleartextTraffic="${allowCleartextTraffic}"
|
|
16
25
|
tools:targetApi="31">
|
|
17
26
|
<activity
|
|
18
|
-
android:name=".MainActivity"
|
|
19
|
-
android:exported="true"
|
|
27
|
+
android:name="io.yourname.androidproject.MainActivity"
|
|
28
|
+
android:exported="true"
|
|
29
|
+
android:screenOrientation="portrait">
|
|
20
30
|
<intent-filter>
|
|
21
31
|
<action android:name="android.intent.action.MAIN" />
|
|
22
32
|
|
|
23
33
|
<category android:name="android.intent.category.LAUNCHER" />
|
|
24
34
|
</intent-filter>
|
|
25
35
|
</activity>
|
|
36
|
+
<provider
|
|
37
|
+
android:name="androidx.core.content.FileProvider"
|
|
38
|
+
android:authorities="io.yourname.androidproject.fileprovider"
|
|
39
|
+
android:exported="false"
|
|
40
|
+
android:grantUriPermissions="true">
|
|
41
|
+
<meta-data
|
|
42
|
+
android:name="android.support.FILE_PROVIDER_PATHS"
|
|
43
|
+
android:resource="@xml/file_paths" />
|
|
44
|
+
</provider>
|
|
26
45
|
</application>
|
|
27
46
|
|
|
28
47
|
</manifest>
|