everything-dev 0.3.2 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -0
- package/cli.js +10 -0
- package/dist/_virtual/_rolldown/runtime.cjs +29 -0
- package/dist/api-contract.cjs +172 -0
- package/dist/api-contract.cjs.map +1 -0
- package/dist/api-contract.mjs +171 -0
- package/dist/api-contract.mjs.map +1 -0
- package/dist/api.cjs +124 -0
- package/dist/api.cjs.map +1 -0
- package/dist/api.d.cts +36 -0
- package/dist/api.d.cts.map +1 -0
- package/dist/api.d.mts +36 -0
- package/dist/api.d.mts.map +1 -0
- package/dist/api.mjs +119 -0
- package/dist/api.mjs.map +1 -0
- package/dist/app.cjs +156 -0
- package/dist/app.cjs.map +1 -0
- package/dist/app.mjs +153 -0
- package/dist/app.mjs.map +1 -0
- package/dist/cli/catalog.cjs +30 -0
- package/dist/cli/catalog.cjs.map +1 -0
- package/dist/cli/catalog.mjs +29 -0
- package/dist/cli/catalog.mjs.map +1 -0
- package/dist/cli/help.cjs +16 -0
- package/dist/cli/help.cjs.map +1 -0
- package/dist/cli/help.mjs +16 -0
- package/dist/cli/help.mjs.map +1 -0
- package/dist/cli/init.cjs +317 -0
- package/dist/cli/init.cjs.map +1 -0
- package/dist/cli/init.d.cts +36 -0
- package/dist/cli/init.d.cts.map +1 -0
- package/dist/cli/init.d.mts +36 -0
- package/dist/cli/init.d.mts.map +1 -0
- package/dist/cli/init.mjs +309 -0
- package/dist/cli/init.mjs.map +1 -0
- package/dist/cli/parse.cjs +96 -0
- package/dist/cli/parse.cjs.map +1 -0
- package/dist/cli/parse.mjs +95 -0
- package/dist/cli/parse.mjs.map +1 -0
- package/dist/cli/prompts.cjs +42 -0
- package/dist/cli/prompts.cjs.map +1 -0
- package/dist/cli/prompts.mjs +41 -0
- package/dist/cli/prompts.mjs.map +1 -0
- package/dist/cli.cjs +167 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +166 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/components/dev-view.cjs +307 -0
- package/dist/components/dev-view.cjs.map +1 -0
- package/dist/components/dev-view.mjs +306 -0
- package/dist/components/dev-view.mjs.map +1 -0
- package/dist/components/streaming-view.cjs +146 -0
- package/dist/components/streaming-view.cjs.map +1 -0
- package/dist/components/streaming-view.mjs +144 -0
- package/dist/components/streaming-view.mjs.map +1 -0
- package/dist/config.cjs +280 -0
- package/dist/config.cjs.map +1 -0
- package/dist/config.d.cts +35 -0
- package/dist/config.d.cts.map +1 -0
- package/dist/config.d.mts +35 -0
- package/dist/config.d.mts.map +1 -0
- package/dist/config.mjs +266 -0
- package/dist/config.mjs.map +1 -0
- package/dist/contract.cjs +209 -0
- package/dist/contract.cjs.map +1 -0
- package/dist/contract.d.cts +490 -0
- package/dist/contract.d.cts.map +1 -0
- package/dist/contract.d.mts +490 -0
- package/dist/contract.d.mts.map +1 -0
- package/dist/contract.meta.cjs +104 -0
- package/dist/contract.meta.cjs.map +1 -0
- package/dist/contract.meta.d.cts +141 -0
- package/dist/contract.meta.d.cts.map +1 -0
- package/dist/contract.meta.d.mts +141 -0
- package/dist/contract.meta.d.mts.map +1 -0
- package/dist/contract.meta.mjs +102 -0
- package/dist/contract.meta.mjs.map +1 -0
- package/dist/contract.mjs +186 -0
- package/dist/contract.mjs.map +1 -0
- package/dist/dev-logs.cjs +53 -0
- package/dist/dev-logs.cjs.map +1 -0
- package/dist/dev-logs.mjs +51 -0
- package/dist/dev-logs.mjs.map +1 -0
- package/dist/dev-session.cjs +195 -0
- package/dist/dev-session.cjs.map +1 -0
- package/dist/dev-session.mjs +194 -0
- package/dist/dev-session.mjs.map +1 -0
- package/dist/fastkv.cjs +89 -0
- package/dist/fastkv.cjs.map +1 -0
- package/dist/fastkv.d.cts +11 -0
- package/dist/fastkv.d.cts.map +1 -0
- package/dist/fastkv.d.mts +11 -0
- package/dist/fastkv.d.mts.map +1 -0
- package/dist/fastkv.mjs +82 -0
- package/dist/fastkv.mjs.map +1 -0
- package/dist/federation.server.cjs +27 -0
- package/dist/federation.server.cjs.map +1 -0
- package/dist/federation.server.mjs +27 -0
- package/dist/federation.server.mjs.map +1 -0
- package/dist/host.cjs +367 -0
- package/dist/host.cjs.map +1 -0
- package/dist/host.d.cts +22 -0
- package/dist/host.d.cts.map +1 -0
- package/dist/host.d.mts +22 -0
- package/dist/host.d.mts.map +1 -0
- package/dist/host.mjs +364 -0
- package/dist/host.mjs.map +1 -0
- package/dist/index.cjs +122 -0
- package/dist/index.d.cts +7 -0
- package/dist/index.d.mts +7 -0
- package/dist/index.mjs +9 -0
- package/dist/integrity.cjs +39 -0
- package/dist/integrity.cjs.map +1 -0
- package/dist/integrity.d.cts +7 -0
- package/dist/integrity.d.cts.map +1 -0
- package/dist/integrity.d.mts +7 -0
- package/dist/integrity.d.mts.map +1 -0
- package/dist/integrity.mjs +35 -0
- package/dist/integrity.mjs.map +1 -0
- package/dist/mf.cjs +77 -0
- package/dist/mf.cjs.map +1 -0
- package/dist/mf.d.cts +19 -0
- package/dist/mf.d.cts.map +1 -0
- package/dist/mf.d.mts +19 -0
- package/dist/mf.d.mts.map +1 -0
- package/dist/mf.mjs +71 -0
- package/dist/mf.mjs.map +1 -0
- package/dist/near-cli.cjs +196 -0
- package/dist/near-cli.cjs.map +1 -0
- package/dist/near-cli.mjs +193 -0
- package/dist/near-cli.mjs.map +1 -0
- package/dist/network.cjs +9 -0
- package/dist/network.cjs.map +1 -0
- package/dist/network.mjs +8 -0
- package/dist/network.mjs.map +1 -0
- package/dist/orchestrator.cjs +441 -0
- package/dist/orchestrator.cjs.map +1 -0
- package/dist/orchestrator.d.cts +40 -0
- package/dist/orchestrator.d.cts.map +1 -0
- package/dist/orchestrator.d.mts +40 -0
- package/dist/orchestrator.d.mts.map +1 -0
- package/dist/orchestrator.mjs +436 -0
- package/dist/orchestrator.mjs.map +1 -0
- package/dist/plugin.cjs +825 -0
- package/dist/plugin.cjs.map +1 -0
- package/dist/plugin.d.cts +347 -0
- package/dist/plugin.d.cts.map +1 -0
- package/dist/plugin.d.mts +348 -0
- package/dist/plugin.d.mts.map +1 -0
- package/dist/plugin.mjs +822 -0
- package/dist/plugin.mjs.map +1 -0
- package/dist/process-registry.cjs +120 -0
- package/dist/process-registry.cjs.map +1 -0
- package/dist/process-registry.d.cts +25 -0
- package/dist/process-registry.d.cts.map +1 -0
- package/dist/process-registry.d.mts +25 -0
- package/dist/process-registry.d.mts.map +1 -0
- package/dist/process-registry.mjs +119 -0
- package/dist/process-registry.mjs.map +1 -0
- package/dist/sdk.cjs +61 -0
- package/dist/sdk.d.cts +5 -0
- package/dist/sdk.d.mts +5 -0
- package/dist/sdk.mjs +6 -0
- package/dist/shared.cjs +143 -0
- package/dist/shared.cjs.map +1 -0
- package/dist/shared.d.cts +33 -0
- package/dist/shared.d.cts.map +1 -0
- package/dist/shared.d.mts +33 -0
- package/dist/shared.d.mts.map +1 -0
- package/dist/shared.mjs +140 -0
- package/dist/shared.mjs.map +1 -0
- package/dist/types.cjs +160 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.cts +269 -0
- package/dist/types.d.cts.map +1 -0
- package/dist/types.d.mts +269 -0
- package/dist/types.d.mts.map +1 -0
- package/dist/types.mjs +144 -0
- package/dist/types.mjs.map +1 -0
- package/dist/ui/head.cjs +67 -0
- package/dist/ui/head.cjs.map +1 -0
- package/dist/ui/head.d.cts +19 -0
- package/dist/ui/head.d.cts.map +1 -0
- package/dist/ui/head.d.mts +19 -0
- package/dist/ui/head.d.mts.map +1 -0
- package/dist/ui/head.mjs +61 -0
- package/dist/ui/head.mjs.map +1 -0
- package/dist/ui/index.cjs +32 -0
- package/dist/ui/index.d.cts +7 -0
- package/dist/ui/index.d.mts +7 -0
- package/dist/ui/index.mjs +6 -0
- package/dist/ui/metadata.cjs +106 -0
- package/dist/ui/metadata.cjs.map +1 -0
- package/dist/ui/metadata.d.cts +35 -0
- package/dist/ui/metadata.d.cts.map +1 -0
- package/dist/ui/metadata.d.mts +35 -0
- package/dist/ui/metadata.d.mts.map +1 -0
- package/dist/ui/metadata.mjs +100 -0
- package/dist/ui/metadata.mjs.map +1 -0
- package/dist/ui/router.cjs +56 -0
- package/dist/ui/router.cjs.map +1 -0
- package/dist/ui/router.d.cts +11 -0
- package/dist/ui/router.d.cts.map +1 -0
- package/dist/ui/router.d.mts +11 -0
- package/dist/ui/router.d.mts.map +1 -0
- package/dist/ui/router.mjs +51 -0
- package/dist/ui/router.mjs.map +1 -0
- package/dist/ui/runtime.cjs +65 -0
- package/dist/ui/runtime.cjs.map +1 -0
- package/dist/ui/runtime.d.cts +29 -0
- package/dist/ui/runtime.d.cts.map +1 -0
- package/dist/ui/runtime.d.mts +29 -0
- package/dist/ui/runtime.d.mts.map +1 -0
- package/dist/ui/runtime.mjs +53 -0
- package/dist/ui/runtime.mjs.map +1 -0
- package/dist/ui/types.cjs +0 -0
- package/dist/ui/types.d.cts +52 -0
- package/dist/ui/types.d.cts.map +1 -0
- package/dist/ui/types.d.mts +52 -0
- package/dist/ui/types.d.mts.map +1 -0
- package/dist/ui/types.mjs +1 -0
- package/dist/utils/banner.cjs +24 -0
- package/dist/utils/banner.cjs.map +1 -0
- package/dist/utils/banner.mjs +23 -0
- package/dist/utils/banner.mjs.map +1 -0
- package/dist/utils/linkify.cjs +15 -0
- package/dist/utils/linkify.cjs.map +1 -0
- package/dist/utils/linkify.mjs +14 -0
- package/dist/utils/linkify.mjs.map +1 -0
- package/dist/utils/run.cjs +40 -0
- package/dist/utils/run.cjs.map +1 -0
- package/dist/utils/run.mjs +39 -0
- package/dist/utils/run.mjs.map +1 -0
- package/dist/utils/theme.cjs +44 -0
- package/dist/utils/theme.cjs.map +1 -0
- package/dist/utils/theme.mjs +37 -0
- package/dist/utils/theme.mjs.map +1 -0
- package/package.json +269 -80
- package/src/api-contract.ts +309 -0
- package/src/api.ts +181 -0
- package/src/app.ts +346 -0
- package/src/cli/catalog.ts +49 -0
- package/src/cli/help.ts +13 -0
- package/src/cli/init.ts +415 -0
- package/src/cli/parse.ts +130 -0
- package/src/cli/prompts.ts +64 -0
- package/src/cli.ts +203 -1507
- package/src/components/dev-view.tsx +104 -41
- package/src/components/streaming-view.ts +89 -22
- package/src/config.ts +462 -532
- package/src/contract.meta.ts +96 -0
- package/src/contract.ts +164 -561
- package/src/dev-logs.ts +85 -0
- package/src/dev-session.ts +318 -0
- package/src/fastkv.ts +153 -0
- package/src/federation.server.ts +43 -0
- package/src/host.ts +526 -0
- package/src/index.ts +6 -3
- package/src/integrity.ts +54 -0
- package/src/mf.ts +105 -0
- package/src/near-cli.ts +284 -0
- package/src/network.ts +3 -0
- package/src/orchestrator.ts +648 -0
- package/src/plugin.ts +1116 -2303
- package/src/process-registry.ts +154 -0
- package/src/scripts/sync-api-contract.ts +24 -0
- package/src/sdk.ts +14 -0
- package/src/shared.ts +206 -0
- package/src/types.ts +152 -206
- package/src/ui/head.ts +34 -27
- package/src/ui/index.ts +3 -3
- package/src/ui/metadata.ts +95 -0
- package/src/ui/router.ts +22 -6
- package/src/ui/runtime.ts +55 -6
- package/src/ui/types.ts +24 -11
- package/src/utils/banner.ts +10 -6
- package/src/utils/run.ts +26 -27
- package/src/utils/theme.ts +3 -66
- package/src/components/monitor-view.tsx +0 -475
- package/src/components/status-view.tsx +0 -173
- package/src/lib/env.ts +0 -109
- package/src/lib/near-cli.ts +0 -289
- package/src/lib/nova.ts +0 -266
- package/src/lib/orchestrator.ts +0 -276
- package/src/lib/process-registry.ts +0 -166
- package/src/lib/process.ts +0 -549
- package/src/lib/resource-monitor/assertions.ts +0 -234
- package/src/lib/resource-monitor/command.ts +0 -283
- package/src/lib/resource-monitor/diff.ts +0 -157
- package/src/lib/resource-monitor/errors.ts +0 -127
- package/src/lib/resource-monitor/index.ts +0 -305
- package/src/lib/resource-monitor/platform/darwin.ts +0 -306
- package/src/lib/resource-monitor/platform/index.ts +0 -35
- package/src/lib/resource-monitor/platform/linux.ts +0 -332
- package/src/lib/resource-monitor/platform/windows.ts +0 -298
- package/src/lib/resource-monitor/snapshot.ts +0 -217
- package/src/lib/resource-monitor/types.ts +0 -74
- package/src/lib/session-recorder/errors.ts +0 -102
- package/src/lib/session-recorder/flows/login.ts +0 -210
- package/src/lib/session-recorder/index.ts +0 -361
- package/src/lib/session-recorder/playwright.ts +0 -257
- package/src/lib/session-recorder/report.ts +0 -353
- package/src/lib/session-recorder/server.ts +0 -267
- package/src/lib/session-recorder/types.ts +0 -115
- package/src/lib/sync.ts +0 -1
- package/src/ui/files.ts +0 -134
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
|
|
2
|
+
const require_linkify = require('../utils/linkify.cjs');
|
|
3
|
+
const require_theme = require('../utils/theme.cjs');
|
|
4
|
+
let chalk = require("chalk");
|
|
5
|
+
chalk = require_runtime.__toESM(chalk, 1);
|
|
6
|
+
|
|
7
|
+
//#region src/components/streaming-view.ts
|
|
8
|
+
const orange = chalk.default.hex("#ffaa00");
|
|
9
|
+
const PLUGIN_PREFIX = "plugin:";
|
|
10
|
+
const getTimestamp = () => {
|
|
11
|
+
const now = /* @__PURE__ */ new Date();
|
|
12
|
+
return `${now.getHours().toString().padStart(2, "0")}:${now.getMinutes().toString().padStart(2, "0")}:${now.getSeconds().toString().padStart(2, "0")}`;
|
|
13
|
+
};
|
|
14
|
+
const write = (text) => process.stdout.write(`${text}\n`);
|
|
15
|
+
const getServiceColor = (name) => {
|
|
16
|
+
if (name.startsWith(PLUGIN_PREFIX)) return orange;
|
|
17
|
+
if (name === "host") return require_theme.colors.cyan;
|
|
18
|
+
if (name === "ui" || name === "ui-ssr") return require_theme.colors.magenta;
|
|
19
|
+
if (name === "api") return require_theme.colors.blue;
|
|
20
|
+
return require_theme.colors.white;
|
|
21
|
+
};
|
|
22
|
+
const getDisplayName = (name) => {
|
|
23
|
+
return name.startsWith(PLUGIN_PREFIX) ? name.slice(7).toUpperCase() : name.toUpperCase();
|
|
24
|
+
};
|
|
25
|
+
const isPlugin = (name) => name.startsWith(PLUGIN_PREFIX);
|
|
26
|
+
const getSectionedProcesses = (processes) => {
|
|
27
|
+
const plugins = processes.filter((p) => isPlugin(p.name));
|
|
28
|
+
const services = processes.filter((p) => !isPlugin(p.name));
|
|
29
|
+
const sections = [];
|
|
30
|
+
if (plugins.length > 0) sections.push({
|
|
31
|
+
key: "plugins",
|
|
32
|
+
title: "PLUGINS",
|
|
33
|
+
processes: plugins
|
|
34
|
+
});
|
|
35
|
+
if (services.length > 0) sections.push({
|
|
36
|
+
key: "services",
|
|
37
|
+
title: "SERVICES",
|
|
38
|
+
processes: services
|
|
39
|
+
});
|
|
40
|
+
return sections;
|
|
41
|
+
};
|
|
42
|
+
const getColumnWidths = (processes) => {
|
|
43
|
+
return {
|
|
44
|
+
name: Math.max(6, ...processes.map((p) => getDisplayName(p.name).length)),
|
|
45
|
+
source: Math.max(10, ...processes.map((p) => p.source ? ` (${p.source})`.length : 0))
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
const getStatusIcon = (status) => {
|
|
49
|
+
switch (status) {
|
|
50
|
+
case "pending": return require_theme.icons.pending;
|
|
51
|
+
case "starting": return require_theme.icons.scan;
|
|
52
|
+
case "ready": return require_theme.icons.ok;
|
|
53
|
+
case "error": return require_theme.icons.err;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
function renderStreamingView(initialProcesses, description, env, onExit) {
|
|
57
|
+
const processes = /* @__PURE__ */ new Map();
|
|
58
|
+
for (const p of initialProcesses) processes.set(p.name, { ...p });
|
|
59
|
+
let allReadyPrinted = false;
|
|
60
|
+
const hostPort = initialProcesses.find((p) => p.name === "host")?.port || 3e3;
|
|
61
|
+
const proxyTarget = env.API_PROXY;
|
|
62
|
+
const sectionedProcesses = getSectionedProcesses(initialProcesses);
|
|
63
|
+
const columnWidths = getColumnWidths(initialProcesses);
|
|
64
|
+
const lastLogBySource = /* @__PURE__ */ new Map();
|
|
65
|
+
console.log();
|
|
66
|
+
console.log(require_theme.colors.cyan(`${"─".repeat(52)}`));
|
|
67
|
+
console.log(` ${require_theme.icons.run} ${require_theme.colors.cyan(description.toUpperCase())}`);
|
|
68
|
+
console.log(require_theme.colors.cyan(`${"─".repeat(52)}`));
|
|
69
|
+
console.log();
|
|
70
|
+
if (proxyTarget) {
|
|
71
|
+
console.log(orange(` ${require_theme.icons.arrow} API PROXY → ${proxyTarget}`));
|
|
72
|
+
console.log();
|
|
73
|
+
}
|
|
74
|
+
for (const section of sectionedProcesses) {
|
|
75
|
+
console.log(require_theme.colors.cyan(` ${section.title}`));
|
|
76
|
+
for (const proc of section.processes) {
|
|
77
|
+
const color = getServiceColor(proc.name);
|
|
78
|
+
const sourceLabel = proc.source ? ` (${proc.source})` : "";
|
|
79
|
+
console.log(`${require_theme.colors.dim(`[${getTimestamp()}]`)} ${color(`[${getDisplayName(proc.name).padEnd(columnWidths.name)}]`)} ${require_theme.icons.pending} waiting${sourceLabel.padEnd(columnWidths.source)}`);
|
|
80
|
+
}
|
|
81
|
+
console.log();
|
|
82
|
+
}
|
|
83
|
+
const checkAllReady = () => {
|
|
84
|
+
if (allReadyPrinted) return;
|
|
85
|
+
if (Array.from(processes.values()).every((p) => p.status === "ready")) {
|
|
86
|
+
allReadyPrinted = true;
|
|
87
|
+
console.log();
|
|
88
|
+
console.log(require_theme.colors.dim(`${"─".repeat(52)}`));
|
|
89
|
+
console.log(require_theme.colors.green(`${require_theme.icons.ok} All ${processes.size} services ready`));
|
|
90
|
+
console.log(require_theme.colors.green(`${require_theme.icons.arrow} http://localhost:${hostPort}`));
|
|
91
|
+
console.log(require_theme.colors.dim(`${"─".repeat(52)}`));
|
|
92
|
+
console.log();
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
const updateProcess = (name, status, message) => {
|
|
96
|
+
const proc = processes.get(name);
|
|
97
|
+
if (!proc) return;
|
|
98
|
+
proc.status = status;
|
|
99
|
+
if (message) proc.message = message;
|
|
100
|
+
const color = getServiceColor(name);
|
|
101
|
+
const icon = getStatusIcon(status);
|
|
102
|
+
const displayName = getDisplayName(name).padEnd(columnWidths.name);
|
|
103
|
+
const sourceLabel = proc?.source ? ` (${proc.source})` : "";
|
|
104
|
+
const statusText = status === "ready" ? "ready" : status === "starting" ? "starting" : status === "error" ? "failed" : "waiting";
|
|
105
|
+
const portStr = proc.port > 0 && status === "ready" ? ` :${proc.port}` : "";
|
|
106
|
+
write(`${require_theme.colors.dim(`[${getTimestamp()}]`)} ${color(`[${displayName}]`)} ${status === "ready" ? require_theme.colors.green(icon) : status === "error" ? require_theme.colors.error(icon) : icon} ${statusText}${sourceLabel.padEnd(columnWidths.source)}${portStr}`);
|
|
107
|
+
checkAllReady();
|
|
108
|
+
};
|
|
109
|
+
const addLog = (source, line, isError = false) => {
|
|
110
|
+
const lastLine = lastLogBySource.get(source);
|
|
111
|
+
const nextLine = `${isError ? "ERR" : "OUT"}:${line}`;
|
|
112
|
+
if (lastLine === nextLine) return;
|
|
113
|
+
lastLogBySource.set(source, nextLine);
|
|
114
|
+
const color = getServiceColor(source);
|
|
115
|
+
const logColor = isError ? require_theme.colors.error : require_theme.colors.dim;
|
|
116
|
+
write(`${require_theme.colors.dim(`[${getTimestamp()}]`)} ${color(`[${source.toUpperCase()}]`)} ${require_theme.colors.dim("│")} ${logColor(require_linkify.linkify(line))}`);
|
|
117
|
+
};
|
|
118
|
+
const unmount = () => onExit?.();
|
|
119
|
+
let signalCount = 0;
|
|
120
|
+
const forceExit = () => {
|
|
121
|
+
console.log("\n[CLI] Force exit");
|
|
122
|
+
process.exit(0);
|
|
123
|
+
};
|
|
124
|
+
process.on("SIGINT", () => {
|
|
125
|
+
signalCount++;
|
|
126
|
+
if (signalCount > 1) {
|
|
127
|
+
forceExit();
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
console.log();
|
|
131
|
+
console.log(require_theme.colors.dim(`[${getTimestamp()}] Shutting down...`));
|
|
132
|
+
const timeout = setTimeout(forceExit, 5e3);
|
|
133
|
+
Promise.resolve(unmount()).then(() => {
|
|
134
|
+
clearTimeout(timeout);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
return {
|
|
138
|
+
updateProcess,
|
|
139
|
+
addLog,
|
|
140
|
+
unmount
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
//#endregion
|
|
145
|
+
exports.renderStreamingView = renderStreamingView;
|
|
146
|
+
//# sourceMappingURL=streaming-view.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streaming-view.cjs","names":["colors","icons","linkify"],"sources":["../../src/components/streaming-view.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport { linkify } from \"../utils/linkify\";\nimport { colors, icons } from \"../utils/theme\";\nimport type { ProcessState, ProcessStatus } from \"./dev-view\";\n\nconst orange = chalk.hex(\"#ffaa00\");\nconst PLUGIN_PREFIX = \"plugin:\";\n\nexport interface StreamingViewHandle {\n updateProcess: (name: string, status: ProcessStatus, message?: string) => void;\n addLog: (source: string, line: string, isError?: boolean) => void;\n unmount: () => Promise<void> | void;\n}\n\nconst getTimestamp = (): string => {\n const now = new Date();\n return `${now.getHours().toString().padStart(2, \"0\")}:${now.getMinutes().toString().padStart(2, \"0\")}:${now.getSeconds().toString().padStart(2, \"0\")}`;\n};\n\nconst write = (text: string) => process.stdout.write(`${text}\\n`);\n\nconst getServiceColor = (name: string): ((s: string) => string) => {\n if (name.startsWith(PLUGIN_PREFIX)) return orange;\n if (name === \"host\") return colors.cyan;\n if (name === \"ui\" || name === \"ui-ssr\") return colors.magenta;\n if (name === \"api\") return colors.blue;\n return colors.white;\n};\n\nconst getDisplayName = (name: string): string => {\n return name.startsWith(PLUGIN_PREFIX)\n ? name.slice(PLUGIN_PREFIX.length).toUpperCase()\n : name.toUpperCase();\n};\n\nconst isPlugin = (name: string): boolean => name.startsWith(PLUGIN_PREFIX);\n\nconst getSectionedProcesses = (processes: ProcessState[]) => {\n const plugins = processes.filter((p) => isPlugin(p.name));\n const services = processes.filter((p) => !isPlugin(p.name));\n const sections: Array<{ key: string; title: string; processes: ProcessState[] }> = [];\n if (plugins.length > 0) sections.push({ key: \"plugins\", title: \"PLUGINS\", processes: plugins });\n if (services.length > 0)\n sections.push({ key: \"services\", title: \"SERVICES\", processes: services });\n return sections;\n};\n\nconst getColumnWidths = (processes: ProcessState[]) => {\n const name = Math.max(6, ...processes.map((p) => getDisplayName(p.name).length));\n const source = Math.max(10, ...processes.map((p) => (p.source ? ` (${p.source})`.length : 0)));\n return { name, source };\n};\n\nconst getStatusIcon = (status: ProcessStatus): string => {\n switch (status) {\n case \"pending\":\n return icons.pending;\n case \"starting\":\n return icons.scan;\n case \"ready\":\n return icons.ok;\n case \"error\":\n return icons.err;\n }\n};\n\nexport function renderStreamingView(\n initialProcesses: ProcessState[],\n description: string,\n env: Record<string, string>,\n onExit?: () => Promise<void> | void,\n): StreamingViewHandle {\n const processes = new Map<string, ProcessState>();\n for (const p of initialProcesses) {\n processes.set(p.name, { ...p });\n }\n\n let allReadyPrinted = false;\n const hostProcess = initialProcesses.find((p) => p.name === \"host\");\n const hostPort = hostProcess?.port || 3000;\n const proxyTarget = env.API_PROXY;\n const sectionedProcesses = getSectionedProcesses(initialProcesses);\n const columnWidths = getColumnWidths(initialProcesses);\n const lastLogBySource = new Map<string, string>();\n\n console.log();\n console.log(colors.cyan(`${\"─\".repeat(52)}`));\n console.log(` ${icons.run} ${colors.cyan(description.toUpperCase())}`);\n console.log(colors.cyan(`${\"─\".repeat(52)}`));\n console.log();\n\n if (proxyTarget) {\n console.log(orange(` ${icons.arrow} API PROXY → ${proxyTarget}`));\n console.log();\n }\n\n for (const section of sectionedProcesses) {\n console.log(colors.cyan(` ${section.title}`));\n for (const proc of section.processes) {\n const color = getServiceColor(proc.name);\n const sourceLabel = proc.source ? ` (${proc.source})` : \"\";\n console.log(\n `${colors.dim(`[${getTimestamp()}]`)} ${color(`[${getDisplayName(proc.name).padEnd(columnWidths.name)}]`)} ${icons.pending} waiting${sourceLabel.padEnd(columnWidths.source)}`,\n );\n }\n console.log();\n }\n\n const checkAllReady = () => {\n if (allReadyPrinted) return;\n const allReady = Array.from(processes.values()).every((p) => p.status === \"ready\");\n if (allReady) {\n allReadyPrinted = true;\n console.log();\n console.log(colors.dim(`${\"─\".repeat(52)}`));\n console.log(colors.green(`${icons.ok} All ${processes.size} services ready`));\n console.log(colors.green(`${icons.arrow} http://localhost:${hostPort}`));\n console.log(colors.dim(`${\"─\".repeat(52)}`));\n console.log();\n }\n };\n\n const updateProcess = (name: string, status: ProcessStatus, message?: string) => {\n const proc = processes.get(name);\n if (!proc) return;\n\n proc.status = status;\n if (message) proc.message = message;\n\n const color = getServiceColor(name);\n const icon = getStatusIcon(status);\n const displayName = getDisplayName(name).padEnd(columnWidths.name);\n const sourceLabel = proc?.source ? ` (${proc.source})` : \"\";\n const statusText =\n status === \"ready\"\n ? \"ready\"\n : status === \"starting\"\n ? \"starting\"\n : status === \"error\"\n ? \"failed\"\n : \"waiting\";\n const portStr = proc.port > 0 && status === \"ready\" ? ` :${proc.port}` : \"\";\n\n write(\n `${colors.dim(`[${getTimestamp()}]`)} ${color(`[${displayName}]`)} ${status === \"ready\" ? colors.green(icon) : status === \"error\" ? colors.error(icon) : icon} ${statusText}${sourceLabel.padEnd(columnWidths.source)}${portStr}`,\n );\n\n checkAllReady();\n };\n\n const addLog = (source: string, line: string, isError = false) => {\n const lastLine = lastLogBySource.get(source);\n const nextLine = `${isError ? \"ERR\" : \"OUT\"}:${line}`;\n if (lastLine === nextLine) return;\n lastLogBySource.set(source, nextLine);\n\n const color = getServiceColor(source);\n const logColor = isError ? colors.error : colors.dim;\n write(\n `${colors.dim(`[${getTimestamp()}]`)} ${color(`[${source.toUpperCase()}]`)} ${colors.dim(\"│\")} ${logColor(linkify(line))}`,\n );\n };\n\n const unmount = () => onExit?.();\n\n let signalCount = 0;\n const forceExit = () => {\n console.log(\"\\n[CLI] Force exit\");\n process.exit(0);\n };\n\n process.on(\"SIGINT\", () => {\n signalCount++;\n if (signalCount > 1) {\n forceExit();\n return;\n }\n console.log();\n console.log(colors.dim(`[${getTimestamp()}] Shutting down...`));\n const timeout = setTimeout(forceExit, 5000);\n Promise.resolve(unmount()).then(() => {\n clearTimeout(timeout);\n });\n });\n\n return { updateProcess, addLog, unmount };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { linkify } from "../utils/linkify.mjs";
|
|
2
|
+
import { colors, icons } from "../utils/theme.mjs";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
|
|
5
|
+
//#region src/components/streaming-view.ts
|
|
6
|
+
const orange = chalk.hex("#ffaa00");
|
|
7
|
+
const PLUGIN_PREFIX = "plugin:";
|
|
8
|
+
const getTimestamp = () => {
|
|
9
|
+
const now = /* @__PURE__ */ new Date();
|
|
10
|
+
return `${now.getHours().toString().padStart(2, "0")}:${now.getMinutes().toString().padStart(2, "0")}:${now.getSeconds().toString().padStart(2, "0")}`;
|
|
11
|
+
};
|
|
12
|
+
const write = (text) => process.stdout.write(`${text}\n`);
|
|
13
|
+
const getServiceColor = (name) => {
|
|
14
|
+
if (name.startsWith(PLUGIN_PREFIX)) return orange;
|
|
15
|
+
if (name === "host") return colors.cyan;
|
|
16
|
+
if (name === "ui" || name === "ui-ssr") return colors.magenta;
|
|
17
|
+
if (name === "api") return colors.blue;
|
|
18
|
+
return colors.white;
|
|
19
|
+
};
|
|
20
|
+
const getDisplayName = (name) => {
|
|
21
|
+
return name.startsWith(PLUGIN_PREFIX) ? name.slice(7).toUpperCase() : name.toUpperCase();
|
|
22
|
+
};
|
|
23
|
+
const isPlugin = (name) => name.startsWith(PLUGIN_PREFIX);
|
|
24
|
+
const getSectionedProcesses = (processes) => {
|
|
25
|
+
const plugins = processes.filter((p) => isPlugin(p.name));
|
|
26
|
+
const services = processes.filter((p) => !isPlugin(p.name));
|
|
27
|
+
const sections = [];
|
|
28
|
+
if (plugins.length > 0) sections.push({
|
|
29
|
+
key: "plugins",
|
|
30
|
+
title: "PLUGINS",
|
|
31
|
+
processes: plugins
|
|
32
|
+
});
|
|
33
|
+
if (services.length > 0) sections.push({
|
|
34
|
+
key: "services",
|
|
35
|
+
title: "SERVICES",
|
|
36
|
+
processes: services
|
|
37
|
+
});
|
|
38
|
+
return sections;
|
|
39
|
+
};
|
|
40
|
+
const getColumnWidths = (processes) => {
|
|
41
|
+
return {
|
|
42
|
+
name: Math.max(6, ...processes.map((p) => getDisplayName(p.name).length)),
|
|
43
|
+
source: Math.max(10, ...processes.map((p) => p.source ? ` (${p.source})`.length : 0))
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
const getStatusIcon = (status) => {
|
|
47
|
+
switch (status) {
|
|
48
|
+
case "pending": return icons.pending;
|
|
49
|
+
case "starting": return icons.scan;
|
|
50
|
+
case "ready": return icons.ok;
|
|
51
|
+
case "error": return icons.err;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
function renderStreamingView(initialProcesses, description, env, onExit) {
|
|
55
|
+
const processes = /* @__PURE__ */ new Map();
|
|
56
|
+
for (const p of initialProcesses) processes.set(p.name, { ...p });
|
|
57
|
+
let allReadyPrinted = false;
|
|
58
|
+
const hostPort = initialProcesses.find((p) => p.name === "host")?.port || 3e3;
|
|
59
|
+
const proxyTarget = env.API_PROXY;
|
|
60
|
+
const sectionedProcesses = getSectionedProcesses(initialProcesses);
|
|
61
|
+
const columnWidths = getColumnWidths(initialProcesses);
|
|
62
|
+
const lastLogBySource = /* @__PURE__ */ new Map();
|
|
63
|
+
console.log();
|
|
64
|
+
console.log(colors.cyan(`${"─".repeat(52)}`));
|
|
65
|
+
console.log(` ${icons.run} ${colors.cyan(description.toUpperCase())}`);
|
|
66
|
+
console.log(colors.cyan(`${"─".repeat(52)}`));
|
|
67
|
+
console.log();
|
|
68
|
+
if (proxyTarget) {
|
|
69
|
+
console.log(orange(` ${icons.arrow} API PROXY → ${proxyTarget}`));
|
|
70
|
+
console.log();
|
|
71
|
+
}
|
|
72
|
+
for (const section of sectionedProcesses) {
|
|
73
|
+
console.log(colors.cyan(` ${section.title}`));
|
|
74
|
+
for (const proc of section.processes) {
|
|
75
|
+
const color = getServiceColor(proc.name);
|
|
76
|
+
const sourceLabel = proc.source ? ` (${proc.source})` : "";
|
|
77
|
+
console.log(`${colors.dim(`[${getTimestamp()}]`)} ${color(`[${getDisplayName(proc.name).padEnd(columnWidths.name)}]`)} ${icons.pending} waiting${sourceLabel.padEnd(columnWidths.source)}`);
|
|
78
|
+
}
|
|
79
|
+
console.log();
|
|
80
|
+
}
|
|
81
|
+
const checkAllReady = () => {
|
|
82
|
+
if (allReadyPrinted) return;
|
|
83
|
+
if (Array.from(processes.values()).every((p) => p.status === "ready")) {
|
|
84
|
+
allReadyPrinted = true;
|
|
85
|
+
console.log();
|
|
86
|
+
console.log(colors.dim(`${"─".repeat(52)}`));
|
|
87
|
+
console.log(colors.green(`${icons.ok} All ${processes.size} services ready`));
|
|
88
|
+
console.log(colors.green(`${icons.arrow} http://localhost:${hostPort}`));
|
|
89
|
+
console.log(colors.dim(`${"─".repeat(52)}`));
|
|
90
|
+
console.log();
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
const updateProcess = (name, status, message) => {
|
|
94
|
+
const proc = processes.get(name);
|
|
95
|
+
if (!proc) return;
|
|
96
|
+
proc.status = status;
|
|
97
|
+
if (message) proc.message = message;
|
|
98
|
+
const color = getServiceColor(name);
|
|
99
|
+
const icon = getStatusIcon(status);
|
|
100
|
+
const displayName = getDisplayName(name).padEnd(columnWidths.name);
|
|
101
|
+
const sourceLabel = proc?.source ? ` (${proc.source})` : "";
|
|
102
|
+
const statusText = status === "ready" ? "ready" : status === "starting" ? "starting" : status === "error" ? "failed" : "waiting";
|
|
103
|
+
const portStr = proc.port > 0 && status === "ready" ? ` :${proc.port}` : "";
|
|
104
|
+
write(`${colors.dim(`[${getTimestamp()}]`)} ${color(`[${displayName}]`)} ${status === "ready" ? colors.green(icon) : status === "error" ? colors.error(icon) : icon} ${statusText}${sourceLabel.padEnd(columnWidths.source)}${portStr}`);
|
|
105
|
+
checkAllReady();
|
|
106
|
+
};
|
|
107
|
+
const addLog = (source, line, isError = false) => {
|
|
108
|
+
const lastLine = lastLogBySource.get(source);
|
|
109
|
+
const nextLine = `${isError ? "ERR" : "OUT"}:${line}`;
|
|
110
|
+
if (lastLine === nextLine) return;
|
|
111
|
+
lastLogBySource.set(source, nextLine);
|
|
112
|
+
const color = getServiceColor(source);
|
|
113
|
+
const logColor = isError ? colors.error : colors.dim;
|
|
114
|
+
write(`${colors.dim(`[${getTimestamp()}]`)} ${color(`[${source.toUpperCase()}]`)} ${colors.dim("│")} ${logColor(linkify(line))}`);
|
|
115
|
+
};
|
|
116
|
+
const unmount = () => onExit?.();
|
|
117
|
+
let signalCount = 0;
|
|
118
|
+
const forceExit = () => {
|
|
119
|
+
console.log("\n[CLI] Force exit");
|
|
120
|
+
process.exit(0);
|
|
121
|
+
};
|
|
122
|
+
process.on("SIGINT", () => {
|
|
123
|
+
signalCount++;
|
|
124
|
+
if (signalCount > 1) {
|
|
125
|
+
forceExit();
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
console.log();
|
|
129
|
+
console.log(colors.dim(`[${getTimestamp()}] Shutting down...`));
|
|
130
|
+
const timeout = setTimeout(forceExit, 5e3);
|
|
131
|
+
Promise.resolve(unmount()).then(() => {
|
|
132
|
+
clearTimeout(timeout);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
return {
|
|
136
|
+
updateProcess,
|
|
137
|
+
addLog,
|
|
138
|
+
unmount
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
//#endregion
|
|
143
|
+
export { renderStreamingView };
|
|
144
|
+
//# sourceMappingURL=streaming-view.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streaming-view.mjs","names":[],"sources":["../../src/components/streaming-view.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport { linkify } from \"../utils/linkify\";\nimport { colors, icons } from \"../utils/theme\";\nimport type { ProcessState, ProcessStatus } from \"./dev-view\";\n\nconst orange = chalk.hex(\"#ffaa00\");\nconst PLUGIN_PREFIX = \"plugin:\";\n\nexport interface StreamingViewHandle {\n updateProcess: (name: string, status: ProcessStatus, message?: string) => void;\n addLog: (source: string, line: string, isError?: boolean) => void;\n unmount: () => Promise<void> | void;\n}\n\nconst getTimestamp = (): string => {\n const now = new Date();\n return `${now.getHours().toString().padStart(2, \"0\")}:${now.getMinutes().toString().padStart(2, \"0\")}:${now.getSeconds().toString().padStart(2, \"0\")}`;\n};\n\nconst write = (text: string) => process.stdout.write(`${text}\\n`);\n\nconst getServiceColor = (name: string): ((s: string) => string) => {\n if (name.startsWith(PLUGIN_PREFIX)) return orange;\n if (name === \"host\") return colors.cyan;\n if (name === \"ui\" || name === \"ui-ssr\") return colors.magenta;\n if (name === \"api\") return colors.blue;\n return colors.white;\n};\n\nconst getDisplayName = (name: string): string => {\n return name.startsWith(PLUGIN_PREFIX)\n ? name.slice(PLUGIN_PREFIX.length).toUpperCase()\n : name.toUpperCase();\n};\n\nconst isPlugin = (name: string): boolean => name.startsWith(PLUGIN_PREFIX);\n\nconst getSectionedProcesses = (processes: ProcessState[]) => {\n const plugins = processes.filter((p) => isPlugin(p.name));\n const services = processes.filter((p) => !isPlugin(p.name));\n const sections: Array<{ key: string; title: string; processes: ProcessState[] }> = [];\n if (plugins.length > 0) sections.push({ key: \"plugins\", title: \"PLUGINS\", processes: plugins });\n if (services.length > 0)\n sections.push({ key: \"services\", title: \"SERVICES\", processes: services });\n return sections;\n};\n\nconst getColumnWidths = (processes: ProcessState[]) => {\n const name = Math.max(6, ...processes.map((p) => getDisplayName(p.name).length));\n const source = Math.max(10, ...processes.map((p) => (p.source ? ` (${p.source})`.length : 0)));\n return { name, source };\n};\n\nconst getStatusIcon = (status: ProcessStatus): string => {\n switch (status) {\n case \"pending\":\n return icons.pending;\n case \"starting\":\n return icons.scan;\n case \"ready\":\n return icons.ok;\n case \"error\":\n return icons.err;\n }\n};\n\nexport function renderStreamingView(\n initialProcesses: ProcessState[],\n description: string,\n env: Record<string, string>,\n onExit?: () => Promise<void> | void,\n): StreamingViewHandle {\n const processes = new Map<string, ProcessState>();\n for (const p of initialProcesses) {\n processes.set(p.name, { ...p });\n }\n\n let allReadyPrinted = false;\n const hostProcess = initialProcesses.find((p) => p.name === \"host\");\n const hostPort = hostProcess?.port || 3000;\n const proxyTarget = env.API_PROXY;\n const sectionedProcesses = getSectionedProcesses(initialProcesses);\n const columnWidths = getColumnWidths(initialProcesses);\n const lastLogBySource = new Map<string, string>();\n\n console.log();\n console.log(colors.cyan(`${\"─\".repeat(52)}`));\n console.log(` ${icons.run} ${colors.cyan(description.toUpperCase())}`);\n console.log(colors.cyan(`${\"─\".repeat(52)}`));\n console.log();\n\n if (proxyTarget) {\n console.log(orange(` ${icons.arrow} API PROXY → ${proxyTarget}`));\n console.log();\n }\n\n for (const section of sectionedProcesses) {\n console.log(colors.cyan(` ${section.title}`));\n for (const proc of section.processes) {\n const color = getServiceColor(proc.name);\n const sourceLabel = proc.source ? ` (${proc.source})` : \"\";\n console.log(\n `${colors.dim(`[${getTimestamp()}]`)} ${color(`[${getDisplayName(proc.name).padEnd(columnWidths.name)}]`)} ${icons.pending} waiting${sourceLabel.padEnd(columnWidths.source)}`,\n );\n }\n console.log();\n }\n\n const checkAllReady = () => {\n if (allReadyPrinted) return;\n const allReady = Array.from(processes.values()).every((p) => p.status === \"ready\");\n if (allReady) {\n allReadyPrinted = true;\n console.log();\n console.log(colors.dim(`${\"─\".repeat(52)}`));\n console.log(colors.green(`${icons.ok} All ${processes.size} services ready`));\n console.log(colors.green(`${icons.arrow} http://localhost:${hostPort}`));\n console.log(colors.dim(`${\"─\".repeat(52)}`));\n console.log();\n }\n };\n\n const updateProcess = (name: string, status: ProcessStatus, message?: string) => {\n const proc = processes.get(name);\n if (!proc) return;\n\n proc.status = status;\n if (message) proc.message = message;\n\n const color = getServiceColor(name);\n const icon = getStatusIcon(status);\n const displayName = getDisplayName(name).padEnd(columnWidths.name);\n const sourceLabel = proc?.source ? ` (${proc.source})` : \"\";\n const statusText =\n status === \"ready\"\n ? \"ready\"\n : status === \"starting\"\n ? \"starting\"\n : status === \"error\"\n ? \"failed\"\n : \"waiting\";\n const portStr = proc.port > 0 && status === \"ready\" ? ` :${proc.port}` : \"\";\n\n write(\n `${colors.dim(`[${getTimestamp()}]`)} ${color(`[${displayName}]`)} ${status === \"ready\" ? colors.green(icon) : status === \"error\" ? colors.error(icon) : icon} ${statusText}${sourceLabel.padEnd(columnWidths.source)}${portStr}`,\n );\n\n checkAllReady();\n };\n\n const addLog = (source: string, line: string, isError = false) => {\n const lastLine = lastLogBySource.get(source);\n const nextLine = `${isError ? \"ERR\" : \"OUT\"}:${line}`;\n if (lastLine === nextLine) return;\n lastLogBySource.set(source, nextLine);\n\n const color = getServiceColor(source);\n const logColor = isError ? colors.error : colors.dim;\n write(\n `${colors.dim(`[${getTimestamp()}]`)} ${color(`[${source.toUpperCase()}]`)} ${colors.dim(\"│\")} ${logColor(linkify(line))}`,\n );\n };\n\n const unmount = () => onExit?.();\n\n let signalCount = 0;\n const forceExit = () => {\n console.log(\"\\n[CLI] Force exit\");\n process.exit(0);\n };\n\n process.on(\"SIGINT\", () => {\n signalCount++;\n if (signalCount > 1) {\n forceExit();\n return;\n }\n console.log();\n console.log(colors.dim(`[${getTimestamp()}] Shutting down...`));\n const timeout = setTimeout(forceExit, 5000);\n Promise.resolve(unmount()).then(() => {\n clearTimeout(timeout);\n });\n });\n\n return { updateProcess, addLog, unmount };\n}\n"],"mappings":";;;;;AAKA,MAAM,SAAS,MAAM,IAAI,UAAU;AACnC,MAAM,gBAAgB;AAQtB,MAAM,qBAA6B;CACjC,MAAM,sBAAM,IAAI,MAAM;AACtB,QAAO,GAAG,IAAI,UAAU,CAAC,UAAU,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,IAAI,YAAY,CAAC,UAAU,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,IAAI,YAAY,CAAC,UAAU,CAAC,SAAS,GAAG,IAAI;;AAGtJ,MAAM,SAAS,SAAiB,QAAQ,OAAO,MAAM,GAAG,KAAK,IAAI;AAEjE,MAAM,mBAAmB,SAA0C;AACjE,KAAI,KAAK,WAAW,cAAc,CAAE,QAAO;AAC3C,KAAI,SAAS,OAAQ,QAAO,OAAO;AACnC,KAAI,SAAS,QAAQ,SAAS,SAAU,QAAO,OAAO;AACtD,KAAI,SAAS,MAAO,QAAO,OAAO;AAClC,QAAO,OAAO;;AAGhB,MAAM,kBAAkB,SAAyB;AAC/C,QAAO,KAAK,WAAW,cAAc,GACjC,KAAK,MAAM,EAAqB,CAAC,aAAa,GAC9C,KAAK,aAAa;;AAGxB,MAAM,YAAY,SAA0B,KAAK,WAAW,cAAc;AAE1E,MAAM,yBAAyB,cAA8B;CAC3D,MAAM,UAAU,UAAU,QAAQ,MAAM,SAAS,EAAE,KAAK,CAAC;CACzD,MAAM,WAAW,UAAU,QAAQ,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC;CAC3D,MAAM,WAA6E,EAAE;AACrF,KAAI,QAAQ,SAAS,EAAG,UAAS,KAAK;EAAE,KAAK;EAAW,OAAO;EAAW,WAAW;EAAS,CAAC;AAC/F,KAAI,SAAS,SAAS,EACpB,UAAS,KAAK;EAAE,KAAK;EAAY,OAAO;EAAY,WAAW;EAAU,CAAC;AAC5E,QAAO;;AAGT,MAAM,mBAAmB,cAA8B;AAGrD,QAAO;EAAE,MAFI,KAAK,IAAI,GAAG,GAAG,UAAU,KAAK,MAAM,eAAe,EAAE,KAAK,CAAC,OAAO,CAAC;EAEjE,QADA,KAAK,IAAI,IAAI,GAAG,UAAU,KAAK,MAAO,EAAE,SAAS,KAAK,EAAE,OAAO,GAAG,SAAS,EAAG,CAAC;EACvE;;AAGzB,MAAM,iBAAiB,WAAkC;AACvD,SAAQ,QAAR;EACE,KAAK,UACH,QAAO,MAAM;EACf,KAAK,WACH,QAAO,MAAM;EACf,KAAK,QACH,QAAO,MAAM;EACf,KAAK,QACH,QAAO,MAAM;;;AAInB,SAAgB,oBACd,kBACA,aACA,KACA,QACqB;CACrB,MAAM,4BAAY,IAAI,KAA2B;AACjD,MAAK,MAAM,KAAK,iBACd,WAAU,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;CAGjC,IAAI,kBAAkB;CAEtB,MAAM,WADc,iBAAiB,MAAM,MAAM,EAAE,SAAS,OAAO,EACrC,QAAQ;CACtC,MAAM,cAAc,IAAI;CACxB,MAAM,qBAAqB,sBAAsB,iBAAiB;CAClE,MAAM,eAAe,gBAAgB,iBAAiB;CACtD,MAAM,kCAAkB,IAAI,KAAqB;AAEjD,SAAQ,KAAK;AACb,SAAQ,IAAI,OAAO,KAAK,GAAG,IAAI,OAAO,GAAG,GAAG,CAAC;AAC7C,SAAQ,IAAI,KAAK,MAAM,IAAI,GAAG,OAAO,KAAK,YAAY,aAAa,CAAC,GAAG;AACvE,SAAQ,IAAI,OAAO,KAAK,GAAG,IAAI,OAAO,GAAG,GAAG,CAAC;AAC7C,SAAQ,KAAK;AAEb,KAAI,aAAa;AACf,UAAQ,IAAI,OAAO,KAAK,MAAM,MAAM,eAAe,cAAc,CAAC;AAClE,UAAQ,KAAK;;AAGf,MAAK,MAAM,WAAW,oBAAoB;AACxC,UAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,QAAQ,CAAC;AAC9C,OAAK,MAAM,QAAQ,QAAQ,WAAW;GACpC,MAAM,QAAQ,gBAAgB,KAAK,KAAK;GACxC,MAAM,cAAc,KAAK,SAAS,KAAK,KAAK,OAAO,KAAK;AACxD,WAAQ,IACN,GAAG,OAAO,IAAI,IAAI,cAAc,CAAC,GAAG,CAAC,GAAG,MAAM,IAAI,eAAe,KAAK,KAAK,CAAC,OAAO,aAAa,KAAK,CAAC,GAAG,CAAC,IAAI,MAAM,QAAQ,UAAU,YAAY,OAAO,aAAa,OAAO,GAC9K;;AAEH,UAAQ,KAAK;;CAGf,MAAM,sBAAsB;AAC1B,MAAI,gBAAiB;AAErB,MADiB,MAAM,KAAK,UAAU,QAAQ,CAAC,CAAC,OAAO,MAAM,EAAE,WAAW,QAAQ,EACpE;AACZ,qBAAkB;AAClB,WAAQ,KAAK;AACb,WAAQ,IAAI,OAAO,IAAI,GAAG,IAAI,OAAO,GAAG,GAAG,CAAC;AAC5C,WAAQ,IAAI,OAAO,MAAM,GAAG,MAAM,GAAG,OAAO,UAAU,KAAK,iBAAiB,CAAC;AAC7E,WAAQ,IAAI,OAAO,MAAM,GAAG,MAAM,MAAM,oBAAoB,WAAW,CAAC;AACxE,WAAQ,IAAI,OAAO,IAAI,GAAG,IAAI,OAAO,GAAG,GAAG,CAAC;AAC5C,WAAQ,KAAK;;;CAIjB,MAAM,iBAAiB,MAAc,QAAuB,YAAqB;EAC/E,MAAM,OAAO,UAAU,IAAI,KAAK;AAChC,MAAI,CAAC,KAAM;AAEX,OAAK,SAAS;AACd,MAAI,QAAS,MAAK,UAAU;EAE5B,MAAM,QAAQ,gBAAgB,KAAK;EACnC,MAAM,OAAO,cAAc,OAAO;EAClC,MAAM,cAAc,eAAe,KAAK,CAAC,OAAO,aAAa,KAAK;EAClE,MAAM,cAAc,MAAM,SAAS,KAAK,KAAK,OAAO,KAAK;EACzD,MAAM,aACJ,WAAW,UACP,UACA,WAAW,aACT,aACA,WAAW,UACT,WACA;EACV,MAAM,UAAU,KAAK,OAAO,KAAK,WAAW,UAAU,KAAK,KAAK,SAAS;AAEzE,QACE,GAAG,OAAO,IAAI,IAAI,cAAc,CAAC,GAAG,CAAC,GAAG,MAAM,IAAI,YAAY,GAAG,CAAC,IAAI,WAAW,UAAU,OAAO,MAAM,KAAK,GAAG,WAAW,UAAU,OAAO,MAAM,KAAK,GAAG,KAAK,GAAG,aAAa,YAAY,OAAO,aAAa,OAAO,GAAG,UAC1N;AAED,iBAAe;;CAGjB,MAAM,UAAU,QAAgB,MAAc,UAAU,UAAU;EAChE,MAAM,WAAW,gBAAgB,IAAI,OAAO;EAC5C,MAAM,WAAW,GAAG,UAAU,QAAQ,MAAM,GAAG;AAC/C,MAAI,aAAa,SAAU;AAC3B,kBAAgB,IAAI,QAAQ,SAAS;EAErC,MAAM,QAAQ,gBAAgB,OAAO;EACrC,MAAM,WAAW,UAAU,OAAO,QAAQ,OAAO;AACjD,QACE,GAAG,OAAO,IAAI,IAAI,cAAc,CAAC,GAAG,CAAC,GAAG,MAAM,IAAI,OAAO,aAAa,CAAC,GAAG,CAAC,IAAI,OAAO,IAAI,IAAI,CAAC,GAAG,SAAS,QAAQ,KAAK,CAAC,GAC1H;;CAGH,MAAM,gBAAgB,UAAU;CAEhC,IAAI,cAAc;CAClB,MAAM,kBAAkB;AACtB,UAAQ,IAAI,qBAAqB;AACjC,UAAQ,KAAK,EAAE;;AAGjB,SAAQ,GAAG,gBAAgB;AACzB;AACA,MAAI,cAAc,GAAG;AACnB,cAAW;AACX;;AAEF,UAAQ,KAAK;AACb,UAAQ,IAAI,OAAO,IAAI,IAAI,cAAc,CAAC,oBAAoB,CAAC;EAC/D,MAAM,UAAU,WAAW,WAAW,IAAK;AAC3C,UAAQ,QAAQ,SAAS,CAAC,CAAC,WAAW;AACpC,gBAAa,QAAQ;IACrB;GACF;AAEF,QAAO;EAAE;EAAe;EAAQ;EAAS"}
|
package/dist/config.cjs
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
|
|
3
|
+
const require_fastkv = require('./fastkv.cjs');
|
|
4
|
+
const require_network = require('./network.cjs');
|
|
5
|
+
const require_types = require('./types.cjs');
|
|
6
|
+
let node_fs = require("node:fs");
|
|
7
|
+
let node_path = require("node:path");
|
|
8
|
+
|
|
9
|
+
//#region src/config.ts
|
|
10
|
+
const LOCAL_PREFIX = "local:";
|
|
11
|
+
const DEFAULT_HOST_PORT = 3e3;
|
|
12
|
+
let cachedConfig = null;
|
|
13
|
+
let projectRoot = null;
|
|
14
|
+
function clearConfigCache() {
|
|
15
|
+
cachedConfig = null;
|
|
16
|
+
projectRoot = null;
|
|
17
|
+
}
|
|
18
|
+
function findConfigPath(cwd) {
|
|
19
|
+
let dir = cwd ?? process.cwd();
|
|
20
|
+
while (dir !== "/") {
|
|
21
|
+
const configPath = (0, node_path.join)(dir, "bos.config.json");
|
|
22
|
+
if ((0, node_fs.existsSync)(configPath)) return configPath;
|
|
23
|
+
dir = (0, node_path.dirname)(dir);
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
function getConfig() {
|
|
28
|
+
return cachedConfig;
|
|
29
|
+
}
|
|
30
|
+
function getProjectRoot() {
|
|
31
|
+
if (!projectRoot) throw new Error("Config not loaded. Call loadConfig() first.");
|
|
32
|
+
return projectRoot;
|
|
33
|
+
}
|
|
34
|
+
async function loadConfig(options) {
|
|
35
|
+
const configPath = options?.path ?? findConfigPath(options?.cwd);
|
|
36
|
+
if (!configPath) {
|
|
37
|
+
projectRoot = options?.cwd ?? process.cwd();
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
const baseDir = (0, node_path.dirname)(configPath);
|
|
41
|
+
try {
|
|
42
|
+
const extendedChain = [];
|
|
43
|
+
const parsed = await resolveConfigWithExtends(configPath, baseDir, /* @__PURE__ */ new Set(), extendedChain);
|
|
44
|
+
const config = require_types.BosConfigSchema.parse(parsed);
|
|
45
|
+
cachedConfig = config;
|
|
46
|
+
projectRoot = baseDir;
|
|
47
|
+
const pluginRuntime = await resolveRuntimePlugins(config.plugins ?? {}, baseDir, options?.env ?? "development");
|
|
48
|
+
return {
|
|
49
|
+
config,
|
|
50
|
+
runtime: buildRuntimeConfig(config, baseDir, options?.env ?? "development", { plugins: pluginRuntime }),
|
|
51
|
+
source: {
|
|
52
|
+
path: configPath,
|
|
53
|
+
extended: extendedChain.length > 0 ? extendedChain : void 0,
|
|
54
|
+
remote: extendedChain.some((entry) => entry.startsWith("bos://"))
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
} catch (error) {
|
|
58
|
+
throw new Error(`Failed to load config from ${configPath}: ${error}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async function loadBosConfig(options) {
|
|
62
|
+
const result = await loadConfig(options);
|
|
63
|
+
if (!result) throw new Error("No bos.config.json found");
|
|
64
|
+
return result.runtime;
|
|
65
|
+
}
|
|
66
|
+
async function buildRuntimePluginsForConfig(config, baseDir, env) {
|
|
67
|
+
const plugins = await resolveRuntimePlugins(config.plugins ?? {}, baseDir, env);
|
|
68
|
+
return Object.keys(plugins).length > 0 ? plugins : void 0;
|
|
69
|
+
}
|
|
70
|
+
function buildRuntimeConfig(config, baseDir, env, options) {
|
|
71
|
+
const uiConfig = config.app.ui;
|
|
72
|
+
const apiConfig = config.app.api;
|
|
73
|
+
const uiRuntime = env === "development" ? resolveRuntimeTarget(uiConfig.development, baseDir) : resolveRuntimeTarget(uiConfig.production, baseDir, "remote");
|
|
74
|
+
const apiRuntime = env === "development" ? resolveRuntimeTarget(apiConfig.development, baseDir) : resolveRuntimeTarget(apiConfig.production, baseDir, "remote");
|
|
75
|
+
return {
|
|
76
|
+
env,
|
|
77
|
+
account: config.account,
|
|
78
|
+
domain: config.domain,
|
|
79
|
+
networkId: require_network.getNetworkIdForAccount(config.account),
|
|
80
|
+
repository: config.repository,
|
|
81
|
+
hostUrl: env === "development" ? resolveDevelopmentHostUrl(config.app.host.development) : config.app.host.production,
|
|
82
|
+
shared: config.shared,
|
|
83
|
+
ui: {
|
|
84
|
+
name: uiConfig.name,
|
|
85
|
+
url: uiRuntime.url,
|
|
86
|
+
entry: uiRuntime.url ? `${uiRuntime.url}/mf-manifest.json` : "/mf-manifest.json",
|
|
87
|
+
localPath: uiRuntime.localPath,
|
|
88
|
+
port: uiRuntime.port,
|
|
89
|
+
ssrUrl: uiConfig.ssr,
|
|
90
|
+
ssrIntegrity: env === "production" ? uiConfig.ssrIntegrity : void 0,
|
|
91
|
+
integrity: env === "production" ? uiConfig.productionIntegrity : void 0,
|
|
92
|
+
source: uiRuntime.source
|
|
93
|
+
},
|
|
94
|
+
api: {
|
|
95
|
+
name: apiConfig.name,
|
|
96
|
+
url: apiRuntime.url,
|
|
97
|
+
entry: apiRuntime.url ? `${apiRuntime.url}/mf-manifest.json` : "/mf-manifest.json",
|
|
98
|
+
localPath: apiRuntime.localPath,
|
|
99
|
+
port: apiRuntime.port,
|
|
100
|
+
source: apiRuntime.source,
|
|
101
|
+
proxy: apiConfig.proxy,
|
|
102
|
+
variables: apiConfig.variables,
|
|
103
|
+
secrets: apiConfig.secrets,
|
|
104
|
+
integrity: env === "production" ? apiConfig.productionIntegrity : void 0
|
|
105
|
+
},
|
|
106
|
+
plugins: options?.plugins && Object.keys(options.plugins).length > 0 ? options.plugins : void 0
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
async function loadConfigFile(configPath, baseDir) {
|
|
110
|
+
if (configPath.startsWith("bos://")) return require_fastkv.fetchBosConfigFromFastKv(configPath);
|
|
111
|
+
const resolvedPath = (0, node_path.isAbsolute)(configPath) ? configPath : (0, node_path.resolve)(baseDir, configPath);
|
|
112
|
+
return JSON.parse((0, node_fs.readFileSync)(resolvedPath, "utf-8"));
|
|
113
|
+
}
|
|
114
|
+
async function resolveConfigWithExtends(configPath, baseDir, visited, chain) {
|
|
115
|
+
if (visited.has(configPath)) throw new Error(`Circular extends detected: ${[...visited, configPath].join(" -> ")}`);
|
|
116
|
+
const config = await loadConfigFile(configPath, baseDir);
|
|
117
|
+
if (configPath.startsWith("bos://")) chain.push(configPath);
|
|
118
|
+
if (!config.extends) return config;
|
|
119
|
+
const nextVisited = new Set(visited);
|
|
120
|
+
nextVisited.add(configPath);
|
|
121
|
+
const parentPath = config.extends;
|
|
122
|
+
return mergeConfigs(await resolveConfigWithExtends(parentPath, parentPath.startsWith("bos://") ? baseDir : (0, node_path.isAbsolute)(parentPath) ? (0, node_path.dirname)(parentPath) : baseDir, nextVisited, chain), config);
|
|
123
|
+
}
|
|
124
|
+
function mergeConfigs(parent, child) {
|
|
125
|
+
const result = mergeValues(parent, child);
|
|
126
|
+
if (child.plugins !== void 0) result.plugins = child.plugins;
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
async function resolveRuntimePlugins(plugins, baseDir, env, prefix = []) {
|
|
130
|
+
const out = {};
|
|
131
|
+
for (const [pluginId, pluginInput] of Object.entries(plugins)) {
|
|
132
|
+
const runtimeKey = [...prefix, pluginId].join("/");
|
|
133
|
+
const { config: resolvedConfig, baseDir: pluginBaseDir } = await resolveBosConfigInput(pluginInput, baseDir, /* @__PURE__ */ new Set(), []);
|
|
134
|
+
const pluginRuntime = buildRuntimePluginConfig(runtimeKey, resolvedConfig, pluginBaseDir, env, pluginInput);
|
|
135
|
+
if (pluginRuntime.source === "remote" && pluginRuntime.url && !pluginRuntime.localPath && typeof resolvedConfig.app?.api?.name !== "string") pluginRuntime.name = await resolveRemotePluginRuntimeName(pluginRuntime.url, pluginRuntime.name);
|
|
136
|
+
const productionIntegrity = pluginInput.productionIntegrity;
|
|
137
|
+
if (env === "production" && productionIntegrity) pluginRuntime.integrity = productionIntegrity;
|
|
138
|
+
out[runtimeKey] = pluginRuntime;
|
|
139
|
+
if (resolvedConfig.plugins && Object.keys(resolvedConfig.plugins).length > 0) {
|
|
140
|
+
const nested = await resolveRuntimePlugins(resolvedConfig.plugins, pluginBaseDir, env, [...prefix, pluginId]);
|
|
141
|
+
Object.assign(out, nested);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return out;
|
|
145
|
+
}
|
|
146
|
+
async function resolveRemotePluginRuntimeName(baseUrl, fallback) {
|
|
147
|
+
try {
|
|
148
|
+
const response = await fetch(`${baseUrl.replace(/\/$/, "")}/plugin.manifest.json`);
|
|
149
|
+
if (!response.ok) return fallback;
|
|
150
|
+
const manifest = await response.json();
|
|
151
|
+
return typeof manifest.plugin?.name === "string" && manifest.plugin.name.length > 0 ? manifest.plugin.name : fallback;
|
|
152
|
+
} catch {
|
|
153
|
+
return fallback;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function buildRuntimePluginConfig(pluginId, config, baseDir, env, source) {
|
|
157
|
+
const apiConfig = config.app?.api ?? {};
|
|
158
|
+
const apiDevelopment = typeof apiConfig.development === "string" ? apiConfig.development : void 0;
|
|
159
|
+
const apiProduction = typeof apiConfig.production === "string" ? apiConfig.production : void 0;
|
|
160
|
+
const sourceDevelopment = typeof source.development === "string" ? source.development : void 0;
|
|
161
|
+
const sourceProduction = typeof source.production === "string" ? source.production : void 0;
|
|
162
|
+
const proxy = typeof apiConfig.proxy === "string" ? apiConfig.proxy : void 0;
|
|
163
|
+
const runtimeTarget = env === "development" ? resolveRuntimeTarget(apiDevelopment ?? sourceDevelopment, baseDir) : resolveRuntimeTarget(apiProduction ?? sourceProduction, baseDir, "remote");
|
|
164
|
+
return {
|
|
165
|
+
name: resolvePluginRuntimeName(typeof apiConfig.name === "string" ? apiConfig.name : void 0, runtimeTarget.localPath, pluginId),
|
|
166
|
+
url: runtimeTarget.url,
|
|
167
|
+
entry: runtimeTarget.url ? `${runtimeTarget.url.replace(/\/$/, "")}/mf-manifest.json` : "/mf-manifest.json",
|
|
168
|
+
source: runtimeTarget.source,
|
|
169
|
+
localPath: runtimeTarget.localPath,
|
|
170
|
+
port: runtimeTarget.port,
|
|
171
|
+
proxy: proxy ?? (typeof source.proxy === "string" ? source.proxy : void 0),
|
|
172
|
+
variables: normalizeStringRecord(apiConfig.variables ?? source.variables),
|
|
173
|
+
secrets: normalizeStringArray(apiConfig.secrets ?? source.secrets)
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
function resolvePluginRuntimeName(explicitName, localPath, fallback) {
|
|
177
|
+
if (explicitName) return explicitName;
|
|
178
|
+
if (!localPath) return fallback;
|
|
179
|
+
try {
|
|
180
|
+
const packageJsonPath = (0, node_path.join)(localPath, "package.json");
|
|
181
|
+
const packageJson = JSON.parse((0, node_fs.readFileSync)(packageJsonPath, "utf-8"));
|
|
182
|
+
if (typeof packageJson.name === "string" && packageJson.name.length > 0) return packageJson.name;
|
|
183
|
+
} catch {}
|
|
184
|
+
return fallback;
|
|
185
|
+
}
|
|
186
|
+
async function resolveBosConfigInput(input, baseDir, visited, chain) {
|
|
187
|
+
if (input.extends) {
|
|
188
|
+
const parentBaseDir = input.extends.startsWith("bos://") ? baseDir : (0, node_path.isAbsolute)(input.extends) ? (0, node_path.dirname)(input.extends) : baseDir;
|
|
189
|
+
return {
|
|
190
|
+
config: mergeConfigs(await resolveConfigWithExtends(input.extends, parentBaseDir, visited, chain), input),
|
|
191
|
+
baseDir: parentBaseDir
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
config: input,
|
|
196
|
+
baseDir
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
function mergeValues(parent, child) {
|
|
200
|
+
if (Array.isArray(parent) && Array.isArray(child)) return child;
|
|
201
|
+
if (isPlainObject(parent) && isPlainObject(child)) {
|
|
202
|
+
const merged = { ...parent };
|
|
203
|
+
for (const [key, value] of Object.entries(child)) merged[key] = key in merged ? mergeValues(merged[key], value) : value;
|
|
204
|
+
return merged;
|
|
205
|
+
}
|
|
206
|
+
return child ?? parent;
|
|
207
|
+
}
|
|
208
|
+
function isPlainObject(value) {
|
|
209
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
210
|
+
}
|
|
211
|
+
function normalizeStringRecord(value) {
|
|
212
|
+
if (!isPlainObject(value)) return void 0;
|
|
213
|
+
const out = {};
|
|
214
|
+
for (const [key, raw] of Object.entries(value)) if (typeof raw === "string") out[key] = raw;
|
|
215
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
216
|
+
}
|
|
217
|
+
function normalizeStringArray(value) {
|
|
218
|
+
if (!Array.isArray(value)) return void 0;
|
|
219
|
+
const out = value.filter((item) => typeof item === "string" && item.length > 0);
|
|
220
|
+
return out.length > 0 ? out : void 0;
|
|
221
|
+
}
|
|
222
|
+
function resolveRuntimeTarget(value, baseDir, defaultSource = "remote") {
|
|
223
|
+
if (!value) return {
|
|
224
|
+
source: defaultSource,
|
|
225
|
+
url: ""
|
|
226
|
+
};
|
|
227
|
+
if (value.startsWith(LOCAL_PREFIX)) {
|
|
228
|
+
const localTarget = value.slice(6).trim();
|
|
229
|
+
if (!localTarget) throw new Error(`Invalid local development target: ${value}`);
|
|
230
|
+
return {
|
|
231
|
+
source: "local",
|
|
232
|
+
url: "",
|
|
233
|
+
localPath: (0, node_path.resolve)(baseDir, localTarget)
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
return {
|
|
237
|
+
source: defaultSource,
|
|
238
|
+
url: value.replace(/\/$/, ""),
|
|
239
|
+
port: parsePort(value)
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
function isLocalDevelopmentTarget(value) {
|
|
243
|
+
return typeof value === "string" && value.startsWith(LOCAL_PREFIX);
|
|
244
|
+
}
|
|
245
|
+
function resolveLocalDevelopmentPath(value, baseDir) {
|
|
246
|
+
if (!isLocalDevelopmentTarget(value)) return null;
|
|
247
|
+
const localTarget = value.slice(6).trim();
|
|
248
|
+
return localTarget ? (0, node_path.resolve)(baseDir, localTarget) : null;
|
|
249
|
+
}
|
|
250
|
+
function resolveDevelopmentHostUrl(value) {
|
|
251
|
+
if (!value || isLocalDevelopmentTarget(value)) return `http://localhost:${DEFAULT_HOST_PORT}`;
|
|
252
|
+
return value.replace(/\/$/, "");
|
|
253
|
+
}
|
|
254
|
+
function getHostDevelopmentPort(value) {
|
|
255
|
+
return parsePort(resolveDevelopmentHostUrl(value));
|
|
256
|
+
}
|
|
257
|
+
function parsePort(url) {
|
|
258
|
+
try {
|
|
259
|
+
const parsed = new URL(url);
|
|
260
|
+
return parsed.port ? parseInt(parsed.port, 10) : parsed.protocol === "https:" ? 443 : 80;
|
|
261
|
+
} catch {
|
|
262
|
+
return 3e3;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
//#endregion
|
|
267
|
+
exports.BosConfigSchema = require_types.BosConfigSchema;
|
|
268
|
+
exports.buildRuntimePluginsForConfig = buildRuntimePluginsForConfig;
|
|
269
|
+
exports.clearConfigCache = clearConfigCache;
|
|
270
|
+
exports.findConfigPath = findConfigPath;
|
|
271
|
+
exports.getConfig = getConfig;
|
|
272
|
+
exports.getHostDevelopmentPort = getHostDevelopmentPort;
|
|
273
|
+
exports.getProjectRoot = getProjectRoot;
|
|
274
|
+
exports.isLocalDevelopmentTarget = isLocalDevelopmentTarget;
|
|
275
|
+
exports.loadBosConfig = loadBosConfig;
|
|
276
|
+
exports.loadConfig = loadConfig;
|
|
277
|
+
exports.parsePort = parsePort;
|
|
278
|
+
exports.resolveDevelopmentHostUrl = resolveDevelopmentHostUrl;
|
|
279
|
+
exports.resolveLocalDevelopmentPath = resolveLocalDevelopmentPath;
|
|
280
|
+
//# sourceMappingURL=config.cjs.map
|