pakstr 0.2.1 → 0.3.1
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/android-template/app/src/main/java/com/pakstr/app/LocalServer.kt +100 -1
- package/android-template/app/src/main/java/com/pakstr/app/RuntimeConfig.kt +51 -0
- package/android-template/app/src/main/java/com/pakstr/app/ShellRuntime.kt +0 -11
- package/dist/commands/build.js +6 -0
- package/dist/runtime/runtimeConfig.js +17 -0
- package/package.json +1 -1
|
@@ -6,14 +6,37 @@ import fi.iki.elonen.NanoHTTPD
|
|
|
6
6
|
import java.io.IOException
|
|
7
7
|
import java.util.Locale
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
import java.net.HttpURLConnection
|
|
10
|
+
import java.net.URL
|
|
11
|
+
|
|
12
|
+
class LocalServer(
|
|
13
|
+
|
|
14
|
+
private val context: Context,
|
|
15
|
+
|
|
16
|
+
port: Int
|
|
17
|
+
|
|
18
|
+
) : NanoHTTPD(port) {
|
|
10
19
|
|
|
11
20
|
override fun serve(session: IHTTPSession?): Response {
|
|
12
21
|
// Fallback to root if URI is null
|
|
13
22
|
val uri =
|
|
23
|
+
|
|
14
24
|
(session?.uri ?: "/")
|
|
25
|
+
|
|
15
26
|
.replace("..", "")
|
|
16
27
|
|
|
28
|
+
if (uri.startsWith("/api/")) {
|
|
29
|
+
|
|
30
|
+
return proxyApi(
|
|
31
|
+
|
|
32
|
+
session,
|
|
33
|
+
|
|
34
|
+
uri
|
|
35
|
+
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
}
|
|
39
|
+
|
|
17
40
|
// Map the root URL to index.html, otherwise target the requested file in the assets folder
|
|
18
41
|
val filePath = when {
|
|
19
42
|
|
|
@@ -73,4 +96,80 @@ class LocalServer(private val context: Context, port: Int) : NanoHTTPD(port) {
|
|
|
73
96
|
?: "application/octet-stream"
|
|
74
97
|
}
|
|
75
98
|
}
|
|
99
|
+
|
|
100
|
+
private fun proxyApi(
|
|
101
|
+
session: IHTTPSession?,
|
|
102
|
+
uri: String
|
|
103
|
+
): Response {
|
|
104
|
+
|
|
105
|
+
val apiBase =
|
|
106
|
+
|
|
107
|
+
RuntimeConfig.load(context)
|
|
108
|
+
|
|
109
|
+
.optString("apiBase", null)
|
|
110
|
+
|
|
111
|
+
?: return newFixedLengthResponse(
|
|
112
|
+
|
|
113
|
+
Response.Status.INTERNAL_ERROR,
|
|
114
|
+
|
|
115
|
+
"application/json",
|
|
116
|
+
|
|
117
|
+
"""{"error":"apiBase missing"}"""
|
|
118
|
+
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
return try {
|
|
123
|
+
|
|
124
|
+
val url =
|
|
125
|
+
URL(
|
|
126
|
+
apiBase.removeSuffix("/") + uri
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
val connection =
|
|
131
|
+
url.openConnection() as HttpURLConnection
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
connection.requestMethod =
|
|
135
|
+
session?.method?.name ?: "GET"
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
connection.connectTimeout = 10000
|
|
139
|
+
connection.readTimeout = 10000
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
val code =
|
|
143
|
+
connection.responseCode
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
val stream =
|
|
147
|
+
if (code >= 400)
|
|
148
|
+
connection.errorStream
|
|
149
|
+
else
|
|
150
|
+
connection.inputStream
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
newChunkedResponse(
|
|
154
|
+
Response.Status.lookup(code)
|
|
155
|
+
?: Response.Status.OK,
|
|
156
|
+
connection.contentType ?: "application/json",
|
|
157
|
+
stream
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
} catch (e: Exception) {
|
|
162
|
+
|
|
163
|
+
newFixedLengthResponse(
|
|
164
|
+
Response.Status.INTERNAL_ERROR,
|
|
165
|
+
"application/json",
|
|
166
|
+
"""
|
|
167
|
+
{
|
|
168
|
+
"error":"proxy_failed",
|
|
169
|
+
"message":"${e.message}"
|
|
170
|
+
}
|
|
171
|
+
""".trimIndent()
|
|
172
|
+
)
|
|
173
|
+
}
|
|
174
|
+
}
|
|
76
175
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
package com.pakstr.app
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import org.json.JSONObject
|
|
5
|
+
|
|
6
|
+
object RuntimeConfig {
|
|
7
|
+
|
|
8
|
+
private var config: JSONObject? = null
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
fun load(context: Context): JSONObject {
|
|
12
|
+
|
|
13
|
+
if (config != null) {
|
|
14
|
+
return config!!
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
config = try {
|
|
19
|
+
|
|
20
|
+
val input =
|
|
21
|
+
context.assets.open("pakstr-runtime.json")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
val json =
|
|
25
|
+
input.bufferedReader()
|
|
26
|
+
.use { it.readText() }
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
JSONObject(json)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
} catch (e: Exception) {
|
|
33
|
+
|
|
34
|
+
JSONObject()
|
|
35
|
+
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
return config!!
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
fun apiBase(context: Context): String? {
|
|
44
|
+
|
|
45
|
+
return load(context)
|
|
46
|
+
.optString("apiBase")
|
|
47
|
+
.takeIf {
|
|
48
|
+
it.isNotBlank()
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -24,7 +24,6 @@ class ShellRuntime(
|
|
|
24
24
|
|
|
25
25
|
private lateinit var controller: WebViewController
|
|
26
26
|
|
|
27
|
-
|
|
28
27
|
fun start() {
|
|
29
28
|
|
|
30
29
|
controller = WebViewController(
|
|
@@ -35,7 +34,6 @@ class ShellRuntime(
|
|
|
35
34
|
permissionHandler
|
|
36
35
|
)
|
|
37
36
|
|
|
38
|
-
|
|
39
37
|
CoroutineScope(Dispatchers.IO).launch {
|
|
40
38
|
|
|
41
39
|
val ok = startServer()
|
|
@@ -69,7 +67,6 @@ class ShellRuntime(
|
|
|
69
67
|
if (server != null)
|
|
70
68
|
return true
|
|
71
69
|
|
|
72
|
-
|
|
73
70
|
return try {
|
|
74
71
|
|
|
75
72
|
server = LocalServer(
|
|
@@ -77,35 +74,27 @@ class ShellRuntime(
|
|
|
77
74
|
port
|
|
78
75
|
)
|
|
79
76
|
|
|
80
|
-
|
|
81
77
|
server?.start(
|
|
82
78
|
NanoHTTPD.SOCKET_READ_TIMEOUT,
|
|
83
79
|
false
|
|
84
80
|
)
|
|
85
81
|
|
|
86
|
-
|
|
87
82
|
AppDebugLogger.log(
|
|
88
83
|
"SERVER",
|
|
89
84
|
"Started OK"
|
|
90
85
|
)
|
|
91
86
|
|
|
92
|
-
|
|
93
87
|
true
|
|
94
88
|
|
|
95
|
-
|
|
96
89
|
} catch (e: Exception) {
|
|
97
90
|
|
|
98
|
-
|
|
99
91
|
AppDebugLogger.log(
|
|
100
92
|
"SERVER",
|
|
101
93
|
"Failed to start: ${e.message}"
|
|
102
94
|
)
|
|
103
95
|
|
|
104
|
-
|
|
105
96
|
false
|
|
106
|
-
|
|
107
97
|
}
|
|
108
|
-
|
|
109
98
|
}
|
|
110
99
|
|
|
111
100
|
|
package/dist/commands/build.js
CHANGED
|
@@ -18,6 +18,7 @@ const version_1 = require("../android/version");
|
|
|
18
18
|
const icon_1 = require("../android/icon");
|
|
19
19
|
const splash_1 = require("../android/splash");
|
|
20
20
|
const permissions_1 = require("../android/permissions");
|
|
21
|
+
const runtimeConfig_1 = require("../runtime/runtimeConfig");
|
|
21
22
|
async function buildCommand(args) {
|
|
22
23
|
const ctx = (0, buildContext_1.createBuildContext)(args);
|
|
23
24
|
const config = (0, config_1.loadConfig)(process.cwd());
|
|
@@ -56,6 +57,11 @@ async function buildCommand(args) {
|
|
|
56
57
|
});
|
|
57
58
|
copyFolder(distPath, assetsTarget);
|
|
58
59
|
console.log("📦 Web assets copied successfully");
|
|
60
|
+
(0, runtimeConfig_1.generateRuntimeConfig)(assetsTarget, manifest);
|
|
61
|
+
console.log("runtime files:", fs_1.default.readdirSync(assetsTarget)
|
|
62
|
+
.filter(f => f.includes("pakstr")));
|
|
63
|
+
console.log(fs_1.default.existsSync(path_1.default.join(assetsTarget, "pakstr-runtime.json")));
|
|
64
|
+
console.log(fs_1.default.readdirSync(assetsTarget));
|
|
59
65
|
// -----------------------------
|
|
60
66
|
// 3. PATCH ANDROID PROJECT
|
|
61
67
|
// -----------------------------
|
|
@@ -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.generateRuntimeConfig = generateRuntimeConfig;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
function generateRuntimeConfig(webRoot, manifest) {
|
|
10
|
+
const runtime = manifest.runtime ?? {};
|
|
11
|
+
const jsContent = `
|
|
12
|
+
window.PAKSTR_CONFIG = ${JSON.stringify(runtime, null, 2)};
|
|
13
|
+
`;
|
|
14
|
+
fs_1.default.writeFileSync(path_1.default.join(webRoot, "pakstr-config.js"), jsContent.trim());
|
|
15
|
+
fs_1.default.writeFileSync(path_1.default.join(webRoot, "pakstr-runtime.json"), JSON.stringify(runtime, null, 2));
|
|
16
|
+
console.log("⚙️ Runtime config generated");
|
|
17
|
+
}
|