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,193 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { generateKeyPairSync } from "node:crypto";
|
|
3
|
+
import { spawn } from "node:child_process";
|
|
4
|
+
|
|
5
|
+
//#region src/near-cli.ts
|
|
6
|
+
const INSTALLER_URL = `https://github.com/near/near-cli-rs/releases/download/v0.23.5/near-cli-rs-installer.sh`;
|
|
7
|
+
const BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
8
|
+
var NearCliNotFoundError = class extends Error {
|
|
9
|
+
_tag = "NearCliNotFoundError";
|
|
10
|
+
constructor() {
|
|
11
|
+
super("NEAR CLI not found");
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
var NearCliInstallError = class extends Error {
|
|
15
|
+
_tag = "NearCliInstallError";
|
|
16
|
+
constructor(message) {
|
|
17
|
+
super(`Failed to install NEAR CLI: ${message}`);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
var NearTransactionError = class extends Error {
|
|
21
|
+
_tag = "NearTransactionError";
|
|
22
|
+
};
|
|
23
|
+
function base64UrlToBytes(input) {
|
|
24
|
+
const normalized = input.replace(/-/g, "+").replace(/_/g, "/");
|
|
25
|
+
return new Uint8Array(Buffer.from(normalized, "base64"));
|
|
26
|
+
}
|
|
27
|
+
function base58Encode(input) {
|
|
28
|
+
if (input.length === 0) return "";
|
|
29
|
+
const digits = [0];
|
|
30
|
+
for (const byte of input) {
|
|
31
|
+
let carry = byte;
|
|
32
|
+
for (let i = 0; i < digits.length; i++) {
|
|
33
|
+
carry += digits[i] << 8;
|
|
34
|
+
digits[i] = carry % 58;
|
|
35
|
+
carry = Math.floor(carry / 58);
|
|
36
|
+
}
|
|
37
|
+
while (carry > 0) {
|
|
38
|
+
digits.push(carry % 58);
|
|
39
|
+
carry = Math.floor(carry / 58);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
let output = "";
|
|
43
|
+
for (const byte of input) if (byte === 0) output += BASE58_ALPHABET[0];
|
|
44
|
+
else break;
|
|
45
|
+
for (let i = digits.length - 1; i >= 0; i--) output += BASE58_ALPHABET[digits[i]];
|
|
46
|
+
return output;
|
|
47
|
+
}
|
|
48
|
+
function generateNearKeyPair() {
|
|
49
|
+
const { publicKey, privateKey } = generateKeyPairSync("ed25519");
|
|
50
|
+
const publicJwk = publicKey.export({ format: "jwk" });
|
|
51
|
+
const privateJwk = privateKey.export({ format: "jwk" });
|
|
52
|
+
if (!publicJwk.x || !privateJwk.d) throw new Error("Failed to generate NEAR keypair");
|
|
53
|
+
const publicBytes = base64UrlToBytes(publicJwk.x);
|
|
54
|
+
const privateSeed = base64UrlToBytes(privateJwk.d);
|
|
55
|
+
const secretBytes = new Uint8Array(privateSeed.length + publicBytes.length);
|
|
56
|
+
secretBytes.set(privateSeed, 0);
|
|
57
|
+
secretBytes.set(publicBytes, privateSeed.length);
|
|
58
|
+
return {
|
|
59
|
+
publicKey: `ed25519:${base58Encode(publicBytes)}`,
|
|
60
|
+
privateKey: `ed25519:${base58Encode(secretBytes)}`
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
const checkNearCliInstalled = Effect.tryPromise({
|
|
64
|
+
try: async () => {
|
|
65
|
+
return await new Promise((resolve) => {
|
|
66
|
+
const proc = spawn("near", ["--version"], { stdio: "pipe" });
|
|
67
|
+
proc.on("close", (code) => resolve(code === 0));
|
|
68
|
+
proc.on("error", () => resolve(false));
|
|
69
|
+
});
|
|
70
|
+
},
|
|
71
|
+
catch: () => /* @__PURE__ */ new Error("Failed to check NEAR CLI")
|
|
72
|
+
});
|
|
73
|
+
const installNearCli = Effect.tryPromise({
|
|
74
|
+
try: async () => {
|
|
75
|
+
return await new Promise((resolve, reject) => {
|
|
76
|
+
const proc = spawn("sh", ["-c", `curl --proto '=https' --tlsv1.2 -LsSf ${INSTALLER_URL} | sh`], { stdio: "inherit" });
|
|
77
|
+
proc.on("close", (code) => {
|
|
78
|
+
if (code === 0) resolve();
|
|
79
|
+
else reject(new NearCliInstallError(`Installer exited with code ${code}`));
|
|
80
|
+
});
|
|
81
|
+
proc.on("error", (err) => reject(new NearCliInstallError(err.message)));
|
|
82
|
+
});
|
|
83
|
+
},
|
|
84
|
+
catch: (error) => error
|
|
85
|
+
});
|
|
86
|
+
async function runNearCommand(args) {
|
|
87
|
+
await new Promise((resolve, reject) => {
|
|
88
|
+
const proc = spawn("near", args, { stdio: "inherit" });
|
|
89
|
+
proc.on("close", (code) => {
|
|
90
|
+
if (code === 0) resolve();
|
|
91
|
+
else reject(/* @__PURE__ */ new Error(`near ${args.join(" ")} failed with exit code ${code}`));
|
|
92
|
+
});
|
|
93
|
+
proc.on("error", (err) => reject(new Error(err.message)));
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
const ensureNearCli = Effect.gen(function* () {
|
|
97
|
+
if (yield* checkNearCliInstalled) return;
|
|
98
|
+
if (process.env.BOS_INSTALL_NEAR_CLI === "true") {
|
|
99
|
+
yield* installNearCli;
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
console.log();
|
|
103
|
+
console.log(" NEAR CLI not found");
|
|
104
|
+
console.log();
|
|
105
|
+
console.log(` To install manually: curl --proto '=https' --tlsv1.2 -LsSf ${INSTALLER_URL} | sh`);
|
|
106
|
+
console.log();
|
|
107
|
+
yield* Effect.fail(new NearCliNotFoundError());
|
|
108
|
+
});
|
|
109
|
+
const executeTransaction = (config) => Effect.gen(function* () {
|
|
110
|
+
const gas = (config.gas || "300Tgas").replace(/\s+/g, "");
|
|
111
|
+
const deposit = (config.deposit || "0NEAR").replace(/\s+/g, "");
|
|
112
|
+
const network = config.network || (config.account.endsWith(".testnet") ? "testnet" : "mainnet");
|
|
113
|
+
const args = [
|
|
114
|
+
"contract",
|
|
115
|
+
"call-function",
|
|
116
|
+
"as-transaction",
|
|
117
|
+
config.contract,
|
|
118
|
+
config.method,
|
|
119
|
+
"base64-args",
|
|
120
|
+
config.argsBase64,
|
|
121
|
+
"prepaid-gas",
|
|
122
|
+
gas,
|
|
123
|
+
"attached-deposit",
|
|
124
|
+
deposit,
|
|
125
|
+
"sign-as",
|
|
126
|
+
config.account,
|
|
127
|
+
"network-config",
|
|
128
|
+
network
|
|
129
|
+
];
|
|
130
|
+
if (config.privateKey) args.push("sign-with-plaintext-private-key", config.privateKey, "send");
|
|
131
|
+
else args.push("sign-with-keychain", "send");
|
|
132
|
+
const output = yield* Effect.tryPromise({
|
|
133
|
+
try: async () => {
|
|
134
|
+
return await new Promise((resolve, reject) => {
|
|
135
|
+
const proc = spawn("near", args, { stdio: [
|
|
136
|
+
"inherit",
|
|
137
|
+
"pipe",
|
|
138
|
+
"pipe"
|
|
139
|
+
] });
|
|
140
|
+
let stdout = "";
|
|
141
|
+
let stderr = "";
|
|
142
|
+
proc.stdout?.on("data", (data) => {
|
|
143
|
+
const text = data.toString();
|
|
144
|
+
stdout += text;
|
|
145
|
+
process.stdout.write(text);
|
|
146
|
+
});
|
|
147
|
+
proc.stderr?.on("data", (data) => {
|
|
148
|
+
const text = data.toString();
|
|
149
|
+
stderr += text;
|
|
150
|
+
});
|
|
151
|
+
proc.on("close", (code) => {
|
|
152
|
+
const combined = `${stdout}\n${stderr}`;
|
|
153
|
+
const txHashMatch = combined.match(/Transaction ID:\s*([A-Za-z0-9]+)/i) || combined.match(/([A-HJ-NP-Za-km-z1-9]{43,44})/);
|
|
154
|
+
const softSuccess = Boolean(txHashMatch?.[1]) && /CodeDoesNotExist/i.test(combined) && /Transaction failed/i.test(combined);
|
|
155
|
+
if (code === 0 || softSuccess) resolve(combined);
|
|
156
|
+
else reject(new NearTransactionError(stderr || `Transaction failed with code ${code}`));
|
|
157
|
+
});
|
|
158
|
+
proc.on("error", (err) => reject(new NearTransactionError(err.message)));
|
|
159
|
+
});
|
|
160
|
+
},
|
|
161
|
+
catch: (error) => error
|
|
162
|
+
});
|
|
163
|
+
return {
|
|
164
|
+
success: true,
|
|
165
|
+
txHash: (output.match(/Transaction ID:\s*([A-Za-z0-9]+)/i) || output.match(/([A-HJ-NP-Za-km-z1-9]{43,44})/))?.[1] || "unknown"
|
|
166
|
+
};
|
|
167
|
+
});
|
|
168
|
+
async function addFunctionCallAccessKey(config) {
|
|
169
|
+
const keyPair = generateNearKeyPair();
|
|
170
|
+
await runNearCommand([
|
|
171
|
+
"account",
|
|
172
|
+
"add-key",
|
|
173
|
+
config.account,
|
|
174
|
+
"grant-function-call-access",
|
|
175
|
+
"--allowance",
|
|
176
|
+
config.allowance,
|
|
177
|
+
"--contract-account-id",
|
|
178
|
+
config.contract,
|
|
179
|
+
"--function-names",
|
|
180
|
+
config.functionNames.join(", "),
|
|
181
|
+
"use-manually-provided-public-key",
|
|
182
|
+
keyPair.publicKey,
|
|
183
|
+
"network-config",
|
|
184
|
+
config.network || (config.account.endsWith(".testnet") ? "testnet" : "mainnet"),
|
|
185
|
+
"sign-with-keychain",
|
|
186
|
+
"send"
|
|
187
|
+
]);
|
|
188
|
+
return keyPair;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
//#endregion
|
|
192
|
+
export { addFunctionCallAccessKey, ensureNearCli, executeTransaction };
|
|
193
|
+
//# sourceMappingURL=near-cli.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"near-cli.mjs","names":[],"sources":["../src/near-cli.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport { generateKeyPairSync } from \"node:crypto\";\nimport { Effect } from \"effect\";\n\nexport interface NearTransactionConfig {\n account: string;\n contract: string;\n method: string;\n argsBase64: string;\n network?: \"mainnet\" | \"testnet\";\n privateKey?: string;\n gas?: string;\n deposit?: string;\n}\n\nexport interface NearTransactionResult {\n success: boolean;\n txHash?: string;\n error?: string;\n}\n\nexport interface NearKeyPair {\n publicKey: string;\n privateKey: string;\n}\n\nexport interface FunctionCallAccessKeyConfig {\n account: string;\n contract: string;\n allowance: string;\n functionNames: string[];\n network?: \"mainnet\" | \"testnet\";\n}\n\nconst NEAR_CLI_VERSION = \"0.23.5\";\nconst INSTALLER_URL = `https://github.com/near/near-cli-rs/releases/download/v${NEAR_CLI_VERSION}/near-cli-rs-installer.sh`;\nconst BASE58_ALPHABET = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\n\nexport class NearCliNotFoundError extends Error {\n readonly _tag = \"NearCliNotFoundError\";\n constructor() {\n super(\"NEAR CLI not found\");\n }\n}\n\nexport class NearCliInstallError extends Error {\n readonly _tag = \"NearCliInstallError\";\n constructor(message: string) {\n super(`Failed to install NEAR CLI: ${message}`);\n }\n}\n\nexport class NearTransactionError extends Error {\n readonly _tag = \"NearTransactionError\";\n}\n\nfunction base64UrlToBytes(input: string): Uint8Array {\n const normalized = input.replace(/-/g, \"+\").replace(/_/g, \"/\");\n return new Uint8Array(Buffer.from(normalized, \"base64\"));\n}\n\nfunction base58Encode(input: Uint8Array): string {\n if (input.length === 0) return \"\";\n\n const digits: number[] = [0];\n for (const byte of input) {\n let carry = byte;\n for (let i = 0; i < digits.length; i++) {\n carry += digits[i]! << 8;\n digits[i] = carry % 58;\n carry = Math.floor(carry / 58);\n }\n while (carry > 0) {\n digits.push(carry % 58);\n carry = Math.floor(carry / 58);\n }\n }\n\n let output = \"\";\n for (const byte of input) {\n if (byte === 0) output += BASE58_ALPHABET[0];\n else break;\n }\n\n for (let i = digits.length - 1; i >= 0; i--) {\n output += BASE58_ALPHABET[digits[i]!]!;\n }\n\n return output;\n}\n\nexport function generateNearKeyPair(): NearKeyPair {\n const { publicKey, privateKey } = generateKeyPairSync(\"ed25519\");\n const publicJwk = publicKey.export({ format: \"jwk\" }) as JsonWebKey;\n const privateJwk = privateKey.export({ format: \"jwk\" }) as JsonWebKey;\n\n if (!publicJwk.x || !privateJwk.d) {\n throw new Error(\"Failed to generate NEAR keypair\");\n }\n\n const publicBytes = base64UrlToBytes(publicJwk.x);\n const privateSeed = base64UrlToBytes(privateJwk.d);\n const secretBytes = new Uint8Array(privateSeed.length + publicBytes.length);\n secretBytes.set(privateSeed, 0);\n secretBytes.set(publicBytes, privateSeed.length);\n\n return {\n publicKey: `ed25519:${base58Encode(publicBytes)}`,\n privateKey: `ed25519:${base58Encode(secretBytes)}`,\n };\n}\n\nconst checkNearCliInstalled = Effect.tryPromise({\n try: async () => {\n return await new Promise<boolean>((resolve) => {\n const proc = spawn(\"near\", [\"--version\"], { stdio: \"pipe\" });\n proc.on(\"close\", (code) => resolve(code === 0));\n proc.on(\"error\", () => resolve(false));\n });\n },\n catch: () => new Error(\"Failed to check NEAR CLI\"),\n});\n\nconst installNearCli = Effect.tryPromise({\n try: async () => {\n return await new Promise<void>((resolve, reject) => {\n const proc = spawn(\n \"sh\",\n [\"-c\", `curl --proto '=https' --tlsv1.2 -LsSf ${INSTALLER_URL} | sh`],\n {\n stdio: \"inherit\",\n },\n );\n\n proc.on(\"close\", (code) => {\n if (code === 0) resolve();\n else reject(new NearCliInstallError(`Installer exited with code ${code}`));\n });\n proc.on(\"error\", (err) => reject(new NearCliInstallError(err.message)));\n });\n },\n catch: (error) => error as Error,\n});\n\nasync function runNearCommand(args: string[]): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const proc = spawn(\"near\", args, {\n stdio: \"inherit\",\n });\n\n proc.on(\"close\", (code) => {\n if (code === 0) resolve();\n else reject(new Error(`near ${args.join(\" \")} failed with exit code ${code}`));\n });\n\n proc.on(\"error\", (err) => reject(new Error(err.message)));\n });\n}\n\nexport const ensureNearCli = Effect.gen(function* () {\n const isInstalled = yield* checkNearCliInstalled;\n if (isInstalled) return;\n\n if (process.env.BOS_INSTALL_NEAR_CLI === \"true\") {\n yield* installNearCli;\n return;\n }\n\n console.log();\n console.log(\" NEAR CLI not found\");\n\n console.log();\n console.log(` To install manually: curl --proto '=https' --tlsv1.2 -LsSf ${INSTALLER_URL} | sh`);\n console.log();\n yield* Effect.fail(new NearCliNotFoundError());\n});\n\nexport const executeTransaction = (\n config: NearTransactionConfig,\n): Effect.Effect<NearTransactionResult, Error> =>\n Effect.gen(function* () {\n const gas = (config.gas || \"300Tgas\").replace(/\\s+/g, \"\");\n const deposit = (config.deposit || \"0NEAR\").replace(/\\s+/g, \"\");\n const network = config.network || (config.account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\");\n\n const args = [\n \"contract\",\n \"call-function\",\n \"as-transaction\",\n config.contract,\n config.method,\n \"base64-args\",\n config.argsBase64,\n \"prepaid-gas\",\n gas,\n \"attached-deposit\",\n deposit,\n \"sign-as\",\n config.account,\n \"network-config\",\n network,\n ];\n\n if (config.privateKey) {\n args.push(\"sign-with-plaintext-private-key\", config.privateKey, \"send\");\n } else {\n args.push(\"sign-with-keychain\", \"send\");\n }\n\n const output = yield* Effect.tryPromise({\n try: async () => {\n return await new Promise<string>((resolve, reject) => {\n const proc = spawn(\"near\", args, { stdio: [\"inherit\", \"pipe\", \"pipe\"] });\n\n let stdout = \"\";\n let stderr = \"\";\n\n proc.stdout?.on(\"data\", (data) => {\n const text = data.toString();\n stdout += text;\n process.stdout.write(text);\n });\n\n proc.stderr?.on(\"data\", (data) => {\n const text = data.toString();\n stderr += text;\n });\n\n proc.on(\"close\", (code) => {\n const combined = `${stdout}\\n${stderr}`;\n const txHashMatch =\n combined.match(/Transaction ID:\\s*([A-Za-z0-9]+)/i) ||\n combined.match(/([A-HJ-NP-Za-km-z1-9]{43,44})/);\n const softSuccess =\n Boolean(txHashMatch?.[1]) &&\n /CodeDoesNotExist/i.test(combined) &&\n /Transaction failed/i.test(combined);\n\n if (code === 0 || softSuccess) resolve(combined);\n else reject(new NearTransactionError(stderr || `Transaction failed with code ${code}`));\n });\n\n proc.on(\"error\", (err) => reject(new NearTransactionError(err.message)));\n });\n },\n catch: (error) => error as Error,\n });\n\n const txHashMatch =\n output.match(/Transaction ID:\\s*([A-Za-z0-9]+)/i) ||\n output.match(/([A-HJ-NP-Za-km-z1-9]{43,44})/);\n\n return {\n success: true,\n txHash: txHashMatch?.[1] || \"unknown\",\n };\n });\n\nexport async function addFunctionCallAccessKey(\n config: FunctionCallAccessKeyConfig,\n): Promise<NearKeyPair> {\n const keyPair = generateNearKeyPair();\n const args = [\n \"account\",\n \"add-key\",\n config.account,\n \"grant-function-call-access\",\n \"--allowance\",\n config.allowance,\n \"--contract-account-id\",\n config.contract,\n \"--function-names\",\n config.functionNames.join(\", \"),\n \"use-manually-provided-public-key\",\n keyPair.publicKey,\n \"network-config\",\n config.network || (config.account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\"),\n \"sign-with-keychain\",\n \"send\",\n ];\n\n await runNearCommand(args);\n return keyPair;\n}\n"],"mappings":"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"}
|
package/dist/network.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network.cjs","names":[],"sources":["../src/network.ts"],"sourcesContent":["export function getNetworkIdForAccount(account: string): \"mainnet\" | \"testnet\" {\n return account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\";\n}\n"],"mappings":";;AAAA,SAAgB,uBAAuB,SAAwC;AAC7E,QAAO,QAAQ,SAAS,WAAW,GAAG,YAAY"}
|
package/dist/network.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network.mjs","names":[],"sources":["../src/network.ts"],"sourcesContent":["export function getNetworkIdForAccount(account: string): \"mainnet\" | \"testnet\" {\n return account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\";\n}\n"],"mappings":";AAAA,SAAgB,uBAAuB,SAAwC;AAC7E,QAAO,QAAQ,SAAS,WAAW,GAAG,YAAY"}
|
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
|
|
3
|
+
const require_config = require('./config.cjs');
|
|
4
|
+
const require_mf = require('./mf.cjs');
|
|
5
|
+
let effect = require("effect");
|
|
6
|
+
let node_net = require("node:net");
|
|
7
|
+
|
|
8
|
+
//#region src/orchestrator.ts
|
|
9
|
+
const processConfigBases = {
|
|
10
|
+
"host-build": {
|
|
11
|
+
name: "host-build",
|
|
12
|
+
command: "bun",
|
|
13
|
+
args: ["run", "build"],
|
|
14
|
+
cwd: "host",
|
|
15
|
+
readyPatterns: [/built in/i, /compiled.*successfully/i],
|
|
16
|
+
errorPatterns: [
|
|
17
|
+
/error:/i,
|
|
18
|
+
/failed/i,
|
|
19
|
+
/exception/i
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
host: {
|
|
23
|
+
name: "host",
|
|
24
|
+
command: "bun",
|
|
25
|
+
args: ["run", "dev"],
|
|
26
|
+
cwd: "host",
|
|
27
|
+
readyPatterns: [/Host (dev|production) server running at/i, /Server running at/i],
|
|
28
|
+
errorPatterns: [
|
|
29
|
+
/error:/i,
|
|
30
|
+
/failed/i,
|
|
31
|
+
/exception/i
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
ui: {
|
|
35
|
+
name: "ui",
|
|
36
|
+
command: "bun",
|
|
37
|
+
args: ["run", "dev"],
|
|
38
|
+
cwd: "ui",
|
|
39
|
+
readyPatterns: [
|
|
40
|
+
/\bready\s+built in\b/i,
|
|
41
|
+
/\bLocal:\b/i,
|
|
42
|
+
/\bcompiled\b.*successfully/i
|
|
43
|
+
],
|
|
44
|
+
errorPatterns: [/error/i, /failed to compile/i]
|
|
45
|
+
},
|
|
46
|
+
"ui-ssr": {
|
|
47
|
+
name: "ui-ssr",
|
|
48
|
+
command: "bun",
|
|
49
|
+
args: ["run", "dev:ssr"],
|
|
50
|
+
cwd: "ui",
|
|
51
|
+
readyPatterns: [/\bready\s+built in\b/i, /\bcompiled\b.*successfully/i],
|
|
52
|
+
errorPatterns: [/error/i, /failed/i]
|
|
53
|
+
},
|
|
54
|
+
api: {
|
|
55
|
+
name: "api",
|
|
56
|
+
command: "bun",
|
|
57
|
+
args: ["run", "dev"],
|
|
58
|
+
cwd: "api",
|
|
59
|
+
readyPatterns: [
|
|
60
|
+
/ready in/i,
|
|
61
|
+
/compiled.*successfully/i,
|
|
62
|
+
/listening/i,
|
|
63
|
+
/started/i
|
|
64
|
+
],
|
|
65
|
+
errorPatterns: [/error/i, /failed/i]
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
function getProcessConfig(pkg, env, portOverride, bosConfig, runtimeConfig) {
|
|
69
|
+
if (pkg.startsWith("plugin:")) {
|
|
70
|
+
const pluginId = pkg.slice(7);
|
|
71
|
+
const pluginConfig = runtimeConfig?.plugins?.[pluginId] ?? null;
|
|
72
|
+
const localPath = pluginConfig?.localPath;
|
|
73
|
+
if (!localPath || pluginConfig?.source !== "local") return null;
|
|
74
|
+
return {
|
|
75
|
+
name: pkg,
|
|
76
|
+
command: "bun",
|
|
77
|
+
args: ["run", "dev"],
|
|
78
|
+
cwd: localPath,
|
|
79
|
+
port: portOverride ?? pluginConfig?.port ?? (pluginConfig?.url ? require_config.parsePort(pluginConfig.url) : 0),
|
|
80
|
+
readyPatterns: [
|
|
81
|
+
/ready in/i,
|
|
82
|
+
/compiled.*successfully/i,
|
|
83
|
+
/listening/i,
|
|
84
|
+
/started/i
|
|
85
|
+
],
|
|
86
|
+
errorPatterns: [/error/i, /failed/i],
|
|
87
|
+
env
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
const base = processConfigBases[pkg];
|
|
91
|
+
if (!base) return null;
|
|
92
|
+
let port;
|
|
93
|
+
if (pkg === "host") port = portOverride ?? (runtimeConfig?.hostUrl ? require_config.parsePort(runtimeConfig.hostUrl) : bosConfig ? require_config.getHostDevelopmentPort(bosConfig.app.host.development) : 3e3);
|
|
94
|
+
else if (pkg === "ui") port = runtimeConfig?.ui.port ?? (runtimeConfig?.ui.url ? require_config.parsePort(runtimeConfig.ui.url) : 3002);
|
|
95
|
+
else if (pkg === "ui-ssr") port = runtimeConfig?.ui.ssrUrl ? require_config.parsePort(runtimeConfig.ui.ssrUrl) : runtimeConfig?.ui.port ? runtimeConfig.ui.port + 1 : 3003;
|
|
96
|
+
else if (pkg === "api") port = runtimeConfig?.api.port ?? (runtimeConfig?.api.url ? require_config.parsePort(runtimeConfig.api.url) : 3014);
|
|
97
|
+
else port = 0;
|
|
98
|
+
const cwd = pkg === "ui" ? runtimeConfig?.ui.localPath ?? base.cwd : pkg === "api" ? runtimeConfig?.api.localPath ?? base.cwd : base.cwd;
|
|
99
|
+
return {
|
|
100
|
+
...base,
|
|
101
|
+
cwd,
|
|
102
|
+
port,
|
|
103
|
+
env
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
const stripAnsi = (input) => {
|
|
107
|
+
const ESC = String.fromCharCode(27);
|
|
108
|
+
const BEL = String.fromCharCode(7);
|
|
109
|
+
return input.replace(new RegExp(`${ESC}\\][^${BEL}]*${BEL}`, "g"), "").replace(new RegExp(`${ESC}\\[[0-?]*[ -/]*[@-~]`, "g"), "");
|
|
110
|
+
};
|
|
111
|
+
const probeHttpOk = async (url, timeoutMs = 400) => {
|
|
112
|
+
const controller = new AbortController();
|
|
113
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
114
|
+
try {
|
|
115
|
+
return (await fetch(url, { signal: controller.signal })).ok;
|
|
116
|
+
} catch {
|
|
117
|
+
return false;
|
|
118
|
+
} finally {
|
|
119
|
+
clearTimeout(timer);
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
const probeTcpOpen = async (port, timeoutMs = 250) => {
|
|
123
|
+
return new Promise((resolve) => {
|
|
124
|
+
const socket = (0, node_net.createConnection)({
|
|
125
|
+
host: "127.0.0.1",
|
|
126
|
+
port
|
|
127
|
+
});
|
|
128
|
+
const timer = setTimeout(() => {
|
|
129
|
+
socket.destroy();
|
|
130
|
+
resolve(false);
|
|
131
|
+
}, timeoutMs);
|
|
132
|
+
socket.once("connect", () => {
|
|
133
|
+
clearTimeout(timer);
|
|
134
|
+
socket.destroy();
|
|
135
|
+
resolve(true);
|
|
136
|
+
});
|
|
137
|
+
socket.once("error", () => {
|
|
138
|
+
clearTimeout(timer);
|
|
139
|
+
resolve(false);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
const detectStatus = (line, config) => {
|
|
144
|
+
const cleanLine = stripAnsi(line);
|
|
145
|
+
for (const pattern of config.errorPatterns) if (pattern.test(cleanLine)) return {
|
|
146
|
+
status: "error",
|
|
147
|
+
isError: true
|
|
148
|
+
};
|
|
149
|
+
for (const pattern of config.readyPatterns) if (pattern.test(cleanLine)) return {
|
|
150
|
+
status: "ready",
|
|
151
|
+
isError: false
|
|
152
|
+
};
|
|
153
|
+
return null;
|
|
154
|
+
};
|
|
155
|
+
const killProcessTree = (pid) => effect.Effect.gen(function* () {
|
|
156
|
+
const killSignal = (signal) => effect.Effect.try({
|
|
157
|
+
try: () => {
|
|
158
|
+
process.kill(-pid, signal);
|
|
159
|
+
},
|
|
160
|
+
catch: () => null
|
|
161
|
+
}).pipe(effect.Effect.ignore);
|
|
162
|
+
const killDirect = (signal) => effect.Effect.try({
|
|
163
|
+
try: () => {
|
|
164
|
+
process.kill(pid, signal);
|
|
165
|
+
},
|
|
166
|
+
catch: () => null
|
|
167
|
+
}).pipe(effect.Effect.ignore);
|
|
168
|
+
const isRunning = () => effect.Effect.try({
|
|
169
|
+
try: () => {
|
|
170
|
+
process.kill(pid, 0);
|
|
171
|
+
return true;
|
|
172
|
+
},
|
|
173
|
+
catch: () => false
|
|
174
|
+
});
|
|
175
|
+
yield* killSignal("SIGTERM");
|
|
176
|
+
yield* killDirect("SIGTERM");
|
|
177
|
+
yield* effect.Effect.sleep("200 millis");
|
|
178
|
+
if (yield* isRunning()) {
|
|
179
|
+
yield* killSignal("SIGKILL");
|
|
180
|
+
yield* killDirect("SIGKILL");
|
|
181
|
+
yield* effect.Effect.sleep("100 millis");
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
const patchConsole = (name, callbacks) => {
|
|
185
|
+
const originalLog = console.log;
|
|
186
|
+
const originalError = console.error;
|
|
187
|
+
const originalWarn = console.warn;
|
|
188
|
+
const originalInfo = console.info;
|
|
189
|
+
const formatArgs = (args) => {
|
|
190
|
+
return args.map((arg) => typeof arg === "object" ? JSON.stringify(arg, null, 2) : String(arg)).join(" ");
|
|
191
|
+
};
|
|
192
|
+
console.log = (...args) => {
|
|
193
|
+
callbacks.onLog(name, formatArgs(args), false);
|
|
194
|
+
};
|
|
195
|
+
console.error = (...args) => {
|
|
196
|
+
callbacks.onLog(name, formatArgs(args), true);
|
|
197
|
+
};
|
|
198
|
+
console.warn = (...args) => {
|
|
199
|
+
callbacks.onLog(name, formatArgs(args), false);
|
|
200
|
+
};
|
|
201
|
+
console.info = (...args) => {
|
|
202
|
+
callbacks.onLog(name, formatArgs(args), false);
|
|
203
|
+
};
|
|
204
|
+
return () => {
|
|
205
|
+
console.log = originalLog;
|
|
206
|
+
console.error = originalError;
|
|
207
|
+
console.warn = originalWarn;
|
|
208
|
+
console.info = originalInfo;
|
|
209
|
+
};
|
|
210
|
+
};
|
|
211
|
+
const spawnRemoteHost = (config, callbacks, runtimeConfig) => effect.Effect.gen(function* () {
|
|
212
|
+
const remoteUrl = config.env?.HOST_REMOTE_URL;
|
|
213
|
+
if (!remoteUrl) return yield* effect.Effect.fail(/* @__PURE__ */ new Error("HOST_REMOTE_URL not provided for remote host"));
|
|
214
|
+
if (config.env) for (const [key, value] of Object.entries(config.env)) process.env[key] = value;
|
|
215
|
+
callbacks.onStatus(config.name, "starting");
|
|
216
|
+
callbacks.onLog(config.name, `Remote: ${remoteUrl}`);
|
|
217
|
+
const restoreConsole = patchConsole(config.name, callbacks);
|
|
218
|
+
callbacks.onLog(config.name, "Loading Module Federation runtime...");
|
|
219
|
+
const mfRuntime = yield* effect.Effect.tryPromise({
|
|
220
|
+
try: () => import("@module-federation/enhanced/runtime"),
|
|
221
|
+
catch: (e) => /* @__PURE__ */ new Error(`Failed to load MF runtime: ${e}`)
|
|
222
|
+
});
|
|
223
|
+
const mfCore = yield* effect.Effect.tryPromise({
|
|
224
|
+
try: () => import("@module-federation/runtime-core"),
|
|
225
|
+
catch: (e) => /* @__PURE__ */ new Error(`Failed to load MF core: ${e}`)
|
|
226
|
+
});
|
|
227
|
+
let mf = mfRuntime.getInstance();
|
|
228
|
+
if (!mf) {
|
|
229
|
+
mf = mfRuntime.createInstance({
|
|
230
|
+
name: "cli-host",
|
|
231
|
+
remotes: []
|
|
232
|
+
});
|
|
233
|
+
mfCore.setGlobalFederationInstance(mf);
|
|
234
|
+
}
|
|
235
|
+
require_mf.patchManifestFetchForSsrPublicPath(mf);
|
|
236
|
+
const baseUrl = remoteUrl.replace(/\/remoteEntry\.js$/, "").replace(/\/mf-manifest\.json$/, "").replace(/\/$/, "");
|
|
237
|
+
const remoteEntryUrl = `${baseUrl}/remoteEntry.js`;
|
|
238
|
+
const manifestUrl = `${baseUrl}/mf-manifest.json`;
|
|
239
|
+
const entryUrl = yield* effect.Effect.tryPromise({
|
|
240
|
+
try: async () => {
|
|
241
|
+
try {
|
|
242
|
+
const res = await fetch(manifestUrl);
|
|
243
|
+
if (!res.ok) return remoteEntryUrl;
|
|
244
|
+
const json = await res.json();
|
|
245
|
+
if (json && typeof json === "object" && "metaData" in json && "exposes" in json && "shared" in json) return manifestUrl;
|
|
246
|
+
} catch {}
|
|
247
|
+
return remoteEntryUrl;
|
|
248
|
+
},
|
|
249
|
+
catch: () => remoteEntryUrl
|
|
250
|
+
});
|
|
251
|
+
mf.registerRemotes([{
|
|
252
|
+
name: "host",
|
|
253
|
+
entry: entryUrl
|
|
254
|
+
}]);
|
|
255
|
+
callbacks.onLog(config.name, `Loading host from ${entryUrl}...`);
|
|
256
|
+
const hostModule = yield* effect.Effect.tryPromise({
|
|
257
|
+
try: () => mf.loadRemote("host/Server"),
|
|
258
|
+
catch: (e) => /* @__PURE__ */ new Error(`Failed to load host module: ${e}`)
|
|
259
|
+
});
|
|
260
|
+
if (!hostModule?.runServer) return yield* effect.Effect.fail(/* @__PURE__ */ new Error("Host module does not export runServer function"));
|
|
261
|
+
callbacks.onLog(config.name, "Starting server...");
|
|
262
|
+
const serverHandle = hostModule.runServer({ config: runtimeConfig });
|
|
263
|
+
yield* effect.Effect.tryPromise({
|
|
264
|
+
try: () => serverHandle.ready,
|
|
265
|
+
catch: (e) => /* @__PURE__ */ new Error(`Server failed to start: ${e}`)
|
|
266
|
+
});
|
|
267
|
+
callbacks.onStatus(config.name, "ready");
|
|
268
|
+
return {
|
|
269
|
+
name: config.name,
|
|
270
|
+
pid: process.pid,
|
|
271
|
+
kill: async () => {
|
|
272
|
+
callbacks.onLog(config.name, "Shutting down remote host...");
|
|
273
|
+
restoreConsole();
|
|
274
|
+
await serverHandle.shutdown();
|
|
275
|
+
},
|
|
276
|
+
waitForReady: effect.Effect.succeed(void 0),
|
|
277
|
+
waitForExit: effect.Effect.never
|
|
278
|
+
};
|
|
279
|
+
});
|
|
280
|
+
const spawnDevProcess = (config, callbacks, runtimeConfig, registry) => effect.Effect.gen(function* () {
|
|
281
|
+
let configDir;
|
|
282
|
+
try {
|
|
283
|
+
configDir = require_config.getProjectRoot();
|
|
284
|
+
} catch {
|
|
285
|
+
configDir = process.cwd();
|
|
286
|
+
}
|
|
287
|
+
const fullCwd = config.cwd.startsWith("/") ? config.cwd : `${configDir}/${config.cwd}`;
|
|
288
|
+
const readyDeferred = yield* effect.Deferred.make();
|
|
289
|
+
const statusRef = yield* effect.Ref.make("starting");
|
|
290
|
+
callbacks.onStatus(config.name, "starting");
|
|
291
|
+
const envVars = {
|
|
292
|
+
...process.env,
|
|
293
|
+
...config.env,
|
|
294
|
+
FORCE_COLOR: "1",
|
|
295
|
+
...config.port > 0 ? { PORT: String(config.port) } : {}
|
|
296
|
+
};
|
|
297
|
+
if (runtimeConfig && config.name === "host") envVars.BOS_RUNTIME_CONFIG = JSON.stringify(runtimeConfig);
|
|
298
|
+
const proc = Bun.spawn({
|
|
299
|
+
cmd: [config.command, ...config.args],
|
|
300
|
+
cwd: fullCwd,
|
|
301
|
+
env: envVars,
|
|
302
|
+
stdio: [
|
|
303
|
+
"inherit",
|
|
304
|
+
"pipe",
|
|
305
|
+
"pipe"
|
|
306
|
+
]
|
|
307
|
+
});
|
|
308
|
+
const markReady = effect.Effect.gen(function* () {
|
|
309
|
+
const currentStatus = yield* effect.Ref.get(statusRef);
|
|
310
|
+
if (currentStatus === "ready" || currentStatus === "error") return;
|
|
311
|
+
yield* effect.Ref.set(statusRef, "ready");
|
|
312
|
+
callbacks.onStatus(config.name, "ready");
|
|
313
|
+
yield* effect.Deferred.succeed(readyDeferred, void 0).pipe(effect.Effect.ignore);
|
|
314
|
+
});
|
|
315
|
+
if (config.port > 0) {
|
|
316
|
+
const readinessPath = config.name === "host" ? "/health" : config.name === "ui-ssr" ? "/" : "/remoteEntry.js";
|
|
317
|
+
const url = `http://127.0.0.1:${config.port}${readinessPath}`;
|
|
318
|
+
yield* effect.Effect.fork(effect.Effect.gen(function* () {
|
|
319
|
+
const deadline = Date.now() + 9e4;
|
|
320
|
+
while (Date.now() < deadline) {
|
|
321
|
+
const status = yield* effect.Ref.get(statusRef);
|
|
322
|
+
if (status === "ready" || status === "error") return;
|
|
323
|
+
if (url ? yield* effect.Effect.tryPromise({
|
|
324
|
+
try: () => probeHttpOk(url),
|
|
325
|
+
catch: () => false
|
|
326
|
+
}) : yield* effect.Effect.tryPromise({
|
|
327
|
+
try: () => probeTcpOpen(config.port),
|
|
328
|
+
catch: () => false
|
|
329
|
+
})) {
|
|
330
|
+
yield* markReady;
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
yield* effect.Effect.sleep("200 millis");
|
|
334
|
+
}
|
|
335
|
+
}));
|
|
336
|
+
}
|
|
337
|
+
if (registry && proc.pid) yield* registry.track({
|
|
338
|
+
pid: proc.pid,
|
|
339
|
+
name: config.name,
|
|
340
|
+
port: config.port,
|
|
341
|
+
startedAt: Date.now(),
|
|
342
|
+
command: [config.command, ...config.args].join(" ")
|
|
343
|
+
});
|
|
344
|
+
yield* effect.Effect.fork(effect.Effect.promise(() => proc.exited).pipe(effect.Effect.andThen((code) => effect.Effect.gen(function* () {
|
|
345
|
+
if (registry && proc.pid) yield* registry.untrack(proc.pid).pipe(effect.Effect.ignore);
|
|
346
|
+
if ((yield* effect.Ref.get(statusRef)) === "ready") return;
|
|
347
|
+
callbacks.onLog(config.name, `Process exited before ready (exit code: ${code})`, true);
|
|
348
|
+
yield* effect.Ref.set(statusRef, "error");
|
|
349
|
+
callbacks.onStatus(config.name, "error");
|
|
350
|
+
yield* effect.Deferred.fail(readyDeferred, /* @__PURE__ */ new Error(`Process exited before ready: ${config.name}`)).pipe(effect.Effect.ignore);
|
|
351
|
+
}))));
|
|
352
|
+
const handleLine = (line, isStderr) => effect.Effect.gen(function* () {
|
|
353
|
+
if (!line.trim()) return;
|
|
354
|
+
callbacks.onLog(config.name, line, isStderr);
|
|
355
|
+
if ((yield* effect.Ref.get(statusRef)) === "ready") return;
|
|
356
|
+
const detected = detectStatus(line, config);
|
|
357
|
+
if (detected) {
|
|
358
|
+
yield* effect.Ref.set(statusRef, detected.status);
|
|
359
|
+
callbacks.onStatus(config.name, detected.status);
|
|
360
|
+
if (detected.status === "ready" || detected.status === "error") if (detected.status === "ready") yield* effect.Deferred.succeed(readyDeferred, void 0).pipe(effect.Effect.ignore);
|
|
361
|
+
else yield* effect.Deferred.fail(readyDeferred, /* @__PURE__ */ new Error(`Process failed: ${config.name}`)).pipe(effect.Effect.ignore);
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
const decoder = new TextDecoder();
|
|
365
|
+
const stdoutFiber = yield* effect.Effect.fork(effect.Effect.async((resume) => {
|
|
366
|
+
if (!proc.stdout) {
|
|
367
|
+
resume(effect.Effect.void);
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
const reader = proc.stdout.getReader();
|
|
371
|
+
let buffer = "";
|
|
372
|
+
const pump = () => reader.read().then(({ done, value }) => {
|
|
373
|
+
if (done) {
|
|
374
|
+
if (buffer) effect.Effect.runSync(handleLine(buffer, false));
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
buffer += decoder.decode(value, { stream: true }).replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
378
|
+
const lines = buffer.split("\n");
|
|
379
|
+
buffer = lines.pop() ?? "";
|
|
380
|
+
for (const line of lines) effect.Effect.runSync(handleLine(line, false));
|
|
381
|
+
return pump();
|
|
382
|
+
});
|
|
383
|
+
pump().then(() => resume(effect.Effect.void));
|
|
384
|
+
}));
|
|
385
|
+
const stderrFiber = yield* effect.Effect.fork(effect.Effect.async((resume) => {
|
|
386
|
+
if (!proc.stderr) {
|
|
387
|
+
resume(effect.Effect.void);
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
const reader = proc.stderr.getReader();
|
|
391
|
+
let buffer = "";
|
|
392
|
+
const pump = () => reader.read().then(({ done, value }) => {
|
|
393
|
+
if (done) {
|
|
394
|
+
if (buffer) effect.Effect.runSync(handleLine(buffer, true));
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
buffer += decoder.decode(value, { stream: true }).replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
398
|
+
const lines = buffer.split("\n");
|
|
399
|
+
buffer = lines.pop() ?? "";
|
|
400
|
+
for (const line of lines) effect.Effect.runSync(handleLine(line, true));
|
|
401
|
+
return pump();
|
|
402
|
+
});
|
|
403
|
+
pump().then(() => resume(effect.Effect.void));
|
|
404
|
+
}));
|
|
405
|
+
return {
|
|
406
|
+
name: config.name,
|
|
407
|
+
pid: proc.pid,
|
|
408
|
+
kill: async () => {
|
|
409
|
+
const pid = proc.pid;
|
|
410
|
+
if (pid) await effect.Effect.runPromise(killProcessTree(pid));
|
|
411
|
+
else {
|
|
412
|
+
proc.kill("SIGTERM");
|
|
413
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
414
|
+
try {
|
|
415
|
+
proc.kill("SIGKILL");
|
|
416
|
+
} catch {}
|
|
417
|
+
}
|
|
418
|
+
},
|
|
419
|
+
waitForReady: effect.Deferred.await(readyDeferred),
|
|
420
|
+
waitForExit: effect.Effect.gen(function* () {
|
|
421
|
+
yield* effect.Fiber.joinAll([stdoutFiber, stderrFiber]);
|
|
422
|
+
return yield* effect.Effect.promise(() => proc.exited);
|
|
423
|
+
})
|
|
424
|
+
};
|
|
425
|
+
});
|
|
426
|
+
const makeDevProcess = (pkg, env, callbacks, portOverride, bosConfig, runtimeConfig, registry) => effect.Effect.gen(function* () {
|
|
427
|
+
const config = getProcessConfig(pkg, env, portOverride, bosConfig, runtimeConfig);
|
|
428
|
+
if (!config) return yield* effect.Effect.fail(/* @__PURE__ */ new Error(`Unknown package: ${pkg}`));
|
|
429
|
+
if (pkg === "host" && runtimeConfig) {
|
|
430
|
+
if (env?.HOST_SOURCE === "remote") return yield* spawnRemoteHost(config, callbacks, runtimeConfig);
|
|
431
|
+
return yield* spawnDevProcess(config, callbacks, runtimeConfig, registry);
|
|
432
|
+
}
|
|
433
|
+
return yield* spawnDevProcess(config, callbacks, runtimeConfig, registry);
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
//#endregion
|
|
437
|
+
exports.getProcessConfig = getProcessConfig;
|
|
438
|
+
exports.makeDevProcess = makeDevProcess;
|
|
439
|
+
exports.spawnDevProcess = spawnDevProcess;
|
|
440
|
+
exports.spawnRemoteHost = spawnRemoteHost;
|
|
441
|
+
//# sourceMappingURL=orchestrator.cjs.map
|