@zappdev/cli 0.1.0
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 +55 -0
- package/dist/zapp-cli.js +9471 -0
- package/native/src/app/app.zc +490 -0
- package/native/src/event/event.zc +24 -0
- package/native/src/event/events.zc +70 -0
- package/native/src/platform/darwin/backend.zc +923 -0
- package/native/src/platform/darwin/backend_bootstrap.zc +9 -0
- package/native/src/platform/darwin/bootstrap.zc +9 -0
- package/native/src/platform/darwin/engine_jsc.zc +86 -0
- package/native/src/platform/darwin/engine_qjs.zc +92 -0
- package/native/src/platform/darwin/platform.zc +156 -0
- package/native/src/platform/darwin/webview.zc +550 -0
- package/native/src/platform/darwin/webview_bootstrap.zc +9 -0
- package/native/src/platform/darwin/window.zc +1223 -0
- package/native/src/platform/darwin/worker/common.zc +223 -0
- package/native/src/platform/darwin/worker/core/base64_core.zc +29 -0
- package/native/src/platform/darwin/worker/core/crypto_core.zc +19 -0
- package/native/src/platform/darwin/worker/core/encoding_core.zc +32 -0
- package/native/src/platform/darwin/worker/core/fetch_core.zc +145 -0
- package/native/src/platform/darwin/worker/core/url_core.zc +69 -0
- package/native/src/platform/darwin/worker/core/websocket_core.zc +179 -0
- package/native/src/platform/darwin/worker/dispatch.zc +55 -0
- package/native/src/platform/darwin/worker/jsc/base64_jsc.zc +39 -0
- package/native/src/platform/darwin/worker/jsc/crypto_jsc.zc +49 -0
- package/native/src/platform/darwin/worker/jsc/encoding_jsc.zc +86 -0
- package/native/src/platform/darwin/worker/jsc/fetch_jsc.zc +149 -0
- package/native/src/platform/darwin/worker/jsc/url_jsc.zc +54 -0
- package/native/src/platform/darwin/worker/jsc/websocket_jsc.zc +127 -0
- package/native/src/platform/darwin/worker/jsc.zc +670 -0
- package/native/src/platform/darwin/worker/mod.zc +30 -0
- package/native/src/platform/darwin/worker/qjs/fetch_qjs.zc +233 -0
- package/native/src/platform/darwin/worker/qjs/qjs_macros.zc +23 -0
- package/native/src/platform/darwin/worker/qjs/websocket_qjs.zc +223 -0
- package/native/src/platform/darwin/worker/qjs.zc +1053 -0
- package/native/src/platform/darwin/worker/timers.zc +149 -0
- package/native/src/platform/darwin/worker/timers_qjs.zc +209 -0
- package/native/src/platform/platform.zc +64 -0
- package/native/src/platform/shared/log.zc +156 -0
- package/native/src/platform/shared/worker/qjs/base64_qjs.zc +38 -0
- package/native/src/platform/shared/worker/qjs/crypto_qjs.zc +44 -0
- package/native/src/platform/shared/worker/qjs/encoding_qjs.zc +95 -0
- package/native/src/platform/shared/worker/qjs/url_qjs.zc +65 -0
- package/native/src/platform/shared/worker_registry.zc +206 -0
- package/native/src/platform/window.zc +446 -0
- package/native/src/platform/windows/backend.zc +452 -0
- package/native/src/platform/windows/backend_bootstrap.zc +9 -0
- package/native/src/platform/windows/bootstrap.zc +9 -0
- package/native/src/platform/windows/engine_qjs.zc +60 -0
- package/native/src/platform/windows/platform.zc +387 -0
- package/native/src/platform/windows/webview.zc +1175 -0
- package/native/src/platform/windows/webview_bootstrap.zc +9 -0
- package/native/src/platform/windows/window.zc +1271 -0
- package/native/src/platform/windows/worker/common.zc +409 -0
- package/native/src/platform/windows/worker/core/base64_core.zc +52 -0
- package/native/src/platform/windows/worker/core/crypto_core.zc +34 -0
- package/native/src/platform/windows/worker/core/encoding_core.zc +60 -0
- package/native/src/platform/windows/worker/core/fetch_core.zc +274 -0
- package/native/src/platform/windows/worker/core/url_core.zc +216 -0
- package/native/src/platform/windows/worker/core/websocket_core.zc +343 -0
- package/native/src/platform/windows/worker/dispatch.zc +34 -0
- package/native/src/platform/windows/worker/mod.zc +46 -0
- package/native/src/platform/windows/worker/qjs/fetch_qjs.zc +255 -0
- package/native/src/platform/windows/worker/qjs/websocket_qjs.zc +263 -0
- package/native/src/platform/windows/worker/qjs.zc +1049 -0
- package/native/src/platform/windows/worker/timers_qjs.zc +288 -0
- package/native/src/platform/worker.zc +8 -0
- package/native/src/service/service.zc +228 -0
- package/native/vendor/quickjs-ng/.gitattributes +4 -0
- package/native/vendor/quickjs-ng/.github/dependabot.yml +7 -0
- package/native/vendor/quickjs-ng/.github/workflows/ci.yml +812 -0
- package/native/vendor/quickjs-ng/.github/workflows/docs.yml +49 -0
- package/native/vendor/quickjs-ng/.github/workflows/release.yml +162 -0
- package/native/vendor/quickjs-ng/.github/workflows/test-docs.yml +23 -0
- package/native/vendor/quickjs-ng/.github/workflows/tsan.yml +32 -0
- package/native/vendor/quickjs-ng/.github/workflows/valgrind.yml +33 -0
- package/native/vendor/quickjs-ng/.gitmodules +5 -0
- package/native/vendor/quickjs-ng/CMakeLists.txt +553 -0
- package/native/vendor/quickjs-ng/LICENSE +24 -0
- package/native/vendor/quickjs-ng/Makefile +149 -0
- package/native/vendor/quickjs-ng/amalgam.js +53 -0
- package/native/vendor/quickjs-ng/api-test.c +927 -0
- package/native/vendor/quickjs-ng/builtin-array-fromasync.h +119 -0
- package/native/vendor/quickjs-ng/builtin-array-fromasync.js +36 -0
- package/native/vendor/quickjs-ng/builtin-iterator-zip-keyed.h +332 -0
- package/native/vendor/quickjs-ng/builtin-iterator-zip-keyed.js +194 -0
- package/native/vendor/quickjs-ng/builtin-iterator-zip.h +337 -0
- package/native/vendor/quickjs-ng/builtin-iterator-zip.js +210 -0
- package/native/vendor/quickjs-ng/ctest.c +17 -0
- package/native/vendor/quickjs-ng/cutils.h +2013 -0
- package/native/vendor/quickjs-ng/cxxtest.cc +2 -0
- package/native/vendor/quickjs-ng/dtoa.c +1619 -0
- package/native/vendor/quickjs-ng/dtoa.h +87 -0
- package/native/vendor/quickjs-ng/examples/fib.c +67 -0
- package/native/vendor/quickjs-ng/examples/fib_module.js +10 -0
- package/native/vendor/quickjs-ng/examples/hello.js +1 -0
- package/native/vendor/quickjs-ng/examples/hello_module.js +6 -0
- package/native/vendor/quickjs-ng/examples/meson.build +17 -0
- package/native/vendor/quickjs-ng/examples/pi_bigint.js +118 -0
- package/native/vendor/quickjs-ng/examples/point.c +154 -0
- package/native/vendor/quickjs-ng/examples/test_fib.js +8 -0
- package/native/vendor/quickjs-ng/examples/test_point.js +43 -0
- package/native/vendor/quickjs-ng/fuzz.c +51 -0
- package/native/vendor/quickjs-ng/gen/function_source.c +81 -0
- package/native/vendor/quickjs-ng/gen/hello.c +53 -0
- package/native/vendor/quickjs-ng/gen/hello_module.c +106 -0
- package/native/vendor/quickjs-ng/gen/repl.c +3053 -0
- package/native/vendor/quickjs-ng/gen/standalone.c +324 -0
- package/native/vendor/quickjs-ng/gen/test_fib.c +81 -0
- package/native/vendor/quickjs-ng/libregexp-opcode.h +58 -0
- package/native/vendor/quickjs-ng/libregexp.c +2687 -0
- package/native/vendor/quickjs-ng/libregexp.h +98 -0
- package/native/vendor/quickjs-ng/libunicode-table.h +4707 -0
- package/native/vendor/quickjs-ng/libunicode.c +1746 -0
- package/native/vendor/quickjs-ng/libunicode.h +126 -0
- package/native/vendor/quickjs-ng/list.h +107 -0
- package/native/vendor/quickjs-ng/lre-test.c +73 -0
- package/native/vendor/quickjs-ng/meson.build +684 -0
- package/native/vendor/quickjs-ng/meson_options.txt +6 -0
- package/native/vendor/quickjs-ng/qjs-wasi-reactor.c +208 -0
- package/native/vendor/quickjs-ng/qjs.c +748 -0
- package/native/vendor/quickjs-ng/qjsc.c +673 -0
- package/native/vendor/quickjs-ng/quickjs-atom.h +267 -0
- package/native/vendor/quickjs-ng/quickjs-c-atomics.h +54 -0
- package/native/vendor/quickjs-ng/quickjs-libc.c +4986 -0
- package/native/vendor/quickjs-ng/quickjs-libc.h +79 -0
- package/native/vendor/quickjs-ng/quickjs-opcode.h +369 -0
- package/native/vendor/quickjs-ng/quickjs.c +60259 -0
- package/native/vendor/quickjs-ng/quickjs.h +1419 -0
- package/native/vendor/quickjs-ng/repl.js +1927 -0
- package/native/vendor/quickjs-ng/run-test262.c +2417 -0
- package/native/vendor/quickjs-ng/standalone.js +129 -0
- package/native/vendor/quickjs-ng/tests/assert.js +49 -0
- package/native/vendor/quickjs-ng/tests/bug1221.js +16 -0
- package/native/vendor/quickjs-ng/tests/bug1296.js +12 -0
- package/native/vendor/quickjs-ng/tests/bug1297.js +22 -0
- package/native/vendor/quickjs-ng/tests/bug1301.js +21 -0
- package/native/vendor/quickjs-ng/tests/bug1302.js +24 -0
- package/native/vendor/quickjs-ng/tests/bug1305.js +26 -0
- package/native/vendor/quickjs-ng/tests/bug1318.js +54 -0
- package/native/vendor/quickjs-ng/tests/bug1352.js +8 -0
- package/native/vendor/quickjs-ng/tests/bug1354.js +6 -0
- package/native/vendor/quickjs-ng/tests/bug1355.js +58 -0
- package/native/vendor/quickjs-ng/tests/bug1368.js +9 -0
- package/native/vendor/quickjs-ng/tests/bug39/1.js +6 -0
- package/native/vendor/quickjs-ng/tests/bug39/2.js +6 -0
- package/native/vendor/quickjs-ng/tests/bug39/3.js +7 -0
- package/native/vendor/quickjs-ng/tests/bug488-upstream.js +7 -0
- package/native/vendor/quickjs-ng/tests/bug633/0.js +7 -0
- package/native/vendor/quickjs-ng/tests/bug633/1.js +4 -0
- package/native/vendor/quickjs-ng/tests/bug633/2.js +4 -0
- package/native/vendor/quickjs-ng/tests/bug633/3.js +4 -0
- package/native/vendor/quickjs-ng/tests/bug645/0.js +4 -0
- package/native/vendor/quickjs-ng/tests/bug645/1.js +9 -0
- package/native/vendor/quickjs-ng/tests/bug645/2.js +7 -0
- package/native/vendor/quickjs-ng/tests/bug648.js +13 -0
- package/native/vendor/quickjs-ng/tests/bug652.js +4 -0
- package/native/vendor/quickjs-ng/tests/bug741.js +19 -0
- package/native/vendor/quickjs-ng/tests/bug775.js +7 -0
- package/native/vendor/quickjs-ng/tests/bug776.js +7 -0
- package/native/vendor/quickjs-ng/tests/bug832.js +2 -0
- package/native/vendor/quickjs-ng/tests/bug858.js +26 -0
- package/native/vendor/quickjs-ng/tests/bug904.js +6 -0
- package/native/vendor/quickjs-ng/tests/bug988.js +7 -0
- package/native/vendor/quickjs-ng/tests/bug999.js +3 -0
- package/native/vendor/quickjs-ng/tests/destructured-export.js +8 -0
- package/native/vendor/quickjs-ng/tests/detect_module/0.js +1 -0
- package/native/vendor/quickjs-ng/tests/detect_module/1.js +2 -0
- package/native/vendor/quickjs-ng/tests/detect_module/2.js +1 -0
- package/native/vendor/quickjs-ng/tests/detect_module/3.js +8 -0
- package/native/vendor/quickjs-ng/tests/detect_module/4.js +3 -0
- package/native/vendor/quickjs-ng/tests/empty.js +0 -0
- package/native/vendor/quickjs-ng/tests/fixture_cyclic_import.js +2 -0
- package/native/vendor/quickjs-ng/tests/fixture_string_exports.js +12 -0
- package/native/vendor/quickjs-ng/tests/function_source.js +14 -0
- package/native/vendor/quickjs-ng/tests/microbench.js +1267 -0
- package/native/vendor/quickjs-ng/tests/null_or_undefined.js +38 -0
- package/native/vendor/quickjs-ng/tests/str-pad-leak.js +5 -0
- package/native/vendor/quickjs-ng/tests/test_bigint.js +107 -0
- package/native/vendor/quickjs-ng/tests/test_bjson.js +366 -0
- package/native/vendor/quickjs-ng/tests/test_builtin.js +1314 -0
- package/native/vendor/quickjs-ng/tests/test_closure.js +220 -0
- package/native/vendor/quickjs-ng/tests/test_cyclic_import.js +12 -0
- package/native/vendor/quickjs-ng/tests/test_domexception.js +35 -0
- package/native/vendor/quickjs-ng/tests/test_language.js +755 -0
- package/native/vendor/quickjs-ng/tests/test_loop.js +367 -0
- package/native/vendor/quickjs-ng/tests/test_queue_microtask.js +39 -0
- package/native/vendor/quickjs-ng/tests/test_std.js +340 -0
- package/native/vendor/quickjs-ng/tests/test_string_exports.js +25 -0
- package/native/vendor/quickjs-ng/tests/test_worker.js +43 -0
- package/native/vendor/quickjs-ng/tests/test_worker_module.js +30 -0
- package/native/vendor/quickjs-ng/tests.conf +14 -0
- package/native/vendor/quickjs-ng/unicode_download.sh +19 -0
- package/native/vendor/quickjs-ng/unicode_gen.c +3108 -0
- package/native/vendor/quickjs-ng/unicode_gen_def.h +310 -0
- package/native/vendor/quickjs-ng/update-version.sh +32 -0
- package/native/vendor/webview2/include/WebView2.h +60636 -0
- package/native/vendor/webview2/include/WebView2EnvironmentOptions.h +406 -0
- package/package.json +33 -0
- package/src/backend.ts +139 -0
- package/src/build-config.ts +87 -0
- package/src/build.ts +276 -0
- package/src/common.ts +195 -0
- package/src/config.ts +89 -0
- package/src/dev.ts +164 -0
- package/src/generate.ts +200 -0
- package/src/icons.ts +116 -0
- package/src/init.ts +190 -0
- package/src/package.ts +150 -0
- package/src/zapp-cli.ts +263 -0
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
raw {
|
|
2
|
+
#ifdef _WIN32
|
|
3
|
+
#include <windows.h>
|
|
4
|
+
#include <winhttp.h>
|
|
5
|
+
#include <stdio.h>
|
|
6
|
+
#include <stdlib.h>
|
|
7
|
+
#include <string.h>
|
|
8
|
+
extern const char* zapp_build_asset_root(void);
|
|
9
|
+
extern int zapp_build_use_embedded_assets(void);
|
|
10
|
+
extern int zapp_build_is_dev_mode(void);
|
|
11
|
+
extern void zapp_dispatch_worker_to_webviews(const char* kind, const char* worker_id, const char* payload_json);
|
|
12
|
+
|
|
13
|
+
// -----------------------------------------------------------------------
|
|
14
|
+
// Simple string -> void* map (fixed-size, linear scan)
|
|
15
|
+
// -----------------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
#define ZAPP_MAP_MAX 512
|
|
18
|
+
|
|
19
|
+
typedef struct {
|
|
20
|
+
char key[128];
|
|
21
|
+
void* val;
|
|
22
|
+
} ZappMapEntry;
|
|
23
|
+
|
|
24
|
+
typedef struct {
|
|
25
|
+
ZappMapEntry entries[ZAPP_MAP_MAX];
|
|
26
|
+
} ZappStringMap;
|
|
27
|
+
|
|
28
|
+
static void zapp_map_init(ZappStringMap* m) {
|
|
29
|
+
memset(m, 0, sizeof(ZappStringMap));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
static void* zapp_map_get(ZappStringMap* m, const char* key) {
|
|
33
|
+
if (!m || !key) return NULL;
|
|
34
|
+
for (int i = 0; i < ZAPP_MAP_MAX; i++) {
|
|
35
|
+
if (m->entries[i].key[0] != '\0' && strcmp(m->entries[i].key, key) == 0) {
|
|
36
|
+
return m->entries[i].val;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return NULL;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static void zapp_map_set(ZappStringMap* m, const char* key, void* val) {
|
|
43
|
+
if (!m || !key) return;
|
|
44
|
+
for (int i = 0; i < ZAPP_MAP_MAX; i++) {
|
|
45
|
+
if (m->entries[i].key[0] != '\0' && strcmp(m->entries[i].key, key) == 0) {
|
|
46
|
+
m->entries[i].val = val;
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
for (int i = 0; i < ZAPP_MAP_MAX; i++) {
|
|
51
|
+
if (m->entries[i].key[0] == '\0') {
|
|
52
|
+
strncpy(m->entries[i].key, key, sizeof(m->entries[i].key) - 1);
|
|
53
|
+
m->entries[i].key[sizeof(m->entries[i].key) - 1] = '\0';
|
|
54
|
+
m->entries[i].val = val;
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
static void zapp_map_remove(ZappStringMap* m, const char* key) {
|
|
61
|
+
if (!m || !key) return;
|
|
62
|
+
for (int i = 0; i < ZAPP_MAP_MAX; i++) {
|
|
63
|
+
if (m->entries[i].key[0] != '\0' && strcmp(m->entries[i].key, key) == 0) {
|
|
64
|
+
m->entries[i].key[0] = '\0';
|
|
65
|
+
m->entries[i].val = NULL;
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
static void zapp_map_clear(ZappStringMap* m) {
|
|
72
|
+
if (m) memset(m, 0, sizeof(ZappStringMap));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
typedef void (*zapp_map_iter_fn)(const char* key, void* val, void* userdata);
|
|
76
|
+
|
|
77
|
+
static void zapp_map_foreach(ZappStringMap* m, zapp_map_iter_fn fn, void* userdata) {
|
|
78
|
+
if (!m || !fn) return;
|
|
79
|
+
for (int i = 0; i < ZAPP_MAP_MAX; i++) {
|
|
80
|
+
if (m->entries[i].key[0] != '\0') {
|
|
81
|
+
fn(m->entries[i].key, m->entries[i].val, userdata);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
static int zapp_map_count_unique_ptrs(ZappStringMap* m) {
|
|
87
|
+
if (!m) return 0;
|
|
88
|
+
void* seen[ZAPP_MAP_MAX];
|
|
89
|
+
int seen_count = 0;
|
|
90
|
+
for (int i = 0; i < ZAPP_MAP_MAX; i++) {
|
|
91
|
+
if (m->entries[i].key[0] == '\0' || m->entries[i].val == NULL) continue;
|
|
92
|
+
int found = 0;
|
|
93
|
+
for (int j = 0; j < seen_count; j++) {
|
|
94
|
+
if (seen[j] == m->entries[i].val) { found = 1; break; }
|
|
95
|
+
}
|
|
96
|
+
if (!found && seen_count < ZAPP_MAP_MAX) {
|
|
97
|
+
seen[seen_count++] = m->entries[i].val;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return seen_count;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// -----------------------------------------------------------------------
|
|
104
|
+
// Minimal JSON field extraction (avoids needing a JSON parser library)
|
|
105
|
+
// -----------------------------------------------------------------------
|
|
106
|
+
|
|
107
|
+
char* zapp_json_get_string(const char* json, const char* key) {
|
|
108
|
+
if (!json || !key) return NULL;
|
|
109
|
+
char pattern[256];
|
|
110
|
+
snprintf(pattern, sizeof(pattern), "\"%s\":\"", key);
|
|
111
|
+
const char* start = strstr(json, pattern);
|
|
112
|
+
if (!start) return NULL;
|
|
113
|
+
start += strlen(pattern);
|
|
114
|
+
const char* end = start;
|
|
115
|
+
while (*end && *end != '"') {
|
|
116
|
+
if (*end == '\\' && *(end + 1)) end++;
|
|
117
|
+
end++;
|
|
118
|
+
}
|
|
119
|
+
size_t len = (size_t)(end - start);
|
|
120
|
+
char* result = (char*)malloc(len + 1);
|
|
121
|
+
memcpy(result, start, len);
|
|
122
|
+
result[len] = '\0';
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
int zapp_json_get_bool(const char* json, const char* key, int default_val) {
|
|
127
|
+
if (!json || !key) return default_val;
|
|
128
|
+
char pattern[256];
|
|
129
|
+
snprintf(pattern, sizeof(pattern), "\"%s\":", key);
|
|
130
|
+
const char* start = strstr(json, pattern);
|
|
131
|
+
if (!start) return default_val;
|
|
132
|
+
start += strlen(pattern);
|
|
133
|
+
while (*start == ' ') start++;
|
|
134
|
+
if (*start == 't') return 1;
|
|
135
|
+
if (*start == 'f') return 0;
|
|
136
|
+
return default_val;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
int zapp_json_get_int(const char* json, const char* key, int default_val) {
|
|
140
|
+
if (!json || !key) return default_val;
|
|
141
|
+
char pattern[256];
|
|
142
|
+
snprintf(pattern, sizeof(pattern), "\"%s\":", key);
|
|
143
|
+
const char* start = strstr(json, pattern);
|
|
144
|
+
if (!start) return default_val;
|
|
145
|
+
start += strlen(pattern);
|
|
146
|
+
while (*start == ' ') start++;
|
|
147
|
+
if (*start == '-' || (*start >= '0' && *start <= '9')) return atoi(start);
|
|
148
|
+
return default_val;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
char* zapp_json_get_raw(const char* json, const char* key) {
|
|
152
|
+
if (!json || !key) return NULL;
|
|
153
|
+
char pattern[256];
|
|
154
|
+
snprintf(pattern, sizeof(pattern), "\"%s\":", key);
|
|
155
|
+
const char* start = strstr(json, pattern);
|
|
156
|
+
if (!start) return NULL;
|
|
157
|
+
start += strlen(pattern);
|
|
158
|
+
while (*start == ' ') start++;
|
|
159
|
+
|
|
160
|
+
if (*start == '"') {
|
|
161
|
+
const char* end = start + 1;
|
|
162
|
+
while (*end && *end != '"') {
|
|
163
|
+
if (*end == '\\' && *(end + 1)) end++;
|
|
164
|
+
end++;
|
|
165
|
+
}
|
|
166
|
+
if (*end == '"') end++;
|
|
167
|
+
size_t len = (size_t)(end - start);
|
|
168
|
+
char* result = (char*)malloc(len + 1);
|
|
169
|
+
memcpy(result, start, len);
|
|
170
|
+
result[len] = '\0';
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (*start == '{' || *start == '[') {
|
|
175
|
+
int depth = 0;
|
|
176
|
+
const char* end = start;
|
|
177
|
+
char open = *start;
|
|
178
|
+
char close = (open == '{') ? '}' : ']';
|
|
179
|
+
while (*end) {
|
|
180
|
+
if (*end == open) depth++;
|
|
181
|
+
else if (*end == close) { depth--; if (depth == 0) { end++; break; } }
|
|
182
|
+
else if (*end == '"') {
|
|
183
|
+
end++;
|
|
184
|
+
while (*end && *end != '"') {
|
|
185
|
+
if (*end == '\\' && *(end + 1)) end++;
|
|
186
|
+
end++;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
end++;
|
|
190
|
+
}
|
|
191
|
+
size_t len = (size_t)(end - start);
|
|
192
|
+
char* result = (char*)malloc(len + 1);
|
|
193
|
+
memcpy(result, start, len);
|
|
194
|
+
result[len] = '\0';
|
|
195
|
+
return result;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const char* end = start;
|
|
199
|
+
while (*end && *end != ',' && *end != '}' && *end != ']') end++;
|
|
200
|
+
size_t len = (size_t)(end - start);
|
|
201
|
+
char* result = (char*)malloc(len + 1);
|
|
202
|
+
memcpy(result, start, len);
|
|
203
|
+
result[len] = '\0';
|
|
204
|
+
return result;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// -----------------------------------------------------------------------
|
|
208
|
+
// Worker error dispatch helpers
|
|
209
|
+
// -----------------------------------------------------------------------
|
|
210
|
+
|
|
211
|
+
static void zapp_worker_dispatch_error_message(const char* workerId, const char* message) {
|
|
212
|
+
if (!workerId) return;
|
|
213
|
+
const char* safeMsg = (message && message[0]) ? message : "Worker error";
|
|
214
|
+
char payload[1024];
|
|
215
|
+
snprintf(payload, sizeof(payload), "{\"message\":\"%s\"}", safeMsg);
|
|
216
|
+
zapp_dispatch_worker_to_webviews("error", workerId, payload);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
static void zapp_worker_dispatch_max_workers_error(const char* workerId, int maxWorkers) {
|
|
220
|
+
char msg[256];
|
|
221
|
+
snprintf(msg, sizeof(msg), "Max worker limit (%d) exceeded.", maxWorkers);
|
|
222
|
+
zapp_worker_dispatch_error_message(workerId, msg);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// -----------------------------------------------------------------------
|
|
226
|
+
// Asset / script loading
|
|
227
|
+
// -----------------------------------------------------------------------
|
|
228
|
+
|
|
229
|
+
#ifndef ZAPP_EMBEDDED_ASSET_STRUCT_DEFINED
|
|
230
|
+
#define ZAPP_EMBEDDED_ASSET_STRUCT_DEFINED 1
|
|
231
|
+
struct ZappEmbeddedAsset {
|
|
232
|
+
char* path;
|
|
233
|
+
unsigned char* data;
|
|
234
|
+
int len;
|
|
235
|
+
int is_brotli;
|
|
236
|
+
int uncompressed_len;
|
|
237
|
+
};
|
|
238
|
+
#endif
|
|
239
|
+
|
|
240
|
+
extern struct ZappEmbeddedAsset zapp_embedded_assets[];
|
|
241
|
+
extern int zapp_embedded_assets_count;
|
|
242
|
+
|
|
243
|
+
static const char* zapp_worker_asset_root(void) {
|
|
244
|
+
const char* configuredRoot = zapp_build_asset_root();
|
|
245
|
+
if (configuredRoot != NULL && configuredRoot[0] != '\0') {
|
|
246
|
+
return configuredRoot;
|
|
247
|
+
}
|
|
248
|
+
return "example\\frontend\\dist";
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
#define ZAPP_WORKER_LOCALHOST_PREFIX "https://app.localhost/"
|
|
252
|
+
#define ZAPP_WORKER_LOCALHOST_PREFIX_LEN 22
|
|
253
|
+
|
|
254
|
+
static char* zapp_worker_resolve_rel_path(const char* scriptUrl) {
|
|
255
|
+
if (!scriptUrl) return NULL;
|
|
256
|
+
|
|
257
|
+
const char* rel = NULL;
|
|
258
|
+
|
|
259
|
+
if (strncmp(scriptUrl, ZAPP_WORKER_LOCALHOST_PREFIX, ZAPP_WORKER_LOCALHOST_PREFIX_LEN) == 0) {
|
|
260
|
+
rel = scriptUrl + ZAPP_WORKER_LOCALHOST_PREFIX_LEN;
|
|
261
|
+
} else if (strncmp(scriptUrl, "zapp://", 7) == 0) {
|
|
262
|
+
const char* after_scheme = scriptUrl + 7;
|
|
263
|
+
const char* slash = strchr(after_scheme, '/');
|
|
264
|
+
rel = slash ? slash + 1 : after_scheme;
|
|
265
|
+
} else {
|
|
266
|
+
return NULL;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
while (*rel == '/') rel++;
|
|
270
|
+
if (strncmp(rel, "app/", 4) == 0) rel += 4;
|
|
271
|
+
if (strncmp(rel, "index.html/", 11) == 0) rel += 11;
|
|
272
|
+
|
|
273
|
+
if (!*rel) return NULL;
|
|
274
|
+
return _strdup(rel);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Synchronous HTTP GET using WinHTTP (used in dev mode to fetch worker scripts)
|
|
278
|
+
static char* zapp_worker_http_get(const char* url) {
|
|
279
|
+
if (!url) return NULL;
|
|
280
|
+
|
|
281
|
+
// Parse host, port, path from http://host:port/path
|
|
282
|
+
const char* hostStart = url;
|
|
283
|
+
if (strncmp(url, "http://", 7) == 0) hostStart = url + 7;
|
|
284
|
+
else if (strncmp(url, "https://", 8) == 0) hostStart = url + 8;
|
|
285
|
+
else return NULL;
|
|
286
|
+
|
|
287
|
+
char host[256] = {0};
|
|
288
|
+
INTERNET_PORT port = (url[4] == 's') ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT;
|
|
289
|
+
const char* slash = strchr(hostStart, '/');
|
|
290
|
+
const char* colon = strchr(hostStart, ':');
|
|
291
|
+
if (colon && (!slash || colon < slash)) {
|
|
292
|
+
size_t hlen = (size_t)(colon - hostStart);
|
|
293
|
+
if (hlen >= sizeof(host)) return NULL;
|
|
294
|
+
memcpy(host, hostStart, hlen);
|
|
295
|
+
port = (INTERNET_PORT)atoi(colon + 1);
|
|
296
|
+
} else if (slash) {
|
|
297
|
+
size_t hlen = (size_t)(slash - hostStart);
|
|
298
|
+
if (hlen >= sizeof(host)) return NULL;
|
|
299
|
+
memcpy(host, hostStart, hlen);
|
|
300
|
+
} else {
|
|
301
|
+
strncpy(host, hostStart, sizeof(host) - 1);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const char* pathStr = slash ? slash : "/";
|
|
305
|
+
wchar_t wHost[256], wPath[1024];
|
|
306
|
+
MultiByteToWideChar(CP_UTF8, 0, host, -1, wHost, 256);
|
|
307
|
+
MultiByteToWideChar(CP_UTF8, 0, pathStr, -1, wPath, 1024);
|
|
308
|
+
|
|
309
|
+
HINTERNET session = WinHttpOpen(L"Zapp/1.0", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
|
|
310
|
+
if (!session) return NULL;
|
|
311
|
+
|
|
312
|
+
HINTERNET connection = WinHttpConnect(session, wHost, port, 0);
|
|
313
|
+
if (!connection) { WinHttpCloseHandle(session); return NULL; }
|
|
314
|
+
|
|
315
|
+
DWORD flags = (url[4] == 's') ? WINHTTP_FLAG_SECURE : 0;
|
|
316
|
+
HINTERNET request = WinHttpOpenRequest(connection, L"GET", wPath, NULL, NULL, NULL, flags);
|
|
317
|
+
if (!request) { WinHttpCloseHandle(connection); WinHttpCloseHandle(session); return NULL; }
|
|
318
|
+
|
|
319
|
+
if (!WinHttpSendRequest(request, NULL, 0, NULL, 0, 0, 0) ||
|
|
320
|
+
!WinHttpReceiveResponse(request, NULL)) {
|
|
321
|
+
WinHttpCloseHandle(request); WinHttpCloseHandle(connection); WinHttpCloseHandle(session);
|
|
322
|
+
return NULL;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
size_t totalLen = 0, cap = 4096;
|
|
326
|
+
char* buf = (char*)malloc(cap);
|
|
327
|
+
DWORD bytesRead = 0;
|
|
328
|
+
while (WinHttpReadData(request, buf + totalLen, (DWORD)(cap - totalLen - 1), &bytesRead) && bytesRead > 0) {
|
|
329
|
+
totalLen += bytesRead;
|
|
330
|
+
if (totalLen + 1 >= cap) { cap *= 2; buf = (char*)realloc(buf, cap); }
|
|
331
|
+
bytesRead = 0;
|
|
332
|
+
}
|
|
333
|
+
buf[totalLen] = '\0';
|
|
334
|
+
|
|
335
|
+
WinHttpCloseHandle(request);
|
|
336
|
+
WinHttpCloseHandle(connection);
|
|
337
|
+
WinHttpCloseHandle(session);
|
|
338
|
+
return (totalLen > 0) ? buf : (free(buf), (char*)NULL);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
static char* zapp_worker_read_source(const char* scriptUrl) {
|
|
342
|
+
if (!scriptUrl || !*scriptUrl) return NULL;
|
|
343
|
+
|
|
344
|
+
char* rel = zapp_worker_resolve_rel_path(scriptUrl);
|
|
345
|
+
if (rel) {
|
|
346
|
+
// Try embedded assets first
|
|
347
|
+
if (zapp_build_use_embedded_assets() && zapp_embedded_assets_count > 0) {
|
|
348
|
+
char lookupPath[512];
|
|
349
|
+
snprintf(lookupPath, sizeof(lookupPath), "/%s", rel);
|
|
350
|
+
for (int i = 0; i < zapp_embedded_assets_count; i++) {
|
|
351
|
+
if (strcmp(zapp_embedded_assets[i].path, lookupPath) == 0) {
|
|
352
|
+
char* result = (char*)malloc(zapp_embedded_assets[i].len + 1);
|
|
353
|
+
memcpy(result, zapp_embedded_assets[i].data, zapp_embedded_assets[i].len);
|
|
354
|
+
result[zapp_embedded_assets[i].len] = '\0';
|
|
355
|
+
free(rel);
|
|
356
|
+
return result;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// Try local filesystem
|
|
362
|
+
const char* root = zapp_worker_asset_root();
|
|
363
|
+
char fullPath[1024];
|
|
364
|
+
snprintf(fullPath, sizeof(fullPath), "%s\\%s", root, rel);
|
|
365
|
+
// Normalize slashes
|
|
366
|
+
for (char* p = fullPath; *p; p++) { if (*p == '/') *p = '\\'; }
|
|
367
|
+
|
|
368
|
+
FILE* f = fopen(fullPath, "rb");
|
|
369
|
+
if (f) {
|
|
370
|
+
fseek(f, 0, SEEK_END);
|
|
371
|
+
long len = ftell(f);
|
|
372
|
+
fseek(f, 0, SEEK_SET);
|
|
373
|
+
if (len > 0) {
|
|
374
|
+
char* result = (char*)malloc((size_t)len + 1);
|
|
375
|
+
fread(result, 1, (size_t)len, f);
|
|
376
|
+
result[len] = '\0';
|
|
377
|
+
fclose(f);
|
|
378
|
+
free(rel);
|
|
379
|
+
return result;
|
|
380
|
+
}
|
|
381
|
+
fclose(f);
|
|
382
|
+
}
|
|
383
|
+
free(rel);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// HTTP(S) URLs: fetch from dev server or remote
|
|
387
|
+
if (strncmp(scriptUrl, "http://", 7) == 0 || strncmp(scriptUrl, "https://", 8) == 0) {
|
|
388
|
+
return zapp_worker_http_get(scriptUrl);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
FILE* f = fopen(scriptUrl, "rb");
|
|
392
|
+
if (f) {
|
|
393
|
+
fseek(f, 0, SEEK_END);
|
|
394
|
+
long len = ftell(f);
|
|
395
|
+
fseek(f, 0, SEEK_SET);
|
|
396
|
+
if (len > 0) {
|
|
397
|
+
char* result = (char*)malloc((size_t)len + 1);
|
|
398
|
+
fread(result, 1, (size_t)len, f);
|
|
399
|
+
result[len] = '\0';
|
|
400
|
+
fclose(f);
|
|
401
|
+
return result;
|
|
402
|
+
}
|
|
403
|
+
fclose(f);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
return NULL;
|
|
407
|
+
}
|
|
408
|
+
#endif
|
|
409
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Win32-native base64 encoding/decoding.
|
|
2
|
+
|
|
3
|
+
raw {
|
|
4
|
+
#ifdef _WIN32
|
|
5
|
+
#include <windows.h>
|
|
6
|
+
#include <wincrypt.h>
|
|
7
|
+
#include <stdlib.h>
|
|
8
|
+
#include <string.h>
|
|
9
|
+
|
|
10
|
+
char* zapp_core_btoa(const char* input) {
|
|
11
|
+
if (input == NULL || input[0] == '\0') return _strdup("");
|
|
12
|
+
DWORD inputLen = (DWORD)strlen(input);
|
|
13
|
+
DWORD b64Len = 0;
|
|
14
|
+
|
|
15
|
+
CryptBinaryToStringA((const BYTE*)input, inputLen,
|
|
16
|
+
CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, NULL, &b64Len);
|
|
17
|
+
if (b64Len == 0) return _strdup("");
|
|
18
|
+
|
|
19
|
+
char* b64 = (char*)malloc(b64Len + 1);
|
|
20
|
+
if (!CryptBinaryToStringA((const BYTE*)input, inputLen,
|
|
21
|
+
CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, b64, &b64Len)) {
|
|
22
|
+
free(b64);
|
|
23
|
+
return _strdup("");
|
|
24
|
+
}
|
|
25
|
+
b64[b64Len] = '\0';
|
|
26
|
+
// Trim trailing whitespace
|
|
27
|
+
while (b64Len > 0 && (b64[b64Len - 1] == '\n' || b64[b64Len - 1] == '\r' || b64[b64Len - 1] == ' ')) {
|
|
28
|
+
b64[--b64Len] = '\0';
|
|
29
|
+
}
|
|
30
|
+
return b64;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
char* zapp_core_atob(const char* input) {
|
|
34
|
+
if (input == NULL || input[0] == '\0') return _strdup("");
|
|
35
|
+
DWORD inputLen = (DWORD)strlen(input);
|
|
36
|
+
DWORD binLen = 0;
|
|
37
|
+
|
|
38
|
+
CryptStringToBinaryA(input, inputLen,
|
|
39
|
+
CRYPT_STRING_BASE64, NULL, &binLen, NULL, NULL);
|
|
40
|
+
if (binLen == 0) return _strdup("");
|
|
41
|
+
|
|
42
|
+
BYTE* bin = (BYTE*)malloc(binLen + 1);
|
|
43
|
+
if (!CryptStringToBinaryA(input, inputLen,
|
|
44
|
+
CRYPT_STRING_BASE64, bin, &binLen, NULL, NULL)) {
|
|
45
|
+
free(bin);
|
|
46
|
+
return _strdup("");
|
|
47
|
+
}
|
|
48
|
+
bin[binLen] = '\0';
|
|
49
|
+
return (char*)bin;
|
|
50
|
+
}
|
|
51
|
+
#endif
|
|
52
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Win32-native crypto: random bytes (BCryptGenRandom) and UUID (UuidCreate).
|
|
2
|
+
|
|
3
|
+
//> windows: link: -lbcrypt -lrpcrt4
|
|
4
|
+
|
|
5
|
+
raw {
|
|
6
|
+
#ifdef _WIN32
|
|
7
|
+
#include <windows.h>
|
|
8
|
+
#include <bcrypt.h>
|
|
9
|
+
#include <rpc.h>
|
|
10
|
+
#include <stdio.h>
|
|
11
|
+
#include <stdlib.h>
|
|
12
|
+
#include <string.h>
|
|
13
|
+
|
|
14
|
+
void zapp_core_crypto_random_bytes(unsigned char* buf, size_t len) {
|
|
15
|
+
if (buf && len > 0) {
|
|
16
|
+
BCryptGenRandom(NULL, buf, (ULONG)len, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
char* zapp_core_crypto_random_uuid(void) {
|
|
21
|
+
UUID uuid;
|
|
22
|
+
UuidCreate(&uuid);
|
|
23
|
+
RPC_CSTR uuidStr = NULL;
|
|
24
|
+
UuidToStringA(&uuid, &uuidStr);
|
|
25
|
+
char* result = _strdup((char*)uuidStr);
|
|
26
|
+
RpcStringFreeA(&uuidStr);
|
|
27
|
+
// Lowercase to match web standard
|
|
28
|
+
for (char* p = result; *p; p++) {
|
|
29
|
+
if (*p >= 'A' && *p <= 'F') *p += 32;
|
|
30
|
+
}
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
#endif
|
|
34
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Win32-native text encoding/decoding with proper UTF-8 validation.
|
|
2
|
+
|
|
3
|
+
raw {
|
|
4
|
+
#ifdef _WIN32
|
|
5
|
+
#include <windows.h>
|
|
6
|
+
#include <stdlib.h>
|
|
7
|
+
#include <string.h>
|
|
8
|
+
|
|
9
|
+
// TextEncoder.encode(): converts a UTF-8 string to its byte representation.
|
|
10
|
+
unsigned char* zapp_core_text_encode(const char* input, size_t* out_len) {
|
|
11
|
+
if (out_len) *out_len = 0;
|
|
12
|
+
if (input == NULL) return NULL;
|
|
13
|
+
size_t len = strlen(input);
|
|
14
|
+
if (len == 0) return NULL;
|
|
15
|
+
unsigned char* copy = (unsigned char*)malloc(len);
|
|
16
|
+
if (!copy) return NULL;
|
|
17
|
+
memcpy(copy, input, len);
|
|
18
|
+
if (out_len) *out_len = len;
|
|
19
|
+
return copy;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// TextDecoder.decode(): validates the byte sequence as UTF-8 via
|
|
23
|
+
// MultiByteToWideChar round-trip, returning a valid UTF-8 C string.
|
|
24
|
+
// Invalid sequences are replaced with U+FFFD.
|
|
25
|
+
char* zapp_core_text_decode(const unsigned char* bytes, size_t len) {
|
|
26
|
+
if (bytes == NULL || len == 0) return _strdup("");
|
|
27
|
+
|
|
28
|
+
// First pass: determine required wide-char buffer size.
|
|
29
|
+
int wlen = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, (const char*)bytes, (int)len, NULL, 0);
|
|
30
|
+
if (wlen > 0) {
|
|
31
|
+
// Valid UTF-8 — fast path: just copy as-is.
|
|
32
|
+
char* result = (char*)malloc(len + 1);
|
|
33
|
+
if (!result) return _strdup("");
|
|
34
|
+
memcpy(result, bytes, len);
|
|
35
|
+
result[len] = '\0';
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Invalid UTF-8 detected. Use the lenient flag (0) which replaces
|
|
40
|
+
// bad sequences, then round-trip back to UTF-8.
|
|
41
|
+
wlen = MultiByteToWideChar(CP_UTF8, 0, (const char*)bytes, (int)len, NULL, 0);
|
|
42
|
+
if (wlen <= 0) return _strdup("");
|
|
43
|
+
|
|
44
|
+
wchar_t* wbuf = (wchar_t*)malloc((size_t)wlen * sizeof(wchar_t));
|
|
45
|
+
if (!wbuf) return _strdup("");
|
|
46
|
+
MultiByteToWideChar(CP_UTF8, 0, (const char*)bytes, (int)len, wbuf, wlen);
|
|
47
|
+
|
|
48
|
+
// Convert back to UTF-8
|
|
49
|
+
int ulen = WideCharToMultiByte(CP_UTF8, 0, wbuf, wlen, NULL, 0, NULL, NULL);
|
|
50
|
+
if (ulen <= 0) { free(wbuf); return _strdup(""); }
|
|
51
|
+
|
|
52
|
+
char* result = (char*)malloc((size_t)ulen + 1);
|
|
53
|
+
if (!result) { free(wbuf); return _strdup(""); }
|
|
54
|
+
WideCharToMultiByte(CP_UTF8, 0, wbuf, wlen, result, ulen, NULL, NULL);
|
|
55
|
+
result[ulen] = '\0';
|
|
56
|
+
free(wbuf);
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
#endif
|
|
60
|
+
}
|