@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
package/src/package.ts
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { mkdir, copyFile, chmod } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import { existsSync } from "node:fs";
|
|
5
|
+
import { runCmd } from "./common";
|
|
6
|
+
import type { ResolvedZappConfig } from "./config";
|
|
7
|
+
import { generateIcns, compileIconAsset } from "./icons";
|
|
8
|
+
|
|
9
|
+
export const runPackage = async ({ root, nativeOut, config }: { root: string; nativeOut: string; config: ResolvedZappConfig }) => {
|
|
10
|
+
if (process.platform === "darwin") {
|
|
11
|
+
await packageMacOS({ root, nativeOut, config });
|
|
12
|
+
} else if (process.platform === "win32") {
|
|
13
|
+
console.log("[zapp] Windows packaging: the binary is ready at " + nativeOut);
|
|
14
|
+
console.log("[zapp] Icon embedding happens during 'zapp build' (see build.ts).");
|
|
15
|
+
console.log("[zapp] Installer generation (NSIS/MSIX) is not yet implemented.");
|
|
16
|
+
} else {
|
|
17
|
+
console.error("[zapp] Packaging is not yet supported on this platform.");
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
async function packageMacOS({ root, nativeOut, config }: { root: string; nativeOut: string; config: ResolvedZappConfig }) {
|
|
22
|
+
const appName = config.name;
|
|
23
|
+
const appBundleName = `${appName}.app`;
|
|
24
|
+
const binDir = path.join(root, "bin");
|
|
25
|
+
await mkdir(binDir, { recursive: true });
|
|
26
|
+
const appBundlePath = path.join(binDir, appBundleName);
|
|
27
|
+
|
|
28
|
+
process.stdout.write(`[zapp] packaging ${appName} → ${appBundleName}\n`);
|
|
29
|
+
|
|
30
|
+
const contentsDir = path.join(appBundlePath, "Contents");
|
|
31
|
+
const macosDir = path.join(contentsDir, "MacOS");
|
|
32
|
+
const resourcesDir = path.join(contentsDir, "Resources");
|
|
33
|
+
|
|
34
|
+
await mkdir(macosDir, { recursive: true });
|
|
35
|
+
await mkdir(resourcesDir, { recursive: true });
|
|
36
|
+
|
|
37
|
+
// 1. Copy the executable
|
|
38
|
+
const execPath = path.resolve(root, nativeOut);
|
|
39
|
+
if (!existsSync(execPath)) {
|
|
40
|
+
console.error(`[zapp] binary not found at ${execPath}. Run 'zapp build' first.`);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const destExecPath = path.join(macosDir, appName);
|
|
45
|
+
await copyFile(execPath, destExecPath);
|
|
46
|
+
await chmod(destExecPath, 0o755);
|
|
47
|
+
|
|
48
|
+
// 2. Icons
|
|
49
|
+
let hasIcon = false;
|
|
50
|
+
let hasLiquidGlass = false;
|
|
51
|
+
|
|
52
|
+
// Standard icon: PNG → .icns
|
|
53
|
+
if (config.icon) {
|
|
54
|
+
const iconSource = path.resolve(root, config.icon);
|
|
55
|
+
const icnsPath = await generateIcns(iconSource, resourcesDir);
|
|
56
|
+
if (icnsPath) {
|
|
57
|
+
hasIcon = true;
|
|
58
|
+
process.stdout.write(`[zapp] generated AppIcon.icns\n`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Liquid glass icon: .icon folder → Assets.car
|
|
63
|
+
if (config.macos?.iconLayers) {
|
|
64
|
+
const iconFolder = path.resolve(root, config.macos.iconLayers);
|
|
65
|
+
const carPath = await compileIconAsset(iconFolder, resourcesDir);
|
|
66
|
+
if (carPath) {
|
|
67
|
+
hasLiquidGlass = true;
|
|
68
|
+
process.stdout.write(`[zapp] compiled liquid glass icon → Assets.car\n`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// 3. Generate Info.plist
|
|
73
|
+
const configPlistPath = path.join(root, "config", "darwin", "Info.plist");
|
|
74
|
+
let plistContent = "";
|
|
75
|
+
|
|
76
|
+
if (existsSync(configPlistPath)) {
|
|
77
|
+
plistContent = await Bun.file(configPlistPath).text();
|
|
78
|
+
// Inject icon keys if icon was generated and plist doesn't have them
|
|
79
|
+
if (hasIcon && !plistContent.includes("CFBundleIconFile")) {
|
|
80
|
+
plistContent = plistContent.replace(
|
|
81
|
+
"</dict>",
|
|
82
|
+
` <key>CFBundleIconFile</key>\n <string>AppIcon</string>\n <key>CFBundleIconName</key>\n <string>AppIcon</string>\n</dict>`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
process.stdout.write(`[zapp] using custom Info.plist\n`);
|
|
86
|
+
} else {
|
|
87
|
+
const minVersion = config.macos?.minimumSystemVersion ?? "13.0";
|
|
88
|
+
const category = config.macos?.category ?? "";
|
|
89
|
+
const copyright = config.author ? `Copyright © ${new Date().getFullYear()} ${config.author}` : "";
|
|
90
|
+
|
|
91
|
+
let extraKeys = "";
|
|
92
|
+
if (hasIcon || hasLiquidGlass) {
|
|
93
|
+
extraKeys += ` <key>CFBundleIconFile</key>
|
|
94
|
+
<string>AppIcon</string>
|
|
95
|
+
<key>CFBundleIconName</key>
|
|
96
|
+
<string>AppIcon</string>\n`;
|
|
97
|
+
}
|
|
98
|
+
if (category) {
|
|
99
|
+
extraKeys += ` <key>LSApplicationCategoryType</key>
|
|
100
|
+
<string>${category}</string>\n`;
|
|
101
|
+
}
|
|
102
|
+
if (copyright) {
|
|
103
|
+
extraKeys += ` <key>NSHumanReadableCopyright</key>
|
|
104
|
+
<string>${copyright}</string>\n`;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
plistContent = `<?xml version="1.0" encoding="UTF-8"?>
|
|
108
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
109
|
+
<plist version="1.0">
|
|
110
|
+
<dict>
|
|
111
|
+
<key>CFBundleName</key>
|
|
112
|
+
<string>${appName}</string>
|
|
113
|
+
<key>CFBundleExecutable</key>
|
|
114
|
+
<string>${appName}</string>
|
|
115
|
+
<key>CFBundleIdentifier</key>
|
|
116
|
+
<string>${config.identifier}</string>
|
|
117
|
+
<key>CFBundleVersion</key>
|
|
118
|
+
<string>${config.version}</string>
|
|
119
|
+
<key>CFBundleShortVersionString</key>
|
|
120
|
+
<string>${config.version}</string>
|
|
121
|
+
<key>CFBundlePackageType</key>
|
|
122
|
+
<string>APPL</string>
|
|
123
|
+
<key>LSMinimumSystemVersion</key>
|
|
124
|
+
<string>${minVersion}</string>
|
|
125
|
+
<key>NSHighResolutionCapable</key>
|
|
126
|
+
<true/>
|
|
127
|
+
${extraKeys}</dict>
|
|
128
|
+
</plist>`;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Ensure CFBundleExecutable is set correctly
|
|
132
|
+
if (!plistContent.includes("<key>CFBundleExecutable</key>")) {
|
|
133
|
+
plistContent = plistContent.replace(
|
|
134
|
+
"<dict>",
|
|
135
|
+
`<dict>\n <key>CFBundleExecutable</key>\n <string>${appName}</string>`
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
await Bun.write(path.join(contentsDir, "Info.plist"), plistContent);
|
|
140
|
+
|
|
141
|
+
// 4. Ad-hoc codesign
|
|
142
|
+
try {
|
|
143
|
+
await runCmd("codesign", ["--force", "--deep", "--sign", "-", appBundlePath]);
|
|
144
|
+
process.stdout.write(`[zapp] codesigned (ad-hoc)\n`);
|
|
145
|
+
} catch {
|
|
146
|
+
console.warn("[zapp] codesign failed (non-fatal)");
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
process.stdout.write(`[zapp] packaged → ${appBundlePath}\n`);
|
|
150
|
+
}
|
package/src/zapp-cli.ts
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import yargs from "yargs";
|
|
5
|
+
import { hideBin } from "yargs/helpers";
|
|
6
|
+
import { runDev } from "./dev";
|
|
7
|
+
import { runBuild } from "./build";
|
|
8
|
+
import { runInit } from "./init";
|
|
9
|
+
import { runPackage } from "./package";
|
|
10
|
+
import { runGenerate } from "./generate";
|
|
11
|
+
import { loadConfig } from "./config";
|
|
12
|
+
|
|
13
|
+
const VALID_LOG_LEVELS = ["error", "warn", "info", "debug", "trace"] as const;
|
|
14
|
+
type LogLevel = typeof VALID_LOG_LEVELS[number];
|
|
15
|
+
|
|
16
|
+
const checkPrerequisites = () => {
|
|
17
|
+
const which = Bun.which("zc");
|
|
18
|
+
if (!which) {
|
|
19
|
+
console.error(
|
|
20
|
+
"[zapp] Error: 'zc' (Zen-C compiler) not found on PATH.\n" +
|
|
21
|
+
" Install from: https://github.com/zenc-lang/zenc\n"
|
|
22
|
+
);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const cwd = process.cwd();
|
|
28
|
+
|
|
29
|
+
const commonOptions = {
|
|
30
|
+
root: {
|
|
31
|
+
type: "string" as const,
|
|
32
|
+
default: ".",
|
|
33
|
+
describe: "Project root directory",
|
|
34
|
+
},
|
|
35
|
+
frontend: {
|
|
36
|
+
type: "string" as const,
|
|
37
|
+
default: ".",
|
|
38
|
+
describe: "Frontend directory",
|
|
39
|
+
},
|
|
40
|
+
input: {
|
|
41
|
+
type: "string" as const,
|
|
42
|
+
default: "zapp/build.zc",
|
|
43
|
+
describe: "Build file (alias: --build-file)",
|
|
44
|
+
},
|
|
45
|
+
out: {
|
|
46
|
+
type: "string" as const,
|
|
47
|
+
describe: "Override output binary path",
|
|
48
|
+
},
|
|
49
|
+
backend: {
|
|
50
|
+
type: "string" as const,
|
|
51
|
+
describe: "Backend script path",
|
|
52
|
+
},
|
|
53
|
+
"log-level": {
|
|
54
|
+
type: "string" as const,
|
|
55
|
+
choices: VALID_LOG_LEVELS,
|
|
56
|
+
describe: "Log level",
|
|
57
|
+
},
|
|
58
|
+
} as const;
|
|
59
|
+
|
|
60
|
+
const cli = yargs(hideBin(process.argv))
|
|
61
|
+
.scriptName("zapp")
|
|
62
|
+
.usage("zapp <command> [options]")
|
|
63
|
+
.strict()
|
|
64
|
+
.demandCommand(1, "Please specify a command")
|
|
65
|
+
.command(
|
|
66
|
+
"init [name]",
|
|
67
|
+
"Scaffold a new Zapp project",
|
|
68
|
+
(yargs) =>
|
|
69
|
+
yargs
|
|
70
|
+
.positional("name", {
|
|
71
|
+
type: "string",
|
|
72
|
+
default: "zapp-app",
|
|
73
|
+
describe: "Project name",
|
|
74
|
+
})
|
|
75
|
+
.option("template", {
|
|
76
|
+
type: "string",
|
|
77
|
+
default: "vanilla-ts",
|
|
78
|
+
describe: "Vite template (e.g. vanilla-ts, react-ts, svelte-ts, vue-ts)",
|
|
79
|
+
})
|
|
80
|
+
.option("root", commonOptions.root),
|
|
81
|
+
async (argv) => {
|
|
82
|
+
const root = path.resolve(cwd, argv.root);
|
|
83
|
+
await runInit({
|
|
84
|
+
root,
|
|
85
|
+
name: argv.name,
|
|
86
|
+
template: argv.template,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
)
|
|
90
|
+
.command(
|
|
91
|
+
"dev",
|
|
92
|
+
"Run Vite + native app together",
|
|
93
|
+
(yargs) =>
|
|
94
|
+
yargs
|
|
95
|
+
.option("root", commonOptions.root)
|
|
96
|
+
.option("frontend", commonOptions.frontend)
|
|
97
|
+
.option("input", commonOptions.input)
|
|
98
|
+
.option("out", commonOptions.out)
|
|
99
|
+
.option("backend", commonOptions.backend)
|
|
100
|
+
.option("log-level", commonOptions["log-level"])
|
|
101
|
+
.option("dev-url", {
|
|
102
|
+
type: "string",
|
|
103
|
+
default: "http://localhost:5173",
|
|
104
|
+
describe: "Dev server URL",
|
|
105
|
+
})
|
|
106
|
+
.option("brotli", {
|
|
107
|
+
type: "boolean",
|
|
108
|
+
default: false,
|
|
109
|
+
describe: "Brotli-compress embedded assets",
|
|
110
|
+
})
|
|
111
|
+
.option("embed-assets", {
|
|
112
|
+
type: "boolean",
|
|
113
|
+
default: false,
|
|
114
|
+
describe: "Embed assets in binary (default: false for dev)",
|
|
115
|
+
}),
|
|
116
|
+
async (argv) => {
|
|
117
|
+
checkPrerequisites();
|
|
118
|
+
const root = path.resolve(cwd, argv.root);
|
|
119
|
+
const frontendDir = path.resolve(root, argv.frontend);
|
|
120
|
+
const buildFile = path.resolve(root, argv.input);
|
|
121
|
+
const config = await loadConfig(root);
|
|
122
|
+
const nativeOut = argv.out
|
|
123
|
+
? path.resolve(root, argv.out)
|
|
124
|
+
: path.resolve(root, "bin", process.platform === "win32" ? `${config.name}.exe` : config.name);
|
|
125
|
+
|
|
126
|
+
await runDev({
|
|
127
|
+
root,
|
|
128
|
+
frontendDir,
|
|
129
|
+
buildFile,
|
|
130
|
+
nativeOut,
|
|
131
|
+
devUrl: argv["dev-url"],
|
|
132
|
+
withBrotli: argv.brotli,
|
|
133
|
+
embedAssets: argv["embed-assets"],
|
|
134
|
+
backendScript: argv.backend,
|
|
135
|
+
logLevel: argv["log-level"] as LogLevel | undefined,
|
|
136
|
+
config,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
)
|
|
140
|
+
.command(
|
|
141
|
+
"build",
|
|
142
|
+
"Build frontend assets + native binary",
|
|
143
|
+
(yargs) =>
|
|
144
|
+
yargs
|
|
145
|
+
.option("root", commonOptions.root)
|
|
146
|
+
.option("frontend", commonOptions.frontend)
|
|
147
|
+
.option("input", commonOptions.input)
|
|
148
|
+
.option("out", commonOptions.out)
|
|
149
|
+
.option("backend", commonOptions.backend)
|
|
150
|
+
.option("log-level", commonOptions["log-level"])
|
|
151
|
+
.option("asset-dir", {
|
|
152
|
+
type: "string",
|
|
153
|
+
default: "dist",
|
|
154
|
+
describe: "Asset directory",
|
|
155
|
+
})
|
|
156
|
+
.option("brotli", {
|
|
157
|
+
type: "boolean",
|
|
158
|
+
default: false,
|
|
159
|
+
describe: "Brotli-compress embedded assets",
|
|
160
|
+
})
|
|
161
|
+
.option("debug", {
|
|
162
|
+
type: "boolean",
|
|
163
|
+
default: false,
|
|
164
|
+
describe: "Debug build (filesystem assets, debug logs, no optimizations)",
|
|
165
|
+
}),
|
|
166
|
+
async (argv) => {
|
|
167
|
+
checkPrerequisites();
|
|
168
|
+
const root = path.resolve(cwd, argv.root);
|
|
169
|
+
const frontendDir = path.resolve(root, argv.frontend);
|
|
170
|
+
const buildFile = path.resolve(root, argv.input);
|
|
171
|
+
const assetDir = path.resolve(frontendDir, argv["asset-dir"]);
|
|
172
|
+
const config = await loadConfig(root);
|
|
173
|
+
const nativeOut = argv.out
|
|
174
|
+
? path.resolve(root, argv.out)
|
|
175
|
+
: path.resolve(root, "bin", process.platform === "win32" ? `${config.name}.exe` : config.name);
|
|
176
|
+
|
|
177
|
+
// Embed assets by default for builds, unless --debug
|
|
178
|
+
const embedAssets = !argv.debug;
|
|
179
|
+
|
|
180
|
+
await runBuild({
|
|
181
|
+
root,
|
|
182
|
+
frontendDir,
|
|
183
|
+
buildFile,
|
|
184
|
+
nativeOut,
|
|
185
|
+
assetDir,
|
|
186
|
+
withBrotli: argv.brotli,
|
|
187
|
+
embedAssets,
|
|
188
|
+
isDebug: argv.debug,
|
|
189
|
+
backendScript: argv.backend,
|
|
190
|
+
logLevel: argv["log-level"] as LogLevel | undefined,
|
|
191
|
+
config,
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
)
|
|
195
|
+
.command(
|
|
196
|
+
"package",
|
|
197
|
+
"Build and package into a platform bundle (.app on macOS)",
|
|
198
|
+
(yargs) =>
|
|
199
|
+
yargs
|
|
200
|
+
.option("root", commonOptions.root)
|
|
201
|
+
.option("frontend", commonOptions.frontend)
|
|
202
|
+
.option("input", commonOptions.input)
|
|
203
|
+
.option("out", commonOptions.out)
|
|
204
|
+
.option("brotli", {
|
|
205
|
+
type: "boolean",
|
|
206
|
+
default: true,
|
|
207
|
+
describe: "Brotli-compress embedded assets",
|
|
208
|
+
})
|
|
209
|
+
.option("skip-build", {
|
|
210
|
+
type: "boolean",
|
|
211
|
+
default: false,
|
|
212
|
+
describe: "Skip the build step (use existing binary)",
|
|
213
|
+
}),
|
|
214
|
+
async (argv) => {
|
|
215
|
+
checkPrerequisites();
|
|
216
|
+
const root = path.resolve(cwd, argv.root);
|
|
217
|
+
const frontendDir = path.resolve(root, argv.frontend);
|
|
218
|
+
const buildFile = path.resolve(root, argv.input);
|
|
219
|
+
const config = await loadConfig(root);
|
|
220
|
+
const nativeOut = argv.out
|
|
221
|
+
? path.resolve(root, argv.out)
|
|
222
|
+
: path.resolve(root, "bin", process.platform === "win32" ? `${config.name}.exe` : config.name);
|
|
223
|
+
|
|
224
|
+
if (!argv["skip-build"]) {
|
|
225
|
+
const assetDir = path.resolve(frontendDir, "dist");
|
|
226
|
+
await runBuild({
|
|
227
|
+
root,
|
|
228
|
+
frontendDir,
|
|
229
|
+
buildFile,
|
|
230
|
+
nativeOut,
|
|
231
|
+
assetDir,
|
|
232
|
+
isDebug: false,
|
|
233
|
+
embedAssets: true,
|
|
234
|
+
withBrotli: argv.brotli,
|
|
235
|
+
config,
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
await runPackage({ root, nativeOut, config });
|
|
240
|
+
}
|
|
241
|
+
)
|
|
242
|
+
.command(
|
|
243
|
+
"generate",
|
|
244
|
+
"Generate TypeScript bindings from Zen-C services",
|
|
245
|
+
(yargs) =>
|
|
246
|
+
yargs
|
|
247
|
+
.option("root", commonOptions.root)
|
|
248
|
+
.option("frontend", commonOptions.frontend)
|
|
249
|
+
.option("out-dir", {
|
|
250
|
+
type: "string",
|
|
251
|
+
describe: "Output directory for generated files",
|
|
252
|
+
}),
|
|
253
|
+
async (argv) => {
|
|
254
|
+
const root = path.resolve(cwd, argv.root);
|
|
255
|
+
const frontendDir = path.resolve(root, argv.frontend);
|
|
256
|
+
await runGenerate({ root, frontendDir, outDir: argv["out-dir"] });
|
|
257
|
+
}
|
|
258
|
+
)
|
|
259
|
+
.alias("h", "help")
|
|
260
|
+
.alias("v", "version")
|
|
261
|
+
.alias("build-file", "input")
|
|
262
|
+
.epilogue("Documentation: https://zapp.dev")
|
|
263
|
+
.parse();
|