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.
@@ -6,14 +6,37 @@ import fi.iki.elonen.NanoHTTPD
6
6
  import java.io.IOException
7
7
  import java.util.Locale
8
8
 
9
- class LocalServer(private val context: Context, port: Int) : NanoHTTPD(port) {
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
 
@@ -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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pakstr",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "description": "CLI for packaging Nostr web apps into Android APKs",
5
5
  "type": "commonjs",
6
6
  "main": "dist/index.js",