@tothalex/nulljs 0.0.60 → 0.0.62
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/dist/cli.js +1232 -651
- package/package.json +4 -4
package/dist/cli.js
CHANGED
|
@@ -12,93 +12,37 @@ var __export = (target, all) => {
|
|
|
12
12
|
};
|
|
13
13
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
14
14
|
var __require = import.meta.require;
|
|
15
|
-
// ../../packages/api/types/index.ts
|
|
16
|
-
var init_types = () => {};
|
|
17
15
|
|
|
18
|
-
//
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (Array.isArray(value)) {
|
|
27
|
-
params.push(`${key}=${value.join(",")}`);
|
|
28
|
-
} else {
|
|
29
|
-
params.push(`${key}=${encodeURIComponent(String(value))}`);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
const queryString = params.join("&");
|
|
33
|
-
if (queryString) {
|
|
34
|
-
fullPath = `${fullPath}?${queryString}`;
|
|
16
|
+
// src/lib/paths.ts
|
|
17
|
+
import { existsSync } from "fs";
|
|
18
|
+
import { join, dirname } from "path";
|
|
19
|
+
var findProjectRoot = (startPath = process.cwd()) => {
|
|
20
|
+
let currentPath = startPath;
|
|
21
|
+
while (currentPath !== dirname(currentPath)) {
|
|
22
|
+
if (existsSync(join(currentPath, "package.json"))) {
|
|
23
|
+
return currentPath;
|
|
35
24
|
}
|
|
25
|
+
currentPath = dirname(currentPath);
|
|
36
26
|
}
|
|
37
|
-
return
|
|
38
|
-
},
|
|
39
|
-
|
|
40
|
-
const headers = {};
|
|
41
|
-
if (options?.publicKey) {
|
|
42
|
-
headers["x-public-key"] = options.publicKey;
|
|
43
|
-
}
|
|
44
|
-
const response = await fetch(url, { headers });
|
|
45
|
-
if (!response.ok) {
|
|
46
|
-
const message = await response.text().catch(() => "");
|
|
47
|
-
throw new Error(`HTTP error! status: ${response.status}${message ? ` message: ${message}` : ""}`);
|
|
48
|
-
}
|
|
49
|
-
return response.json();
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
// ../../packages/api/actions/deployments.ts
|
|
53
|
-
var init_deployments = () => {};
|
|
54
|
-
|
|
55
|
-
// ../../packages/api/actions/invocations.ts
|
|
56
|
-
var init_invocations = () => {};
|
|
57
|
-
|
|
58
|
-
// ../../packages/api/actions/logs.ts
|
|
59
|
-
var getSystemLogs = async (public_key, query, url) => {
|
|
60
|
-
const path = buildUrl("/api/system/logs", { url, query });
|
|
61
|
-
return apiGet(path, { publicKey: public_key });
|
|
62
|
-
}, searchDeploymentLogs = async (public_key, props, url) => {
|
|
63
|
-
const path = buildUrl("/api/logs/search", { url, query: props });
|
|
64
|
-
return apiGet(path, { publicKey: public_key });
|
|
27
|
+
return startPath;
|
|
28
|
+
}, getCloudPath = () => {
|
|
29
|
+
return join(findProjectRoot(), ".nulljs");
|
|
65
30
|
};
|
|
66
|
-
var
|
|
67
|
-
|
|
68
|
-
// ../../packages/api/actions/assets.ts
|
|
69
|
-
var init_assets = () => {};
|
|
70
|
-
|
|
71
|
-
// ../../packages/api/actions/activity.ts
|
|
72
|
-
var init_activity = () => {};
|
|
73
|
-
|
|
74
|
-
// ../../packages/api/actions/index.ts
|
|
75
|
-
var init_actions = __esm(() => {
|
|
76
|
-
init_deployments();
|
|
77
|
-
init_invocations();
|
|
78
|
-
init_logs();
|
|
79
|
-
init_assets();
|
|
80
|
-
init_activity();
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
// ../../packages/api/index.ts
|
|
84
|
-
var init_api = __esm(() => {
|
|
85
|
-
init_types();
|
|
86
|
-
init_actions();
|
|
87
|
-
});
|
|
31
|
+
var init_paths = () => {};
|
|
88
32
|
|
|
89
33
|
// src/config/index.ts
|
|
90
|
-
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
91
|
-
import { join } from "path";
|
|
34
|
+
import { readFileSync, writeFileSync, existsSync as existsSync2, mkdirSync, readdirSync, rmSync } from "fs";
|
|
35
|
+
import { join as join2 } from "path";
|
|
92
36
|
import chalk from "chalk";
|
|
93
|
-
var getLocalConfigDir = () =>
|
|
37
|
+
var getLocalConfigDir = () => getCloudPath(), getLocalConfigFile = () => join2(getLocalConfigDir(), "config.json"), ensureLocalConfigDir = () => {
|
|
94
38
|
const localDir = getLocalConfigDir();
|
|
95
|
-
if (!
|
|
39
|
+
if (!existsSync2(localDir)) {
|
|
96
40
|
mkdirSync(localDir, { recursive: true });
|
|
97
41
|
}
|
|
98
42
|
}, readConfigStore = () => {
|
|
99
43
|
try {
|
|
100
44
|
const localFile = getLocalConfigFile();
|
|
101
|
-
if (!
|
|
45
|
+
if (!existsSync2(localFile)) {
|
|
102
46
|
return null;
|
|
103
47
|
}
|
|
104
48
|
const data = readFileSync(localFile, "utf-8");
|
|
@@ -202,46 +146,59 @@ var getLocalConfigDir = () => join(process.cwd(), ".nulljs"), getLocalConfigFile
|
|
|
202
146
|
}, loadPrivateKey = async (config) => {
|
|
203
147
|
const privateKeyBytes = Uint8Array.from(atob(config.key.private), (c) => c.charCodeAt(0));
|
|
204
148
|
return crypto.subtle.importKey("pkcs8", privateKeyBytes, { name: "Ed25519", namedCurve: "Ed25519" }, false, ["sign"]);
|
|
149
|
+
}, cleanLocalData = () => {
|
|
150
|
+
const localDir = getLocalConfigDir();
|
|
151
|
+
const deleted = [];
|
|
152
|
+
const preserved = [];
|
|
153
|
+
if (!existsSync2(localDir)) {
|
|
154
|
+
return { deleted, preserved };
|
|
155
|
+
}
|
|
156
|
+
const entries = readdirSync(localDir);
|
|
157
|
+
for (const entry of entries) {
|
|
158
|
+
if (entry === "config.json") {
|
|
159
|
+
preserved.push(entry);
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
const entryPath = join2(localDir, entry);
|
|
163
|
+
try {
|
|
164
|
+
rmSync(entryPath, { recursive: true, force: true });
|
|
165
|
+
deleted.push(entry);
|
|
166
|
+
} catch {}
|
|
167
|
+
}
|
|
168
|
+
return { deleted, preserved };
|
|
205
169
|
};
|
|
206
|
-
var init_config = () => {
|
|
170
|
+
var init_config = __esm(() => {
|
|
171
|
+
init_paths();
|
|
172
|
+
});
|
|
207
173
|
|
|
208
174
|
// src/lib/server.ts
|
|
209
|
-
import { existsSync as
|
|
210
|
-
import { join as
|
|
175
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync2, realpathSync } from "fs";
|
|
176
|
+
import { join as join3, dirname as dirname2 } from "path";
|
|
211
177
|
import chalk2 from "chalk";
|
|
212
178
|
var CLI_DIR, PLATFORMS, getPlatformKey = () => {
|
|
213
179
|
return `${process.platform}-${process.arch}`;
|
|
214
|
-
}, findProjectRoot = (startPath = process.cwd()) => {
|
|
215
|
-
let currentPath = startPath;
|
|
216
|
-
while (currentPath !== dirname(currentPath)) {
|
|
217
|
-
if (existsSync2(join2(currentPath, "package.json"))) {
|
|
218
|
-
return currentPath;
|
|
219
|
-
}
|
|
220
|
-
currentPath = dirname(currentPath);
|
|
221
|
-
}
|
|
222
|
-
return startPath;
|
|
223
180
|
}, findMonorepoRoot = (startPath = process.cwd()) => {
|
|
224
181
|
let currentPath = startPath;
|
|
225
|
-
while (currentPath !==
|
|
226
|
-
if (
|
|
182
|
+
while (currentPath !== dirname2(currentPath)) {
|
|
183
|
+
if (existsSync3(join3(currentPath, "Cargo.toml")) && existsSync3(join3(currentPath, "package.json"))) {
|
|
227
184
|
return currentPath;
|
|
228
185
|
}
|
|
229
|
-
currentPath =
|
|
186
|
+
currentPath = dirname2(currentPath);
|
|
230
187
|
}
|
|
231
188
|
return null;
|
|
232
189
|
}, getLocalBinaryPath = () => {
|
|
233
190
|
const envBinary = process.env.NULLJS_SERVER_BINARY;
|
|
234
|
-
if (envBinary &&
|
|
191
|
+
if (envBinary && existsSync3(envBinary)) {
|
|
235
192
|
return { path: envBinary, source: "local-env" };
|
|
236
193
|
}
|
|
237
194
|
const monorepoRoot = findMonorepoRoot() || findMonorepoRoot(CLI_DIR);
|
|
238
195
|
if (monorepoRoot) {
|
|
239
|
-
const debugBinary =
|
|
240
|
-
if (
|
|
196
|
+
const debugBinary = join3(monorepoRoot, "target", "debug", "server");
|
|
197
|
+
if (existsSync3(debugBinary)) {
|
|
241
198
|
return { path: debugBinary, source: "local-debug" };
|
|
242
199
|
}
|
|
243
|
-
const releaseBinary =
|
|
244
|
-
if (
|
|
200
|
+
const releaseBinary = join3(monorepoRoot, "target", "release", "server");
|
|
201
|
+
if (existsSync3(releaseBinary)) {
|
|
245
202
|
return { path: releaseBinary, source: "local-release" };
|
|
246
203
|
}
|
|
247
204
|
}
|
|
@@ -262,10 +219,9 @@ var CLI_DIR, PLATFORMS, getPlatformKey = () => {
|
|
|
262
219
|
const args = ["--dev"];
|
|
263
220
|
args.push("--api-port", "3000");
|
|
264
221
|
args.push("--gateway-port", "3001");
|
|
265
|
-
const
|
|
266
|
-
const cloudPath = join2(projectRoot, ".nulljs");
|
|
222
|
+
const cloudPath = getCloudPath();
|
|
267
223
|
args.push("--cloud-path", cloudPath);
|
|
268
|
-
if (!
|
|
224
|
+
if (!existsSync3(cloudPath)) {
|
|
269
225
|
mkdirSync2(cloudPath, { recursive: true });
|
|
270
226
|
}
|
|
271
227
|
args.push("--public-key", devConfig.key.public);
|
|
@@ -307,7 +263,8 @@ var CLI_DIR, PLATFORMS, getPlatformKey = () => {
|
|
|
307
263
|
};
|
|
308
264
|
var init_server = __esm(() => {
|
|
309
265
|
init_config();
|
|
310
|
-
|
|
266
|
+
init_paths();
|
|
267
|
+
CLI_DIR = dirname2(realpathSync(import.meta.dir));
|
|
311
268
|
PLATFORMS = {
|
|
312
269
|
"linux-x64": "@tothalex/nulljs-linux-x64",
|
|
313
270
|
"linux-arm64": "@tothalex/nulljs-linux-arm64",
|
|
@@ -515,9 +472,9 @@ var init_bundle = __esm(() => {
|
|
|
515
472
|
});
|
|
516
473
|
|
|
517
474
|
// ../../packages/api/actions/http.ts
|
|
518
|
-
import { mkdtempSync, writeFileSync as writeFileSync2, rmSync } from "fs";
|
|
475
|
+
import { mkdtempSync, writeFileSync as writeFileSync2, rmSync as rmSync2 } from "fs";
|
|
519
476
|
import { tmpdir } from "os";
|
|
520
|
-
import { join as
|
|
477
|
+
import { join as join4 } from "path";
|
|
521
478
|
var {$ } = globalThis.Bun;
|
|
522
479
|
var parseCurlResponse = (result) => {
|
|
523
480
|
const lines = result.trim().split(`
|
|
@@ -558,15 +515,15 @@ var parseCurlResponse = (result) => {
|
|
|
558
515
|
const url = options?.baseUrl ? `${options.baseUrl}${path}` : path;
|
|
559
516
|
const headers = options?.headers || {};
|
|
560
517
|
if (options?.useCurl) {
|
|
561
|
-
const tempDir = mkdtempSync(
|
|
562
|
-
const bodyFile =
|
|
518
|
+
const tempDir = mkdtempSync(join4(tmpdir(), "nulljs-http-"));
|
|
519
|
+
const bodyFile = join4(tempDir, "body.json");
|
|
563
520
|
try {
|
|
564
521
|
writeFileSync2(bodyFile, body);
|
|
565
522
|
const headerFlags = buildHeaderFlags(headers);
|
|
566
523
|
const result = await $`curl -s -w '\n%{http_code}' -X POST ${headerFlags} -d @${bodyFile} ${url}`.text();
|
|
567
524
|
return parseCurlResponse(result);
|
|
568
525
|
} finally {
|
|
569
|
-
|
|
526
|
+
rmSync2(tempDir, { recursive: true, force: true });
|
|
570
527
|
}
|
|
571
528
|
}
|
|
572
529
|
const response = await fetch(url, {
|
|
@@ -583,11 +540,11 @@ var parseCurlResponse = (result) => {
|
|
|
583
540
|
const url = options?.baseUrl ? `${options.baseUrl}${path}` : path;
|
|
584
541
|
const headers = options?.headers || {};
|
|
585
542
|
if (options?.useCurl) {
|
|
586
|
-
const tempDir = mkdtempSync(
|
|
543
|
+
const tempDir = mkdtempSync(join4(tmpdir(), "nulljs-http-"));
|
|
587
544
|
try {
|
|
588
545
|
const formParts = [];
|
|
589
546
|
for (const file of files) {
|
|
590
|
-
const filePath =
|
|
547
|
+
const filePath = join4(tempDir, file.fileName);
|
|
591
548
|
writeFileSync2(filePath, file.content);
|
|
592
549
|
formParts.push("-F");
|
|
593
550
|
formParts.push(`${file.fileName}=@${filePath};type=${file.mimeType}`);
|
|
@@ -596,7 +553,7 @@ var parseCurlResponse = (result) => {
|
|
|
596
553
|
const result = await $`curl -s -w '\n%{http_code}' -X POST ${headerFlags} ${formParts} ${url}`.text();
|
|
597
554
|
return parseCurlResponse(result);
|
|
598
555
|
} finally {
|
|
599
|
-
|
|
556
|
+
rmSync2(tempDir, { recursive: true, force: true });
|
|
600
557
|
}
|
|
601
558
|
}
|
|
602
559
|
const form = new FormData;
|
|
@@ -629,10 +586,10 @@ var getMimeType = (fileName) => {
|
|
|
629
586
|
if (fileName.endsWith(".json"))
|
|
630
587
|
return "application/json";
|
|
631
588
|
return "application/octet-stream";
|
|
632
|
-
}, assetsToFileData = (
|
|
589
|
+
}, assetsToFileData = (assets) => {
|
|
633
590
|
const files = [];
|
|
634
591
|
const blobs = [];
|
|
635
|
-
for (const asset of
|
|
592
|
+
for (const asset of assets) {
|
|
636
593
|
const mimeType = getMimeType(asset.fileName);
|
|
637
594
|
const buffer = Buffer.from(asset.code);
|
|
638
595
|
files.push({
|
|
@@ -652,10 +609,10 @@ var getMimeType = (fileName) => {
|
|
|
652
609
|
const dataString = sortedBlobs.map((b) => `${b.fileName}:${b.size}:${b.type}`).join("|");
|
|
653
610
|
const sign = await crypto.subtle.sign("Ed25519", privateKey, Buffer.from(dataString));
|
|
654
611
|
return btoa(String.fromCharCode(...new Uint8Array(sign)));
|
|
655
|
-
}, createFunctionDeployment = async (
|
|
656
|
-
const handler =
|
|
612
|
+
}, createFunctionDeployment = async (deployment, options) => {
|
|
613
|
+
const handler = deployment.assets.find((asset) => asset.fileName === "handler.js");
|
|
657
614
|
if (!handler) {
|
|
658
|
-
throw new Error(`Handler not found for ${
|
|
615
|
+
throw new Error(`Handler not found for ${deployment.name}`);
|
|
659
616
|
}
|
|
660
617
|
const { files, blobs } = assetsToFileData([handler]);
|
|
661
618
|
const signature = await createSignature(blobs, options.privateKey);
|
|
@@ -671,8 +628,8 @@ var getMimeType = (fileName) => {
|
|
|
671
628
|
if (!result.ok) {
|
|
672
629
|
throw new Error(`Deployment failed (${result.status}): ${result.body}`);
|
|
673
630
|
}
|
|
674
|
-
}, createReactDeployment = async (
|
|
675
|
-
const { files, blobs } = assetsToFileData(
|
|
631
|
+
}, createReactDeployment = async (deployment, options) => {
|
|
632
|
+
const { files, blobs } = assetsToFileData(deployment.assets);
|
|
676
633
|
const signature = await createSignature(blobs, options.privateKey);
|
|
677
634
|
const baseUrl = options.url || "";
|
|
678
635
|
const path = "/api/deployment/react";
|
|
@@ -722,21 +679,21 @@ var deployedHashes, clearDeployCache = () => {
|
|
|
722
679
|
}, deployReact = async (filePath, privateKey, apiUrl, useCurl) => {
|
|
723
680
|
const fileName = basename2(filePath);
|
|
724
681
|
const result = await build(spaClientConfig(filePath));
|
|
725
|
-
const
|
|
682
|
+
const assets = [];
|
|
726
683
|
for (const output of result.output) {
|
|
727
684
|
if (output.type === "chunk") {
|
|
728
|
-
|
|
685
|
+
assets.push({ fileName: output.fileName, code: output.code });
|
|
729
686
|
} else if (output.type === "asset" && typeof output.source === "string") {
|
|
730
|
-
|
|
687
|
+
assets.push({ fileName: output.fileName, code: output.source });
|
|
731
688
|
}
|
|
732
689
|
}
|
|
733
|
-
const combinedCode =
|
|
690
|
+
const combinedCode = assets.map((a) => a.code).join("");
|
|
734
691
|
const hash = hashCode(combinedCode);
|
|
735
692
|
const lastHash = deployedHashes.get(filePath);
|
|
736
693
|
if (lastHash === hash) {
|
|
737
694
|
return { deployed: false, skipped: true };
|
|
738
695
|
}
|
|
739
|
-
await createReactDeployment({ name: fileName, assets
|
|
696
|
+
await createReactDeployment({ name: fileName, assets }, { privateKey, url: apiUrl, useCurl });
|
|
740
697
|
deployedHashes.set(filePath, hash);
|
|
741
698
|
return { deployed: true, skipped: false };
|
|
742
699
|
};
|
|
@@ -747,21 +704,21 @@ var init_deploy2 = __esm(() => {
|
|
|
747
704
|
});
|
|
748
705
|
|
|
749
706
|
// src/lib/watcher.ts
|
|
750
|
-
import { watch, existsSync as
|
|
707
|
+
import { watch, existsSync as existsSync4 } from "fs";
|
|
751
708
|
import { readdir } from "fs/promises";
|
|
752
|
-
import { join as
|
|
709
|
+
import { join as join5 } from "path";
|
|
753
710
|
import { build as build2 } from "vite";
|
|
754
711
|
var FUNCTION_DIRS, deployedHashes2, hashCode2 = (code) => {
|
|
755
712
|
return Bun.hash(code).toString(16);
|
|
756
713
|
}, findFunctionEntries = async (functionsPath) => {
|
|
757
714
|
const entries = [];
|
|
758
715
|
for (const dir of FUNCTION_DIRS) {
|
|
759
|
-
const dirPath =
|
|
716
|
+
const dirPath = join5(functionsPath, dir);
|
|
760
717
|
try {
|
|
761
718
|
const items = await readdir(dirPath, { withFileTypes: true });
|
|
762
719
|
for (const item of items) {
|
|
763
720
|
if (item.isFile() && (item.name.endsWith(".ts") || item.name.endsWith(".tsx"))) {
|
|
764
|
-
const fullPath =
|
|
721
|
+
const fullPath = join5(dirPath, item.name);
|
|
765
722
|
const name = `${dir}/${item.name.replace(/\.tsx?$/, "")}`;
|
|
766
723
|
entries.push({
|
|
767
724
|
name,
|
|
@@ -781,7 +738,7 @@ var FUNCTION_DIRS, deployedHashes2, hashCode2 = (code) => {
|
|
|
781
738
|
console.error('No local configuration found. Run "nulljs dev" first.');
|
|
782
739
|
return () => {};
|
|
783
740
|
}
|
|
784
|
-
const functionsPath =
|
|
741
|
+
const functionsPath = join5(srcPath, "function");
|
|
785
742
|
let entries = await findFunctionEntries(functionsPath);
|
|
786
743
|
let viteWatcher = null;
|
|
787
744
|
let isRestarting = false;
|
|
@@ -852,8 +809,8 @@ var FUNCTION_DIRS, deployedHashes2, hashCode2 = (code) => {
|
|
|
852
809
|
viteWatcher = await startViteWatcher();
|
|
853
810
|
const dirWatchers = [];
|
|
854
811
|
for (const dir of FUNCTION_DIRS) {
|
|
855
|
-
const dirPath =
|
|
856
|
-
if (!
|
|
812
|
+
const dirPath = join5(functionsPath, dir);
|
|
813
|
+
if (!existsSync4(dirPath))
|
|
857
814
|
continue;
|
|
858
815
|
try {
|
|
859
816
|
const watcher = watch(dirPath, async (eventType, filename) => {
|
|
@@ -861,10 +818,10 @@ var FUNCTION_DIRS, deployedHashes2, hashCode2 = (code) => {
|
|
|
861
818
|
return;
|
|
862
819
|
if (!filename.endsWith(".ts") && !filename.endsWith(".tsx"))
|
|
863
820
|
return;
|
|
864
|
-
const fullPath =
|
|
821
|
+
const fullPath = join5(dirPath, filename);
|
|
865
822
|
const entryName = `${dir}/${filename.replace(/\.tsx?$/, "")}`;
|
|
866
823
|
const existingEntry = entries.find((e) => e.name === entryName);
|
|
867
|
-
const fileExists =
|
|
824
|
+
const fileExists = existsSync4(fullPath);
|
|
868
825
|
if (!existingEntry && fileExists || existingEntry && !fileExists) {
|
|
869
826
|
await restartViteWatcher();
|
|
870
827
|
}
|
|
@@ -881,23 +838,25 @@ var FUNCTION_DIRS, deployedHashes2, hashCode2 = (code) => {
|
|
|
881
838
|
}
|
|
882
839
|
};
|
|
883
840
|
}, forceDeployAll = async (srcPath, options = {}) => {
|
|
884
|
-
const { onDeploy, onComplete } = options;
|
|
841
|
+
const { onStart, onDeploy, onComplete } = options;
|
|
885
842
|
const config = readLocalConfig();
|
|
886
843
|
if (!config) {
|
|
887
844
|
throw new Error('No local configuration found. Run "nulljs dev" first.');
|
|
888
845
|
}
|
|
889
846
|
const privateKey = await loadPrivateKey(config);
|
|
890
847
|
deployedHashes2.clear();
|
|
891
|
-
const functionsPath =
|
|
848
|
+
const functionsPath = join5(srcPath, "function");
|
|
892
849
|
const entries = await findFunctionEntries(functionsPath);
|
|
893
|
-
const reactEntry =
|
|
894
|
-
const hasReact =
|
|
895
|
-
|
|
850
|
+
const reactEntry = join5(srcPath, "index.tsx");
|
|
851
|
+
const hasReact = existsSync4(reactEntry);
|
|
852
|
+
const total = entries.length + (hasReact ? 1 : 0);
|
|
896
853
|
let successful = 0;
|
|
897
854
|
let failed = 0;
|
|
855
|
+
let completed = 0;
|
|
898
856
|
const { deployFunction: deployFunction2, deployReact: deployReact2, clearDeployCache: clearDeployCache2 } = await Promise.resolve().then(() => (init_deploy2(), exports_deploy));
|
|
899
857
|
clearDeployCache2();
|
|
900
858
|
for (const entry of entries) {
|
|
859
|
+
onStart?.(entry.name, completed, total);
|
|
901
860
|
try {
|
|
902
861
|
await deployFunction2(entry.path, privateKey, config.api);
|
|
903
862
|
successful++;
|
|
@@ -906,9 +865,11 @@ var FUNCTION_DIRS, deployedHashes2, hashCode2 = (code) => {
|
|
|
906
865
|
failed++;
|
|
907
866
|
onDeploy?.(entry.name, false, error instanceof Error ? error.message : String(error));
|
|
908
867
|
}
|
|
868
|
+
completed++;
|
|
909
869
|
}
|
|
910
870
|
if (hasReact) {
|
|
911
871
|
const fileName = "index.tsx";
|
|
872
|
+
onStart?.(fileName, completed, total);
|
|
912
873
|
try {
|
|
913
874
|
await deployReact2(reactEntry, privateKey, config.api);
|
|
914
875
|
successful++;
|
|
@@ -917,6 +878,7 @@ var FUNCTION_DIRS, deployedHashes2, hashCode2 = (code) => {
|
|
|
917
878
|
failed++;
|
|
918
879
|
onDeploy?.(fileName, false, error instanceof Error ? error.message : String(error));
|
|
919
880
|
}
|
|
881
|
+
completed++;
|
|
920
882
|
}
|
|
921
883
|
onComplete?.(total, successful, failed);
|
|
922
884
|
};
|
|
@@ -930,11 +892,11 @@ var init_watcher = __esm(() => {
|
|
|
930
892
|
|
|
931
893
|
// src/lib/vite.ts
|
|
932
894
|
import { createServer } from "vite";
|
|
933
|
-
import { dirname as
|
|
895
|
+
import { dirname as dirname3, resolve, basename as basename3 } from "path";
|
|
934
896
|
import react3 from "@vitejs/plugin-react";
|
|
935
897
|
import tailwindcss2 from "@tailwindcss/vite";
|
|
936
898
|
import { writeFile, unlink } from "fs/promises";
|
|
937
|
-
import { existsSync as
|
|
899
|
+
import { existsSync as existsSync5 } from "fs";
|
|
938
900
|
var VITE_PORT = 5173, GATEWAY_PORT = 3001, createViteLogger = (onLog) => {
|
|
939
901
|
return {
|
|
940
902
|
info: (msg) => onLog?.(msg, "info"),
|
|
@@ -978,10 +940,10 @@ var VITE_PORT = 5173, GATEWAY_PORT = 3001, createViteLogger = (onLog) => {
|
|
|
978
940
|
</html>`;
|
|
979
941
|
}, startViteServer = async (options) => {
|
|
980
942
|
const indexTsxPath = resolve(options.srcDir, "index.tsx");
|
|
981
|
-
if (!
|
|
943
|
+
if (!existsSync5(indexTsxPath)) {
|
|
982
944
|
return null;
|
|
983
945
|
}
|
|
984
|
-
const projectDir =
|
|
946
|
+
const projectDir = dirname3(options.srcDir);
|
|
985
947
|
const tempIndexPath = resolve(projectDir, "index.html");
|
|
986
948
|
try {
|
|
987
949
|
const indexHtml = createTempIndexHtml(indexTsxPath, projectDir);
|
|
@@ -1022,344 +984,641 @@ var VITE_PORT = 5173, GATEWAY_PORT = 3001, createViteLogger = (onLog) => {
|
|
|
1022
984
|
};
|
|
1023
985
|
var init_vite = () => {};
|
|
1024
986
|
|
|
1025
|
-
// src/
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
case "error":
|
|
1030
|
-
return "red";
|
|
1031
|
-
case "warn":
|
|
1032
|
-
case "warning":
|
|
1033
|
-
return "yellow";
|
|
1034
|
-
case "info":
|
|
1035
|
-
return "cyan";
|
|
1036
|
-
case "debug":
|
|
1037
|
-
return "gray";
|
|
1038
|
-
default:
|
|
1039
|
-
return "white";
|
|
1040
|
-
}
|
|
987
|
+
// src/ui/utils/logs.ts
|
|
988
|
+
var LOG_LEVEL_COLORS, SYSTEM_LOG_LEVEL_COLORS, getLevelColor = (level, variant = "deployment") => {
|
|
989
|
+
const colors = variant === "system" ? SYSTEM_LOG_LEVEL_COLORS : LOG_LEVEL_COLORS;
|
|
990
|
+
return colors[level.toLowerCase()] || "white";
|
|
1041
991
|
}, sanitizeMessage = (message) => {
|
|
1042
992
|
return message.replace(/\x1b\[[0-9;]*m/g, "").replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").trim();
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
}
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
993
|
+
};
|
|
994
|
+
var init_logs = __esm(() => {
|
|
995
|
+
LOG_LEVEL_COLORS = {
|
|
996
|
+
error: "red",
|
|
997
|
+
warn: "yellow",
|
|
998
|
+
warning: "yellow",
|
|
999
|
+
info: "cyan",
|
|
1000
|
+
debug: "gray",
|
|
1001
|
+
trace: "gray"
|
|
1002
|
+
};
|
|
1003
|
+
SYSTEM_LOG_LEVEL_COLORS = {
|
|
1004
|
+
...LOG_LEVEL_COLORS,
|
|
1005
|
+
info: "green"
|
|
1006
|
+
};
|
|
1007
|
+
});
|
|
1008
|
+
|
|
1009
|
+
// src/ui/utils/clipboard.ts
|
|
1010
|
+
import { exec } from "child_process";
|
|
1011
|
+
var copyToClipboard = (text) => {
|
|
1012
|
+
return new Promise((resolve2, reject) => {
|
|
1013
|
+
const proc = exec("pbcopy", (err) => {
|
|
1014
|
+
if (err)
|
|
1015
|
+
reject(err);
|
|
1016
|
+
else
|
|
1017
|
+
resolve2();
|
|
1018
|
+
});
|
|
1019
|
+
proc.stdin?.write(text);
|
|
1020
|
+
proc.stdin?.end();
|
|
1021
|
+
});
|
|
1022
|
+
};
|
|
1023
|
+
var init_clipboard = () => {};
|
|
1024
|
+
|
|
1025
|
+
// src/ui/utils/formatting.ts
|
|
1026
|
+
var getBinarySourceLabel = (source) => {
|
|
1027
|
+
switch (source) {
|
|
1028
|
+
case "local-debug":
|
|
1029
|
+
return "local debug";
|
|
1030
|
+
case "local-release":
|
|
1031
|
+
return "local release";
|
|
1032
|
+
case "local-env":
|
|
1033
|
+
return "env";
|
|
1034
|
+
case "npm":
|
|
1035
|
+
return "npm";
|
|
1036
|
+
default:
|
|
1037
|
+
return source;
|
|
1061
1038
|
}
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1039
|
+
};
|
|
1040
|
+
|
|
1041
|
+
// src/ui/utils/index.ts
|
|
1042
|
+
var init_utils = __esm(() => {
|
|
1043
|
+
init_logs();
|
|
1044
|
+
init_clipboard();
|
|
1045
|
+
});
|
|
1046
|
+
|
|
1047
|
+
// src/ui/components/layout/Header.tsx
|
|
1048
|
+
import { jsxDEV } from "@opentui/react/jsx-dev-runtime";
|
|
1049
|
+
var Header = (props) => {
|
|
1050
|
+
const { activeTab, functionCount, viteRunning, isDeploying, binarySource } = props;
|
|
1051
|
+
return /* @__PURE__ */ jsxDEV("box", {
|
|
1052
|
+
flexDirection: "column",
|
|
1053
|
+
children: /* @__PURE__ */ jsxDEV("box", {
|
|
1054
|
+
flexDirection: "row",
|
|
1055
|
+
justifyContent: "space-between",
|
|
1056
|
+
children: [
|
|
1057
|
+
/* @__PURE__ */ jsxDEV("box", {
|
|
1058
|
+
flexDirection: "row",
|
|
1059
|
+
gap: 2,
|
|
1074
1060
|
children: [
|
|
1075
|
-
/* @__PURE__ */ jsxDEV("
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
fg: getLevelColor(log.level),
|
|
1081
|
-
children: ` ${level} `
|
|
1082
|
-
}, undefined, false, undefined, this),
|
|
1083
|
-
/* @__PURE__ */ jsxDEV("span", {
|
|
1084
|
-
fg: "blue",
|
|
1085
|
-
children: `(${log.deployment_name})`
|
|
1061
|
+
/* @__PURE__ */ jsxDEV("text", {
|
|
1062
|
+
children: /* @__PURE__ */ jsxDEV("span", {
|
|
1063
|
+
fg: activeTab === "system" ? "cyan" : "gray",
|
|
1064
|
+
children: "[1] System Logs"
|
|
1065
|
+
}, undefined, false, undefined, this)
|
|
1086
1066
|
}, undefined, false, undefined, this),
|
|
1087
|
-
/* @__PURE__ */ jsxDEV("
|
|
1088
|
-
|
|
1089
|
-
|
|
1067
|
+
/* @__PURE__ */ jsxDEV("text", {
|
|
1068
|
+
children: /* @__PURE__ */ jsxDEV("span", {
|
|
1069
|
+
fg: "gray",
|
|
1070
|
+
children: " | "
|
|
1071
|
+
}, undefined, false, undefined, this)
|
|
1090
1072
|
}, undefined, false, undefined, this),
|
|
1091
|
-
/* @__PURE__ */ jsxDEV("
|
|
1092
|
-
children:
|
|
1073
|
+
/* @__PURE__ */ jsxDEV("text", {
|
|
1074
|
+
children: /* @__PURE__ */ jsxDEV("span", {
|
|
1075
|
+
fg: activeTab === "deployment" ? "cyan" : "gray",
|
|
1076
|
+
children: "[2] Deployment Logs"
|
|
1077
|
+
}, undefined, false, undefined, this)
|
|
1093
1078
|
}, undefined, false, undefined, this)
|
|
1094
1079
|
]
|
|
1095
|
-
}, undefined, true, undefined, this)
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
};
|
|
1100
|
-
var init_DeploymentLogsPane = () => {};
|
|
1101
|
-
|
|
1102
|
-
// src/components/SystemLogsPane.tsx
|
|
1103
|
-
import { jsxDEV as jsxDEV2 } from "@opentui/react/jsx-dev-runtime";
|
|
1104
|
-
var getLevelColor2 = (level) => {
|
|
1105
|
-
switch (level.toLowerCase()) {
|
|
1106
|
-
case "error":
|
|
1107
|
-
return "red";
|
|
1108
|
-
case "warn":
|
|
1109
|
-
case "warning":
|
|
1110
|
-
return "yellow";
|
|
1111
|
-
case "info":
|
|
1112
|
-
return "green";
|
|
1113
|
-
case "debug":
|
|
1114
|
-
case "trace":
|
|
1115
|
-
return "gray";
|
|
1116
|
-
default:
|
|
1117
|
-
return "white";
|
|
1118
|
-
}
|
|
1119
|
-
}, sanitizeMessage2 = (message) => {
|
|
1120
|
-
return message.replace(/\x1b\[[0-9;]*m/g, "").replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").trim();
|
|
1121
|
-
}, SystemLogsPane = (props) => {
|
|
1122
|
-
if (props.loading && props.logs.length === 0) {
|
|
1123
|
-
return /* @__PURE__ */ jsxDEV2("box", {
|
|
1124
|
-
flexDirection: "column",
|
|
1125
|
-
padding: 1,
|
|
1126
|
-
children: /* @__PURE__ */ jsxDEV2("text", {
|
|
1127
|
-
children: "Loading system logs..."
|
|
1128
|
-
}, undefined, false, undefined, this)
|
|
1129
|
-
}, undefined, false, undefined, this);
|
|
1130
|
-
}
|
|
1131
|
-
if (!props.loading && props.logs.length === 0) {
|
|
1132
|
-
return /* @__PURE__ */ jsxDEV2("box", {
|
|
1133
|
-
flexDirection: "column",
|
|
1134
|
-
padding: 1,
|
|
1135
|
-
children: /* @__PURE__ */ jsxDEV2("text", {
|
|
1136
|
-
children: "No system logs found"
|
|
1137
|
-
}, undefined, false, undefined, this)
|
|
1138
|
-
}, undefined, false, undefined, this);
|
|
1139
|
-
}
|
|
1140
|
-
const logsInOrder = [...props.logs].reverse();
|
|
1141
|
-
return /* @__PURE__ */ jsxDEV2("scrollbox", {
|
|
1142
|
-
focused: true,
|
|
1143
|
-
stickyStart: props.autoScroll ? "bottom" : "top",
|
|
1144
|
-
stickyScroll: props.autoScroll,
|
|
1145
|
-
children: logsInOrder.map((log) => {
|
|
1146
|
-
const time = new Date(log.timestamp).toLocaleTimeString();
|
|
1147
|
-
const timestamp = `[${time}]`;
|
|
1148
|
-
const level = log.level.toUpperCase();
|
|
1149
|
-
return /* @__PURE__ */ jsxDEV2("box", {
|
|
1150
|
-
flexDirection: "row",
|
|
1151
|
-
children: /* @__PURE__ */ jsxDEV2("text", {
|
|
1080
|
+
}, undefined, true, undefined, this),
|
|
1081
|
+
/* @__PURE__ */ jsxDEV("box", {
|
|
1082
|
+
flexDirection: "row",
|
|
1083
|
+
gap: 2,
|
|
1152
1084
|
children: [
|
|
1153
|
-
/* @__PURE__ */
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
fg: getLevelColor2(log.level),
|
|
1159
|
-
children: ` ${level} `
|
|
1085
|
+
isDeploying && /* @__PURE__ */ jsxDEV("text", {
|
|
1086
|
+
children: /* @__PURE__ */ jsxDEV("span", {
|
|
1087
|
+
fg: "yellow",
|
|
1088
|
+
children: "deploying..."
|
|
1089
|
+
}, undefined, false, undefined, this)
|
|
1160
1090
|
}, undefined, false, undefined, this),
|
|
1161
|
-
/* @__PURE__ */
|
|
1162
|
-
children:
|
|
1091
|
+
/* @__PURE__ */ jsxDEV("text", {
|
|
1092
|
+
children: /* @__PURE__ */ jsxDEV("span", {
|
|
1093
|
+
fg: "gray",
|
|
1094
|
+
children: [
|
|
1095
|
+
functionCount,
|
|
1096
|
+
" functions | vite ",
|
|
1097
|
+
viteRunning ? "running" : "stopped",
|
|
1098
|
+
" |",
|
|
1099
|
+
" ",
|
|
1100
|
+
getBinarySourceLabel(binarySource),
|
|
1101
|
+
" | ?=help"
|
|
1102
|
+
]
|
|
1103
|
+
}, undefined, true, undefined, this)
|
|
1163
1104
|
}, undefined, false, undefined, this)
|
|
1164
1105
|
]
|
|
1165
1106
|
}, undefined, true, undefined, this)
|
|
1166
|
-
|
|
1167
|
-
})
|
|
1168
|
-
},
|
|
1107
|
+
]
|
|
1108
|
+
}, undefined, true, undefined, this)
|
|
1109
|
+
}, undefined, false, undefined, this);
|
|
1169
1110
|
};
|
|
1170
|
-
var
|
|
1111
|
+
var init_Header = __esm(() => {
|
|
1112
|
+
init_utils();
|
|
1113
|
+
});
|
|
1171
1114
|
|
|
1172
|
-
// src/
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
}
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
}
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1115
|
+
// src/ui/constants/colors.ts
|
|
1116
|
+
var STATUS_COLORS, DEPLOY_COLORS;
|
|
1117
|
+
var init_colors = __esm(() => {
|
|
1118
|
+
STATUS_COLORS = {
|
|
1119
|
+
success: "#22c55e",
|
|
1120
|
+
warning: "#eab308",
|
|
1121
|
+
error: "#ef4444",
|
|
1122
|
+
info: "#3b82f6"
|
|
1123
|
+
};
|
|
1124
|
+
DEPLOY_COLORS = {
|
|
1125
|
+
success: "#22c55e",
|
|
1126
|
+
warning: "#eab308",
|
|
1127
|
+
error: "#ef4444",
|
|
1128
|
+
progress: "#3b82f6",
|
|
1129
|
+
muted: "#666"
|
|
1130
|
+
};
|
|
1131
|
+
});
|
|
1132
|
+
|
|
1133
|
+
// src/ui/constants/keybindings.ts
|
|
1134
|
+
var KEYBINDINGS, KEYBINDING_DESCRIPTIONS;
|
|
1135
|
+
var init_keybindings = __esm(() => {
|
|
1136
|
+
KEYBINDINGS = {
|
|
1137
|
+
"1": { type: "NAVIGATE", tab: "system" },
|
|
1138
|
+
"2": { type: "NAVIGATE", tab: "deployment" },
|
|
1139
|
+
"\t": { type: "CYCLE_TAB" },
|
|
1140
|
+
h: { type: "NAVIGATE", tab: "system" },
|
|
1141
|
+
l: { type: "NAVIGATE", tab: "deployment" },
|
|
1142
|
+
g: { type: "SCROLL", to: "top" },
|
|
1143
|
+
G: { type: "SCROLL", to: "bottom" },
|
|
1144
|
+
"?": { type: "TOGGLE_HELP" },
|
|
1145
|
+
"\x1B": { type: "CLOSE_MODAL" },
|
|
1146
|
+
d: { type: "DEPLOY" },
|
|
1147
|
+
y: { type: "YANK" },
|
|
1148
|
+
x: { type: "CLEAN" }
|
|
1149
|
+
};
|
|
1150
|
+
KEYBINDING_DESCRIPTIONS = [
|
|
1151
|
+
{ section: "Navigation", bindings: [
|
|
1152
|
+
{ keys: "1/2", description: "Switch tabs" },
|
|
1153
|
+
{ keys: "h/l", description: "Previous/next tab" },
|
|
1154
|
+
{ keys: "Tab", description: "Cycle tabs" }
|
|
1155
|
+
] },
|
|
1156
|
+
{ section: "Scrolling", bindings: [
|
|
1157
|
+
{ keys: "j/k", description: "Scroll down/up" },
|
|
1158
|
+
{ keys: "g/G", description: "Top/bottom" }
|
|
1159
|
+
] },
|
|
1160
|
+
{ section: "Actions", bindings: [
|
|
1161
|
+
{ keys: "y", description: "Yank (copy) selection" },
|
|
1162
|
+
{ keys: "d", description: "Deploy all" },
|
|
1163
|
+
{ keys: "x", description: "Clean local data" },
|
|
1164
|
+
{ keys: "?", description: "Toggle help" },
|
|
1165
|
+
{ keys: "Esc", description: "Close help" }
|
|
1166
|
+
] }
|
|
1167
|
+
];
|
|
1168
|
+
});
|
|
1169
|
+
|
|
1170
|
+
// src/ui/constants/index.ts
|
|
1171
|
+
var init_constants = __esm(() => {
|
|
1172
|
+
init_colors();
|
|
1173
|
+
init_keybindings();
|
|
1174
|
+
});
|
|
1175
|
+
|
|
1176
|
+
// src/ui/components/deploy/DeployProgress.tsx
|
|
1177
|
+
import { jsxDEV as jsxDEV2 } from "@opentui/react/jsx-dev-runtime";
|
|
1178
|
+
var DeployProgress = (props) => {
|
|
1179
|
+
const { currentFile, completedFiles, totalFiles } = props.progress;
|
|
1180
|
+
const completedCount = completedFiles.length;
|
|
1181
|
+
const failedCount = completedFiles.filter((f) => !f.success).length;
|
|
1182
|
+
return /* @__PURE__ */ jsxDEV2("box", {
|
|
1226
1183
|
backgroundColor: "black",
|
|
1227
1184
|
flexDirection: "row",
|
|
1228
1185
|
paddingLeft: 1,
|
|
1229
1186
|
paddingRight: 1,
|
|
1230
|
-
children: /* @__PURE__ */
|
|
1187
|
+
children: /* @__PURE__ */ jsxDEV2("text", {
|
|
1231
1188
|
children: [
|
|
1232
|
-
/* @__PURE__ */
|
|
1233
|
-
fg:
|
|
1234
|
-
children:
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
current.success ? "\u2713" : "\u2717"
|
|
1238
|
-
]
|
|
1239
|
-
}, undefined, true, undefined, this),
|
|
1240
|
-
/* @__PURE__ */ jsxDEV3("span", {
|
|
1189
|
+
/* @__PURE__ */ jsxDEV2("span", {
|
|
1190
|
+
fg: DEPLOY_COLORS.progress,
|
|
1191
|
+
children: "\u27F3 Deploying"
|
|
1192
|
+
}, undefined, false, undefined, this),
|
|
1193
|
+
/* @__PURE__ */ jsxDEV2("span", {
|
|
1241
1194
|
children: [
|
|
1242
1195
|
" ",
|
|
1243
|
-
|
|
1196
|
+
currentFile
|
|
1244
1197
|
]
|
|
1245
1198
|
}, undefined, true, undefined, this),
|
|
1246
|
-
|
|
1247
|
-
fg:
|
|
1199
|
+
/* @__PURE__ */ jsxDEV2("span", {
|
|
1200
|
+
fg: DEPLOY_COLORS.muted,
|
|
1248
1201
|
children: [
|
|
1249
1202
|
" ",
|
|
1250
1203
|
"(",
|
|
1251
|
-
|
|
1204
|
+
completedCount + 1,
|
|
1252
1205
|
"/",
|
|
1253
|
-
|
|
1206
|
+
totalFiles,
|
|
1254
1207
|
")"
|
|
1255
1208
|
]
|
|
1209
|
+
}, undefined, true, undefined, this),
|
|
1210
|
+
failedCount > 0 && /* @__PURE__ */ jsxDEV2("span", {
|
|
1211
|
+
fg: DEPLOY_COLORS.error,
|
|
1212
|
+
children: [
|
|
1213
|
+
" (",
|
|
1214
|
+
failedCount,
|
|
1215
|
+
" failed)"
|
|
1216
|
+
]
|
|
1256
1217
|
}, undefined, true, undefined, this)
|
|
1257
1218
|
]
|
|
1258
1219
|
}, undefined, true, undefined, this)
|
|
1259
1220
|
}, undefined, false, undefined, this);
|
|
1260
1221
|
};
|
|
1261
|
-
var
|
|
1222
|
+
var init_DeployProgress = __esm(() => {
|
|
1223
|
+
init_constants();
|
|
1224
|
+
});
|
|
1262
1225
|
|
|
1263
|
-
// src/components/
|
|
1264
|
-
import {
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1226
|
+
// src/ui/components/deploy/DeployComplete.tsx
|
|
1227
|
+
import { useEffect, useState } from "react";
|
|
1228
|
+
import { jsxDEV as jsxDEV3, Fragment } from "@opentui/react/jsx-dev-runtime";
|
|
1229
|
+
var DeployComplete = (props) => {
|
|
1230
|
+
const { results, onComplete } = props;
|
|
1231
|
+
const [visible, setVisible] = useState(true);
|
|
1232
|
+
const successCount = results.filter((r) => r.success).length;
|
|
1233
|
+
const failedCount = results.filter((r) => !r.success).length;
|
|
1234
|
+
useEffect(() => {
|
|
1235
|
+
const timer = setTimeout(() => {
|
|
1236
|
+
setVisible(false);
|
|
1237
|
+
onComplete();
|
|
1238
|
+
}, 3000);
|
|
1239
|
+
return () => clearTimeout(timer);
|
|
1240
|
+
}, [onComplete]);
|
|
1241
|
+
if (!visible || results.length === 0) {
|
|
1242
|
+
return null;
|
|
1275
1243
|
}
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
return /* @__PURE__ */ jsxDEV4("box", {
|
|
1244
|
+
return /* @__PURE__ */ jsxDEV3("box", {
|
|
1245
|
+
backgroundColor: "black",
|
|
1279
1246
|
flexDirection: "row",
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1247
|
+
paddingLeft: 1,
|
|
1248
|
+
paddingRight: 1,
|
|
1249
|
+
children: /* @__PURE__ */ jsxDEV3("text", {
|
|
1250
|
+
children: failedCount === 0 ? /* @__PURE__ */ jsxDEV3("span", {
|
|
1251
|
+
fg: DEPLOY_COLORS.success,
|
|
1284
1252
|
children: [
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
}, undefined, false, undefined, this),
|
|
1289
|
-
/* @__PURE__ */ jsxDEV4("text", {
|
|
1290
|
-
content: " | "
|
|
1291
|
-
}, undefined, false, undefined, this),
|
|
1292
|
-
/* @__PURE__ */ jsxDEV4("text", {
|
|
1293
|
-
fg: activeTab === "deployment" ? "cyan" : undefined,
|
|
1294
|
-
content: "[2] Deployment Logs"
|
|
1295
|
-
}, undefined, false, undefined, this)
|
|
1253
|
+
"\u2713 Deployed ",
|
|
1254
|
+
successCount,
|
|
1255
|
+
" files"
|
|
1296
1256
|
]
|
|
1297
|
-
}, undefined, true, undefined, this),
|
|
1298
|
-
/* @__PURE__ */ jsxDEV4("box", {
|
|
1299
|
-
flexDirection: "row",
|
|
1257
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV3(Fragment, {
|
|
1300
1258
|
children: [
|
|
1301
|
-
|
|
1302
|
-
fg:
|
|
1303
|
-
content: "\u25CF deploying all..."
|
|
1304
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV4("text", {
|
|
1305
|
-
fg: functionCount > 0 ? "green" : "yellow",
|
|
1306
|
-
content: "\u25CF watching"
|
|
1307
|
-
}, undefined, false, undefined, this),
|
|
1308
|
-
/* @__PURE__ */ jsxDEV4("text", {
|
|
1309
|
-
fg: "gray",
|
|
1310
|
-
content: ` (${functionCount} functions)`
|
|
1311
|
-
}, undefined, false, undefined, this),
|
|
1312
|
-
viteRunning && /* @__PURE__ */ jsxDEV4(Fragment, {
|
|
1259
|
+
/* @__PURE__ */ jsxDEV3("span", {
|
|
1260
|
+
fg: DEPLOY_COLORS.success,
|
|
1313
1261
|
children: [
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
}, undefined, false, undefined, this),
|
|
1318
|
-
/* @__PURE__ */ jsxDEV4("text", {
|
|
1319
|
-
fg: "magenta",
|
|
1320
|
-
content: ":5173"
|
|
1321
|
-
}, undefined, false, undefined, this)
|
|
1262
|
+
"\u2713 ",
|
|
1263
|
+
successCount,
|
|
1264
|
+
" deployed"
|
|
1322
1265
|
]
|
|
1323
1266
|
}, undefined, true, undefined, this),
|
|
1324
|
-
/* @__PURE__ */
|
|
1325
|
-
fg:
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
}, undefined,
|
|
1267
|
+
/* @__PURE__ */ jsxDEV3("span", {
|
|
1268
|
+
fg: DEPLOY_COLORS.error,
|
|
1269
|
+
children: [
|
|
1270
|
+
" \u2717 ",
|
|
1271
|
+
failedCount,
|
|
1272
|
+
" failed"
|
|
1273
|
+
]
|
|
1274
|
+
}, undefined, true, undefined, this)
|
|
1332
1275
|
]
|
|
1333
1276
|
}, undefined, true, undefined, this)
|
|
1334
|
-
|
|
1335
|
-
}, undefined,
|
|
1277
|
+
}, undefined, false, undefined, this)
|
|
1278
|
+
}, undefined, false, undefined, this);
|
|
1336
1279
|
};
|
|
1337
|
-
var
|
|
1280
|
+
var init_DeployComplete = __esm(() => {
|
|
1281
|
+
init_constants();
|
|
1282
|
+
});
|
|
1338
1283
|
|
|
1339
|
-
// src/components/
|
|
1340
|
-
import {
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1284
|
+
// src/ui/components/deploy/CleanProgress.tsx
|
|
1285
|
+
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
1286
|
+
import { jsxDEV as jsxDEV4 } from "@opentui/react/jsx-dev-runtime";
|
|
1287
|
+
var CleanProgress = (props) => {
|
|
1288
|
+
const { items, onRestartServer, onComplete } = props;
|
|
1289
|
+
const [currentIndex, setCurrentIndex] = useState2(0);
|
|
1290
|
+
const [phase, setPhase] = useState2("deleting");
|
|
1291
|
+
useEffect2(() => {
|
|
1292
|
+
if (items.length === 0) {
|
|
1293
|
+
onComplete();
|
|
1294
|
+
return;
|
|
1295
|
+
}
|
|
1296
|
+
if (phase === "deleting") {
|
|
1297
|
+
if (currentIndex >= items.length) {
|
|
1298
|
+
setPhase("restarting");
|
|
1299
|
+
return;
|
|
1300
|
+
}
|
|
1301
|
+
const timer = setTimeout(() => {
|
|
1302
|
+
setCurrentIndex((prev) => prev + 1);
|
|
1303
|
+
}, 300);
|
|
1304
|
+
return () => clearTimeout(timer);
|
|
1305
|
+
}
|
|
1306
|
+
if (phase === "restarting") {
|
|
1307
|
+
onRestartServer().then(() => {
|
|
1308
|
+
setPhase("complete");
|
|
1309
|
+
});
|
|
1310
|
+
return;
|
|
1311
|
+
}
|
|
1312
|
+
if (phase === "complete") {
|
|
1313
|
+
const timer = setTimeout(onComplete, 2000);
|
|
1314
|
+
return () => clearTimeout(timer);
|
|
1315
|
+
}
|
|
1316
|
+
}, [currentIndex, items.length, phase, onRestartServer, onComplete]);
|
|
1317
|
+
if (items.length === 0) {
|
|
1318
|
+
return null;
|
|
1319
|
+
}
|
|
1320
|
+
if (phase === "complete") {
|
|
1321
|
+
return /* @__PURE__ */ jsxDEV4("box", {
|
|
1322
|
+
backgroundColor: "black",
|
|
1323
|
+
flexDirection: "row",
|
|
1324
|
+
paddingLeft: 1,
|
|
1325
|
+
paddingRight: 1,
|
|
1326
|
+
children: /* @__PURE__ */ jsxDEV4("text", {
|
|
1327
|
+
children: /* @__PURE__ */ jsxDEV4("span", {
|
|
1328
|
+
fg: DEPLOY_COLORS.success,
|
|
1329
|
+
children: [
|
|
1330
|
+
"\u2713 Cleaned ",
|
|
1331
|
+
items.length,
|
|
1332
|
+
" items, server restarted"
|
|
1333
|
+
]
|
|
1334
|
+
}, undefined, true, undefined, this)
|
|
1335
|
+
}, undefined, false, undefined, this)
|
|
1336
|
+
}, undefined, false, undefined, this);
|
|
1337
|
+
}
|
|
1338
|
+
if (phase === "restarting") {
|
|
1339
|
+
return /* @__PURE__ */ jsxDEV4("box", {
|
|
1340
|
+
backgroundColor: "black",
|
|
1341
|
+
flexDirection: "row",
|
|
1342
|
+
paddingLeft: 1,
|
|
1343
|
+
paddingRight: 1,
|
|
1344
|
+
children: /* @__PURE__ */ jsxDEV4("text", {
|
|
1345
|
+
children: /* @__PURE__ */ jsxDEV4("span", {
|
|
1346
|
+
fg: DEPLOY_COLORS.warning,
|
|
1347
|
+
children: "\u27F3 Restarting server..."
|
|
1348
|
+
}, undefined, false, undefined, this)
|
|
1349
|
+
}, undefined, false, undefined, this)
|
|
1350
|
+
}, undefined, false, undefined, this);
|
|
1351
|
+
}
|
|
1352
|
+
const current = items[currentIndex];
|
|
1353
|
+
return /* @__PURE__ */ jsxDEV4("box", {
|
|
1354
|
+
backgroundColor: "black",
|
|
1355
|
+
flexDirection: "row",
|
|
1356
|
+
paddingLeft: 1,
|
|
1357
|
+
paddingRight: 1,
|
|
1358
|
+
children: /* @__PURE__ */ jsxDEV4("text", {
|
|
1359
|
+
children: [
|
|
1360
|
+
/* @__PURE__ */ jsxDEV4("span", {
|
|
1361
|
+
fg: DEPLOY_COLORS.error,
|
|
1362
|
+
children: "\u2717 Deleting"
|
|
1363
|
+
}, undefined, false, undefined, this),
|
|
1364
|
+
/* @__PURE__ */ jsxDEV4("span", {
|
|
1365
|
+
children: [
|
|
1366
|
+
" ",
|
|
1367
|
+
current
|
|
1368
|
+
]
|
|
1369
|
+
}, undefined, true, undefined, this),
|
|
1370
|
+
/* @__PURE__ */ jsxDEV4("span", {
|
|
1371
|
+
fg: DEPLOY_COLORS.muted,
|
|
1372
|
+
children: [
|
|
1373
|
+
" ",
|
|
1374
|
+
"(",
|
|
1375
|
+
currentIndex + 1,
|
|
1376
|
+
"/",
|
|
1377
|
+
items.length,
|
|
1378
|
+
")"
|
|
1379
|
+
]
|
|
1380
|
+
}, undefined, true, undefined, this)
|
|
1381
|
+
]
|
|
1382
|
+
}, undefined, true, undefined, this)
|
|
1383
|
+
}, undefined, false, undefined, this);
|
|
1384
|
+
};
|
|
1385
|
+
var init_CleanProgress = __esm(() => {
|
|
1386
|
+
init_constants();
|
|
1387
|
+
});
|
|
1388
|
+
|
|
1389
|
+
// src/ui/components/layout/StatusBar.tsx
|
|
1390
|
+
import { jsxDEV as jsxDEV5 } from "@opentui/react/jsx-dev-runtime";
|
|
1391
|
+
var StatusBar = (props) => {
|
|
1392
|
+
const { deployProgress, deployComplete, cleanProgress, message } = props;
|
|
1393
|
+
if (!deployProgress && !deployComplete?.results.length && !cleanProgress && !message) {
|
|
1394
|
+
return null;
|
|
1395
|
+
}
|
|
1396
|
+
if (deployProgress) {
|
|
1397
|
+
return /* @__PURE__ */ jsxDEV5("box", {
|
|
1398
|
+
position: "absolute",
|
|
1399
|
+
bottom: 0,
|
|
1400
|
+
left: 0,
|
|
1401
|
+
width: "100%",
|
|
1402
|
+
flexDirection: "column",
|
|
1403
|
+
children: /* @__PURE__ */ jsxDEV5(DeployProgress, {
|
|
1404
|
+
progress: deployProgress
|
|
1405
|
+
}, undefined, false, undefined, this)
|
|
1406
|
+
}, undefined, false, undefined, this);
|
|
1407
|
+
}
|
|
1408
|
+
if (deployComplete && deployComplete.results.length > 0) {
|
|
1409
|
+
return /* @__PURE__ */ jsxDEV5("box", {
|
|
1410
|
+
position: "absolute",
|
|
1411
|
+
bottom: 0,
|
|
1412
|
+
left: 0,
|
|
1413
|
+
width: "100%",
|
|
1414
|
+
flexDirection: "column",
|
|
1415
|
+
children: /* @__PURE__ */ jsxDEV5(DeployComplete, {
|
|
1416
|
+
results: deployComplete.results,
|
|
1417
|
+
onComplete: deployComplete.onComplete
|
|
1418
|
+
}, undefined, false, undefined, this)
|
|
1419
|
+
}, undefined, false, undefined, this);
|
|
1420
|
+
}
|
|
1421
|
+
if (cleanProgress && cleanProgress.items.length > 0) {
|
|
1422
|
+
return /* @__PURE__ */ jsxDEV5("box", {
|
|
1423
|
+
position: "absolute",
|
|
1424
|
+
bottom: 0,
|
|
1425
|
+
left: 0,
|
|
1426
|
+
width: "100%",
|
|
1427
|
+
flexDirection: "column",
|
|
1428
|
+
children: /* @__PURE__ */ jsxDEV5(CleanProgress, {
|
|
1429
|
+
items: cleanProgress.items,
|
|
1430
|
+
onRestartServer: cleanProgress.onRestartServer,
|
|
1431
|
+
onComplete: cleanProgress.onComplete
|
|
1432
|
+
}, undefined, false, undefined, this)
|
|
1433
|
+
}, undefined, false, undefined, this);
|
|
1434
|
+
}
|
|
1435
|
+
if (message) {
|
|
1436
|
+
return /* @__PURE__ */ jsxDEV5("box", {
|
|
1437
|
+
position: "absolute",
|
|
1438
|
+
bottom: 0,
|
|
1439
|
+
left: 0,
|
|
1440
|
+
width: "100%",
|
|
1441
|
+
flexDirection: "column",
|
|
1442
|
+
children: /* @__PURE__ */ jsxDEV5("box", {
|
|
1443
|
+
backgroundColor: "black",
|
|
1444
|
+
paddingLeft: 1,
|
|
1445
|
+
paddingRight: 1,
|
|
1446
|
+
children: /* @__PURE__ */ jsxDEV5("text", {
|
|
1447
|
+
children: [
|
|
1448
|
+
/* @__PURE__ */ jsxDEV5("span", {
|
|
1449
|
+
fg: STATUS_COLORS[message.type],
|
|
1450
|
+
children: [
|
|
1451
|
+
message.icon,
|
|
1452
|
+
" ",
|
|
1453
|
+
message.text
|
|
1454
|
+
]
|
|
1455
|
+
}, undefined, true, undefined, this),
|
|
1456
|
+
message.detail && /* @__PURE__ */ jsxDEV5("span", {
|
|
1457
|
+
fg: "#666",
|
|
1458
|
+
children: [
|
|
1459
|
+
" ",
|
|
1460
|
+
message.detail
|
|
1461
|
+
]
|
|
1462
|
+
}, undefined, true, undefined, this)
|
|
1463
|
+
]
|
|
1464
|
+
}, undefined, true, undefined, this)
|
|
1465
|
+
}, undefined, false, undefined, this)
|
|
1466
|
+
}, undefined, false, undefined, this);
|
|
1467
|
+
}
|
|
1468
|
+
return null;
|
|
1469
|
+
};
|
|
1470
|
+
var init_StatusBar = __esm(() => {
|
|
1471
|
+
init_DeployProgress();
|
|
1472
|
+
init_DeployComplete();
|
|
1473
|
+
init_CleanProgress();
|
|
1474
|
+
init_constants();
|
|
1475
|
+
});
|
|
1476
|
+
|
|
1477
|
+
// src/ui/components/layout/LogPane.tsx
|
|
1478
|
+
import { jsxDEV as jsxDEV6 } from "@opentui/react/jsx-dev-runtime";
|
|
1479
|
+
var LogPane = (props) => {
|
|
1480
|
+
const { logs: logs2, loading, autoScroll, jumpTrigger, emptyMessage, loadingMessage, children } = props;
|
|
1481
|
+
if (loading && logs2.length === 0) {
|
|
1482
|
+
return /* @__PURE__ */ jsxDEV6("box", {
|
|
1483
|
+
flexDirection: "column",
|
|
1484
|
+
padding: 1,
|
|
1485
|
+
children: /* @__PURE__ */ jsxDEV6("text", {
|
|
1486
|
+
children: loadingMessage
|
|
1487
|
+
}, undefined, false, undefined, this)
|
|
1488
|
+
}, undefined, false, undefined, this);
|
|
1489
|
+
}
|
|
1490
|
+
if (!loading && logs2.length === 0) {
|
|
1491
|
+
return /* @__PURE__ */ jsxDEV6("box", {
|
|
1492
|
+
flexDirection: "column",
|
|
1493
|
+
padding: 1,
|
|
1494
|
+
children: /* @__PURE__ */ jsxDEV6("text", {
|
|
1495
|
+
children: emptyMessage
|
|
1496
|
+
}, undefined, false, undefined, this)
|
|
1497
|
+
}, undefined, false, undefined, this);
|
|
1498
|
+
}
|
|
1499
|
+
return /* @__PURE__ */ jsxDEV6("scrollbox", {
|
|
1500
|
+
focused: true,
|
|
1501
|
+
flexGrow: 1,
|
|
1502
|
+
height: "100%",
|
|
1503
|
+
stickyStart: autoScroll ? "bottom" : "top",
|
|
1504
|
+
stickyScroll: autoScroll,
|
|
1505
|
+
children
|
|
1506
|
+
}, `${autoScroll}-${jumpTrigger}`, false, undefined, this);
|
|
1507
|
+
};
|
|
1508
|
+
var init_LogPane = () => {};
|
|
1509
|
+
|
|
1510
|
+
// src/ui/components/layout/index.ts
|
|
1511
|
+
var init_layout = __esm(() => {
|
|
1512
|
+
init_Header();
|
|
1513
|
+
init_StatusBar();
|
|
1514
|
+
init_LogPane();
|
|
1515
|
+
});
|
|
1516
|
+
|
|
1517
|
+
// src/ui/components/logs/LogEntry.tsx
|
|
1518
|
+
import { jsxDEV as jsxDEV7 } from "@opentui/react/jsx-dev-runtime";
|
|
1519
|
+
var LogEntry = (props) => {
|
|
1520
|
+
const { timestamp, level, message, variant = "deployment", deploymentName, trigger } = props;
|
|
1521
|
+
return /* @__PURE__ */ jsxDEV7("box", {
|
|
1522
|
+
flexDirection: "row",
|
|
1523
|
+
children: /* @__PURE__ */ jsxDEV7("text", {
|
|
1524
|
+
children: [
|
|
1525
|
+
/* @__PURE__ */ jsxDEV7("span", {
|
|
1526
|
+
fg: "gray",
|
|
1527
|
+
children: [
|
|
1528
|
+
"[",
|
|
1529
|
+
timestamp,
|
|
1530
|
+
"]"
|
|
1531
|
+
]
|
|
1532
|
+
}, undefined, true, undefined, this),
|
|
1533
|
+
/* @__PURE__ */ jsxDEV7("span", {
|
|
1534
|
+
fg: getLevelColor(level, variant),
|
|
1535
|
+
children: ` ${level.toUpperCase()} `
|
|
1536
|
+
}, undefined, false, undefined, this),
|
|
1537
|
+
deploymentName && /* @__PURE__ */ jsxDEV7("span", {
|
|
1538
|
+
fg: "blue",
|
|
1539
|
+
children: `(${deploymentName})`
|
|
1540
|
+
}, undefined, false, undefined, this),
|
|
1541
|
+
trigger && /* @__PURE__ */ jsxDEV7("span", {
|
|
1542
|
+
fg: "cyan",
|
|
1543
|
+
children: ` ${trigger} `
|
|
1544
|
+
}, undefined, false, undefined, this),
|
|
1545
|
+
/* @__PURE__ */ jsxDEV7("span", {
|
|
1546
|
+
children: sanitizeMessage(message)
|
|
1547
|
+
}, undefined, false, undefined, this)
|
|
1548
|
+
]
|
|
1549
|
+
}, undefined, true, undefined, this)
|
|
1550
|
+
}, undefined, false, undefined, this);
|
|
1551
|
+
};
|
|
1552
|
+
var init_LogEntry = __esm(() => {
|
|
1553
|
+
init_utils();
|
|
1554
|
+
});
|
|
1555
|
+
|
|
1556
|
+
// src/ui/components/logs/SystemLogs.tsx
|
|
1557
|
+
import { jsxDEV as jsxDEV8 } from "@opentui/react/jsx-dev-runtime";
|
|
1558
|
+
var SystemLogs = (props) => {
|
|
1559
|
+
const { logs: logs2, loading, autoScroll, jumpTrigger } = props;
|
|
1560
|
+
const logsInOrder = [...logs2].reverse();
|
|
1561
|
+
return /* @__PURE__ */ jsxDEV8(LogPane, {
|
|
1562
|
+
logs: logs2,
|
|
1563
|
+
loading,
|
|
1564
|
+
autoScroll,
|
|
1565
|
+
jumpTrigger,
|
|
1566
|
+
loadingMessage: "Loading system logs...",
|
|
1567
|
+
emptyMessage: "No system logs found",
|
|
1568
|
+
children: logsInOrder.map((log) => /* @__PURE__ */ jsxDEV8(LogEntry, {
|
|
1569
|
+
timestamp: new Date(log.timestamp).toLocaleTimeString(),
|
|
1570
|
+
level: log.level,
|
|
1571
|
+
message: log.message,
|
|
1572
|
+
variant: "system"
|
|
1573
|
+
}, log.id, false, undefined, this))
|
|
1574
|
+
}, undefined, false, undefined, this);
|
|
1575
|
+
};
|
|
1576
|
+
var init_SystemLogs = __esm(() => {
|
|
1577
|
+
init_layout();
|
|
1578
|
+
init_LogEntry();
|
|
1579
|
+
});
|
|
1580
|
+
|
|
1581
|
+
// src/ui/components/logs/DeploymentLogs.tsx
|
|
1582
|
+
import { jsxDEV as jsxDEV9 } from "@opentui/react/jsx-dev-runtime";
|
|
1583
|
+
var DeploymentLogs = (props) => {
|
|
1584
|
+
const { logs: logs2, loading, autoScroll, jumpTrigger } = props;
|
|
1585
|
+
const logsInOrder = [...logs2].reverse();
|
|
1586
|
+
return /* @__PURE__ */ jsxDEV9(LogPane, {
|
|
1587
|
+
logs: logs2,
|
|
1588
|
+
loading,
|
|
1589
|
+
autoScroll,
|
|
1590
|
+
jumpTrigger,
|
|
1591
|
+
loadingMessage: "Loading deployment logs...",
|
|
1592
|
+
emptyMessage: "No deployment logs found",
|
|
1593
|
+
children: logsInOrder.map((log) => /* @__PURE__ */ jsxDEV9(LogEntry, {
|
|
1594
|
+
timestamp: new Date(log.time).toLocaleTimeString(),
|
|
1595
|
+
level: log.level,
|
|
1596
|
+
message: log.message,
|
|
1597
|
+
variant: "deployment",
|
|
1598
|
+
deploymentName: log.deployment_name,
|
|
1599
|
+
trigger: log.trigger
|
|
1600
|
+
}, log.id, false, undefined, this))
|
|
1601
|
+
}, undefined, false, undefined, this);
|
|
1602
|
+
};
|
|
1603
|
+
var init_DeploymentLogs = __esm(() => {
|
|
1604
|
+
init_layout();
|
|
1605
|
+
init_LogEntry();
|
|
1606
|
+
});
|
|
1607
|
+
|
|
1608
|
+
// src/ui/components/logs/index.ts
|
|
1609
|
+
var init_logs2 = __esm(() => {
|
|
1610
|
+
init_LogEntry();
|
|
1611
|
+
init_SystemLogs();
|
|
1612
|
+
init_DeploymentLogs();
|
|
1613
|
+
});
|
|
1614
|
+
|
|
1615
|
+
// src/ui/components/modal/Modal.tsx
|
|
1616
|
+
import { jsxDEV as jsxDEV10 } from "@opentui/react/jsx-dev-runtime";
|
|
1617
|
+
var Modal = (props) => {
|
|
1618
|
+
const { visible, width = 50, height = 20, children } = props;
|
|
1619
|
+
if (!visible)
|
|
1620
|
+
return null;
|
|
1621
|
+
return /* @__PURE__ */ jsxDEV10("box", {
|
|
1363
1622
|
position: "absolute",
|
|
1364
1623
|
top: 0,
|
|
1365
1624
|
left: 0,
|
|
@@ -1369,124 +1628,190 @@ var KeyBinding = ({ keys, description }) => /* @__PURE__ */ jsxDEV5("text", {
|
|
|
1369
1628
|
opacity: 0.9,
|
|
1370
1629
|
justifyContent: "center",
|
|
1371
1630
|
alignItems: "center",
|
|
1372
|
-
children: /* @__PURE__ */
|
|
1373
|
-
width
|
|
1374
|
-
height
|
|
1631
|
+
children: /* @__PURE__ */ jsxDEV10("box", {
|
|
1632
|
+
width,
|
|
1633
|
+
height,
|
|
1375
1634
|
border: true,
|
|
1376
1635
|
borderStyle: "rounded",
|
|
1377
1636
|
flexDirection: "column",
|
|
1378
1637
|
padding: 1,
|
|
1379
1638
|
backgroundColor: "black",
|
|
1380
|
-
children
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1639
|
+
children
|
|
1640
|
+
}, undefined, false, undefined, this)
|
|
1641
|
+
}, undefined, false, undefined, this);
|
|
1642
|
+
};
|
|
1643
|
+
var init_Modal = () => {};
|
|
1644
|
+
|
|
1645
|
+
// src/ui/components/modal/HelpModal.tsx
|
|
1646
|
+
import { jsxDEV as jsxDEV11 } from "@opentui/react/jsx-dev-runtime";
|
|
1647
|
+
var KeyBinding = ({ keys, description }) => /* @__PURE__ */ jsxDEV11("text", {
|
|
1648
|
+
children: [
|
|
1649
|
+
" ",
|
|
1650
|
+
/* @__PURE__ */ jsxDEV11("span", {
|
|
1651
|
+
fg: "green",
|
|
1652
|
+
children: keys
|
|
1653
|
+
}, undefined, false, undefined, this),
|
|
1654
|
+
/* @__PURE__ */ jsxDEV11("span", {
|
|
1655
|
+
fg: "gray",
|
|
1656
|
+
children: " - "
|
|
1657
|
+
}, undefined, false, undefined, this),
|
|
1658
|
+
description
|
|
1659
|
+
]
|
|
1660
|
+
}, undefined, true, undefined, this), Section = ({ title }) => /* @__PURE__ */ jsxDEV11("text", {
|
|
1661
|
+
children: /* @__PURE__ */ jsxDEV11("span", {
|
|
1662
|
+
fg: "gray",
|
|
1663
|
+
children: title
|
|
1664
|
+
}, undefined, false, undefined, this)
|
|
1665
|
+
}, undefined, false, undefined, this), HelpModal = ({ visible }) => {
|
|
1666
|
+
return /* @__PURE__ */ jsxDEV11(Modal, {
|
|
1667
|
+
visible,
|
|
1668
|
+
width: 50,
|
|
1669
|
+
height: 20,
|
|
1670
|
+
children: [
|
|
1671
|
+
/* @__PURE__ */ jsxDEV11("text", {
|
|
1672
|
+
children: /* @__PURE__ */ jsxDEV11("span", {
|
|
1673
|
+
fg: "cyan",
|
|
1674
|
+
children: /* @__PURE__ */ jsxDEV11("strong", {
|
|
1675
|
+
children: "Keyboard Shortcuts"
|
|
1387
1676
|
}, undefined, false, undefined, this)
|
|
1388
|
-
}, undefined, false, undefined, this),
|
|
1389
|
-
/* @__PURE__ */ jsxDEV5("text", {}, undefined, false, undefined, this),
|
|
1390
|
-
/* @__PURE__ */ jsxDEV5(Section, {
|
|
1391
|
-
title: "Navigation"
|
|
1392
|
-
}, undefined, false, undefined, this),
|
|
1393
|
-
/* @__PURE__ */ jsxDEV5(KeyBinding, {
|
|
1394
|
-
keys: "1/2",
|
|
1395
|
-
description: "Switch tabs"
|
|
1396
|
-
}, undefined, false, undefined, this),
|
|
1397
|
-
/* @__PURE__ */ jsxDEV5(KeyBinding, {
|
|
1398
|
-
keys: "h/l",
|
|
1399
|
-
description: "Previous/next tab"
|
|
1400
|
-
}, undefined, false, undefined, this),
|
|
1401
|
-
/* @__PURE__ */ jsxDEV5(KeyBinding, {
|
|
1402
|
-
keys: "Tab",
|
|
1403
|
-
description: "Cycle tabs"
|
|
1404
|
-
}, undefined, false, undefined, this),
|
|
1405
|
-
/* @__PURE__ */ jsxDEV5("text", {}, undefined, false, undefined, this),
|
|
1406
|
-
/* @__PURE__ */ jsxDEV5(Section, {
|
|
1407
|
-
title: "Scrolling"
|
|
1408
|
-
}, undefined, false, undefined, this),
|
|
1409
|
-
/* @__PURE__ */ jsxDEV5(KeyBinding, {
|
|
1410
|
-
keys: "j/k",
|
|
1411
|
-
description: "Scroll down/up"
|
|
1412
|
-
}, undefined, false, undefined, this),
|
|
1413
|
-
/* @__PURE__ */ jsxDEV5(KeyBinding, {
|
|
1414
|
-
keys: "g/G",
|
|
1415
|
-
description: "Top/bottom"
|
|
1416
|
-
}, undefined, false, undefined, this),
|
|
1417
|
-
/* @__PURE__ */ jsxDEV5("text", {}, undefined, false, undefined, this),
|
|
1418
|
-
/* @__PURE__ */ jsxDEV5(Section, {
|
|
1419
|
-
title: "Actions"
|
|
1420
|
-
}, undefined, false, undefined, this),
|
|
1421
|
-
/* @__PURE__ */ jsxDEV5(KeyBinding, {
|
|
1422
|
-
keys: "d",
|
|
1423
|
-
description: "Deploy all"
|
|
1424
|
-
}, undefined, false, undefined, this),
|
|
1425
|
-
/* @__PURE__ */ jsxDEV5(KeyBinding, {
|
|
1426
|
-
keys: "?",
|
|
1427
|
-
description: "Toggle help"
|
|
1428
|
-
}, undefined, false, undefined, this),
|
|
1429
|
-
/* @__PURE__ */ jsxDEV5(KeyBinding, {
|
|
1430
|
-
keys: "Esc",
|
|
1431
|
-
description: "Close help"
|
|
1432
1677
|
}, undefined, false, undefined, this)
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1678
|
+
}, undefined, false, undefined, this),
|
|
1679
|
+
/* @__PURE__ */ jsxDEV11("text", {}, undefined, false, undefined, this),
|
|
1680
|
+
KEYBINDING_DESCRIPTIONS.map((section, sectionIndex) => /* @__PURE__ */ jsxDEV11("box", {
|
|
1681
|
+
flexDirection: "column",
|
|
1682
|
+
children: [
|
|
1683
|
+
sectionIndex > 0 && /* @__PURE__ */ jsxDEV11("text", {}, undefined, false, undefined, this),
|
|
1684
|
+
/* @__PURE__ */ jsxDEV11(Section, {
|
|
1685
|
+
title: section.section
|
|
1686
|
+
}, undefined, false, undefined, this),
|
|
1687
|
+
section.bindings.map((binding) => /* @__PURE__ */ jsxDEV11(KeyBinding, {
|
|
1688
|
+
keys: binding.keys,
|
|
1689
|
+
description: binding.description
|
|
1690
|
+
}, binding.keys, false, undefined, this))
|
|
1691
|
+
]
|
|
1692
|
+
}, section.section, true, undefined, this))
|
|
1693
|
+
]
|
|
1694
|
+
}, undefined, true, undefined, this);
|
|
1436
1695
|
};
|
|
1437
|
-
var init_HelpModal = () => {
|
|
1696
|
+
var init_HelpModal = __esm(() => {
|
|
1697
|
+
init_Modal();
|
|
1698
|
+
init_constants();
|
|
1699
|
+
});
|
|
1438
1700
|
|
|
1439
|
-
// src/ui.
|
|
1440
|
-
var
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
var
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
}
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1701
|
+
// src/ui/components/modal/index.ts
|
|
1702
|
+
var init_modal = __esm(() => {
|
|
1703
|
+
init_Modal();
|
|
1704
|
+
init_HelpModal();
|
|
1705
|
+
});
|
|
1706
|
+
// ../../packages/api/types/index.ts
|
|
1707
|
+
var init_types = () => {};
|
|
1708
|
+
|
|
1709
|
+
// ../../packages/api/actions/client.ts
|
|
1710
|
+
var buildUrl = (path, options) => {
|
|
1711
|
+
let fullPath = options?.url ? `${options.url}${path}` : path;
|
|
1712
|
+
if (options?.query) {
|
|
1713
|
+
const params = [];
|
|
1714
|
+
for (const [key, value] of Object.entries(options.query)) {
|
|
1715
|
+
if (value === undefined || value === null)
|
|
1716
|
+
continue;
|
|
1717
|
+
if (Array.isArray(value)) {
|
|
1718
|
+
params.push(`${key}=${value.join(",")}`);
|
|
1719
|
+
} else {
|
|
1720
|
+
params.push(`${key}=${encodeURIComponent(String(value))}`);
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
const queryString = params.join("&");
|
|
1724
|
+
if (queryString) {
|
|
1725
|
+
fullPath = `${fullPath}?${queryString}`;
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
return fullPath;
|
|
1729
|
+
}, apiGet = async (path, options) => {
|
|
1730
|
+
const url = options?.url ? `${options.url}${path}` : path;
|
|
1731
|
+
const headers = {};
|
|
1732
|
+
if (options?.publicKey) {
|
|
1733
|
+
headers["x-public-key"] = options.publicKey;
|
|
1734
|
+
}
|
|
1735
|
+
const response = await fetch(url, { headers });
|
|
1736
|
+
if (!response.ok) {
|
|
1737
|
+
const message = await response.text().catch(() => "");
|
|
1738
|
+
throw new Error(`HTTP error! status: ${response.status}${message ? ` message: ${message}` : ""}`);
|
|
1739
|
+
}
|
|
1740
|
+
return response.json();
|
|
1741
|
+
};
|
|
1742
|
+
|
|
1743
|
+
// ../../packages/api/actions/deployments.ts
|
|
1744
|
+
var init_deployments = () => {};
|
|
1745
|
+
|
|
1746
|
+
// ../../packages/api/actions/invocations.ts
|
|
1747
|
+
var init_invocations = () => {};
|
|
1748
|
+
|
|
1749
|
+
// ../../packages/api/actions/logs.ts
|
|
1750
|
+
var getSystemLogs = async (public_key, query, url) => {
|
|
1751
|
+
const path = buildUrl("/api/system/logs", { url, query });
|
|
1752
|
+
return apiGet(path, { publicKey: public_key });
|
|
1753
|
+
}, searchDeploymentLogs = async (public_key, props, url) => {
|
|
1754
|
+
const path = buildUrl("/api/logs/search", { url, query: props });
|
|
1755
|
+
return apiGet(path, { publicKey: public_key });
|
|
1756
|
+
};
|
|
1757
|
+
var init_logs3 = () => {};
|
|
1758
|
+
|
|
1759
|
+
// ../../packages/api/actions/assets.ts
|
|
1760
|
+
var init_assets = () => {};
|
|
1761
|
+
|
|
1762
|
+
// ../../packages/api/actions/activity.ts
|
|
1763
|
+
var init_activity = () => {};
|
|
1764
|
+
|
|
1765
|
+
// ../../packages/api/actions/index.ts
|
|
1766
|
+
var init_actions = __esm(() => {
|
|
1767
|
+
init_deployments();
|
|
1768
|
+
init_invocations();
|
|
1769
|
+
init_logs3();
|
|
1770
|
+
init_assets();
|
|
1771
|
+
init_activity();
|
|
1772
|
+
});
|
|
1773
|
+
|
|
1774
|
+
// ../../packages/api/index.ts
|
|
1775
|
+
var init_api = __esm(() => {
|
|
1776
|
+
init_types();
|
|
1777
|
+
init_actions();
|
|
1778
|
+
});
|
|
1779
|
+
|
|
1780
|
+
// src/ui/hooks/useLogs.ts
|
|
1781
|
+
import { useEffect as useEffect3, useState as useState3 } from "react";
|
|
1782
|
+
var useLogs = (options) => {
|
|
1783
|
+
const { config, pollInterval = 2000 } = options;
|
|
1784
|
+
const [systemLogs, setSystemLogs] = useState3([]);
|
|
1785
|
+
const [deploymentLogs, setDeploymentLogs] = useState3([]);
|
|
1786
|
+
const [loading, setLoading] = useState3(true);
|
|
1787
|
+
const [error, setError] = useState3(null);
|
|
1788
|
+
useEffect3(() => {
|
|
1789
|
+
const fetchLogs = async () => {
|
|
1464
1790
|
try {
|
|
1465
1791
|
setLoading(true);
|
|
1466
1792
|
setError(null);
|
|
1467
1793
|
const [deploymentLogsData, systemLogsData] = await Promise.all([
|
|
1468
|
-
searchDeploymentLogs(
|
|
1469
|
-
getSystemLogs(
|
|
1794
|
+
searchDeploymentLogs(config.key.public, { limit: 100 }, config.api),
|
|
1795
|
+
getSystemLogs(config.key.public, { limit: 100 }, config.api)
|
|
1470
1796
|
]);
|
|
1471
1797
|
setDeploymentLogs(deploymentLogsData);
|
|
1472
1798
|
setSystemLogs(systemLogsData);
|
|
1473
1799
|
} catch (err) {
|
|
1474
1800
|
setError(err instanceof Error ? err.message : String(err));
|
|
1475
|
-
console.error("Failed to fetch logs:", err);
|
|
1476
1801
|
} finally {
|
|
1477
1802
|
setLoading(false);
|
|
1478
1803
|
}
|
|
1479
1804
|
};
|
|
1480
|
-
|
|
1481
|
-
}, [
|
|
1482
|
-
|
|
1805
|
+
fetchLogs();
|
|
1806
|
+
}, [config.key.public, config.api]);
|
|
1807
|
+
useEffect3(() => {
|
|
1808
|
+
if (loading)
|
|
1809
|
+
return;
|
|
1483
1810
|
const interval = setInterval(async () => {
|
|
1484
|
-
if (loading)
|
|
1485
|
-
return;
|
|
1486
1811
|
try {
|
|
1487
1812
|
const [newDeploymentLogs, newSystemLogs] = await Promise.all([
|
|
1488
|
-
searchDeploymentLogs(
|
|
1489
|
-
getSystemLogs(
|
|
1813
|
+
searchDeploymentLogs(config.key.public, { limit: 100 }, config.api),
|
|
1814
|
+
getSystemLogs(config.key.public, { limit: 100 }, config.api)
|
|
1490
1815
|
]);
|
|
1491
1816
|
if (newDeploymentLogs.length > 0) {
|
|
1492
1817
|
setDeploymentLogs(newDeploymentLogs);
|
|
@@ -1494,59 +1819,206 @@ var App = (props) => {
|
|
|
1494
1819
|
if (newSystemLogs.length > 0) {
|
|
1495
1820
|
setSystemLogs(newSystemLogs);
|
|
1496
1821
|
}
|
|
1497
|
-
} catch
|
|
1498
|
-
|
|
1499
|
-
}
|
|
1500
|
-
}, 2000);
|
|
1822
|
+
} catch {}
|
|
1823
|
+
}, pollInterval);
|
|
1501
1824
|
return () => clearInterval(interval);
|
|
1502
|
-
}, [loading,
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1825
|
+
}, [loading, config.key.public, config.api, pollInterval]);
|
|
1826
|
+
return { systemLogs, deploymentLogs, loading, error };
|
|
1827
|
+
};
|
|
1828
|
+
var init_useLogs = __esm(() => {
|
|
1829
|
+
init_api();
|
|
1830
|
+
});
|
|
1831
|
+
|
|
1832
|
+
// src/ui/hooks/useStatusMessage.ts
|
|
1833
|
+
import { useState as useState4, useCallback, useRef } from "react";
|
|
1834
|
+
var DEFAULT_DURATION = 3000, useStatusMessage = () => {
|
|
1835
|
+
const [message, setMessage] = useState4(null);
|
|
1836
|
+
const timeoutRef = useRef(null);
|
|
1837
|
+
const clearMessage = useCallback(() => {
|
|
1838
|
+
if (timeoutRef.current) {
|
|
1839
|
+
clearTimeout(timeoutRef.current);
|
|
1840
|
+
timeoutRef.current = null;
|
|
1841
|
+
}
|
|
1842
|
+
setMessage(null);
|
|
1843
|
+
}, []);
|
|
1844
|
+
const showMessage = useCallback((type, icon, text, detail, duration = DEFAULT_DURATION) => {
|
|
1845
|
+
clearMessage();
|
|
1846
|
+
setMessage({ type, icon, text, detail });
|
|
1847
|
+
timeoutRef.current = setTimeout(clearMessage, duration);
|
|
1848
|
+
}, [clearMessage]);
|
|
1849
|
+
const showSuccess = useCallback((text, detail, duration) => {
|
|
1850
|
+
showMessage("success", "\u2713", text, detail, duration);
|
|
1851
|
+
}, [showMessage]);
|
|
1852
|
+
const showError = useCallback((text, detail, duration) => {
|
|
1853
|
+
showMessage("error", "\u2717", text, detail, duration);
|
|
1854
|
+
}, [showMessage]);
|
|
1855
|
+
const showWarning = useCallback((text, detail, duration) => {
|
|
1856
|
+
showMessage("warning", "!", text, detail, duration);
|
|
1857
|
+
}, [showMessage]);
|
|
1858
|
+
const showInfo = useCallback((text, detail, duration) => {
|
|
1859
|
+
showMessage("info", "\u25CB", text, detail, duration);
|
|
1860
|
+
}, [showMessage]);
|
|
1861
|
+
return {
|
|
1862
|
+
message,
|
|
1863
|
+
showMessage,
|
|
1864
|
+
showSuccess,
|
|
1865
|
+
showError,
|
|
1866
|
+
showWarning,
|
|
1867
|
+
showInfo,
|
|
1868
|
+
clearMessage
|
|
1869
|
+
};
|
|
1870
|
+
};
|
|
1871
|
+
var init_useStatusMessage = () => {};
|
|
1872
|
+
|
|
1873
|
+
// src/ui/hooks/useScrollControl.ts
|
|
1874
|
+
import { useState as useState5, useCallback as useCallback2 } from "react";
|
|
1875
|
+
var useScrollControl = () => {
|
|
1876
|
+
const [autoScroll, setAutoScroll] = useState5(true);
|
|
1877
|
+
const [jumpTrigger, setJumpTrigger] = useState5(0);
|
|
1878
|
+
const jumpToTop = useCallback2(() => {
|
|
1879
|
+
setAutoScroll(false);
|
|
1880
|
+
setJumpTrigger((prev) => prev + 1);
|
|
1881
|
+
}, []);
|
|
1882
|
+
const jumpToBottom = useCallback2(() => {
|
|
1883
|
+
setAutoScroll(true);
|
|
1884
|
+
setJumpTrigger((prev) => prev + 1);
|
|
1885
|
+
}, []);
|
|
1886
|
+
return {
|
|
1887
|
+
autoScroll,
|
|
1888
|
+
jumpTrigger,
|
|
1889
|
+
jumpToTop,
|
|
1890
|
+
jumpToBottom,
|
|
1891
|
+
setAutoScroll
|
|
1892
|
+
};
|
|
1893
|
+
};
|
|
1894
|
+
var init_useScrollControl = () => {};
|
|
1895
|
+
|
|
1896
|
+
// src/ui/hooks/useDeployment.ts
|
|
1897
|
+
import { useState as useState6, useCallback as useCallback3, useEffect as useEffect4 } from "react";
|
|
1898
|
+
var useDeployment = (options) => {
|
|
1899
|
+
const { onForceDeploy, onWatcherEvent } = options;
|
|
1900
|
+
const [isDeploying, setIsDeploying] = useState6(false);
|
|
1901
|
+
const [progress, setProgress] = useState6(null);
|
|
1902
|
+
const [completedResults, setCompletedResults] = useState6(null);
|
|
1903
|
+
const [watcherResults, setWatcherResults] = useState6(null);
|
|
1904
|
+
useEffect4(() => {
|
|
1905
|
+
onWatcherEvent((event) => {
|
|
1906
|
+
if (event.type === "deploy" && event.deployed?.length) {
|
|
1907
|
+
setWatcherResults(event.deployed);
|
|
1539
1908
|
}
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1909
|
+
});
|
|
1910
|
+
}, [onWatcherEvent]);
|
|
1911
|
+
const deploy = useCallback3(() => {
|
|
1912
|
+
if (isDeploying)
|
|
1913
|
+
return;
|
|
1914
|
+
setIsDeploying(true);
|
|
1915
|
+
onForceDeploy({
|
|
1916
|
+
onProgress: (p) => setProgress(p),
|
|
1917
|
+
onComplete: (results) => {
|
|
1918
|
+
setProgress(null);
|
|
1919
|
+
setCompletedResults(results);
|
|
1543
1920
|
}
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1921
|
+
}).finally(() => {
|
|
1922
|
+
setIsDeploying(false);
|
|
1923
|
+
});
|
|
1924
|
+
}, [isDeploying, onForceDeploy]);
|
|
1925
|
+
const clearCompleted = useCallback3(() => {
|
|
1926
|
+
setCompletedResults(null);
|
|
1927
|
+
}, []);
|
|
1928
|
+
const clearWatcherResults = useCallback3(() => {
|
|
1929
|
+
setWatcherResults(null);
|
|
1930
|
+
}, []);
|
|
1931
|
+
return {
|
|
1932
|
+
isDeploying,
|
|
1933
|
+
progress,
|
|
1934
|
+
completedResults,
|
|
1935
|
+
watcherResults,
|
|
1936
|
+
deploy,
|
|
1937
|
+
clearCompleted,
|
|
1938
|
+
clearWatcherResults
|
|
1939
|
+
};
|
|
1940
|
+
};
|
|
1941
|
+
var init_useDeployment = () => {};
|
|
1942
|
+
|
|
1943
|
+
// src/ui/hooks/useKeyboard.ts
|
|
1944
|
+
import { useEffect as useEffect5 } from "react";
|
|
1945
|
+
import { useRenderer } from "@opentui/react";
|
|
1946
|
+
var useKeyboard = (options) => {
|
|
1947
|
+
const {
|
|
1948
|
+
activeTab,
|
|
1949
|
+
isDeploying,
|
|
1950
|
+
isCleaning,
|
|
1951
|
+
onTabChange,
|
|
1952
|
+
onScrollTop,
|
|
1953
|
+
onScrollBottom,
|
|
1954
|
+
onToggleHelp,
|
|
1955
|
+
onCloseModal,
|
|
1956
|
+
onDeploy,
|
|
1957
|
+
onCopySuccess,
|
|
1958
|
+
onCopyError,
|
|
1959
|
+
onNoSelection,
|
|
1960
|
+
onClean,
|
|
1961
|
+
onCleanEmpty
|
|
1962
|
+
} = options;
|
|
1963
|
+
const renderer = useRenderer();
|
|
1964
|
+
useEffect5(() => {
|
|
1965
|
+
const handleKeyPress = (data) => {
|
|
1966
|
+
const key = data.toString();
|
|
1967
|
+
const action = KEYBINDINGS[key];
|
|
1968
|
+
if (!action)
|
|
1549
1969
|
return;
|
|
1970
|
+
switch (action.type) {
|
|
1971
|
+
case "NAVIGATE":
|
|
1972
|
+
onTabChange(action.tab);
|
|
1973
|
+
break;
|
|
1974
|
+
case "CYCLE_TAB":
|
|
1975
|
+
onTabChange(activeTab === "system" ? "deployment" : "system");
|
|
1976
|
+
break;
|
|
1977
|
+
case "SCROLL":
|
|
1978
|
+
if (action.to === "top") {
|
|
1979
|
+
onScrollTop();
|
|
1980
|
+
} else {
|
|
1981
|
+
onScrollBottom();
|
|
1982
|
+
}
|
|
1983
|
+
break;
|
|
1984
|
+
case "TOGGLE_HELP":
|
|
1985
|
+
onToggleHelp();
|
|
1986
|
+
break;
|
|
1987
|
+
case "CLOSE_MODAL":
|
|
1988
|
+
onCloseModal();
|
|
1989
|
+
break;
|
|
1990
|
+
case "DEPLOY":
|
|
1991
|
+
if (!isDeploying) {
|
|
1992
|
+
onDeploy();
|
|
1993
|
+
}
|
|
1994
|
+
break;
|
|
1995
|
+
case "YANK":
|
|
1996
|
+
if (!renderer.hasSelection) {
|
|
1997
|
+
onNoSelection();
|
|
1998
|
+
return;
|
|
1999
|
+
}
|
|
2000
|
+
const text = renderer.getSelection()?.getSelectedText();
|
|
2001
|
+
if (!text) {
|
|
2002
|
+
onNoSelection();
|
|
2003
|
+
return;
|
|
2004
|
+
}
|
|
2005
|
+
copyToClipboard(text).then(() => {
|
|
2006
|
+
renderer.clearSelection();
|
|
2007
|
+
onCopySuccess(text);
|
|
2008
|
+
}).catch(() => {
|
|
2009
|
+
onCopyError();
|
|
2010
|
+
});
|
|
2011
|
+
break;
|
|
2012
|
+
case "CLEAN":
|
|
2013
|
+
if (isCleaning)
|
|
2014
|
+
return;
|
|
2015
|
+
const { deleted } = cleanLocalData();
|
|
2016
|
+
if (deleted.length > 0) {
|
|
2017
|
+
onClean(deleted);
|
|
2018
|
+
} else {
|
|
2019
|
+
onCleanEmpty();
|
|
2020
|
+
}
|
|
2021
|
+
break;
|
|
1550
2022
|
}
|
|
1551
2023
|
};
|
|
1552
2024
|
process.stdin.setRawMode(true);
|
|
@@ -1555,14 +2027,101 @@ var App = (props) => {
|
|
|
1555
2027
|
process.stdin.setRawMode(false);
|
|
1556
2028
|
process.stdin.off("data", handleKeyPress);
|
|
1557
2029
|
};
|
|
1558
|
-
}, [
|
|
2030
|
+
}, [
|
|
2031
|
+
activeTab,
|
|
2032
|
+
isDeploying,
|
|
2033
|
+
isCleaning,
|
|
2034
|
+
renderer,
|
|
2035
|
+
onTabChange,
|
|
2036
|
+
onScrollTop,
|
|
2037
|
+
onScrollBottom,
|
|
2038
|
+
onToggleHelp,
|
|
2039
|
+
onCloseModal,
|
|
2040
|
+
onDeploy,
|
|
2041
|
+
onCopySuccess,
|
|
2042
|
+
onCopyError,
|
|
2043
|
+
onNoSelection,
|
|
2044
|
+
onClean,
|
|
2045
|
+
onCleanEmpty
|
|
2046
|
+
]);
|
|
2047
|
+
};
|
|
2048
|
+
var init_useKeyboard = __esm(() => {
|
|
2049
|
+
init_constants();
|
|
2050
|
+
init_utils();
|
|
2051
|
+
init_config();
|
|
2052
|
+
});
|
|
2053
|
+
|
|
2054
|
+
// src/ui/hooks/index.ts
|
|
2055
|
+
var init_hooks = __esm(() => {
|
|
2056
|
+
init_useLogs();
|
|
2057
|
+
init_useStatusMessage();
|
|
2058
|
+
init_useScrollControl();
|
|
2059
|
+
init_useDeployment();
|
|
2060
|
+
init_useKeyboard();
|
|
2061
|
+
});
|
|
2062
|
+
|
|
2063
|
+
// src/ui/App.tsx
|
|
2064
|
+
import { useState as useState7, useCallback as useCallback4 } from "react";
|
|
2065
|
+
import { jsxDEV as jsxDEV12 } from "@opentui/react/jsx-dev-runtime";
|
|
2066
|
+
var App = (props) => {
|
|
2067
|
+
const { config, binarySource, functionCount, viteRunning, onWatcherEvent, onForceDeploy, onRestartServer } = props;
|
|
2068
|
+
const [activeTab, setActiveTab] = useState7("system");
|
|
2069
|
+
const [showKeyBindings, setShowKeyBindings] = useState7(false);
|
|
2070
|
+
const [cleaningItems, setCleaningItems] = useState7(null);
|
|
2071
|
+
const { systemLogs, deploymentLogs, loading, error } = useLogs({ config });
|
|
2072
|
+
const { message, showInfo } = useStatusMessage();
|
|
2073
|
+
const { autoScroll, jumpTrigger, jumpToTop, jumpToBottom } = useScrollControl();
|
|
2074
|
+
const {
|
|
2075
|
+
isDeploying,
|
|
2076
|
+
progress: deployProgress,
|
|
2077
|
+
completedResults,
|
|
2078
|
+
watcherResults,
|
|
2079
|
+
deploy,
|
|
2080
|
+
clearCompleted,
|
|
2081
|
+
clearWatcherResults
|
|
2082
|
+
} = useDeployment({ onForceDeploy, onWatcherEvent });
|
|
2083
|
+
const handleCopySuccess = useCallback4((text) => {
|
|
2084
|
+
const preview = text.length > 30 ? text.substring(0, 30) + "..." : text;
|
|
2085
|
+
showInfo("Copied", `"${preview.replace(/\n/g, "\u21B5")}"`);
|
|
2086
|
+
}, [showInfo]);
|
|
2087
|
+
const handleCopyError = useCallback4(() => {
|
|
2088
|
+
showInfo("Failed to copy");
|
|
2089
|
+
}, [showInfo]);
|
|
2090
|
+
const handleNoSelection = useCallback4(() => {
|
|
2091
|
+
showInfo("No selection", "Select text first");
|
|
2092
|
+
}, [showInfo]);
|
|
2093
|
+
const handleClean = useCallback4((deletedItems) => {
|
|
2094
|
+
setCleaningItems(deletedItems);
|
|
2095
|
+
}, []);
|
|
2096
|
+
const handleCleanComplete = useCallback4(() => {
|
|
2097
|
+
setCleaningItems(null);
|
|
2098
|
+
}, []);
|
|
2099
|
+
const handleCleanEmpty = useCallback4(() => {
|
|
2100
|
+
showInfo("Nothing to clean");
|
|
2101
|
+
}, [showInfo]);
|
|
2102
|
+
useKeyboard({
|
|
2103
|
+
activeTab,
|
|
2104
|
+
isDeploying,
|
|
2105
|
+
isCleaning: cleaningItems !== null,
|
|
2106
|
+
onTabChange: setActiveTab,
|
|
2107
|
+
onScrollTop: jumpToTop,
|
|
2108
|
+
onScrollBottom: jumpToBottom,
|
|
2109
|
+
onToggleHelp: () => setShowKeyBindings((prev) => !prev),
|
|
2110
|
+
onCloseModal: () => setShowKeyBindings(false),
|
|
2111
|
+
onDeploy: deploy,
|
|
2112
|
+
onCopySuccess: handleCopySuccess,
|
|
2113
|
+
onCopyError: handleCopyError,
|
|
2114
|
+
onNoSelection: handleNoSelection,
|
|
2115
|
+
onClean: handleClean,
|
|
2116
|
+
onCleanEmpty: handleCleanEmpty
|
|
2117
|
+
});
|
|
1559
2118
|
if (error) {
|
|
1560
|
-
return /* @__PURE__ */
|
|
2119
|
+
return /* @__PURE__ */ jsxDEV12("box", {
|
|
1561
2120
|
flexGrow: 1,
|
|
1562
2121
|
flexDirection: "column",
|
|
1563
2122
|
padding: 1,
|
|
1564
|
-
children: /* @__PURE__ */
|
|
1565
|
-
children: /* @__PURE__ */
|
|
2123
|
+
children: /* @__PURE__ */ jsxDEV12("text", {
|
|
2124
|
+
children: /* @__PURE__ */ jsxDEV12("span", {
|
|
1566
2125
|
fg: "red",
|
|
1567
2126
|
children: [
|
|
1568
2127
|
"Error: ",
|
|
@@ -1572,50 +2131,72 @@ var App = (props) => {
|
|
|
1572
2131
|
}, undefined, false, undefined, this)
|
|
1573
2132
|
}, undefined, false, undefined, this);
|
|
1574
2133
|
}
|
|
1575
|
-
return /* @__PURE__ */
|
|
2134
|
+
return /* @__PURE__ */ jsxDEV12("box", {
|
|
1576
2135
|
flexDirection: "column",
|
|
2136
|
+
height: "100%",
|
|
1577
2137
|
children: [
|
|
1578
|
-
/* @__PURE__ */
|
|
2138
|
+
/* @__PURE__ */ jsxDEV12(Header, {
|
|
1579
2139
|
activeTab,
|
|
1580
|
-
functionCount
|
|
1581
|
-
viteRunning
|
|
2140
|
+
functionCount,
|
|
2141
|
+
viteRunning,
|
|
1582
2142
|
isDeploying,
|
|
1583
|
-
binarySource
|
|
2143
|
+
binarySource
|
|
1584
2144
|
}, undefined, false, undefined, this),
|
|
1585
|
-
/* @__PURE__ */
|
|
2145
|
+
/* @__PURE__ */ jsxDEV12("box", {
|
|
1586
2146
|
paddingTop: 1,
|
|
1587
2147
|
flexDirection: "column",
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
/* @__PURE__ */ jsxDEV6(HelpModal, {
|
|
2148
|
+
flexGrow: 1,
|
|
2149
|
+
overflow: "hidden",
|
|
2150
|
+
children: activeTab === "system" ? /* @__PURE__ */ jsxDEV12(SystemLogs, {
|
|
2151
|
+
logs: systemLogs,
|
|
2152
|
+
loading,
|
|
2153
|
+
autoScroll,
|
|
2154
|
+
jumpTrigger
|
|
2155
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV12(DeploymentLogs, {
|
|
2156
|
+
logs: deploymentLogs,
|
|
2157
|
+
loading,
|
|
2158
|
+
autoScroll,
|
|
2159
|
+
jumpTrigger
|
|
2160
|
+
}, undefined, false, undefined, this)
|
|
2161
|
+
}, undefined, false, undefined, this),
|
|
2162
|
+
/* @__PURE__ */ jsxDEV12(StatusBar, {
|
|
2163
|
+
deployProgress,
|
|
2164
|
+
deployComplete: completedResults ? { results: completedResults, onComplete: clearCompleted } : watcherResults ? { results: watcherResults, onComplete: clearWatcherResults } : undefined,
|
|
2165
|
+
cleanProgress: cleaningItems ? { items: cleaningItems, onRestartServer, onComplete: handleCleanComplete } : null,
|
|
2166
|
+
message
|
|
2167
|
+
}, undefined, false, undefined, this),
|
|
2168
|
+
/* @__PURE__ */ jsxDEV12(HelpModal, {
|
|
1610
2169
|
visible: showKeyBindings
|
|
1611
2170
|
}, undefined, false, undefined, this)
|
|
1612
2171
|
]
|
|
1613
2172
|
}, undefined, true, undefined, this);
|
|
1614
|
-
}
|
|
2173
|
+
};
|
|
2174
|
+
var init_App = __esm(() => {
|
|
2175
|
+
init_layout();
|
|
2176
|
+
init_logs2();
|
|
2177
|
+
init_modal();
|
|
2178
|
+
init_hooks();
|
|
2179
|
+
});
|
|
2180
|
+
|
|
2181
|
+
// src/ui.tsx
|
|
2182
|
+
var exports_ui = {};
|
|
2183
|
+
import { createCliRenderer } from "@opentui/core";
|
|
2184
|
+
import { createRoot } from "@opentui/react";
|
|
2185
|
+
import { jsxDEV as jsxDEV13 } from "@opentui/react/jsx-dev-runtime";
|
|
2186
|
+
var main = async () => {
|
|
1615
2187
|
let serverInfo = null;
|
|
1616
2188
|
let viteInfo = null;
|
|
1617
2189
|
let stopWatcher = null;
|
|
1618
2190
|
let isCleaningUp = false;
|
|
2191
|
+
const stopServer = () => {
|
|
2192
|
+
if (serverInfo) {
|
|
2193
|
+
const pid = serverInfo.process.pid;
|
|
2194
|
+
serverInfo = null;
|
|
2195
|
+
try {
|
|
2196
|
+
process.kill(pid, "SIGTERM");
|
|
2197
|
+
} catch {}
|
|
2198
|
+
}
|
|
2199
|
+
};
|
|
1619
2200
|
const cleanup = async (exitAfter = true) => {
|
|
1620
2201
|
if (isCleaningUp)
|
|
1621
2202
|
return;
|
|
@@ -1628,13 +2209,7 @@ var App = (props) => {
|
|
|
1628
2209
|
await stopViteServer(viteInfo);
|
|
1629
2210
|
viteInfo = null;
|
|
1630
2211
|
}
|
|
1631
|
-
|
|
1632
|
-
const pid = serverInfo.process.pid;
|
|
1633
|
-
serverInfo = null;
|
|
1634
|
-
try {
|
|
1635
|
-
process.kill(pid, "SIGTERM");
|
|
1636
|
-
} catch {}
|
|
1637
|
-
}
|
|
2212
|
+
stopServer();
|
|
1638
2213
|
if (exitAfter) {
|
|
1639
2214
|
process.exit(0);
|
|
1640
2215
|
}
|
|
@@ -1648,11 +2223,12 @@ var App = (props) => {
|
|
|
1648
2223
|
const srcPath = process.cwd() + "/src";
|
|
1649
2224
|
viteInfo = await startViteServer({
|
|
1650
2225
|
srcDir: srcPath,
|
|
1651
|
-
onLog: (
|
|
2226
|
+
onLog: () => {}
|
|
1652
2227
|
});
|
|
1653
2228
|
let watcherEventHandler = null;
|
|
1654
2229
|
let pendingEvents = [];
|
|
1655
2230
|
let functionCount = 0;
|
|
2231
|
+
let isInitialBuild = true;
|
|
1656
2232
|
const sendEvent = (event) => {
|
|
1657
2233
|
if (watcherEventHandler) {
|
|
1658
2234
|
watcherEventHandler(event);
|
|
@@ -1660,22 +2236,27 @@ var App = (props) => {
|
|
|
1660
2236
|
pendingEvents.push(event);
|
|
1661
2237
|
}
|
|
1662
2238
|
};
|
|
2239
|
+
const restartServer = async () => {
|
|
2240
|
+
stopServer();
|
|
2241
|
+
serverInfo = await startServer();
|
|
2242
|
+
};
|
|
1663
2243
|
const renderer = await createCliRenderer();
|
|
1664
2244
|
const root = createRoot(renderer);
|
|
1665
|
-
const handleForceDeploy = async () => {
|
|
2245
|
+
const handleForceDeploy = async (callbacks) => {
|
|
1666
2246
|
const deployResults = [];
|
|
1667
2247
|
await forceDeployAll(srcPath, {
|
|
2248
|
+
onStart: (filePath, completedCount, totalCount) => {
|
|
2249
|
+
callbacks.onProgress({
|
|
2250
|
+
currentFile: filePath,
|
|
2251
|
+
completedFiles: [...deployResults],
|
|
2252
|
+
totalFiles: totalCount
|
|
2253
|
+
});
|
|
2254
|
+
},
|
|
1668
2255
|
onDeploy: (filePath, success, error) => {
|
|
1669
2256
|
deployResults.push({ name: filePath, success, error });
|
|
1670
2257
|
}
|
|
1671
2258
|
});
|
|
1672
|
-
|
|
1673
|
-
sendEvent({
|
|
1674
|
-
type: "deploy",
|
|
1675
|
-
deployed: deployResults,
|
|
1676
|
-
timestamp: new Date
|
|
1677
|
-
});
|
|
1678
|
-
}
|
|
2259
|
+
callbacks.onComplete(deployResults);
|
|
1679
2260
|
};
|
|
1680
2261
|
stopWatcher = await startWatcher(srcPath, {
|
|
1681
2262
|
silent: true,
|
|
@@ -1683,6 +2264,10 @@ var App = (props) => {
|
|
|
1683
2264
|
functionCount = count;
|
|
1684
2265
|
},
|
|
1685
2266
|
onDeployBatch: (results) => {
|
|
2267
|
+
if (isInitialBuild) {
|
|
2268
|
+
isInitialBuild = false;
|
|
2269
|
+
return;
|
|
2270
|
+
}
|
|
1686
2271
|
sendEvent({
|
|
1687
2272
|
type: "deploy",
|
|
1688
2273
|
deployed: results.map((r) => ({
|
|
@@ -1694,7 +2279,7 @@ var App = (props) => {
|
|
|
1694
2279
|
});
|
|
1695
2280
|
}
|
|
1696
2281
|
});
|
|
1697
|
-
root.render(/* @__PURE__ */
|
|
2282
|
+
root.render(/* @__PURE__ */ jsxDEV13(App, {
|
|
1698
2283
|
config: devConfig,
|
|
1699
2284
|
binarySource: serverInfo.binarySource,
|
|
1700
2285
|
functionCount,
|
|
@@ -1708,7 +2293,8 @@ var App = (props) => {
|
|
|
1708
2293
|
pendingEvents = [];
|
|
1709
2294
|
}
|
|
1710
2295
|
},
|
|
1711
|
-
onForceDeploy: handleForceDeploy
|
|
2296
|
+
onForceDeploy: handleForceDeploy,
|
|
2297
|
+
onRestartServer: restartServer
|
|
1712
2298
|
}, undefined, false, undefined, this));
|
|
1713
2299
|
} catch (error) {
|
|
1714
2300
|
console.error("Failed to start server:", error);
|
|
@@ -1716,16 +2302,11 @@ var App = (props) => {
|
|
|
1716
2302
|
}
|
|
1717
2303
|
};
|
|
1718
2304
|
var init_ui = __esm(() => {
|
|
1719
|
-
init_api();
|
|
1720
2305
|
init_server();
|
|
1721
2306
|
init_watcher();
|
|
1722
2307
|
init_vite();
|
|
1723
2308
|
init_config();
|
|
1724
|
-
|
|
1725
|
-
init_SystemLogsPane();
|
|
1726
|
-
init_DeployAnimation();
|
|
1727
|
-
init_Header();
|
|
1728
|
-
init_HelpModal();
|
|
2309
|
+
init_App();
|
|
1729
2310
|
main();
|
|
1730
2311
|
});
|
|
1731
2312
|
|
|
@@ -1743,8 +2324,8 @@ init_config();
|
|
|
1743
2324
|
init_bundle();
|
|
1744
2325
|
init_deploy2();
|
|
1745
2326
|
import chalk3 from "chalk";
|
|
1746
|
-
import { basename as basename4, resolve as resolve2, join as
|
|
1747
|
-
import { existsSync as
|
|
2327
|
+
import { basename as basename4, resolve as resolve2, join as join6 } from "path";
|
|
2328
|
+
import { existsSync as existsSync6 } from "fs";
|
|
1748
2329
|
import { readdir as readdir2 } from "fs/promises";
|
|
1749
2330
|
import * as p from "@clack/prompts";
|
|
1750
2331
|
var FUNCTION_DIRS2 = ["api", "cron", "event"];
|
|
@@ -1773,25 +2354,25 @@ var selectConfig = async () => {
|
|
|
1773
2354
|
};
|
|
1774
2355
|
var findAllDeployables = async (srcPath) => {
|
|
1775
2356
|
const functions = [];
|
|
1776
|
-
const functionsPath =
|
|
2357
|
+
const functionsPath = join6(srcPath, "function");
|
|
1777
2358
|
for (const dir of FUNCTION_DIRS2) {
|
|
1778
|
-
const dirPath =
|
|
2359
|
+
const dirPath = join6(functionsPath, dir);
|
|
1779
2360
|
try {
|
|
1780
2361
|
const items = await readdir2(dirPath, { withFileTypes: true });
|
|
1781
2362
|
for (const item of items) {
|
|
1782
2363
|
if (item.isFile() && (item.name.endsWith(".ts") || item.name.endsWith(".tsx"))) {
|
|
1783
|
-
functions.push(
|
|
2364
|
+
functions.push(join6(dirPath, item.name));
|
|
1784
2365
|
}
|
|
1785
2366
|
}
|
|
1786
2367
|
} catch {}
|
|
1787
2368
|
}
|
|
1788
|
-
const reactEntry =
|
|
1789
|
-
const hasReact =
|
|
2369
|
+
const reactEntry = join6(srcPath, "index.tsx");
|
|
2370
|
+
const hasReact = existsSync6(reactEntry);
|
|
1790
2371
|
return { functions, reactEntry: hasReact ? reactEntry : null };
|
|
1791
2372
|
};
|
|
1792
2373
|
var deployAll = async (config, options) => {
|
|
1793
|
-
const srcPath =
|
|
1794
|
-
if (!
|
|
2374
|
+
const srcPath = join6(process.cwd(), "src");
|
|
2375
|
+
if (!existsSync6(srcPath)) {
|
|
1795
2376
|
console.error(chalk3.red("\u2717 No src directory found"));
|
|
1796
2377
|
process.exit(1);
|
|
1797
2378
|
}
|
|
@@ -1875,7 +2456,7 @@ var registerDeployCommand = (program) => {
|
|
|
1875
2456
|
return;
|
|
1876
2457
|
}
|
|
1877
2458
|
const filePath = resolve2(file);
|
|
1878
|
-
if (!
|
|
2459
|
+
if (!existsSync6(filePath)) {
|
|
1879
2460
|
console.error(chalk3.red(`\u2717 File not found: ${filePath}`));
|
|
1880
2461
|
process.exit(1);
|
|
1881
2462
|
}
|
|
@@ -2046,7 +2627,7 @@ import { Command as Command2 } from "commander";
|
|
|
2046
2627
|
import chalk6 from "chalk";
|
|
2047
2628
|
import { resolve as resolve3 } from "path";
|
|
2048
2629
|
import { readFile, readdir as readdir3 } from "fs/promises";
|
|
2049
|
-
import { existsSync as
|
|
2630
|
+
import { existsSync as existsSync7 } from "fs";
|
|
2050
2631
|
import * as p3 from "@clack/prompts";
|
|
2051
2632
|
|
|
2052
2633
|
// ../../packages/api/actions/secrets.ts
|
|
@@ -2281,7 +2862,7 @@ Secret keys:`));
|
|
|
2281
2862
|
process.exit(1);
|
|
2282
2863
|
}
|
|
2283
2864
|
}
|
|
2284
|
-
if (!
|
|
2865
|
+
if (!existsSync7(filePath)) {
|
|
2285
2866
|
console.error(chalk6.red(`\u2717 File not found: ${filePath}`));
|
|
2286
2867
|
process.exit(1);
|
|
2287
2868
|
}
|
|
@@ -2331,7 +2912,7 @@ Secret keys:`));
|
|
|
2331
2912
|
process.exit(1);
|
|
2332
2913
|
}
|
|
2333
2914
|
}
|
|
2334
|
-
if (!
|
|
2915
|
+
if (!existsSync7(filePath)) {
|
|
2335
2916
|
console.error(chalk6.red(`\u2717 File not found: ${filePath}`));
|
|
2336
2917
|
process.exit(1);
|
|
2337
2918
|
}
|
|
@@ -2370,8 +2951,8 @@ Secret keys:`));
|
|
|
2370
2951
|
}));
|
|
2371
2952
|
};
|
|
2372
2953
|
// src/commands/host.ts
|
|
2373
|
-
import { existsSync as
|
|
2374
|
-
import { join as
|
|
2954
|
+
import { existsSync as existsSync8, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync2 } from "fs";
|
|
2955
|
+
import { join as join7 } from "path";
|
|
2375
2956
|
import { homedir } from "os";
|
|
2376
2957
|
var {$: $2 } = globalThis.Bun;
|
|
2377
2958
|
import chalk7 from "chalk";
|
|
@@ -2404,7 +2985,7 @@ var generateProductionKeys = async () => {
|
|
|
2404
2985
|
return { privateKey, publicKey };
|
|
2405
2986
|
};
|
|
2406
2987
|
var saveProductionConfig = async (cloudPath, privateKey, publicKey) => {
|
|
2407
|
-
const configPath =
|
|
2988
|
+
const configPath = join7(cloudPath, "config.json");
|
|
2408
2989
|
const config = {
|
|
2409
2990
|
key: {
|
|
2410
2991
|
private: privateKey,
|
|
@@ -2438,7 +3019,7 @@ WantedBy=multi-user.target
|
|
|
2438
3019
|
return serviceContent;
|
|
2439
3020
|
};
|
|
2440
3021
|
var ensureCloudDirectory = (cloudPath) => {
|
|
2441
|
-
if (!
|
|
3022
|
+
if (!existsSync8(cloudPath)) {
|
|
2442
3023
|
console.log(chalk7.blue("Creating cloud directory..."));
|
|
2443
3024
|
try {
|
|
2444
3025
|
mkdirSync3(cloudPath, { recursive: true });
|
|
@@ -2468,15 +3049,15 @@ var validateLinux = () => {
|
|
|
2468
3049
|
}
|
|
2469
3050
|
};
|
|
2470
3051
|
var validateServerBinary = (serverBinPath) => {
|
|
2471
|
-
if (!
|
|
3052
|
+
if (!existsSync8(serverBinPath)) {
|
|
2472
3053
|
console.log(chalk7.red("Server binary not found at:"), serverBinPath);
|
|
2473
3054
|
console.log(chalk7.yellow("Make sure you have installed the package correctly"));
|
|
2474
3055
|
process.exit(1);
|
|
2475
3056
|
}
|
|
2476
3057
|
};
|
|
2477
3058
|
var checkExistingProductionConfig = (cloudPath) => {
|
|
2478
|
-
const configPath =
|
|
2479
|
-
if (!
|
|
3059
|
+
const configPath = join7(cloudPath, "config.json");
|
|
3060
|
+
if (!existsSync8(configPath)) {
|
|
2480
3061
|
return null;
|
|
2481
3062
|
}
|
|
2482
3063
|
try {
|
|
@@ -2507,15 +3088,15 @@ var unhost = async (options = {}) => {
|
|
|
2507
3088
|
console.log(chalk7.yellow("Service was not enabled"));
|
|
2508
3089
|
}
|
|
2509
3090
|
const servicePath = "/etc/systemd/system/nulljs.service";
|
|
2510
|
-
if (
|
|
3091
|
+
if (existsSync8(servicePath)) {
|
|
2511
3092
|
console.log(chalk7.blue("Removing systemd service file..."));
|
|
2512
3093
|
await $2`sudo rm ${servicePath}`;
|
|
2513
3094
|
await $2`sudo systemctl daemon-reload`;
|
|
2514
3095
|
console.log(chalk7.green("Systemd service file removed"));
|
|
2515
3096
|
}
|
|
2516
3097
|
if (!options.keepData) {
|
|
2517
|
-
const defaultCloudPath =
|
|
2518
|
-
if (
|
|
3098
|
+
const defaultCloudPath = join7(homedir(), ".nulljs");
|
|
3099
|
+
if (existsSync8(defaultCloudPath)) {
|
|
2519
3100
|
console.log(chalk7.blue("Removing cloud directory..."));
|
|
2520
3101
|
await $2`rm -rf ${defaultCloudPath}`;
|
|
2521
3102
|
console.log(chalk7.green("Cloud directory removed"));
|
|
@@ -2539,9 +3120,9 @@ var unhost = async (options = {}) => {
|
|
|
2539
3120
|
};
|
|
2540
3121
|
var update = async () => {
|
|
2541
3122
|
validateLinux();
|
|
2542
|
-
const cloudPath =
|
|
3123
|
+
const cloudPath = join7(homedir(), ".nulljs");
|
|
2543
3124
|
const servicePath = "/etc/systemd/system/nulljs.service";
|
|
2544
|
-
if (!
|
|
3125
|
+
if (!existsSync8(servicePath)) {
|
|
2545
3126
|
console.log(chalk7.red("NullJS service is not installed."));
|
|
2546
3127
|
console.log(chalk7.gray('Run "nulljs host" to set up hosting first.'));
|
|
2547
3128
|
process.exit(1);
|
|
@@ -2572,7 +3153,7 @@ var update = async () => {
|
|
|
2572
3153
|
};
|
|
2573
3154
|
var host = async (cloudPath) => {
|
|
2574
3155
|
validateLinux();
|
|
2575
|
-
const resolvedCloudPath = cloudPath ? cloudPath.startsWith("/") ? cloudPath :
|
|
3156
|
+
const resolvedCloudPath = cloudPath ? cloudPath.startsWith("/") ? cloudPath : join7(process.cwd(), cloudPath) : join7(homedir(), ".nulljs");
|
|
2576
3157
|
console.log(chalk7.blue("Setting up NullJS production hosting..."));
|
|
2577
3158
|
console.log(chalk7.gray(` Cloud path: ${resolvedCloudPath}`));
|
|
2578
3159
|
const serverBinPath = getServerBinPath();
|