everything-dev 1.48.0 → 1.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.cjs +66 -86
- package/dist/app.cjs.map +1 -1
- package/dist/app.mjs +66 -87
- package/dist/app.mjs.map +1 -1
- package/dist/cli/db-doctor.cjs +6 -23
- package/dist/cli/db-doctor.cjs.map +1 -1
- package/dist/cli/db-doctor.mjs +7 -24
- package/dist/cli/db-doctor.mjs.map +1 -1
- package/dist/cli/db-repair.cjs +25 -20
- package/dist/cli/db-repair.cjs.map +1 -1
- package/dist/cli/db-repair.mjs +25 -20
- package/dist/cli/db-repair.mjs.map +1 -1
- package/dist/cli/db-studio.cjs +4 -2
- package/dist/cli/db-studio.cjs.map +1 -1
- package/dist/cli/db-studio.mjs +5 -3
- package/dist/cli/db-studio.mjs.map +1 -1
- package/dist/cli/framework-version.cjs +45 -9
- package/dist/cli/framework-version.cjs.map +1 -1
- package/dist/cli/framework-version.mjs +45 -10
- package/dist/cli/framework-version.mjs.map +1 -1
- package/dist/cli/infra.cjs +89 -3
- package/dist/cli/infra.cjs.map +1 -1
- package/dist/cli/infra.mjs +83 -4
- package/dist/cli/infra.mjs.map +1 -1
- package/dist/cli/init.cjs +39 -15
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.d.cts +8 -3
- package/dist/cli/init.d.cts.map +1 -1
- package/dist/cli/init.d.mts +8 -3
- package/dist/cli/init.d.mts.map +1 -1
- package/dist/cli/init.mjs +39 -16
- package/dist/cli/init.mjs.map +1 -1
- package/dist/cli/status.cjs +6 -2
- package/dist/cli/status.cjs.map +1 -1
- package/dist/cli/status.mjs +7 -3
- package/dist/cli/status.mjs.map +1 -1
- package/dist/cli/sync.cjs +1 -3
- package/dist/cli/sync.cjs.map +1 -1
- package/dist/cli/sync.mjs +1 -3
- package/dist/cli/sync.mjs.map +1 -1
- package/dist/cli/upgrade.cjs +8 -4
- package/dist/cli/upgrade.cjs.map +1 -1
- package/dist/cli/upgrade.mjs +8 -4
- package/dist/cli/upgrade.mjs.map +1 -1
- package/dist/cli.cjs +73 -9
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +74 -10
- package/dist/cli.mjs.map +1 -1
- package/dist/config.cjs +7 -3
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.cts.map +1 -1
- package/dist/config.d.mts.map +1 -1
- package/dist/config.mjs +7 -3
- package/dist/config.mjs.map +1 -1
- package/dist/contract.cjs +76 -4
- package/dist/contract.cjs.map +1 -1
- package/dist/contract.d.cts +164 -19
- package/dist/contract.d.cts.map +1 -1
- package/dist/contract.d.mts +164 -19
- package/dist/contract.d.mts.map +1 -1
- package/dist/contract.meta.cjs +17 -2
- package/dist/contract.meta.cjs.map +1 -1
- package/dist/contract.meta.d.cts +23 -2
- package/dist/contract.meta.d.mts +23 -2
- package/dist/contract.meta.mjs +17 -2
- package/dist/contract.meta.mjs.map +1 -1
- package/dist/contract.mjs +72 -5
- package/dist/contract.mjs.map +1 -1
- package/dist/db.cjs +33 -25
- package/dist/db.cjs.map +1 -1
- package/dist/db.d.cts +16 -9
- package/dist/db.d.cts.map +1 -1
- package/dist/db.d.mts +16 -9
- package/dist/db.d.mts.map +1 -1
- package/dist/db.mjs +33 -24
- package/dist/db.mjs.map +1 -1
- package/dist/dev-session.cjs +28 -0
- package/dist/dev-session.cjs.map +1 -1
- package/dist/dev-session.mjs +29 -1
- package/dist/dev-session.mjs.map +1 -1
- package/dist/index.cjs +5 -0
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/infra/planner.cjs +337 -0
- package/dist/infra/planner.cjs.map +1 -0
- package/dist/infra/planner.mjs +336 -0
- package/dist/infra/planner.mjs.map +1 -0
- package/dist/infra/preflight.cjs +131 -0
- package/dist/infra/preflight.cjs.map +1 -0
- package/dist/infra/preflight.mjs +130 -0
- package/dist/infra/preflight.mjs.map +1 -0
- package/dist/infra/types.cjs +9 -0
- package/dist/infra/types.cjs.map +1 -0
- package/dist/infra/types.mjs +8 -0
- package/dist/infra/types.mjs.map +1 -0
- package/dist/near-cli.cjs +37 -0
- package/dist/near-cli.cjs.map +1 -1
- package/dist/near-cli.mjs +36 -1
- package/dist/near-cli.mjs.map +1 -1
- package/dist/orchestrator.cjs +10 -2
- package/dist/orchestrator.cjs.map +1 -1
- package/dist/orchestrator.mjs +10 -2
- package/dist/orchestrator.mjs.map +1 -1
- package/dist/plugin.cjs +160 -43
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +64 -8
- package/dist/plugin.d.cts.map +1 -1
- package/dist/plugin.d.mts +64 -8
- package/dist/plugin.d.mts.map +1 -1
- package/dist/plugin.mjs +164 -47
- package/dist/plugin.mjs.map +1 -1
- package/dist/process-registry.cjs +88 -0
- package/dist/process-registry.cjs.map +1 -0
- package/dist/process-registry.mjs +83 -0
- package/dist/process-registry.mjs.map +1 -0
- package/dist/publish.cjs +4 -0
- package/dist/publish.cjs.map +1 -1
- package/dist/publish.mjs +4 -0
- package/dist/publish.mjs.map +1 -1
- package/dist/service-descriptor.cjs +4 -0
- package/dist/service-descriptor.cjs.map +1 -1
- package/dist/service-descriptor.mjs +4 -1
- package/dist/service-descriptor.mjs.map +1 -1
- package/dist/types.d.cts +2 -2
- package/dist/types.d.mts +2 -2
- package/dist/ui/index.cjs +2 -1
- package/dist/ui/index.d.cts +2 -2
- package/dist/ui/index.d.mts +2 -2
- package/dist/ui/index.mjs +2 -2
- package/dist/ui/router.cjs +40 -0
- package/dist/ui/router.cjs.map +1 -1
- package/dist/ui/router.d.cts +6 -1
- package/dist/ui/router.d.cts.map +1 -1
- package/dist/ui/router.d.mts +6 -1
- package/dist/ui/router.d.mts.map +1 -1
- package/dist/ui/router.mjs +40 -1
- package/dist/ui/router.mjs.map +1 -1
- package/package.json +4 -1
- package/skills/cli-reference/SKILL.md +5 -4
- package/skills/dev-workflow/SKILL.md +40 -11
- package/skills/plugin-development/SKILL.md +9 -2
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { Effect } from "effect";
|
|
4
|
+
import { access } from "node:fs/promises";
|
|
5
|
+
import { homedir } from "node:os";
|
|
6
|
+
|
|
7
|
+
//#region src/process-registry.ts
|
|
8
|
+
function getRegistryDir() {
|
|
9
|
+
return join(homedir(), ".cache", "everything-dev");
|
|
10
|
+
}
|
|
11
|
+
function ensureRegistryDir() {
|
|
12
|
+
const dir = join(getRegistryPath(), "..");
|
|
13
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
14
|
+
}
|
|
15
|
+
function readRegistry() {
|
|
16
|
+
const path = getRegistryPath();
|
|
17
|
+
if (!existsSync(path)) return [];
|
|
18
|
+
try {
|
|
19
|
+
const raw = JSON.parse(readFileSync(path, "utf-8"));
|
|
20
|
+
if (!Array.isArray(raw)) return [];
|
|
21
|
+
return raw.filter((entry) => entry && typeof entry === "object" && typeof entry.pid === "number" && typeof entry.configDir === "string" && typeof entry.role === "string");
|
|
22
|
+
} catch {
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function isPidAlive(pid) {
|
|
27
|
+
try {
|
|
28
|
+
process.kill(pid, 0);
|
|
29
|
+
return true;
|
|
30
|
+
} catch (err) {
|
|
31
|
+
return err.code !== "ESRCH";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function pruneDead(entries) {
|
|
35
|
+
return entries.filter((entry) => entry.pid > 1 && existsSync(entry.configDir) && isPidAlive(entry.pid));
|
|
36
|
+
}
|
|
37
|
+
function pruneDeadEffect(entries) {
|
|
38
|
+
return Effect.forEach(entries, (entry) => {
|
|
39
|
+
if (entry.pid <= 1) return Effect.succeed(null);
|
|
40
|
+
return Effect.gen(function* () {
|
|
41
|
+
if (!(yield* Effect.promise(() => access(entry.configDir).then(() => true).catch(() => false)))) return null;
|
|
42
|
+
if (!isPidAlive(entry.pid)) return null;
|
|
43
|
+
return entry;
|
|
44
|
+
});
|
|
45
|
+
}, { concurrency: "unbounded" }).pipe(Effect.map((results) => results.filter((e) => e !== null)));
|
|
46
|
+
}
|
|
47
|
+
function writeRegistry(entries) {
|
|
48
|
+
ensureRegistryDir();
|
|
49
|
+
const path = getRegistryPath();
|
|
50
|
+
const tmpPath = `${path}.tmp`;
|
|
51
|
+
writeFileSync(tmpPath, `${JSON.stringify(entries, null, 2)}\n`);
|
|
52
|
+
renameSync(tmpPath, path);
|
|
53
|
+
}
|
|
54
|
+
function registerStandalone(entry) {
|
|
55
|
+
const live = pruneDead(readRegistry());
|
|
56
|
+
const full = {
|
|
57
|
+
...entry,
|
|
58
|
+
role: "standalone"
|
|
59
|
+
};
|
|
60
|
+
const withoutSelf = live.filter((existing) => existing.pid !== entry.pid);
|
|
61
|
+
withoutSelf.push(full);
|
|
62
|
+
writeRegistry(withoutSelf);
|
|
63
|
+
return full;
|
|
64
|
+
}
|
|
65
|
+
function unregisterPid(pid) {
|
|
66
|
+
const live = pruneDead(readRegistry());
|
|
67
|
+
const next = live.filter((entry) => entry.pid !== pid);
|
|
68
|
+
if (next.length === live.length) return;
|
|
69
|
+
writeRegistry(next);
|
|
70
|
+
}
|
|
71
|
+
function getRegistryPath() {
|
|
72
|
+
return process.env.BO_PID_REGISTRY_PATH ?? join(getRegistryDir(), "pids.json");
|
|
73
|
+
}
|
|
74
|
+
function claimedPorts() {
|
|
75
|
+
const live = pruneDead(readRegistry());
|
|
76
|
+
const out = /* @__PURE__ */ new Set();
|
|
77
|
+
for (const entry of live) for (const port of Object.values(entry.ports)) if (typeof port === "number") out.add(port);
|
|
78
|
+
return out;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
//#endregion
|
|
82
|
+
export { claimedPorts, pruneDeadEffect, readRegistry, registerStandalone, unregisterPid };
|
|
83
|
+
//# sourceMappingURL=process-registry.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-registry.mjs","names":[],"sources":["../src/process-registry.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from \"node:fs\";\nimport { access } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { Effect } from \"effect\";\n\nexport type ProcessRole = \"standalone\" | \"workspace-parent\" | \"workspace-child\";\n\nexport interface PidEntry {\n pid: number;\n configDir: string;\n parentPid?: number;\n role: ProcessRole;\n ports: Record<string, number>;\n budget?: { min: number; max: number };\n startedAt: number;\n description: string;\n}\n\nfunction getRegistryDir(): string {\n return join(homedir(), \".cache\", \"everything-dev\");\n}\n\nfunction ensureRegistryDir(): void {\n const path = getRegistryPath();\n const dir = join(path, \"..\");\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n}\n\nexport function readRegistry(): PidEntry[] {\n const path = getRegistryPath();\n if (!existsSync(path)) return [];\n try {\n const raw = JSON.parse(readFileSync(path, \"utf-8\"));\n if (!Array.isArray(raw)) return [];\n return raw.filter(\n (entry): entry is PidEntry =>\n entry &&\n typeof entry === \"object\" &&\n typeof entry.pid === \"number\" &&\n typeof entry.configDir === \"string\" &&\n typeof entry.role === \"string\",\n );\n } catch {\n return [];\n }\n}\n\nexport function isPidAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (err) {\n return (err as NodeJS.ErrnoException).code !== \"ESRCH\";\n }\n}\n\nexport function pruneDead(entries: PidEntry[]): PidEntry[] {\n return entries.filter(\n (entry) => entry.pid > 1 && existsSync(entry.configDir) && isPidAlive(entry.pid),\n );\n}\n\nexport function pruneDeadEffect(entries: PidEntry[]): Effect.Effect<PidEntry[]> {\n return Effect.forEach(\n entries,\n (entry) => {\n if (entry.pid <= 1) return Effect.succeed(null);\n return Effect.gen(function* () {\n const dirExists = yield* Effect.promise(() =>\n access(entry.configDir)\n .then(() => true)\n .catch(() => false),\n );\n if (!dirExists) return null;\n if (!isPidAlive(entry.pid)) return null;\n return entry;\n });\n },\n { concurrency: \"unbounded\" },\n ).pipe(Effect.map((results) => results.filter((e): e is PidEntry => e !== null)));\n}\n\nexport function writeRegistry(entries: PidEntry[]): void {\n ensureRegistryDir();\n const path = getRegistryPath();\n const tmpPath = `${path}.tmp`;\n writeFileSync(tmpPath, `${JSON.stringify(entries, null, 2)}\\n`);\n renameSync(tmpPath, path);\n}\n\nexport function registerStandalone(entry: Omit<PidEntry, \"role\">): PidEntry {\n const live = pruneDead(readRegistry());\n const full: PidEntry = { ...entry, role: \"standalone\" };\n const withoutSelf = live.filter((existing) => existing.pid !== entry.pid);\n withoutSelf.push(full);\n writeRegistry(withoutSelf);\n return full;\n}\n\nexport function registerEntry(entry: PidEntry): void {\n const live = pruneDead(readRegistry());\n const withoutSelf = live.filter((existing) => existing.pid !== entry.pid);\n withoutSelf.push(entry);\n writeRegistry(withoutSelf);\n}\n\nexport function unregisterPid(pid: number): void {\n const live = pruneDead(readRegistry());\n const next = live.filter((entry) => entry.pid !== pid);\n if (next.length === live.length) return;\n writeRegistry(next);\n}\n\nexport function removeRegistryFile(): void {\n const path = getRegistryPath();\n if (existsSync(path)) {\n rmSync(path, { force: true });\n }\n}\n\nexport function getRegistryPath(): string {\n return process.env.BO_PID_REGISTRY_PATH ?? join(getRegistryDir(), \"pids.json\");\n}\n\nexport function claimedPorts(): Set<number> {\n const live = pruneDead(readRegistry());\n const out = new Set<number>();\n for (const entry of live) {\n for (const port of Object.values(entry.ports)) {\n if (typeof port === \"number\") out.add(port);\n }\n }\n return out;\n}\n"],"mappings":";;;;;;;AAmBA,SAAS,iBAAyB;AAChC,QAAO,KAAK,SAAS,EAAE,UAAU,iBAAiB;;AAGpD,SAAS,oBAA0B;CAEjC,MAAM,MAAM,KADC,iBACQ,EAAE,KAAK;AAC5B,KAAI,CAAC,WAAW,IAAI,CAClB,WAAU,KAAK,EAAE,WAAW,MAAM,CAAC;;AAIvC,SAAgB,eAA2B;CACzC,MAAM,OAAO,iBAAiB;AAC9B,KAAI,CAAC,WAAW,KAAK,CAAE,QAAO,EAAE;AAChC,KAAI;EACF,MAAM,MAAM,KAAK,MAAM,aAAa,MAAM,QAAQ,CAAC;AACnD,MAAI,CAAC,MAAM,QAAQ,IAAI,CAAE,QAAO,EAAE;AAClC,SAAO,IAAI,QACR,UACC,SACA,OAAO,UAAU,YACjB,OAAO,MAAM,QAAQ,YACrB,OAAO,MAAM,cAAc,YAC3B,OAAO,MAAM,SAAS,SACzB;SACK;AACN,SAAO,EAAE;;;AAIb,SAAgB,WAAW,KAAsB;AAC/C,KAAI;AACF,UAAQ,KAAK,KAAK,EAAE;AACpB,SAAO;UACA,KAAK;AACZ,SAAQ,IAA8B,SAAS;;;AAInD,SAAgB,UAAU,SAAiC;AACzD,QAAO,QAAQ,QACZ,UAAU,MAAM,MAAM,KAAK,WAAW,MAAM,UAAU,IAAI,WAAW,MAAM,IAAI,CACjF;;AAGH,SAAgB,gBAAgB,SAAgD;AAC9E,QAAO,OAAO,QACZ,UACC,UAAU;AACT,MAAI,MAAM,OAAO,EAAG,QAAO,OAAO,QAAQ,KAAK;AAC/C,SAAO,OAAO,IAAI,aAAa;AAM7B,OAAI,EAAC,OALoB,OAAO,cAC9B,OAAO,MAAM,UAAU,CACpB,WAAW,KAAK,CAChB,YAAY,MAAM,CACtB,EACe,QAAO;AACvB,OAAI,CAAC,WAAW,MAAM,IAAI,CAAE,QAAO;AACnC,UAAO;IACP;IAEJ,EAAE,aAAa,aAAa,CAC7B,CAAC,KAAK,OAAO,KAAK,YAAY,QAAQ,QAAQ,MAAqB,MAAM,KAAK,CAAC,CAAC;;AAGnF,SAAgB,cAAc,SAA2B;AACvD,oBAAmB;CACnB,MAAM,OAAO,iBAAiB;CAC9B,MAAM,UAAU,GAAG,KAAK;AACxB,eAAc,SAAS,GAAG,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC,IAAI;AAC/D,YAAW,SAAS,KAAK;;AAG3B,SAAgB,mBAAmB,OAAyC;CAC1E,MAAM,OAAO,UAAU,cAAc,CAAC;CACtC,MAAM,OAAiB;EAAE,GAAG;EAAO,MAAM;EAAc;CACvD,MAAM,cAAc,KAAK,QAAQ,aAAa,SAAS,QAAQ,MAAM,IAAI;AACzE,aAAY,KAAK,KAAK;AACtB,eAAc,YAAY;AAC1B,QAAO;;AAUT,SAAgB,cAAc,KAAmB;CAC/C,MAAM,OAAO,UAAU,cAAc,CAAC;CACtC,MAAM,OAAO,KAAK,QAAQ,UAAU,MAAM,QAAQ,IAAI;AACtD,KAAI,KAAK,WAAW,KAAK,OAAQ;AACjC,eAAc,KAAK;;AAUrB,SAAgB,kBAA0B;AACxC,QAAO,QAAQ,IAAI,wBAAwB,KAAK,gBAAgB,EAAE,YAAY;;AAGhF,SAAgB,eAA4B;CAC1C,MAAM,OAAO,UAAU,cAAc,CAAC;CACtC,MAAM,sBAAM,IAAI,KAAa;AAC7B,MAAK,MAAM,SAAS,KAClB,MAAK,MAAM,QAAQ,OAAO,OAAO,MAAM,MAAM,CAC3C,KAAI,OAAO,SAAS,SAAU,KAAI,IAAI,KAAK;AAG/C,QAAO"}
|
package/dist/publish.cjs
CHANGED
|
@@ -206,6 +206,10 @@ async function publishToFastKv(input) {
|
|
|
206
206
|
}
|
|
207
207
|
function formatNearError(error) {
|
|
208
208
|
const message = error instanceof Error ? error.message : String(error);
|
|
209
|
+
if (message.includes("does not have enough allowance")) return `The publish access key has insufficient allowance to cover this transaction.
|
|
210
|
+
Regenerate your key with a higher allowance:
|
|
211
|
+
bos key generate
|
|
212
|
+
Original: ${message}`;
|
|
209
213
|
if (message.includes("exceeded gas") || message.includes("GasLimitExceeded")) return `Transaction exceeded gas limit.\n Original: ${message}`;
|
|
210
214
|
if (message.includes("timeout") || message.includes("Timeout")) return `Transaction timed out. Check NEAR network status.\n Original: ${message}`;
|
|
211
215
|
return message;
|
package/dist/publish.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish.cjs","names":["process","fetchBosConfigFromFastKv","getNetworkIdForAccount","buildRegistryConfigUrlForNetwork","selectWorkspaceTargets","resolveNearSigningMode","Effect","ensureNearCli","generateCodeArtifacts","buildWorkspaceTargets","colors","icons","padRight","loadResolvedConfig","executeTransaction","getRegistryNamespaceForNetwork"],"sources":["../src/publish.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport process from \"node:process\";\nimport { Effect } from \"effect\";\nimport { buildWorkspaceTargets, selectWorkspaceTargets } from \"./build\";\nimport { generateCodeArtifacts } from \"./code-artifacts\";\nimport { loadResolvedConfig } from \"./config\";\nimport type { WorkspaceDeployResult } from \"./contract\";\nimport {\n buildRegistryConfigUrlForNetwork,\n fetchBosConfigFromFastKv,\n getRegistryNamespaceForNetwork,\n} from \"./fastkv\";\nimport { ensureNearCli, executeTransaction, resolveNearSigningMode } from \"./near-cli\";\nimport { getNetworkIdForAccount } from \"./network\";\nimport type { BosConfig, BosConfigInput, RuntimeConfig } from \"./types\";\nimport { padRight } from \"./utils/string\";\nimport { colors, icons } from \"./utils/theme\";\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function extractPublishedUrl(output: string): string | null {\n const deployMatch = output.match(/🚀.*Deployed:\\s*(https?:\\S+)/);\n if (deployMatch) return deployMatch[1];\n const match = output.match(/https?:\\/\\/[^\\s\"'<>]+/g);\n if (!match || match.length === 0) return null;\n return match[match.length - 1] ?? null;\n}\n\nexport async function waitForPublishedConfig(opts: {\n account: string;\n gateway: string;\n publishConfig: BosConfigInput;\n timeoutMs?: number;\n intervalMs?: number;\n}): Promise<void> {\n const envTimeoutMs = Number(process.env.BOS_PUBLISH_CONFIRMATION_TIMEOUT_MS);\n const envIntervalMs = Number(process.env.BOS_PUBLISH_CONFIRMATION_INTERVAL_MS);\n const timeoutMs =\n opts.timeoutMs ?? (Number.isFinite(envTimeoutMs) ? envTimeoutMs : undefined) ?? 120_000;\n const intervalMs =\n opts.intervalMs ?? (Number.isFinite(envIntervalMs) ? envIntervalMs : undefined) ?? 3_000;\n const startedAt = Date.now();\n let lastError: unknown;\n\n while (Date.now() - startedAt < timeoutMs) {\n try {\n const verifiedConfig = await fetchBosConfigFromFastKv<BosConfigInput>(\n `bos://${opts.account}/${opts.gateway}`,\n );\n\n if (JSON.stringify(verifiedConfig) === JSON.stringify(opts.publishConfig)) {\n return;\n }\n } catch (error) {\n lastError = error;\n }\n\n await sleep(intervalMs);\n }\n\n const reason = lastError instanceof Error ? ` Last error: ${lastError.message}` : \"\";\n throw new Error(\n `Timed out waiting for publish confirmation at bos://${opts.account}/${opts.gateway}.${reason}`,\n );\n}\n\ninterface PublishToFastKvInput {\n bosConfig: BosConfig;\n runtimeConfig: RuntimeConfig | null;\n configDir: string;\n env: \"production\" | \"staging\";\n build: boolean;\n dryRun: boolean;\n verbose: boolean;\n packages: string;\n network?: \"mainnet\" | \"testnet\";\n privateKey?: string;\n}\n\ninterface PublishToFastKvResult {\n status: \"published\" | \"error\" | \"dry-run\";\n registryUrl: string;\n txHash?: string;\n built?: string[];\n skipped?: string[];\n error?: string;\n publishConfig?: BosConfigInput;\n deployResults?: WorkspaceDeployResult[];\n}\n\nexport async function publishToFastKv(input: PublishToFastKvInput): Promise<PublishToFastKvResult> {\n const { env, dryRun, configDir } = input;\n let bosConfig = input.bosConfig;\n const runtimeConfig = input.runtimeConfig;\n\n const isStaging = env === \"staging\";\n const account = bosConfig.account;\n const gateway = isStaging ? (bosConfig.staging?.domain ?? bosConfig.domain) : bosConfig.domain;\n if (!gateway) {\n return {\n status: \"error\",\n registryUrl: \"\",\n error: \"bos.config.json must define domain to publish\",\n };\n }\n\n const network = input.network ?? getNetworkIdForAccount(account);\n const registryUrl = buildRegistryConfigUrlForNetwork(network, account, gateway);\n const targets = selectWorkspaceTargets(input.packages, bosConfig);\n\n let built: string[] | undefined;\n let skipped: string[] | undefined;\n let deployResults: WorkspaceDeployResult[] | undefined;\n\n if (dryRun) {\n return { status: \"dry-run\", registryUrl, built, skipped };\n }\n\n const privateKey =\n input.privateKey || process.env.NEAR_PRIVATE_KEY || process.env.BOS_NEAR_PRIVATE_KEY;\n let signingMode: ReturnType<typeof resolveNearSigningMode>;\n try {\n signingMode = resolveNearSigningMode(privateKey);\n } catch (error) {\n return {\n status: \"error\" as const,\n registryUrl,\n error: error instanceof Error ? error.message : \"Unknown error\",\n };\n }\n\n if (input.build) {\n console.log(\" Ensuring NEAR CLI...\");\n await Effect.runPromise(ensureNearCli);\n console.log(\" NEAR CLI ready\");\n\n await generateCodeArtifacts(configDir, bosConfig, {\n env: \"production\",\n runtimeConfig: runtimeConfig ?? undefined,\n });\n\n const result = await buildWorkspaceTargets({\n configDir,\n bosConfig,\n runtimeConfig,\n targets,\n deploy: true,\n verbose: input.verbose,\n });\n built = result.built;\n skipped = result.skipped;\n deployResults = result.deployResults;\n\n if (deployResults) {\n const failures = deployResults.filter((r) => !r.success);\n if (failures.length > 0) {\n const total = deployResults.length;\n console.log();\n console.log(\n colors.error(\n ` ${icons.err} Deploy failed — ${failures.length} of ${total} workspace${total > 1 ? \"s\" : \"\"} failed`,\n ),\n );\n console.log();\n for (const f of failures) {\n const errorLine = (f.error ?? \"Failed\").split(\"\\n\")[0];\n console.log(` ${colors.error(icons.err)} ${padRight(f.key, 28)} ${errorLine}`);\n }\n console.log();\n if (!input.verbose) {\n console.log(colors.dim(\" Run with --verbose for full build output.\"));\n console.log();\n }\n return {\n status: \"error\" as const,\n registryUrl,\n built,\n skipped,\n deployResults,\n error: `${failures.length} of ${total} workspaces failed to deploy`,\n };\n }\n }\n\n const refreshed = await loadResolvedConfig({ cwd: configDir });\n if (!refreshed?.config) {\n return {\n status: \"error\",\n registryUrl,\n built,\n skipped,\n deployResults,\n error: \"Failed to reload bos.config.json after build\",\n };\n }\n\n bosConfig = refreshed.config;\n }\n\n const rawConfigPath = join(configDir, \"bos.config.json\");\n const rawConfig = JSON.parse(readFileSync(rawConfigPath, \"utf-8\")) as BosConfigInput;\n const publishPayload: BosConfigInput = isStaging ? { ...rawConfig, domain: gateway } : rawConfig;\n\n const registryEntries: Record<string, string> = {\n [`apps/${account}/${gateway}/bos.config.json`]: JSON.stringify(publishPayload),\n };\n\n const payload = JSON.stringify(registryEntries);\n const argsBase64 = Buffer.from(payload).toString(\"base64\");\n\n console.log();\n console.log(\" Publishing to:\");\n console.log(` ${colors.cyan(registryUrl)}`);\n\n try {\n let txHash: string | undefined;\n\n console.log(` Submitting transaction on ${network}...`);\n\n try {\n const tx = await Effect.runPromise(\n executeTransaction(\n {\n account,\n contract: getRegistryNamespaceForNetwork(network),\n method: \"__fastdata_kv\",\n argsBase64,\n network,\n privateKey: signingMode._tag === \"privateKey\" ? signingMode.privateKey : undefined,\n gas: \"300Tgas\",\n deposit: \"0NEAR\",\n verbose: input.verbose,\n },\n signingMode,\n ),\n );\n txHash = tx.txHash;\n if (txHash && !tx.output?.includes(\"CodeDoesNotExist\")) {\n console.log(` Transaction submitted: ${colors.dim(txHash)}`);\n }\n } catch (error) {\n console.log(colors.dim(\" Transaction reported an error — verifying publish...\"));\n try {\n await waitForPublishedConfig({\n account,\n gateway,\n publishConfig: publishPayload,\n timeoutMs: 30_000,\n intervalMs: 2_000,\n });\n txHash = extractTransactionHash(error);\n } catch {\n throw error;\n }\n }\n\n console.log(\" Waiting for publish confirmation...\");\n await waitForPublishedConfig({\n account,\n gateway,\n publishConfig: publishPayload,\n });\n\n return {\n status: \"published\",\n registryUrl,\n txHash,\n built,\n skipped,\n deployResults,\n publishConfig: publishPayload,\n };\n } catch (error) {\n return {\n status: \"error\",\n registryUrl,\n error: formatNearError(error),\n built,\n skipped,\n deployResults,\n };\n }\n}\n\nfunction formatNearError(error: unknown): string {\n const message = error instanceof Error ? error.message : String(error);\n\n if (message.includes(\"exceeded gas\") || message.includes(\"GasLimitExceeded\")) {\n return `Transaction exceeded gas limit.\\n Original: ${message}`;\n }\n\n if (message.includes(\"timeout\") || message.includes(\"Timeout\")) {\n return `Transaction timed out. Check NEAR network status.\\n Original: ${message}`;\n }\n\n return message;\n}\n\nfunction extractTransactionHash(error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n const match = message.match(/Transaction ID:\\s*([A-Za-z0-9]+)/i);\n return match?.[1];\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAmBA,SAAS,MAAM,IAA2B;AACxC,QAAO,IAAI,SAAS,YAAY,WAAW,SAAS,GAAG,CAAC;;AAG1D,SAAgB,oBAAoB,QAA+B;CACjE,MAAM,cAAc,OAAO,MAAM,+BAA+B;AAChE,KAAI,YAAa,QAAO,YAAY;CACpC,MAAM,QAAQ,OAAO,MAAM,yBAAyB;AACpD,KAAI,CAAC,SAAS,MAAM,WAAW,EAAG,QAAO;AACzC,QAAO,MAAM,MAAM,SAAS,MAAM;;AAGpC,eAAsB,uBAAuB,MAM3B;CAChB,MAAM,eAAe,OAAOA,qBAAQ,IAAI,oCAAoC;CAC5E,MAAM,gBAAgB,OAAOA,qBAAQ,IAAI,qCAAqC;CAC9E,MAAM,YACJ,KAAK,cAAc,OAAO,SAAS,aAAa,GAAG,eAAe,WAAc;CAClF,MAAM,aACJ,KAAK,eAAe,OAAO,SAAS,cAAc,GAAG,gBAAgB,WAAc;CACrF,MAAM,YAAY,KAAK,KAAK;CAC5B,IAAI;AAEJ,QAAO,KAAK,KAAK,GAAG,YAAY,WAAW;AACzC,MAAI;GACF,MAAM,iBAAiB,MAAMC,wCAC3B,SAAS,KAAK,QAAQ,GAAG,KAAK,UAC/B;AAED,OAAI,KAAK,UAAU,eAAe,KAAK,KAAK,UAAU,KAAK,cAAc,CACvE;WAEK,OAAO;AACd,eAAY;;AAGd,QAAM,MAAM,WAAW;;CAGzB,MAAM,SAAS,qBAAqB,QAAQ,gBAAgB,UAAU,YAAY;AAClF,OAAM,IAAI,MACR,uDAAuD,KAAK,QAAQ,GAAG,KAAK,QAAQ,GAAG,SACxF;;AA2BH,eAAsB,gBAAgB,OAA6D;CACjG,MAAM,EAAE,KAAK,QAAQ,cAAc;CACnC,IAAI,YAAY,MAAM;CACtB,MAAM,gBAAgB,MAAM;CAE5B,MAAM,YAAY,QAAQ;CAC1B,MAAM,UAAU,UAAU;CAC1B,MAAM,UAAU,YAAa,UAAU,SAAS,UAAU,UAAU,SAAU,UAAU;AACxF,KAAI,CAAC,QACH,QAAO;EACL,QAAQ;EACR,aAAa;EACb,OAAO;EACR;CAGH,MAAM,UAAU,MAAM,WAAWC,uCAAuB,QAAQ;CAChE,MAAM,cAAcC,gDAAiC,SAAS,SAAS,QAAQ;CAC/E,MAAM,UAAUC,qCAAuB,MAAM,UAAU,UAAU;CAEjE,IAAI;CACJ,IAAI;CACJ,IAAI;AAEJ,KAAI,OACF,QAAO;EAAE,QAAQ;EAAW;EAAa;EAAO;EAAS;CAG3D,MAAM,aACJ,MAAM,cAAcJ,qBAAQ,IAAI,oBAAoBA,qBAAQ,IAAI;CAClE,IAAI;AACJ,KAAI;AACF,gBAAcK,wCAAuB,WAAW;UACzC,OAAO;AACd,SAAO;GACL,QAAQ;GACR;GACA,OAAO,iBAAiB,QAAQ,MAAM,UAAU;GACjD;;AAGH,KAAI,MAAM,OAAO;AACf,UAAQ,IAAI,yBAAyB;AACrC,QAAMC,cAAO,WAAWC,+BAAc;AACtC,UAAQ,IAAI,mBAAmB;AAE/B,QAAMC,6CAAsB,WAAW,WAAW;GAChD,KAAK;GACL,eAAe,iBAAiB;GACjC,CAAC;EAEF,MAAM,SAAS,MAAMC,oCAAsB;GACzC;GACA;GACA;GACA;GACA,QAAQ;GACR,SAAS,MAAM;GAChB,CAAC;AACF,UAAQ,OAAO;AACf,YAAU,OAAO;AACjB,kBAAgB,OAAO;AAEvB,MAAI,eAAe;GACjB,MAAM,WAAW,cAAc,QAAQ,MAAM,CAAC,EAAE,QAAQ;AACxD,OAAI,SAAS,SAAS,GAAG;IACvB,MAAM,QAAQ,cAAc;AAC5B,YAAQ,KAAK;AACb,YAAQ,IACNC,qBAAO,MACL,KAAKC,oBAAM,IAAI,mBAAmB,SAAS,OAAO,MAAM,MAAM,YAAY,QAAQ,IAAI,MAAM,GAAG,SAChG,CACF;AACD,YAAQ,KAAK;AACb,SAAK,MAAM,KAAK,UAAU;KACxB,MAAM,aAAa,EAAE,SAAS,UAAU,MAAM,KAAK,CAAC;AACpD,aAAQ,IAAI,OAAOD,qBAAO,MAAMC,oBAAM,IAAI,CAAC,GAAGC,wBAAS,EAAE,KAAK,GAAG,CAAC,GAAG,YAAY;;AAEnF,YAAQ,KAAK;AACb,QAAI,CAAC,MAAM,SAAS;AAClB,aAAQ,IAAIF,qBAAO,IAAI,8CAA8C,CAAC;AACtE,aAAQ,KAAK;;AAEf,WAAO;KACL,QAAQ;KACR;KACA;KACA;KACA;KACA,OAAO,GAAG,SAAS,OAAO,MAAM,MAAM;KACvC;;;EAIL,MAAM,YAAY,MAAMG,kCAAmB,EAAE,KAAK,WAAW,CAAC;AAC9D,MAAI,CAAC,WAAW,OACd,QAAO;GACL,QAAQ;GACR;GACA;GACA;GACA;GACA,OAAO;GACR;AAGH,cAAY,UAAU;;CAGxB,MAAM,oCAAqB,WAAW,kBAAkB;CACxD,MAAM,YAAY,KAAK,gCAAmB,eAAe,QAAQ,CAAC;CAClE,MAAM,iBAAiC,YAAY;EAAE,GAAG;EAAW,QAAQ;EAAS,GAAG;CAEvF,MAAM,kBAA0C,GAC7C,QAAQ,QAAQ,GAAG,QAAQ,oBAAoB,KAAK,UAAU,eAAe,EAC/E;CAED,MAAM,UAAU,KAAK,UAAU,gBAAgB;CAC/C,MAAM,aAAa,OAAO,KAAK,QAAQ,CAAC,SAAS,SAAS;AAE1D,SAAQ,KAAK;AACb,SAAQ,IAAI,mBAAmB;AAC/B,SAAQ,IAAI,OAAOH,qBAAO,KAAK,YAAY,GAAG;AAE9C,KAAI;EACF,IAAI;AAEJ,UAAQ,IAAI,+BAA+B,QAAQ,KAAK;AAExD,MAAI;GACF,MAAM,KAAK,MAAMJ,cAAO,WACtBQ,oCACE;IACE;IACA,UAAUC,8CAA+B,QAAQ;IACjD,QAAQ;IACR;IACA;IACA,YAAY,YAAY,SAAS,eAAe,YAAY,aAAa;IACzE,KAAK;IACL,SAAS;IACT,SAAS,MAAM;IAChB,EACD,YACD,CACF;AACD,YAAS,GAAG;AACZ,OAAI,UAAU,CAAC,GAAG,QAAQ,SAAS,mBAAmB,CACpD,SAAQ,IAAI,4BAA4BL,qBAAO,IAAI,OAAO,GAAG;WAExD,OAAO;AACd,WAAQ,IAAIA,qBAAO,IAAI,yDAAyD,CAAC;AACjF,OAAI;AACF,UAAM,uBAAuB;KAC3B;KACA;KACA,eAAe;KACf,WAAW;KACX,YAAY;KACb,CAAC;AACF,aAAS,uBAAuB,MAAM;WAChC;AACN,UAAM;;;AAIV,UAAQ,IAAI,wCAAwC;AACpD,QAAM,uBAAuB;GAC3B;GACA;GACA,eAAe;GAChB,CAAC;AAEF,SAAO;GACL,QAAQ;GACR;GACA;GACA;GACA;GACA;GACA,eAAe;GAChB;UACM,OAAO;AACd,SAAO;GACL,QAAQ;GACR;GACA,OAAO,gBAAgB,MAAM;GAC7B;GACA;GACA;GACD;;;AAIL,SAAS,gBAAgB,OAAwB;CAC/C,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAEtE,KAAI,QAAQ,SAAS,eAAe,IAAI,QAAQ,SAAS,mBAAmB,CAC1E,QAAO,gDAAgD;AAGzD,KAAI,QAAQ,SAAS,UAAU,IAAI,QAAQ,SAAS,UAAU,CAC5D,QAAO,kEAAkE;AAG3E,QAAO;;AAGT,SAAS,uBAAuB,OAAgB;AAG9C,SAFgB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,EAChD,MAAM,oCAChB,GAAG"}
|
|
1
|
+
{"version":3,"file":"publish.cjs","names":["process","fetchBosConfigFromFastKv","getNetworkIdForAccount","buildRegistryConfigUrlForNetwork","selectWorkspaceTargets","resolveNearSigningMode","Effect","ensureNearCli","generateCodeArtifacts","buildWorkspaceTargets","colors","icons","padRight","loadResolvedConfig","executeTransaction","getRegistryNamespaceForNetwork"],"sources":["../src/publish.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport process from \"node:process\";\nimport { Effect } from \"effect\";\nimport { buildWorkspaceTargets, selectWorkspaceTargets } from \"./build\";\nimport { generateCodeArtifacts } from \"./code-artifacts\";\nimport { loadResolvedConfig } from \"./config\";\nimport type { WorkspaceDeployResult } from \"./contract\";\nimport {\n buildRegistryConfigUrlForNetwork,\n fetchBosConfigFromFastKv,\n getRegistryNamespaceForNetwork,\n} from \"./fastkv\";\nimport { ensureNearCli, executeTransaction, resolveNearSigningMode } from \"./near-cli\";\nimport { getNetworkIdForAccount } from \"./network\";\nimport type { BosConfig, BosConfigInput, RuntimeConfig } from \"./types\";\nimport { padRight } from \"./utils/string\";\nimport { colors, icons } from \"./utils/theme\";\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function extractPublishedUrl(output: string): string | null {\n const deployMatch = output.match(/🚀.*Deployed:\\s*(https?:\\S+)/);\n if (deployMatch) return deployMatch[1];\n const match = output.match(/https?:\\/\\/[^\\s\"'<>]+/g);\n if (!match || match.length === 0) return null;\n return match[match.length - 1] ?? null;\n}\n\nexport async function waitForPublishedConfig(opts: {\n account: string;\n gateway: string;\n publishConfig: BosConfigInput;\n timeoutMs?: number;\n intervalMs?: number;\n}): Promise<void> {\n const envTimeoutMs = Number(process.env.BOS_PUBLISH_CONFIRMATION_TIMEOUT_MS);\n const envIntervalMs = Number(process.env.BOS_PUBLISH_CONFIRMATION_INTERVAL_MS);\n const timeoutMs =\n opts.timeoutMs ?? (Number.isFinite(envTimeoutMs) ? envTimeoutMs : undefined) ?? 120_000;\n const intervalMs =\n opts.intervalMs ?? (Number.isFinite(envIntervalMs) ? envIntervalMs : undefined) ?? 3_000;\n const startedAt = Date.now();\n let lastError: unknown;\n\n while (Date.now() - startedAt < timeoutMs) {\n try {\n const verifiedConfig = await fetchBosConfigFromFastKv<BosConfigInput>(\n `bos://${opts.account}/${opts.gateway}`,\n );\n\n if (JSON.stringify(verifiedConfig) === JSON.stringify(opts.publishConfig)) {\n return;\n }\n } catch (error) {\n lastError = error;\n }\n\n await sleep(intervalMs);\n }\n\n const reason = lastError instanceof Error ? ` Last error: ${lastError.message}` : \"\";\n throw new Error(\n `Timed out waiting for publish confirmation at bos://${opts.account}/${opts.gateway}.${reason}`,\n );\n}\n\ninterface PublishToFastKvInput {\n bosConfig: BosConfig;\n runtimeConfig: RuntimeConfig | null;\n configDir: string;\n env: \"production\" | \"staging\";\n build: boolean;\n dryRun: boolean;\n verbose: boolean;\n packages: string;\n network?: \"mainnet\" | \"testnet\";\n privateKey?: string;\n}\n\ninterface PublishToFastKvResult {\n status: \"published\" | \"error\" | \"dry-run\";\n registryUrl: string;\n txHash?: string;\n built?: string[];\n skipped?: string[];\n error?: string;\n publishConfig?: BosConfigInput;\n deployResults?: WorkspaceDeployResult[];\n}\n\nexport async function publishToFastKv(input: PublishToFastKvInput): Promise<PublishToFastKvResult> {\n const { env, dryRun, configDir } = input;\n let bosConfig = input.bosConfig;\n const runtimeConfig = input.runtimeConfig;\n\n const isStaging = env === \"staging\";\n const account = bosConfig.account;\n const gateway = isStaging ? (bosConfig.staging?.domain ?? bosConfig.domain) : bosConfig.domain;\n if (!gateway) {\n return {\n status: \"error\",\n registryUrl: \"\",\n error: \"bos.config.json must define domain to publish\",\n };\n }\n\n const network = input.network ?? getNetworkIdForAccount(account);\n const registryUrl = buildRegistryConfigUrlForNetwork(network, account, gateway);\n const targets = selectWorkspaceTargets(input.packages, bosConfig);\n\n let built: string[] | undefined;\n let skipped: string[] | undefined;\n let deployResults: WorkspaceDeployResult[] | undefined;\n\n if (dryRun) {\n return { status: \"dry-run\", registryUrl, built, skipped };\n }\n\n const privateKey =\n input.privateKey || process.env.NEAR_PRIVATE_KEY || process.env.BOS_NEAR_PRIVATE_KEY;\n let signingMode: ReturnType<typeof resolveNearSigningMode>;\n try {\n signingMode = resolveNearSigningMode(privateKey);\n } catch (error) {\n return {\n status: \"error\" as const,\n registryUrl,\n error: error instanceof Error ? error.message : \"Unknown error\",\n };\n }\n\n if (input.build) {\n console.log(\" Ensuring NEAR CLI...\");\n await Effect.runPromise(ensureNearCli);\n console.log(\" NEAR CLI ready\");\n\n await generateCodeArtifacts(configDir, bosConfig, {\n env: \"production\",\n runtimeConfig: runtimeConfig ?? undefined,\n });\n\n const result = await buildWorkspaceTargets({\n configDir,\n bosConfig,\n runtimeConfig,\n targets,\n deploy: true,\n verbose: input.verbose,\n });\n built = result.built;\n skipped = result.skipped;\n deployResults = result.deployResults;\n\n if (deployResults) {\n const failures = deployResults.filter((r) => !r.success);\n if (failures.length > 0) {\n const total = deployResults.length;\n console.log();\n console.log(\n colors.error(\n ` ${icons.err} Deploy failed — ${failures.length} of ${total} workspace${total > 1 ? \"s\" : \"\"} failed`,\n ),\n );\n console.log();\n for (const f of failures) {\n const errorLine = (f.error ?? \"Failed\").split(\"\\n\")[0];\n console.log(` ${colors.error(icons.err)} ${padRight(f.key, 28)} ${errorLine}`);\n }\n console.log();\n if (!input.verbose) {\n console.log(colors.dim(\" Run with --verbose for full build output.\"));\n console.log();\n }\n return {\n status: \"error\" as const,\n registryUrl,\n built,\n skipped,\n deployResults,\n error: `${failures.length} of ${total} workspaces failed to deploy`,\n };\n }\n }\n\n const refreshed = await loadResolvedConfig({ cwd: configDir });\n if (!refreshed?.config) {\n return {\n status: \"error\",\n registryUrl,\n built,\n skipped,\n deployResults,\n error: \"Failed to reload bos.config.json after build\",\n };\n }\n\n bosConfig = refreshed.config;\n }\n\n const rawConfigPath = join(configDir, \"bos.config.json\");\n const rawConfig = JSON.parse(readFileSync(rawConfigPath, \"utf-8\")) as BosConfigInput;\n const publishPayload: BosConfigInput = isStaging ? { ...rawConfig, domain: gateway } : rawConfig;\n\n const registryEntries: Record<string, string> = {\n [`apps/${account}/${gateway}/bos.config.json`]: JSON.stringify(publishPayload),\n };\n\n const payload = JSON.stringify(registryEntries);\n const argsBase64 = Buffer.from(payload).toString(\"base64\");\n\n console.log();\n console.log(\" Publishing to:\");\n console.log(` ${colors.cyan(registryUrl)}`);\n\n try {\n let txHash: string | undefined;\n\n console.log(` Submitting transaction on ${network}...`);\n\n try {\n const tx = await Effect.runPromise(\n executeTransaction(\n {\n account,\n contract: getRegistryNamespaceForNetwork(network),\n method: \"__fastdata_kv\",\n argsBase64,\n network,\n privateKey: signingMode._tag === \"privateKey\" ? signingMode.privateKey : undefined,\n gas: \"300Tgas\",\n deposit: \"0NEAR\",\n verbose: input.verbose,\n },\n signingMode,\n ),\n );\n txHash = tx.txHash;\n if (txHash && !tx.output?.includes(\"CodeDoesNotExist\")) {\n console.log(` Transaction submitted: ${colors.dim(txHash)}`);\n }\n } catch (error) {\n console.log(colors.dim(\" Transaction reported an error — verifying publish...\"));\n try {\n await waitForPublishedConfig({\n account,\n gateway,\n publishConfig: publishPayload,\n timeoutMs: 30_000,\n intervalMs: 2_000,\n });\n txHash = extractTransactionHash(error);\n } catch {\n throw error;\n }\n }\n\n console.log(\" Waiting for publish confirmation...\");\n await waitForPublishedConfig({\n account,\n gateway,\n publishConfig: publishPayload,\n });\n\n return {\n status: \"published\",\n registryUrl,\n txHash,\n built,\n skipped,\n deployResults,\n publishConfig: publishPayload,\n };\n } catch (error) {\n return {\n status: \"error\",\n registryUrl,\n error: formatNearError(error),\n built,\n skipped,\n deployResults,\n };\n }\n}\n\nfunction formatNearError(error: unknown): string {\n const message = error instanceof Error ? error.message : String(error);\n\n if (message.includes(\"does not have enough allowance\")) {\n return (\n \"The publish access key has insufficient allowance to cover this transaction.\\n\" +\n \" Regenerate your key with a higher allowance:\\n\" +\n \" bos key generate\\n\" +\n ` Original: ${message}`\n );\n }\n\n if (message.includes(\"exceeded gas\") || message.includes(\"GasLimitExceeded\")) {\n return `Transaction exceeded gas limit.\\n Original: ${message}`;\n }\n\n if (message.includes(\"timeout\") || message.includes(\"Timeout\")) {\n return `Transaction timed out. Check NEAR network status.\\n Original: ${message}`;\n }\n\n return message;\n}\n\nfunction extractTransactionHash(error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n const match = message.match(/Transaction ID:\\s*([A-Za-z0-9]+)/i);\n return match?.[1];\n}\n"],"mappings":"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"}
|
package/dist/publish.mjs
CHANGED
|
@@ -204,6 +204,10 @@ async function publishToFastKv(input) {
|
|
|
204
204
|
}
|
|
205
205
|
function formatNearError(error) {
|
|
206
206
|
const message = error instanceof Error ? error.message : String(error);
|
|
207
|
+
if (message.includes("does not have enough allowance")) return `The publish access key has insufficient allowance to cover this transaction.
|
|
208
|
+
Regenerate your key with a higher allowance:
|
|
209
|
+
bos key generate
|
|
210
|
+
Original: ${message}`;
|
|
207
211
|
if (message.includes("exceeded gas") || message.includes("GasLimitExceeded")) return `Transaction exceeded gas limit.\n Original: ${message}`;
|
|
208
212
|
if (message.includes("timeout") || message.includes("Timeout")) return `Transaction timed out. Check NEAR network status.\n Original: ${message}`;
|
|
209
213
|
return message;
|
package/dist/publish.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish.mjs","names":[],"sources":["../src/publish.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport process from \"node:process\";\nimport { Effect } from \"effect\";\nimport { buildWorkspaceTargets, selectWorkspaceTargets } from \"./build\";\nimport { generateCodeArtifacts } from \"./code-artifacts\";\nimport { loadResolvedConfig } from \"./config\";\nimport type { WorkspaceDeployResult } from \"./contract\";\nimport {\n buildRegistryConfigUrlForNetwork,\n fetchBosConfigFromFastKv,\n getRegistryNamespaceForNetwork,\n} from \"./fastkv\";\nimport { ensureNearCli, executeTransaction, resolveNearSigningMode } from \"./near-cli\";\nimport { getNetworkIdForAccount } from \"./network\";\nimport type { BosConfig, BosConfigInput, RuntimeConfig } from \"./types\";\nimport { padRight } from \"./utils/string\";\nimport { colors, icons } from \"./utils/theme\";\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function extractPublishedUrl(output: string): string | null {\n const deployMatch = output.match(/🚀.*Deployed:\\s*(https?:\\S+)/);\n if (deployMatch) return deployMatch[1];\n const match = output.match(/https?:\\/\\/[^\\s\"'<>]+/g);\n if (!match || match.length === 0) return null;\n return match[match.length - 1] ?? null;\n}\n\nexport async function waitForPublishedConfig(opts: {\n account: string;\n gateway: string;\n publishConfig: BosConfigInput;\n timeoutMs?: number;\n intervalMs?: number;\n}): Promise<void> {\n const envTimeoutMs = Number(process.env.BOS_PUBLISH_CONFIRMATION_TIMEOUT_MS);\n const envIntervalMs = Number(process.env.BOS_PUBLISH_CONFIRMATION_INTERVAL_MS);\n const timeoutMs =\n opts.timeoutMs ?? (Number.isFinite(envTimeoutMs) ? envTimeoutMs : undefined) ?? 120_000;\n const intervalMs =\n opts.intervalMs ?? (Number.isFinite(envIntervalMs) ? envIntervalMs : undefined) ?? 3_000;\n const startedAt = Date.now();\n let lastError: unknown;\n\n while (Date.now() - startedAt < timeoutMs) {\n try {\n const verifiedConfig = await fetchBosConfigFromFastKv<BosConfigInput>(\n `bos://${opts.account}/${opts.gateway}`,\n );\n\n if (JSON.stringify(verifiedConfig) === JSON.stringify(opts.publishConfig)) {\n return;\n }\n } catch (error) {\n lastError = error;\n }\n\n await sleep(intervalMs);\n }\n\n const reason = lastError instanceof Error ? ` Last error: ${lastError.message}` : \"\";\n throw new Error(\n `Timed out waiting for publish confirmation at bos://${opts.account}/${opts.gateway}.${reason}`,\n );\n}\n\ninterface PublishToFastKvInput {\n bosConfig: BosConfig;\n runtimeConfig: RuntimeConfig | null;\n configDir: string;\n env: \"production\" | \"staging\";\n build: boolean;\n dryRun: boolean;\n verbose: boolean;\n packages: string;\n network?: \"mainnet\" | \"testnet\";\n privateKey?: string;\n}\n\ninterface PublishToFastKvResult {\n status: \"published\" | \"error\" | \"dry-run\";\n registryUrl: string;\n txHash?: string;\n built?: string[];\n skipped?: string[];\n error?: string;\n publishConfig?: BosConfigInput;\n deployResults?: WorkspaceDeployResult[];\n}\n\nexport async function publishToFastKv(input: PublishToFastKvInput): Promise<PublishToFastKvResult> {\n const { env, dryRun, configDir } = input;\n let bosConfig = input.bosConfig;\n const runtimeConfig = input.runtimeConfig;\n\n const isStaging = env === \"staging\";\n const account = bosConfig.account;\n const gateway = isStaging ? (bosConfig.staging?.domain ?? bosConfig.domain) : bosConfig.domain;\n if (!gateway) {\n return {\n status: \"error\",\n registryUrl: \"\",\n error: \"bos.config.json must define domain to publish\",\n };\n }\n\n const network = input.network ?? getNetworkIdForAccount(account);\n const registryUrl = buildRegistryConfigUrlForNetwork(network, account, gateway);\n const targets = selectWorkspaceTargets(input.packages, bosConfig);\n\n let built: string[] | undefined;\n let skipped: string[] | undefined;\n let deployResults: WorkspaceDeployResult[] | undefined;\n\n if (dryRun) {\n return { status: \"dry-run\", registryUrl, built, skipped };\n }\n\n const privateKey =\n input.privateKey || process.env.NEAR_PRIVATE_KEY || process.env.BOS_NEAR_PRIVATE_KEY;\n let signingMode: ReturnType<typeof resolveNearSigningMode>;\n try {\n signingMode = resolveNearSigningMode(privateKey);\n } catch (error) {\n return {\n status: \"error\" as const,\n registryUrl,\n error: error instanceof Error ? error.message : \"Unknown error\",\n };\n }\n\n if (input.build) {\n console.log(\" Ensuring NEAR CLI...\");\n await Effect.runPromise(ensureNearCli);\n console.log(\" NEAR CLI ready\");\n\n await generateCodeArtifacts(configDir, bosConfig, {\n env: \"production\",\n runtimeConfig: runtimeConfig ?? undefined,\n });\n\n const result = await buildWorkspaceTargets({\n configDir,\n bosConfig,\n runtimeConfig,\n targets,\n deploy: true,\n verbose: input.verbose,\n });\n built = result.built;\n skipped = result.skipped;\n deployResults = result.deployResults;\n\n if (deployResults) {\n const failures = deployResults.filter((r) => !r.success);\n if (failures.length > 0) {\n const total = deployResults.length;\n console.log();\n console.log(\n colors.error(\n ` ${icons.err} Deploy failed — ${failures.length} of ${total} workspace${total > 1 ? \"s\" : \"\"} failed`,\n ),\n );\n console.log();\n for (const f of failures) {\n const errorLine = (f.error ?? \"Failed\").split(\"\\n\")[0];\n console.log(` ${colors.error(icons.err)} ${padRight(f.key, 28)} ${errorLine}`);\n }\n console.log();\n if (!input.verbose) {\n console.log(colors.dim(\" Run with --verbose for full build output.\"));\n console.log();\n }\n return {\n status: \"error\" as const,\n registryUrl,\n built,\n skipped,\n deployResults,\n error: `${failures.length} of ${total} workspaces failed to deploy`,\n };\n }\n }\n\n const refreshed = await loadResolvedConfig({ cwd: configDir });\n if (!refreshed?.config) {\n return {\n status: \"error\",\n registryUrl,\n built,\n skipped,\n deployResults,\n error: \"Failed to reload bos.config.json after build\",\n };\n }\n\n bosConfig = refreshed.config;\n }\n\n const rawConfigPath = join(configDir, \"bos.config.json\");\n const rawConfig = JSON.parse(readFileSync(rawConfigPath, \"utf-8\")) as BosConfigInput;\n const publishPayload: BosConfigInput = isStaging ? { ...rawConfig, domain: gateway } : rawConfig;\n\n const registryEntries: Record<string, string> = {\n [`apps/${account}/${gateway}/bos.config.json`]: JSON.stringify(publishPayload),\n };\n\n const payload = JSON.stringify(registryEntries);\n const argsBase64 = Buffer.from(payload).toString(\"base64\");\n\n console.log();\n console.log(\" Publishing to:\");\n console.log(` ${colors.cyan(registryUrl)}`);\n\n try {\n let txHash: string | undefined;\n\n console.log(` Submitting transaction on ${network}...`);\n\n try {\n const tx = await Effect.runPromise(\n executeTransaction(\n {\n account,\n contract: getRegistryNamespaceForNetwork(network),\n method: \"__fastdata_kv\",\n argsBase64,\n network,\n privateKey: signingMode._tag === \"privateKey\" ? signingMode.privateKey : undefined,\n gas: \"300Tgas\",\n deposit: \"0NEAR\",\n verbose: input.verbose,\n },\n signingMode,\n ),\n );\n txHash = tx.txHash;\n if (txHash && !tx.output?.includes(\"CodeDoesNotExist\")) {\n console.log(` Transaction submitted: ${colors.dim(txHash)}`);\n }\n } catch (error) {\n console.log(colors.dim(\" Transaction reported an error — verifying publish...\"));\n try {\n await waitForPublishedConfig({\n account,\n gateway,\n publishConfig: publishPayload,\n timeoutMs: 30_000,\n intervalMs: 2_000,\n });\n txHash = extractTransactionHash(error);\n } catch {\n throw error;\n }\n }\n\n console.log(\" Waiting for publish confirmation...\");\n await waitForPublishedConfig({\n account,\n gateway,\n publishConfig: publishPayload,\n });\n\n return {\n status: \"published\",\n registryUrl,\n txHash,\n built,\n skipped,\n deployResults,\n publishConfig: publishPayload,\n };\n } catch (error) {\n return {\n status: \"error\",\n registryUrl,\n error: formatNearError(error),\n built,\n skipped,\n deployResults,\n };\n }\n}\n\nfunction formatNearError(error: unknown): string {\n const message = error instanceof Error ? error.message : String(error);\n\n if (message.includes(\"exceeded gas\") || message.includes(\"GasLimitExceeded\")) {\n return `Transaction exceeded gas limit.\\n Original: ${message}`;\n }\n\n if (message.includes(\"timeout\") || message.includes(\"Timeout\")) {\n return `Transaction timed out. Check NEAR network status.\\n Original: ${message}`;\n }\n\n return message;\n}\n\nfunction extractTransactionHash(error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n const match = message.match(/Transaction ID:\\s*([A-Za-z0-9]+)/i);\n return match?.[1];\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"publish.mjs","names":[],"sources":["../src/publish.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport process from \"node:process\";\nimport { Effect } from \"effect\";\nimport { buildWorkspaceTargets, selectWorkspaceTargets } from \"./build\";\nimport { generateCodeArtifacts } from \"./code-artifacts\";\nimport { loadResolvedConfig } from \"./config\";\nimport type { WorkspaceDeployResult } from \"./contract\";\nimport {\n buildRegistryConfigUrlForNetwork,\n fetchBosConfigFromFastKv,\n getRegistryNamespaceForNetwork,\n} from \"./fastkv\";\nimport { ensureNearCli, executeTransaction, resolveNearSigningMode } from \"./near-cli\";\nimport { getNetworkIdForAccount } from \"./network\";\nimport type { BosConfig, BosConfigInput, RuntimeConfig } from \"./types\";\nimport { padRight } from \"./utils/string\";\nimport { colors, icons } from \"./utils/theme\";\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function extractPublishedUrl(output: string): string | null {\n const deployMatch = output.match(/🚀.*Deployed:\\s*(https?:\\S+)/);\n if (deployMatch) return deployMatch[1];\n const match = output.match(/https?:\\/\\/[^\\s\"'<>]+/g);\n if (!match || match.length === 0) return null;\n return match[match.length - 1] ?? null;\n}\n\nexport async function waitForPublishedConfig(opts: {\n account: string;\n gateway: string;\n publishConfig: BosConfigInput;\n timeoutMs?: number;\n intervalMs?: number;\n}): Promise<void> {\n const envTimeoutMs = Number(process.env.BOS_PUBLISH_CONFIRMATION_TIMEOUT_MS);\n const envIntervalMs = Number(process.env.BOS_PUBLISH_CONFIRMATION_INTERVAL_MS);\n const timeoutMs =\n opts.timeoutMs ?? (Number.isFinite(envTimeoutMs) ? envTimeoutMs : undefined) ?? 120_000;\n const intervalMs =\n opts.intervalMs ?? (Number.isFinite(envIntervalMs) ? envIntervalMs : undefined) ?? 3_000;\n const startedAt = Date.now();\n let lastError: unknown;\n\n while (Date.now() - startedAt < timeoutMs) {\n try {\n const verifiedConfig = await fetchBosConfigFromFastKv<BosConfigInput>(\n `bos://${opts.account}/${opts.gateway}`,\n );\n\n if (JSON.stringify(verifiedConfig) === JSON.stringify(opts.publishConfig)) {\n return;\n }\n } catch (error) {\n lastError = error;\n }\n\n await sleep(intervalMs);\n }\n\n const reason = lastError instanceof Error ? ` Last error: ${lastError.message}` : \"\";\n throw new Error(\n `Timed out waiting for publish confirmation at bos://${opts.account}/${opts.gateway}.${reason}`,\n );\n}\n\ninterface PublishToFastKvInput {\n bosConfig: BosConfig;\n runtimeConfig: RuntimeConfig | null;\n configDir: string;\n env: \"production\" | \"staging\";\n build: boolean;\n dryRun: boolean;\n verbose: boolean;\n packages: string;\n network?: \"mainnet\" | \"testnet\";\n privateKey?: string;\n}\n\ninterface PublishToFastKvResult {\n status: \"published\" | \"error\" | \"dry-run\";\n registryUrl: string;\n txHash?: string;\n built?: string[];\n skipped?: string[];\n error?: string;\n publishConfig?: BosConfigInput;\n deployResults?: WorkspaceDeployResult[];\n}\n\nexport async function publishToFastKv(input: PublishToFastKvInput): Promise<PublishToFastKvResult> {\n const { env, dryRun, configDir } = input;\n let bosConfig = input.bosConfig;\n const runtimeConfig = input.runtimeConfig;\n\n const isStaging = env === \"staging\";\n const account = bosConfig.account;\n const gateway = isStaging ? (bosConfig.staging?.domain ?? bosConfig.domain) : bosConfig.domain;\n if (!gateway) {\n return {\n status: \"error\",\n registryUrl: \"\",\n error: \"bos.config.json must define domain to publish\",\n };\n }\n\n const network = input.network ?? getNetworkIdForAccount(account);\n const registryUrl = buildRegistryConfigUrlForNetwork(network, account, gateway);\n const targets = selectWorkspaceTargets(input.packages, bosConfig);\n\n let built: string[] | undefined;\n let skipped: string[] | undefined;\n let deployResults: WorkspaceDeployResult[] | undefined;\n\n if (dryRun) {\n return { status: \"dry-run\", registryUrl, built, skipped };\n }\n\n const privateKey =\n input.privateKey || process.env.NEAR_PRIVATE_KEY || process.env.BOS_NEAR_PRIVATE_KEY;\n let signingMode: ReturnType<typeof resolveNearSigningMode>;\n try {\n signingMode = resolveNearSigningMode(privateKey);\n } catch (error) {\n return {\n status: \"error\" as const,\n registryUrl,\n error: error instanceof Error ? error.message : \"Unknown error\",\n };\n }\n\n if (input.build) {\n console.log(\" Ensuring NEAR CLI...\");\n await Effect.runPromise(ensureNearCli);\n console.log(\" NEAR CLI ready\");\n\n await generateCodeArtifacts(configDir, bosConfig, {\n env: \"production\",\n runtimeConfig: runtimeConfig ?? undefined,\n });\n\n const result = await buildWorkspaceTargets({\n configDir,\n bosConfig,\n runtimeConfig,\n targets,\n deploy: true,\n verbose: input.verbose,\n });\n built = result.built;\n skipped = result.skipped;\n deployResults = result.deployResults;\n\n if (deployResults) {\n const failures = deployResults.filter((r) => !r.success);\n if (failures.length > 0) {\n const total = deployResults.length;\n console.log();\n console.log(\n colors.error(\n ` ${icons.err} Deploy failed — ${failures.length} of ${total} workspace${total > 1 ? \"s\" : \"\"} failed`,\n ),\n );\n console.log();\n for (const f of failures) {\n const errorLine = (f.error ?? \"Failed\").split(\"\\n\")[0];\n console.log(` ${colors.error(icons.err)} ${padRight(f.key, 28)} ${errorLine}`);\n }\n console.log();\n if (!input.verbose) {\n console.log(colors.dim(\" Run with --verbose for full build output.\"));\n console.log();\n }\n return {\n status: \"error\" as const,\n registryUrl,\n built,\n skipped,\n deployResults,\n error: `${failures.length} of ${total} workspaces failed to deploy`,\n };\n }\n }\n\n const refreshed = await loadResolvedConfig({ cwd: configDir });\n if (!refreshed?.config) {\n return {\n status: \"error\",\n registryUrl,\n built,\n skipped,\n deployResults,\n error: \"Failed to reload bos.config.json after build\",\n };\n }\n\n bosConfig = refreshed.config;\n }\n\n const rawConfigPath = join(configDir, \"bos.config.json\");\n const rawConfig = JSON.parse(readFileSync(rawConfigPath, \"utf-8\")) as BosConfigInput;\n const publishPayload: BosConfigInput = isStaging ? { ...rawConfig, domain: gateway } : rawConfig;\n\n const registryEntries: Record<string, string> = {\n [`apps/${account}/${gateway}/bos.config.json`]: JSON.stringify(publishPayload),\n };\n\n const payload = JSON.stringify(registryEntries);\n const argsBase64 = Buffer.from(payload).toString(\"base64\");\n\n console.log();\n console.log(\" Publishing to:\");\n console.log(` ${colors.cyan(registryUrl)}`);\n\n try {\n let txHash: string | undefined;\n\n console.log(` Submitting transaction on ${network}...`);\n\n try {\n const tx = await Effect.runPromise(\n executeTransaction(\n {\n account,\n contract: getRegistryNamespaceForNetwork(network),\n method: \"__fastdata_kv\",\n argsBase64,\n network,\n privateKey: signingMode._tag === \"privateKey\" ? signingMode.privateKey : undefined,\n gas: \"300Tgas\",\n deposit: \"0NEAR\",\n verbose: input.verbose,\n },\n signingMode,\n ),\n );\n txHash = tx.txHash;\n if (txHash && !tx.output?.includes(\"CodeDoesNotExist\")) {\n console.log(` Transaction submitted: ${colors.dim(txHash)}`);\n }\n } catch (error) {\n console.log(colors.dim(\" Transaction reported an error — verifying publish...\"));\n try {\n await waitForPublishedConfig({\n account,\n gateway,\n publishConfig: publishPayload,\n timeoutMs: 30_000,\n intervalMs: 2_000,\n });\n txHash = extractTransactionHash(error);\n } catch {\n throw error;\n }\n }\n\n console.log(\" Waiting for publish confirmation...\");\n await waitForPublishedConfig({\n account,\n gateway,\n publishConfig: publishPayload,\n });\n\n return {\n status: \"published\",\n registryUrl,\n txHash,\n built,\n skipped,\n deployResults,\n publishConfig: publishPayload,\n };\n } catch (error) {\n return {\n status: \"error\",\n registryUrl,\n error: formatNearError(error),\n built,\n skipped,\n deployResults,\n };\n }\n}\n\nfunction formatNearError(error: unknown): string {\n const message = error instanceof Error ? error.message : String(error);\n\n if (message.includes(\"does not have enough allowance\")) {\n return (\n \"The publish access key has insufficient allowance to cover this transaction.\\n\" +\n \" Regenerate your key with a higher allowance:\\n\" +\n \" bos key generate\\n\" +\n ` Original: ${message}`\n );\n }\n\n if (message.includes(\"exceeded gas\") || message.includes(\"GasLimitExceeded\")) {\n return `Transaction exceeded gas limit.\\n Original: ${message}`;\n }\n\n if (message.includes(\"timeout\") || message.includes(\"Timeout\")) {\n return `Transaction timed out. Check NEAR network status.\\n Original: ${message}`;\n }\n\n return message;\n}\n\nfunction extractTransactionHash(error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n const match = message.match(/Transaction ID:\\s*([A-Za-z0-9]+)/i);\n return match?.[1];\n}\n"],"mappings":"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"}
|
|
@@ -185,6 +185,9 @@ function buildServiceDescriptorMap(runtimeConfig, options) {
|
|
|
185
185
|
}
|
|
186
186
|
const ServiceDescriptorMapLive = (map) => effect.Layer.succeed(ServiceDescriptorMap, map);
|
|
187
187
|
const DevRuntimeConfigLive = (config) => effect.Layer.succeed(DevRuntimeConfig, config);
|
|
188
|
+
function buildServiceDescriptorMapFromPlan(plan, options) {
|
|
189
|
+
return buildServiceDescriptorMap(plan.runtimeConfig, options);
|
|
190
|
+
}
|
|
188
191
|
function buildDescription(map) {
|
|
189
192
|
const descriptors = [...map.values()].filter((d) => d.key !== "ui-ssr" && !d.key.startsWith("plugin:"));
|
|
190
193
|
const allLocal = descriptors.every((d) => d.source === "local");
|
|
@@ -206,4 +209,5 @@ exports.ServiceDescriptorMap = ServiceDescriptorMap;
|
|
|
206
209
|
exports.ServiceDescriptorMapLive = ServiceDescriptorMapLive;
|
|
207
210
|
exports.buildDescription = buildDescription;
|
|
208
211
|
exports.buildServiceDescriptorMap = buildServiceDescriptorMap;
|
|
212
|
+
exports.buildServiceDescriptorMapFromPlan = buildServiceDescriptorMapFromPlan;
|
|
209
213
|
//# sourceMappingURL=service-descriptor.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-descriptor.cjs","names":["Context","Layer"],"sources":["../src/service-descriptor.ts"],"sourcesContent":["import { Context, Layer } from \"effect\";\nimport type { JsonObject, RuntimeConfig, SourceMode } from \"./types\";\n\nexport interface ServiceDescriptor {\n key: string;\n source: SourceMode;\n url: string;\n remoteUrl?: string;\n entry: string;\n name: string;\n localPath?: string;\n port?: number;\n readinessPath: string;\n defaultPort: number;\n integrity?: string;\n proxy?: string;\n variables?: JsonObject;\n secrets?: string[];\n ssr?: boolean;\n command?: string;\n args?: string[];\n readyPatterns?: RegExp[];\n errorPatterns?: RegExp[];\n}\n\nexport class ServiceDescriptorMap extends Context.Tag(\"ServiceDescriptorMap\")<\n ServiceDescriptorMap,\n Map<string, ServiceDescriptor>\n>() {}\n\nexport class DevRuntimeConfig extends Context.Tag(\"DevRuntimeConfig\")<\n DevRuntimeConfig,\n RuntimeConfig\n>() {}\n\nconst PLUGIN_READY_PATTERNS = [/ready in/i, /compiled.*successfully/i, /listening/i, /started/i];\n\nconst PLUGIN_ERROR_PATTERNS = [/error/i, /failed/i];\n\nconst SERVICE_CONFIGS: Record<\n string,\n Pick<\n ServiceDescriptor,\n \"command\" | \"args\" | \"readyPatterns\" | \"errorPatterns\" | \"defaultPort\" | \"readinessPath\"\n >\n> = {\n host: {\n command: \"bun\",\n args: [\"run\", \"dev\"],\n readyPatterns: [/Host (dev|production) server running at/i, /Server running at/i],\n errorPatterns: [/error:/i, /failed/i, /exception/i],\n defaultPort: 3000,\n readinessPath: \"/health\",\n },\n auth: {\n command: \"bun\",\n args: [\"run\", \"dev\"],\n readyPatterns: PLUGIN_READY_PATTERNS,\n errorPatterns: PLUGIN_ERROR_PATTERNS,\n defaultPort: 3002,\n readinessPath: \"/remoteEntry.js\",\n },\n ui: {\n command: \"bun\",\n args: [\"run\", \"dev\"],\n readyPatterns: [/\\bready\\s+built in\\b/i, /\\bLocal:\\b/i, /\\bcompiled\\b.*successfully/i],\n errorPatterns: [/error/i, /failed to compile/i],\n defaultPort: 3003,\n readinessPath: \"/remoteEntry.js\",\n },\n \"ui-ssr\": {\n command: \"bun\",\n args: [\"run\", \"dev:ssr\"],\n readyPatterns: [/\\bready\\s+built in\\b/i, /\\bcompiled\\b.*successfully/i],\n errorPatterns: [/error/i, /failed/i],\n defaultPort: 3004,\n readinessPath: \"/\",\n },\n api: {\n command: \"bun\",\n args: [\"run\", \"dev\"],\n readyPatterns: PLUGIN_READY_PATTERNS,\n errorPatterns: PLUGIN_ERROR_PATTERNS,\n defaultPort: 3001,\n readinessPath: \"/remoteEntry.js\",\n },\n};\n\nexport function buildServiceDescriptorMap(\n runtimeConfig: RuntimeConfig,\n options?: { ssr?: boolean; proxy?: boolean },\n): Map<string, ServiceDescriptor> {\n const map = new Map<string, ServiceDescriptor>();\n const ssr = options?.ssr ?? false;\n\n const hostIsRemote = runtimeConfig.host.source === \"remote\";\n const hostProbeUrl = hostIsRemote\n ? (runtimeConfig.host.remoteUrl ?? runtimeConfig.host.url)\n : runtimeConfig.host.url;\n map.set(\"host\", {\n key: \"host\",\n source: runtimeConfig.host.source,\n url: hostProbeUrl,\n remoteUrl: runtimeConfig.host.remoteUrl,\n entry: hostIsRemote\n ? hostProbeUrl\n ? `${hostProbeUrl}/mf-manifest.json`\n : \"/mf-manifest.json\"\n : runtimeConfig.host.entry,\n name: runtimeConfig.host.name,\n localPath: runtimeConfig.host.localPath,\n port: runtimeConfig.host.port,\n integrity: runtimeConfig.host.integrity,\n secrets: runtimeConfig.host.secrets,\n ...SERVICE_CONFIGS.host,\n });\n\n map.set(\"ui\", {\n key: \"ui\",\n source: runtimeConfig.ui.source,\n url: runtimeConfig.ui.url,\n remoteUrl: runtimeConfig.ui.source === \"remote\" ? runtimeConfig.ui.url : undefined,\n entry: runtimeConfig.ui.entry,\n name: runtimeConfig.ui.name,\n localPath: runtimeConfig.ui.localPath,\n port: runtimeConfig.ui.port,\n integrity: runtimeConfig.ui.integrity,\n ssr,\n ...SERVICE_CONFIGS.ui,\n });\n\n if (ssr && runtimeConfig.ui.source === \"local\") {\n map.set(\"ui-ssr\", {\n key: \"ui-ssr\",\n source: runtimeConfig.ui.source,\n url: runtimeConfig.ui.ssrUrl ?? \"\",\n entry: \"\",\n name: \"ui-ssr\",\n localPath: runtimeConfig.ui.localPath,\n port: runtimeConfig.ui.ssrUrl\n ? Number.parseInt(new URL(runtimeConfig.ui.ssrUrl).port, 10)\n : (runtimeConfig.ui.port ?? 3003) + 1,\n ...SERVICE_CONFIGS[\"ui-ssr\"],\n });\n }\n\n map.set(\"api\", {\n key: \"api\",\n source: runtimeConfig.api.source,\n url: runtimeConfig.api.url,\n remoteUrl: runtimeConfig.api.source === \"remote\" ? runtimeConfig.api.url : undefined,\n entry: runtimeConfig.api.entry,\n name: runtimeConfig.api.name,\n localPath: runtimeConfig.api.localPath,\n port: runtimeConfig.api.port,\n integrity: runtimeConfig.api.integrity,\n proxy: runtimeConfig.api.proxy,\n variables: runtimeConfig.api.variables,\n secrets: runtimeConfig.api.secrets,\n ...SERVICE_CONFIGS.api,\n });\n\n if (runtimeConfig.auth) {\n map.set(\"auth\", {\n key: \"auth\",\n source: runtimeConfig.auth.source,\n url: runtimeConfig.auth.url,\n remoteUrl: runtimeConfig.auth.source === \"remote\" ? runtimeConfig.auth.url : undefined,\n entry: runtimeConfig.auth.entry,\n name: runtimeConfig.auth.name,\n localPath: runtimeConfig.auth.localPath,\n port: runtimeConfig.auth.port,\n integrity: runtimeConfig.auth.integrity,\n proxy: runtimeConfig.auth.proxy,\n variables: runtimeConfig.auth.variables,\n secrets: runtimeConfig.auth.secrets,\n ...SERVICE_CONFIGS.auth,\n });\n }\n\n if (runtimeConfig.plugins) {\n let pluginBasePort = 3010;\n for (const [pluginId, pluginConfig] of Object.entries(runtimeConfig.plugins)) {\n const pluginKey = `plugin:${pluginId}`;\n const resolvedPort = pluginConfig.port ?? pluginBasePort;\n pluginBasePort = resolvedPort + 1;\n\n map.set(pluginKey, {\n key: pluginKey,\n source: pluginConfig.source,\n url: pluginConfig.url,\n remoteUrl: pluginConfig.source === \"remote\" ? pluginConfig.url : undefined,\n entry: pluginConfig.entry,\n name: pluginConfig.name,\n localPath: pluginConfig.localPath,\n port: resolvedPort,\n integrity: pluginConfig.integrity,\n proxy: pluginConfig.proxy,\n variables: pluginConfig.variables,\n secrets: pluginConfig.secrets,\n command: \"bun\",\n args: [\"run\", \"dev\"],\n readyPatterns: PLUGIN_READY_PATTERNS,\n errorPatterns: PLUGIN_ERROR_PATTERNS,\n defaultPort: resolvedPort,\n readinessPath: \"/remoteEntry.js\",\n });\n\n if (pluginConfig.ui?.localPath && pluginConfig.ui.source === \"local\") {\n const uiKey = `plugin-ui:${pluginId}`;\n const uiPort = pluginConfig.ui.port ?? pluginBasePort;\n pluginBasePort = uiPort + 1;\n\n map.set(uiKey, {\n key: uiKey,\n source: pluginConfig.ui.source,\n url: pluginConfig.ui.url,\n entry: pluginConfig.ui.entry,\n name: pluginConfig.ui.name,\n localPath: pluginConfig.ui.localPath,\n port: uiPort,\n integrity: pluginConfig.ui.integrity,\n command: \"bun\",\n args: [\"run\", \"dev\"],\n readyPatterns: PLUGIN_READY_PATTERNS,\n errorPatterns: PLUGIN_ERROR_PATTERNS,\n defaultPort: uiPort,\n readinessPath: \"/remoteEntry.js\",\n });\n }\n }\n }\n\n return map;\n}\n\nexport interface AppOrchestrator {\n packages: string[];\n description: string;\n env: Record<string, string>;\n port?: number;\n interactive?: boolean;\n noLogs?: boolean;\n}\n\nexport const ServiceDescriptorMapLive = (map: Map<string, ServiceDescriptor>) =>\n Layer.succeed(ServiceDescriptorMap, map);\n\nexport const DevRuntimeConfigLive = (config: RuntimeConfig) =>\n Layer.succeed(DevRuntimeConfig, config);\n\nexport function buildDescription(map: Map<string, ServiceDescriptor>): string {\n const descriptors = [...map.values()].filter(\n (d) => d.key !== \"ui-ssr\" && !d.key.startsWith(\"plugin:\"),\n );\n\n const allLocal = descriptors.every((d) => d.source === \"local\");\n const hasProxy = [...map.values()].some((d) => d.proxy && d.source === \"local\");\n if (allLocal && !hasProxy) return \"Full Local Development\";\n\n const parts: string[] = [];\n for (const d of descriptors) {\n if (d.source === \"remote\") {\n const label =\n d.key === \"host\"\n ? \"Remote Host\"\n : d.key === \"ui\"\n ? \"Remote UI\"\n : d.key === \"api\"\n ? hasProxy\n ? undefined\n : \"Remote API\"\n : d.key === \"auth\"\n ? \"Remote Auth\"\n : undefined;\n if (label) parts.push(label);\n }\n }\n if (hasProxy) parts.push(\"Proxy API → Production\");\n return parts.join(\" + \") || \"Remote Mode\";\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"service-descriptor.cjs","names":["Context","Layer"],"sources":["../src/service-descriptor.ts"],"sourcesContent":["import { Context, Layer } from \"effect\";\nimport type { JsonObject, RuntimeConfig, SourceMode } from \"./types\";\n\nexport interface ServiceDescriptor {\n key: string;\n source: SourceMode;\n url: string;\n remoteUrl?: string;\n entry: string;\n name: string;\n localPath?: string;\n port?: number;\n readinessPath: string;\n defaultPort: number;\n integrity?: string;\n proxy?: string;\n variables?: JsonObject;\n secrets?: string[];\n ssr?: boolean;\n command?: string;\n args?: string[];\n readyPatterns?: RegExp[];\n errorPatterns?: RegExp[];\n}\n\nexport class ServiceDescriptorMap extends Context.Tag(\"ServiceDescriptorMap\")<\n ServiceDescriptorMap,\n Map<string, ServiceDescriptor>\n>() {}\n\nexport class DevRuntimeConfig extends Context.Tag(\"DevRuntimeConfig\")<\n DevRuntimeConfig,\n RuntimeConfig\n>() {}\n\nconst PLUGIN_READY_PATTERNS = [/ready in/i, /compiled.*successfully/i, /listening/i, /started/i];\n\nconst PLUGIN_ERROR_PATTERNS = [/error/i, /failed/i];\n\nconst SERVICE_CONFIGS: Record<\n string,\n Pick<\n ServiceDescriptor,\n \"command\" | \"args\" | \"readyPatterns\" | \"errorPatterns\" | \"defaultPort\" | \"readinessPath\"\n >\n> = {\n host: {\n command: \"bun\",\n args: [\"run\", \"dev\"],\n readyPatterns: [/Host (dev|production) server running at/i, /Server running at/i],\n errorPatterns: [/error:/i, /failed/i, /exception/i],\n defaultPort: 3000,\n readinessPath: \"/health\",\n },\n auth: {\n command: \"bun\",\n args: [\"run\", \"dev\"],\n readyPatterns: PLUGIN_READY_PATTERNS,\n errorPatterns: PLUGIN_ERROR_PATTERNS,\n defaultPort: 3002,\n readinessPath: \"/remoteEntry.js\",\n },\n ui: {\n command: \"bun\",\n args: [\"run\", \"dev\"],\n readyPatterns: [/\\bready\\s+built in\\b/i, /\\bLocal:\\b/i, /\\bcompiled\\b.*successfully/i],\n errorPatterns: [/error/i, /failed to compile/i],\n defaultPort: 3003,\n readinessPath: \"/remoteEntry.js\",\n },\n \"ui-ssr\": {\n command: \"bun\",\n args: [\"run\", \"dev:ssr\"],\n readyPatterns: [/\\bready\\s+built in\\b/i, /\\bcompiled\\b.*successfully/i],\n errorPatterns: [/error/i, /failed/i],\n defaultPort: 3004,\n readinessPath: \"/\",\n },\n api: {\n command: \"bun\",\n args: [\"run\", \"dev\"],\n readyPatterns: PLUGIN_READY_PATTERNS,\n errorPatterns: PLUGIN_ERROR_PATTERNS,\n defaultPort: 3001,\n readinessPath: \"/remoteEntry.js\",\n },\n};\n\nexport function buildServiceDescriptorMap(\n runtimeConfig: RuntimeConfig,\n options?: { ssr?: boolean; proxy?: boolean },\n): Map<string, ServiceDescriptor> {\n const map = new Map<string, ServiceDescriptor>();\n const ssr = options?.ssr ?? false;\n\n const hostIsRemote = runtimeConfig.host.source === \"remote\";\n const hostProbeUrl = hostIsRemote\n ? (runtimeConfig.host.remoteUrl ?? runtimeConfig.host.url)\n : runtimeConfig.host.url;\n map.set(\"host\", {\n key: \"host\",\n source: runtimeConfig.host.source,\n url: hostProbeUrl,\n remoteUrl: runtimeConfig.host.remoteUrl,\n entry: hostIsRemote\n ? hostProbeUrl\n ? `${hostProbeUrl}/mf-manifest.json`\n : \"/mf-manifest.json\"\n : runtimeConfig.host.entry,\n name: runtimeConfig.host.name,\n localPath: runtimeConfig.host.localPath,\n port: runtimeConfig.host.port,\n integrity: runtimeConfig.host.integrity,\n secrets: runtimeConfig.host.secrets,\n ...SERVICE_CONFIGS.host,\n });\n\n map.set(\"ui\", {\n key: \"ui\",\n source: runtimeConfig.ui.source,\n url: runtimeConfig.ui.url,\n remoteUrl: runtimeConfig.ui.source === \"remote\" ? runtimeConfig.ui.url : undefined,\n entry: runtimeConfig.ui.entry,\n name: runtimeConfig.ui.name,\n localPath: runtimeConfig.ui.localPath,\n port: runtimeConfig.ui.port,\n integrity: runtimeConfig.ui.integrity,\n ssr,\n ...SERVICE_CONFIGS.ui,\n });\n\n if (ssr && runtimeConfig.ui.source === \"local\") {\n map.set(\"ui-ssr\", {\n key: \"ui-ssr\",\n source: runtimeConfig.ui.source,\n url: runtimeConfig.ui.ssrUrl ?? \"\",\n entry: \"\",\n name: \"ui-ssr\",\n localPath: runtimeConfig.ui.localPath,\n port: runtimeConfig.ui.ssrUrl\n ? Number.parseInt(new URL(runtimeConfig.ui.ssrUrl).port, 10)\n : (runtimeConfig.ui.port ?? 3003) + 1,\n ...SERVICE_CONFIGS[\"ui-ssr\"],\n });\n }\n\n map.set(\"api\", {\n key: \"api\",\n source: runtimeConfig.api.source,\n url: runtimeConfig.api.url,\n remoteUrl: runtimeConfig.api.source === \"remote\" ? runtimeConfig.api.url : undefined,\n entry: runtimeConfig.api.entry,\n name: runtimeConfig.api.name,\n localPath: runtimeConfig.api.localPath,\n port: runtimeConfig.api.port,\n integrity: runtimeConfig.api.integrity,\n proxy: runtimeConfig.api.proxy,\n variables: runtimeConfig.api.variables,\n secrets: runtimeConfig.api.secrets,\n ...SERVICE_CONFIGS.api,\n });\n\n if (runtimeConfig.auth) {\n map.set(\"auth\", {\n key: \"auth\",\n source: runtimeConfig.auth.source,\n url: runtimeConfig.auth.url,\n remoteUrl: runtimeConfig.auth.source === \"remote\" ? runtimeConfig.auth.url : undefined,\n entry: runtimeConfig.auth.entry,\n name: runtimeConfig.auth.name,\n localPath: runtimeConfig.auth.localPath,\n port: runtimeConfig.auth.port,\n integrity: runtimeConfig.auth.integrity,\n proxy: runtimeConfig.auth.proxy,\n variables: runtimeConfig.auth.variables,\n secrets: runtimeConfig.auth.secrets,\n ...SERVICE_CONFIGS.auth,\n });\n }\n\n if (runtimeConfig.plugins) {\n let pluginBasePort = 3010;\n for (const [pluginId, pluginConfig] of Object.entries(runtimeConfig.plugins)) {\n const pluginKey = `plugin:${pluginId}`;\n const resolvedPort = pluginConfig.port ?? pluginBasePort;\n pluginBasePort = resolvedPort + 1;\n\n map.set(pluginKey, {\n key: pluginKey,\n source: pluginConfig.source,\n url: pluginConfig.url,\n remoteUrl: pluginConfig.source === \"remote\" ? pluginConfig.url : undefined,\n entry: pluginConfig.entry,\n name: pluginConfig.name,\n localPath: pluginConfig.localPath,\n port: resolvedPort,\n integrity: pluginConfig.integrity,\n proxy: pluginConfig.proxy,\n variables: pluginConfig.variables,\n secrets: pluginConfig.secrets,\n command: \"bun\",\n args: [\"run\", \"dev\"],\n readyPatterns: PLUGIN_READY_PATTERNS,\n errorPatterns: PLUGIN_ERROR_PATTERNS,\n defaultPort: resolvedPort,\n readinessPath: \"/remoteEntry.js\",\n });\n\n if (pluginConfig.ui?.localPath && pluginConfig.ui.source === \"local\") {\n const uiKey = `plugin-ui:${pluginId}`;\n const uiPort = pluginConfig.ui.port ?? pluginBasePort;\n pluginBasePort = uiPort + 1;\n\n map.set(uiKey, {\n key: uiKey,\n source: pluginConfig.ui.source,\n url: pluginConfig.ui.url,\n entry: pluginConfig.ui.entry,\n name: pluginConfig.ui.name,\n localPath: pluginConfig.ui.localPath,\n port: uiPort,\n integrity: pluginConfig.ui.integrity,\n command: \"bun\",\n args: [\"run\", \"dev\"],\n readyPatterns: PLUGIN_READY_PATTERNS,\n errorPatterns: PLUGIN_ERROR_PATTERNS,\n defaultPort: uiPort,\n readinessPath: \"/remoteEntry.js\",\n });\n }\n }\n }\n\n return map;\n}\n\nexport interface AppOrchestrator {\n packages: string[];\n description: string;\n env: Record<string, string>;\n port?: number;\n interactive?: boolean;\n noLogs?: boolean;\n}\n\nexport const ServiceDescriptorMapLive = (map: Map<string, ServiceDescriptor>) =>\n Layer.succeed(ServiceDescriptorMap, map);\n\nexport const DevRuntimeConfigLive = (config: RuntimeConfig) =>\n Layer.succeed(DevRuntimeConfig, config);\n\nexport function buildServiceDescriptorMapFromPlan(\n plan: {\n runtimeConfig: RuntimeConfig;\n resolvedPorts: { host?: number; api?: number; auth?: number; ui?: number; uiSsr?: number };\n },\n options?: { ssr?: boolean; proxy?: boolean },\n): Map<string, ServiceDescriptor> {\n return buildServiceDescriptorMap(plan.runtimeConfig, options);\n}\n\ninterface ServiceDescriptorInfo {\n key: string;\n source: string;\n proxy?: string;\n}\n\nexport function buildDescription(map: Map<string, ServiceDescriptorInfo>): string {\n const descriptors = [...map.values()].filter(\n (d) => d.key !== \"ui-ssr\" && !d.key.startsWith(\"plugin:\"),\n );\n\n const allLocal = descriptors.every((d) => d.source === \"local\");\n const hasProxy = [...map.values()].some((d) => d.proxy && d.source === \"local\");\n if (allLocal && !hasProxy) return \"Full Local Development\";\n\n const parts: string[] = [];\n for (const d of descriptors) {\n if (d.source === \"remote\") {\n const label =\n d.key === \"host\"\n ? \"Remote Host\"\n : d.key === \"ui\"\n ? \"Remote UI\"\n : d.key === \"api\"\n ? hasProxy\n ? undefined\n : \"Remote API\"\n : d.key === \"auth\"\n ? \"Remote Auth\"\n : undefined;\n if (label) parts.push(label);\n }\n }\n if (hasProxy) parts.push(\"Proxy API → Production\");\n return parts.join(\" + \") || \"Remote Mode\";\n}\n"],"mappings":"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"}
|
|
@@ -184,6 +184,9 @@ function buildServiceDescriptorMap(runtimeConfig, options) {
|
|
|
184
184
|
}
|
|
185
185
|
const ServiceDescriptorMapLive = (map) => Layer.succeed(ServiceDescriptorMap, map);
|
|
186
186
|
const DevRuntimeConfigLive = (config) => Layer.succeed(DevRuntimeConfig, config);
|
|
187
|
+
function buildServiceDescriptorMapFromPlan(plan, options) {
|
|
188
|
+
return buildServiceDescriptorMap(plan.runtimeConfig, options);
|
|
189
|
+
}
|
|
187
190
|
function buildDescription(map) {
|
|
188
191
|
const descriptors = [...map.values()].filter((d) => d.key !== "ui-ssr" && !d.key.startsWith("plugin:"));
|
|
189
192
|
const allLocal = descriptors.every((d) => d.source === "local");
|
|
@@ -199,5 +202,5 @@ function buildDescription(map) {
|
|
|
199
202
|
}
|
|
200
203
|
|
|
201
204
|
//#endregion
|
|
202
|
-
export { DevRuntimeConfig, DevRuntimeConfigLive, ServiceDescriptorMap, ServiceDescriptorMapLive, buildDescription, buildServiceDescriptorMap };
|
|
205
|
+
export { DevRuntimeConfig, DevRuntimeConfigLive, ServiceDescriptorMap, ServiceDescriptorMapLive, buildDescription, buildServiceDescriptorMap, buildServiceDescriptorMapFromPlan };
|
|
203
206
|
//# sourceMappingURL=service-descriptor.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-descriptor.mjs","names":[],"sources":["../src/service-descriptor.ts"],"sourcesContent":["import { Context, Layer } from \"effect\";\nimport type { JsonObject, RuntimeConfig, SourceMode } from \"./types\";\n\nexport interface ServiceDescriptor {\n key: string;\n source: SourceMode;\n url: string;\n remoteUrl?: string;\n entry: string;\n name: string;\n localPath?: string;\n port?: number;\n readinessPath: string;\n defaultPort: number;\n integrity?: string;\n proxy?: string;\n variables?: JsonObject;\n secrets?: string[];\n ssr?: boolean;\n command?: string;\n args?: string[];\n readyPatterns?: RegExp[];\n errorPatterns?: RegExp[];\n}\n\nexport class ServiceDescriptorMap extends Context.Tag(\"ServiceDescriptorMap\")<\n ServiceDescriptorMap,\n Map<string, ServiceDescriptor>\n>() {}\n\nexport class DevRuntimeConfig extends Context.Tag(\"DevRuntimeConfig\")<\n DevRuntimeConfig,\n RuntimeConfig\n>() {}\n\nconst PLUGIN_READY_PATTERNS = [/ready in/i, /compiled.*successfully/i, /listening/i, /started/i];\n\nconst PLUGIN_ERROR_PATTERNS = [/error/i, /failed/i];\n\nconst SERVICE_CONFIGS: Record<\n string,\n Pick<\n ServiceDescriptor,\n \"command\" | \"args\" | \"readyPatterns\" | \"errorPatterns\" | \"defaultPort\" | \"readinessPath\"\n >\n> = {\n host: {\n command: \"bun\",\n args: [\"run\", \"dev\"],\n readyPatterns: [/Host (dev|production) server running at/i, /Server running at/i],\n errorPatterns: [/error:/i, /failed/i, /exception/i],\n defaultPort: 3000,\n readinessPath: \"/health\",\n },\n auth: {\n command: \"bun\",\n args: [\"run\", \"dev\"],\n readyPatterns: PLUGIN_READY_PATTERNS,\n errorPatterns: PLUGIN_ERROR_PATTERNS,\n defaultPort: 3002,\n readinessPath: \"/remoteEntry.js\",\n },\n ui: {\n command: \"bun\",\n args: [\"run\", \"dev\"],\n readyPatterns: [/\\bready\\s+built in\\b/i, /\\bLocal:\\b/i, /\\bcompiled\\b.*successfully/i],\n errorPatterns: [/error/i, /failed to compile/i],\n defaultPort: 3003,\n readinessPath: \"/remoteEntry.js\",\n },\n \"ui-ssr\": {\n command: \"bun\",\n args: [\"run\", \"dev:ssr\"],\n readyPatterns: [/\\bready\\s+built in\\b/i, /\\bcompiled\\b.*successfully/i],\n errorPatterns: [/error/i, /failed/i],\n defaultPort: 3004,\n readinessPath: \"/\",\n },\n api: {\n command: \"bun\",\n args: [\"run\", \"dev\"],\n readyPatterns: PLUGIN_READY_PATTERNS,\n errorPatterns: PLUGIN_ERROR_PATTERNS,\n defaultPort: 3001,\n readinessPath: \"/remoteEntry.js\",\n },\n};\n\nexport function buildServiceDescriptorMap(\n runtimeConfig: RuntimeConfig,\n options?: { ssr?: boolean; proxy?: boolean },\n): Map<string, ServiceDescriptor> {\n const map = new Map<string, ServiceDescriptor>();\n const ssr = options?.ssr ?? false;\n\n const hostIsRemote = runtimeConfig.host.source === \"remote\";\n const hostProbeUrl = hostIsRemote\n ? (runtimeConfig.host.remoteUrl ?? runtimeConfig.host.url)\n : runtimeConfig.host.url;\n map.set(\"host\", {\n key: \"host\",\n source: runtimeConfig.host.source,\n url: hostProbeUrl,\n remoteUrl: runtimeConfig.host.remoteUrl,\n entry: hostIsRemote\n ? hostProbeUrl\n ? `${hostProbeUrl}/mf-manifest.json`\n : \"/mf-manifest.json\"\n : runtimeConfig.host.entry,\n name: runtimeConfig.host.name,\n localPath: runtimeConfig.host.localPath,\n port: runtimeConfig.host.port,\n integrity: runtimeConfig.host.integrity,\n secrets: runtimeConfig.host.secrets,\n ...SERVICE_CONFIGS.host,\n });\n\n map.set(\"ui\", {\n key: \"ui\",\n source: runtimeConfig.ui.source,\n url: runtimeConfig.ui.url,\n remoteUrl: runtimeConfig.ui.source === \"remote\" ? runtimeConfig.ui.url : undefined,\n entry: runtimeConfig.ui.entry,\n name: runtimeConfig.ui.name,\n localPath: runtimeConfig.ui.localPath,\n port: runtimeConfig.ui.port,\n integrity: runtimeConfig.ui.integrity,\n ssr,\n ...SERVICE_CONFIGS.ui,\n });\n\n if (ssr && runtimeConfig.ui.source === \"local\") {\n map.set(\"ui-ssr\", {\n key: \"ui-ssr\",\n source: runtimeConfig.ui.source,\n url: runtimeConfig.ui.ssrUrl ?? \"\",\n entry: \"\",\n name: \"ui-ssr\",\n localPath: runtimeConfig.ui.localPath,\n port: runtimeConfig.ui.ssrUrl\n ? Number.parseInt(new URL(runtimeConfig.ui.ssrUrl).port, 10)\n : (runtimeConfig.ui.port ?? 3003) + 1,\n ...SERVICE_CONFIGS[\"ui-ssr\"],\n });\n }\n\n map.set(\"api\", {\n key: \"api\",\n source: runtimeConfig.api.source,\n url: runtimeConfig.api.url,\n remoteUrl: runtimeConfig.api.source === \"remote\" ? runtimeConfig.api.url : undefined,\n entry: runtimeConfig.api.entry,\n name: runtimeConfig.api.name,\n localPath: runtimeConfig.api.localPath,\n port: runtimeConfig.api.port,\n integrity: runtimeConfig.api.integrity,\n proxy: runtimeConfig.api.proxy,\n variables: runtimeConfig.api.variables,\n secrets: runtimeConfig.api.secrets,\n ...SERVICE_CONFIGS.api,\n });\n\n if (runtimeConfig.auth) {\n map.set(\"auth\", {\n key: \"auth\",\n source: runtimeConfig.auth.source,\n url: runtimeConfig.auth.url,\n remoteUrl: runtimeConfig.auth.source === \"remote\" ? runtimeConfig.auth.url : undefined,\n entry: runtimeConfig.auth.entry,\n name: runtimeConfig.auth.name,\n localPath: runtimeConfig.auth.localPath,\n port: runtimeConfig.auth.port,\n integrity: runtimeConfig.auth.integrity,\n proxy: runtimeConfig.auth.proxy,\n variables: runtimeConfig.auth.variables,\n secrets: runtimeConfig.auth.secrets,\n ...SERVICE_CONFIGS.auth,\n });\n }\n\n if (runtimeConfig.plugins) {\n let pluginBasePort = 3010;\n for (const [pluginId, pluginConfig] of Object.entries(runtimeConfig.plugins)) {\n const pluginKey = `plugin:${pluginId}`;\n const resolvedPort = pluginConfig.port ?? pluginBasePort;\n pluginBasePort = resolvedPort + 1;\n\n map.set(pluginKey, {\n key: pluginKey,\n source: pluginConfig.source,\n url: pluginConfig.url,\n remoteUrl: pluginConfig.source === \"remote\" ? pluginConfig.url : undefined,\n entry: pluginConfig.entry,\n name: pluginConfig.name,\n localPath: pluginConfig.localPath,\n port: resolvedPort,\n integrity: pluginConfig.integrity,\n proxy: pluginConfig.proxy,\n variables: pluginConfig.variables,\n secrets: pluginConfig.secrets,\n command: \"bun\",\n args: [\"run\", \"dev\"],\n readyPatterns: PLUGIN_READY_PATTERNS,\n errorPatterns: PLUGIN_ERROR_PATTERNS,\n defaultPort: resolvedPort,\n readinessPath: \"/remoteEntry.js\",\n });\n\n if (pluginConfig.ui?.localPath && pluginConfig.ui.source === \"local\") {\n const uiKey = `plugin-ui:${pluginId}`;\n const uiPort = pluginConfig.ui.port ?? pluginBasePort;\n pluginBasePort = uiPort + 1;\n\n map.set(uiKey, {\n key: uiKey,\n source: pluginConfig.ui.source,\n url: pluginConfig.ui.url,\n entry: pluginConfig.ui.entry,\n name: pluginConfig.ui.name,\n localPath: pluginConfig.ui.localPath,\n port: uiPort,\n integrity: pluginConfig.ui.integrity,\n command: \"bun\",\n args: [\"run\", \"dev\"],\n readyPatterns: PLUGIN_READY_PATTERNS,\n errorPatterns: PLUGIN_ERROR_PATTERNS,\n defaultPort: uiPort,\n readinessPath: \"/remoteEntry.js\",\n });\n }\n }\n }\n\n return map;\n}\n\nexport interface AppOrchestrator {\n packages: string[];\n description: string;\n env: Record<string, string>;\n port?: number;\n interactive?: boolean;\n noLogs?: boolean;\n}\n\nexport const ServiceDescriptorMapLive = (map: Map<string, ServiceDescriptor>) =>\n Layer.succeed(ServiceDescriptorMap, map);\n\nexport const DevRuntimeConfigLive = (config: RuntimeConfig) =>\n Layer.succeed(DevRuntimeConfig, config);\n\nexport function buildDescription(map: Map<string, ServiceDescriptor>): string {\n const descriptors = [...map.values()].filter(\n (d) => d.key !== \"ui-ssr\" && !d.key.startsWith(\"plugin:\"),\n );\n\n const allLocal = descriptors.every((d) => d.source === \"local\");\n const hasProxy = [...map.values()].some((d) => d.proxy && d.source === \"local\");\n if (allLocal && !hasProxy) return \"Full Local Development\";\n\n const parts: string[] = [];\n for (const d of descriptors) {\n if (d.source === \"remote\") {\n const label =\n d.key === \"host\"\n ? \"Remote Host\"\n : d.key === \"ui\"\n ? \"Remote UI\"\n : d.key === \"api\"\n ? hasProxy\n ? undefined\n : \"Remote API\"\n : d.key === \"auth\"\n ? \"Remote Auth\"\n : undefined;\n if (label) parts.push(label);\n }\n }\n if (hasProxy) parts.push(\"Proxy API → Production\");\n return parts.join(\" + \") || \"Remote Mode\";\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"service-descriptor.mjs","names":[],"sources":["../src/service-descriptor.ts"],"sourcesContent":["import { Context, Layer } from \"effect\";\nimport type { JsonObject, RuntimeConfig, SourceMode } from \"./types\";\n\nexport interface ServiceDescriptor {\n key: string;\n source: SourceMode;\n url: string;\n remoteUrl?: string;\n entry: string;\n name: string;\n localPath?: string;\n port?: number;\n readinessPath: string;\n defaultPort: number;\n integrity?: string;\n proxy?: string;\n variables?: JsonObject;\n secrets?: string[];\n ssr?: boolean;\n command?: string;\n args?: string[];\n readyPatterns?: RegExp[];\n errorPatterns?: RegExp[];\n}\n\nexport class ServiceDescriptorMap extends Context.Tag(\"ServiceDescriptorMap\")<\n ServiceDescriptorMap,\n Map<string, ServiceDescriptor>\n>() {}\n\nexport class DevRuntimeConfig extends Context.Tag(\"DevRuntimeConfig\")<\n DevRuntimeConfig,\n RuntimeConfig\n>() {}\n\nconst PLUGIN_READY_PATTERNS = [/ready in/i, /compiled.*successfully/i, /listening/i, /started/i];\n\nconst PLUGIN_ERROR_PATTERNS = [/error/i, /failed/i];\n\nconst SERVICE_CONFIGS: Record<\n string,\n Pick<\n ServiceDescriptor,\n \"command\" | \"args\" | \"readyPatterns\" | \"errorPatterns\" | \"defaultPort\" | \"readinessPath\"\n >\n> = {\n host: {\n command: \"bun\",\n args: [\"run\", \"dev\"],\n readyPatterns: [/Host (dev|production) server running at/i, /Server running at/i],\n errorPatterns: [/error:/i, /failed/i, /exception/i],\n defaultPort: 3000,\n readinessPath: \"/health\",\n },\n auth: {\n command: \"bun\",\n args: [\"run\", \"dev\"],\n readyPatterns: PLUGIN_READY_PATTERNS,\n errorPatterns: PLUGIN_ERROR_PATTERNS,\n defaultPort: 3002,\n readinessPath: \"/remoteEntry.js\",\n },\n ui: {\n command: \"bun\",\n args: [\"run\", \"dev\"],\n readyPatterns: [/\\bready\\s+built in\\b/i, /\\bLocal:\\b/i, /\\bcompiled\\b.*successfully/i],\n errorPatterns: [/error/i, /failed to compile/i],\n defaultPort: 3003,\n readinessPath: \"/remoteEntry.js\",\n },\n \"ui-ssr\": {\n command: \"bun\",\n args: [\"run\", \"dev:ssr\"],\n readyPatterns: [/\\bready\\s+built in\\b/i, /\\bcompiled\\b.*successfully/i],\n errorPatterns: [/error/i, /failed/i],\n defaultPort: 3004,\n readinessPath: \"/\",\n },\n api: {\n command: \"bun\",\n args: [\"run\", \"dev\"],\n readyPatterns: PLUGIN_READY_PATTERNS,\n errorPatterns: PLUGIN_ERROR_PATTERNS,\n defaultPort: 3001,\n readinessPath: \"/remoteEntry.js\",\n },\n};\n\nexport function buildServiceDescriptorMap(\n runtimeConfig: RuntimeConfig,\n options?: { ssr?: boolean; proxy?: boolean },\n): Map<string, ServiceDescriptor> {\n const map = new Map<string, ServiceDescriptor>();\n const ssr = options?.ssr ?? false;\n\n const hostIsRemote = runtimeConfig.host.source === \"remote\";\n const hostProbeUrl = hostIsRemote\n ? (runtimeConfig.host.remoteUrl ?? runtimeConfig.host.url)\n : runtimeConfig.host.url;\n map.set(\"host\", {\n key: \"host\",\n source: runtimeConfig.host.source,\n url: hostProbeUrl,\n remoteUrl: runtimeConfig.host.remoteUrl,\n entry: hostIsRemote\n ? hostProbeUrl\n ? `${hostProbeUrl}/mf-manifest.json`\n : \"/mf-manifest.json\"\n : runtimeConfig.host.entry,\n name: runtimeConfig.host.name,\n localPath: runtimeConfig.host.localPath,\n port: runtimeConfig.host.port,\n integrity: runtimeConfig.host.integrity,\n secrets: runtimeConfig.host.secrets,\n ...SERVICE_CONFIGS.host,\n });\n\n map.set(\"ui\", {\n key: \"ui\",\n source: runtimeConfig.ui.source,\n url: runtimeConfig.ui.url,\n remoteUrl: runtimeConfig.ui.source === \"remote\" ? runtimeConfig.ui.url : undefined,\n entry: runtimeConfig.ui.entry,\n name: runtimeConfig.ui.name,\n localPath: runtimeConfig.ui.localPath,\n port: runtimeConfig.ui.port,\n integrity: runtimeConfig.ui.integrity,\n ssr,\n ...SERVICE_CONFIGS.ui,\n });\n\n if (ssr && runtimeConfig.ui.source === \"local\") {\n map.set(\"ui-ssr\", {\n key: \"ui-ssr\",\n source: runtimeConfig.ui.source,\n url: runtimeConfig.ui.ssrUrl ?? \"\",\n entry: \"\",\n name: \"ui-ssr\",\n localPath: runtimeConfig.ui.localPath,\n port: runtimeConfig.ui.ssrUrl\n ? Number.parseInt(new URL(runtimeConfig.ui.ssrUrl).port, 10)\n : (runtimeConfig.ui.port ?? 3003) + 1,\n ...SERVICE_CONFIGS[\"ui-ssr\"],\n });\n }\n\n map.set(\"api\", {\n key: \"api\",\n source: runtimeConfig.api.source,\n url: runtimeConfig.api.url,\n remoteUrl: runtimeConfig.api.source === \"remote\" ? runtimeConfig.api.url : undefined,\n entry: runtimeConfig.api.entry,\n name: runtimeConfig.api.name,\n localPath: runtimeConfig.api.localPath,\n port: runtimeConfig.api.port,\n integrity: runtimeConfig.api.integrity,\n proxy: runtimeConfig.api.proxy,\n variables: runtimeConfig.api.variables,\n secrets: runtimeConfig.api.secrets,\n ...SERVICE_CONFIGS.api,\n });\n\n if (runtimeConfig.auth) {\n map.set(\"auth\", {\n key: \"auth\",\n source: runtimeConfig.auth.source,\n url: runtimeConfig.auth.url,\n remoteUrl: runtimeConfig.auth.source === \"remote\" ? runtimeConfig.auth.url : undefined,\n entry: runtimeConfig.auth.entry,\n name: runtimeConfig.auth.name,\n localPath: runtimeConfig.auth.localPath,\n port: runtimeConfig.auth.port,\n integrity: runtimeConfig.auth.integrity,\n proxy: runtimeConfig.auth.proxy,\n variables: runtimeConfig.auth.variables,\n secrets: runtimeConfig.auth.secrets,\n ...SERVICE_CONFIGS.auth,\n });\n }\n\n if (runtimeConfig.plugins) {\n let pluginBasePort = 3010;\n for (const [pluginId, pluginConfig] of Object.entries(runtimeConfig.plugins)) {\n const pluginKey = `plugin:${pluginId}`;\n const resolvedPort = pluginConfig.port ?? pluginBasePort;\n pluginBasePort = resolvedPort + 1;\n\n map.set(pluginKey, {\n key: pluginKey,\n source: pluginConfig.source,\n url: pluginConfig.url,\n remoteUrl: pluginConfig.source === \"remote\" ? pluginConfig.url : undefined,\n entry: pluginConfig.entry,\n name: pluginConfig.name,\n localPath: pluginConfig.localPath,\n port: resolvedPort,\n integrity: pluginConfig.integrity,\n proxy: pluginConfig.proxy,\n variables: pluginConfig.variables,\n secrets: pluginConfig.secrets,\n command: \"bun\",\n args: [\"run\", \"dev\"],\n readyPatterns: PLUGIN_READY_PATTERNS,\n errorPatterns: PLUGIN_ERROR_PATTERNS,\n defaultPort: resolvedPort,\n readinessPath: \"/remoteEntry.js\",\n });\n\n if (pluginConfig.ui?.localPath && pluginConfig.ui.source === \"local\") {\n const uiKey = `plugin-ui:${pluginId}`;\n const uiPort = pluginConfig.ui.port ?? pluginBasePort;\n pluginBasePort = uiPort + 1;\n\n map.set(uiKey, {\n key: uiKey,\n source: pluginConfig.ui.source,\n url: pluginConfig.ui.url,\n entry: pluginConfig.ui.entry,\n name: pluginConfig.ui.name,\n localPath: pluginConfig.ui.localPath,\n port: uiPort,\n integrity: pluginConfig.ui.integrity,\n command: \"bun\",\n args: [\"run\", \"dev\"],\n readyPatterns: PLUGIN_READY_PATTERNS,\n errorPatterns: PLUGIN_ERROR_PATTERNS,\n defaultPort: uiPort,\n readinessPath: \"/remoteEntry.js\",\n });\n }\n }\n }\n\n return map;\n}\n\nexport interface AppOrchestrator {\n packages: string[];\n description: string;\n env: Record<string, string>;\n port?: number;\n interactive?: boolean;\n noLogs?: boolean;\n}\n\nexport const ServiceDescriptorMapLive = (map: Map<string, ServiceDescriptor>) =>\n Layer.succeed(ServiceDescriptorMap, map);\n\nexport const DevRuntimeConfigLive = (config: RuntimeConfig) =>\n Layer.succeed(DevRuntimeConfig, config);\n\nexport function buildServiceDescriptorMapFromPlan(\n plan: {\n runtimeConfig: RuntimeConfig;\n resolvedPorts: { host?: number; api?: number; auth?: number; ui?: number; uiSsr?: number };\n },\n options?: { ssr?: boolean; proxy?: boolean },\n): Map<string, ServiceDescriptor> {\n return buildServiceDescriptorMap(plan.runtimeConfig, options);\n}\n\ninterface ServiceDescriptorInfo {\n key: string;\n source: string;\n proxy?: string;\n}\n\nexport function buildDescription(map: Map<string, ServiceDescriptorInfo>): string {\n const descriptors = [...map.values()].filter(\n (d) => d.key !== \"ui-ssr\" && !d.key.startsWith(\"plugin:\"),\n );\n\n const allLocal = descriptors.every((d) => d.source === \"local\");\n const hasProxy = [...map.values()].some((d) => d.proxy && d.source === \"local\");\n if (allLocal && !hasProxy) return \"Full Local Development\";\n\n const parts: string[] = [];\n for (const d of descriptors) {\n if (d.source === \"remote\") {\n const label =\n d.key === \"host\"\n ? \"Remote Host\"\n : d.key === \"ui\"\n ? \"Remote UI\"\n : d.key === \"api\"\n ? hasProxy\n ? undefined\n : \"Remote API\"\n : d.key === \"auth\"\n ? \"Remote Auth\"\n : undefined;\n if (label) parts.push(label);\n }\n }\n if (hasProxy) parts.push(\"Proxy API → Production\");\n return parts.join(\" + \") || \"Remote Mode\";\n}\n"],"mappings":"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"}
|
package/dist/types.d.cts
CHANGED
|
@@ -379,9 +379,9 @@ declare const BosConfigSchema: z.ZodObject<{
|
|
|
379
379
|
type BosConfig = z.infer<typeof BosConfigSchema>;
|
|
380
380
|
declare const RuntimeConfigSchema: z.ZodObject<{
|
|
381
381
|
env: z.ZodEnum<{
|
|
382
|
-
development: "development";
|
|
383
382
|
production: "production";
|
|
384
383
|
staging: "staging";
|
|
384
|
+
development: "development";
|
|
385
385
|
}>;
|
|
386
386
|
account: z.ZodString;
|
|
387
387
|
domain: z.ZodOptional<z.ZodString>;
|
|
@@ -508,9 +508,9 @@ declare const RuntimeConfigSchema: z.ZodObject<{
|
|
|
508
508
|
type RuntimeConfig = z.infer<typeof RuntimeConfigSchema>;
|
|
509
509
|
declare const ClientRuntimeConfigSchema: z.ZodObject<{
|
|
510
510
|
env: z.ZodEnum<{
|
|
511
|
-
development: "development";
|
|
512
511
|
production: "production";
|
|
513
512
|
staging: "staging";
|
|
513
|
+
development: "development";
|
|
514
514
|
}>;
|
|
515
515
|
account: z.ZodString;
|
|
516
516
|
networkId: z.ZodEnum<{
|
package/dist/types.d.mts
CHANGED
|
@@ -379,9 +379,9 @@ declare const BosConfigSchema: z.ZodObject<{
|
|
|
379
379
|
type BosConfig = z.infer<typeof BosConfigSchema>;
|
|
380
380
|
declare const RuntimeConfigSchema: z.ZodObject<{
|
|
381
381
|
env: z.ZodEnum<{
|
|
382
|
-
development: "development";
|
|
383
382
|
production: "production";
|
|
384
383
|
staging: "staging";
|
|
384
|
+
development: "development";
|
|
385
385
|
}>;
|
|
386
386
|
account: z.ZodString;
|
|
387
387
|
domain: z.ZodOptional<z.ZodString>;
|
|
@@ -508,9 +508,9 @@ declare const RuntimeConfigSchema: z.ZodObject<{
|
|
|
508
508
|
type RuntimeConfig = z.infer<typeof RuntimeConfigSchema>;
|
|
509
509
|
declare const ClientRuntimeConfigSchema: z.ZodObject<{
|
|
510
510
|
env: z.ZodEnum<{
|
|
511
|
-
development: "development";
|
|
512
511
|
production: "production";
|
|
513
512
|
staging: "staging";
|
|
513
|
+
development: "development";
|
|
514
514
|
}>;
|
|
515
515
|
account: z.ZodString;
|
|
516
516
|
networkId: z.ZodEnum<{
|
package/dist/ui/index.cjs
CHANGED
|
@@ -21,4 +21,5 @@ exports.getRemoteScripts = require_ui_head.getRemoteScripts;
|
|
|
21
21
|
exports.getRuntimeConfig = require_ui_runtime.getRuntimeConfig;
|
|
22
22
|
exports.getScriptKey = require_ui_router.getScriptKey;
|
|
23
23
|
exports.getSocialImageMeta = require_ui_metadata.getSocialImageMeta;
|
|
24
|
-
exports.getThemeInitScript = require_ui_head.getThemeInitScript;
|
|
24
|
+
exports.getThemeInitScript = require_ui_head.getThemeInitScript;
|
|
25
|
+
exports.serializeHeadData = require_ui_router.serializeHeadData;
|
package/dist/ui/index.d.cts
CHANGED
|
@@ -2,6 +2,6 @@ import { ClientRuntimeInfo } from "../types.cjs";
|
|
|
2
2
|
import { CreateRouterOptions, HeadData, HeadLink, HeadMeta, HeadScript, RenderOptions, RenderOptionsWithApi, RenderResult, RouterContext, RouterContextWithApi, RouterModule } from "./types.cjs";
|
|
3
3
|
import { RemoteScriptsOptions, getBaseStyles, getHydrateScript, getRemoteScripts, getThemeInitScript } from "./head.cjs";
|
|
4
4
|
import { DotIconSvgOptions, SOCIAL_IMAGE_HEIGHT, SOCIAL_IMAGE_WIDTH, SocialImageMetaOptions, createDotIconSvg, createPngIcoBuffer, getSocialImageMeta } from "./metadata.cjs";
|
|
5
|
-
import { collectHeadData, getLinkKey, getMetaKey, getScriptKey } from "./router.cjs";
|
|
5
|
+
import { collectHeadData, getLinkKey, getMetaKey, getScriptKey, serializeHeadData } from "./router.cjs";
|
|
6
6
|
import { buildPublishedAccountHref, buildPublishedGatewayHref, buildRuntimeHref, getCspNonce, getRuntimeConfig } from "./runtime.cjs";
|
|
7
|
-
export { ClientRuntimeInfo, CreateRouterOptions, DotIconSvgOptions, HeadData, HeadLink, HeadMeta, HeadScript, RemoteScriptsOptions, RenderOptions, RenderOptionsWithApi, RenderResult, RouterContext, RouterContextWithApi, RouterModule, SOCIAL_IMAGE_HEIGHT, SOCIAL_IMAGE_WIDTH, SocialImageMetaOptions, buildPublishedAccountHref, buildPublishedGatewayHref, buildRuntimeHref, collectHeadData, createDotIconSvg, createPngIcoBuffer, getBaseStyles, getCspNonce, getHydrateScript, getLinkKey, getMetaKey, getRemoteScripts, getRuntimeConfig, getScriptKey, getSocialImageMeta, getThemeInitScript };
|
|
7
|
+
export { ClientRuntimeInfo, CreateRouterOptions, DotIconSvgOptions, HeadData, HeadLink, HeadMeta, HeadScript, RemoteScriptsOptions, RenderOptions, RenderOptionsWithApi, RenderResult, RouterContext, RouterContextWithApi, RouterModule, SOCIAL_IMAGE_HEIGHT, SOCIAL_IMAGE_WIDTH, SocialImageMetaOptions, buildPublishedAccountHref, buildPublishedGatewayHref, buildRuntimeHref, collectHeadData, createDotIconSvg, createPngIcoBuffer, getBaseStyles, getCspNonce, getHydrateScript, getLinkKey, getMetaKey, getRemoteScripts, getRuntimeConfig, getScriptKey, getSocialImageMeta, getThemeInitScript, serializeHeadData };
|
package/dist/ui/index.d.mts
CHANGED
|
@@ -2,6 +2,6 @@ import { ClientRuntimeInfo } from "../types.mjs";
|
|
|
2
2
|
import { CreateRouterOptions, HeadData, HeadLink, HeadMeta, HeadScript, RenderOptions, RenderOptionsWithApi, RenderResult, RouterContext, RouterContextWithApi, RouterModule } from "./types.mjs";
|
|
3
3
|
import { RemoteScriptsOptions, getBaseStyles, getHydrateScript, getRemoteScripts, getThemeInitScript } from "./head.mjs";
|
|
4
4
|
import { DotIconSvgOptions, SOCIAL_IMAGE_HEIGHT, SOCIAL_IMAGE_WIDTH, SocialImageMetaOptions, createDotIconSvg, createPngIcoBuffer, getSocialImageMeta } from "./metadata.mjs";
|
|
5
|
-
import { collectHeadData, getLinkKey, getMetaKey, getScriptKey } from "./router.mjs";
|
|
5
|
+
import { collectHeadData, getLinkKey, getMetaKey, getScriptKey, serializeHeadData } from "./router.mjs";
|
|
6
6
|
import { buildPublishedAccountHref, buildPublishedGatewayHref, buildRuntimeHref, getCspNonce, getRuntimeConfig } from "./runtime.mjs";
|
|
7
|
-
export { ClientRuntimeInfo, CreateRouterOptions, DotIconSvgOptions, HeadData, HeadLink, HeadMeta, HeadScript, RemoteScriptsOptions, RenderOptions, RenderOptionsWithApi, RenderResult, RouterContext, RouterContextWithApi, RouterModule, SOCIAL_IMAGE_HEIGHT, SOCIAL_IMAGE_WIDTH, SocialImageMetaOptions, buildPublishedAccountHref, buildPublishedGatewayHref, buildRuntimeHref, collectHeadData, createDotIconSvg, createPngIcoBuffer, getBaseStyles, getCspNonce, getHydrateScript, getLinkKey, getMetaKey, getRemoteScripts, getRuntimeConfig, getScriptKey, getSocialImageMeta, getThemeInitScript };
|
|
7
|
+
export { ClientRuntimeInfo, CreateRouterOptions, DotIconSvgOptions, HeadData, HeadLink, HeadMeta, HeadScript, RemoteScriptsOptions, RenderOptions, RenderOptionsWithApi, RenderResult, RouterContext, RouterContextWithApi, RouterModule, SOCIAL_IMAGE_HEIGHT, SOCIAL_IMAGE_WIDTH, SocialImageMetaOptions, buildPublishedAccountHref, buildPublishedGatewayHref, buildRuntimeHref, collectHeadData, createDotIconSvg, createPngIcoBuffer, getBaseStyles, getCspNonce, getHydrateScript, getLinkKey, getMetaKey, getRemoteScripts, getRuntimeConfig, getScriptKey, getSocialImageMeta, getThemeInitScript, serializeHeadData };
|
package/dist/ui/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getBaseStyles, getHydrateScript, getRemoteScripts, getThemeInitScript } from "./head.mjs";
|
|
2
2
|
import { SOCIAL_IMAGE_HEIGHT, SOCIAL_IMAGE_WIDTH, createDotIconSvg, createPngIcoBuffer, getSocialImageMeta } from "./metadata.mjs";
|
|
3
|
-
import { collectHeadData, getLinkKey, getMetaKey, getScriptKey } from "./router.mjs";
|
|
3
|
+
import { collectHeadData, getLinkKey, getMetaKey, getScriptKey, serializeHeadData } from "./router.mjs";
|
|
4
4
|
import { buildPublishedAccountHref, buildPublishedGatewayHref, buildRuntimeHref, getCspNonce, getRuntimeConfig } from "./runtime.mjs";
|
|
5
5
|
|
|
6
|
-
export { SOCIAL_IMAGE_HEIGHT, SOCIAL_IMAGE_WIDTH, buildPublishedAccountHref, buildPublishedGatewayHref, buildRuntimeHref, collectHeadData, createDotIconSvg, createPngIcoBuffer, getBaseStyles, getCspNonce, getHydrateScript, getLinkKey, getMetaKey, getRemoteScripts, getRuntimeConfig, getScriptKey, getSocialImageMeta, getThemeInitScript };
|
|
6
|
+
export { SOCIAL_IMAGE_HEIGHT, SOCIAL_IMAGE_WIDTH, buildPublishedAccountHref, buildPublishedGatewayHref, buildRuntimeHref, collectHeadData, createDotIconSvg, createPngIcoBuffer, getBaseStyles, getCspNonce, getHydrateScript, getLinkKey, getMetaKey, getRemoteScripts, getRuntimeConfig, getScriptKey, getSocialImageMeta, getThemeInitScript, serializeHeadData };
|
package/dist/ui/router.cjs
CHANGED
|
@@ -47,10 +47,50 @@ async function collectHeadData(router) {
|
|
|
47
47
|
scripts: [...scriptMap.values()]
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
|
+
function escapeHtml(s) {
|
|
51
|
+
return s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
52
|
+
}
|
|
53
|
+
function serializeMeta(meta) {
|
|
54
|
+
if (!meta) return "";
|
|
55
|
+
if ("charSet" in meta) return `<meta charset="${escapeHtml(String(meta.charSet))}">`;
|
|
56
|
+
if ("title" in meta) return `<title>${escapeHtml(String(meta.title))}</title>`;
|
|
57
|
+
return `<meta ${Object.entries(meta).filter(([, v]) => v != null).map(([k, v]) => `${k}="${escapeHtml(String(v))}"`).join(" ")}>`;
|
|
58
|
+
}
|
|
59
|
+
function serializeLink(link) {
|
|
60
|
+
if (!link) return "";
|
|
61
|
+
return `<link ${Object.entries(link).filter(([, v]) => v != null).map(([k, v]) => `${k}="${escapeHtml(String(v))}"`).join(" ")}>`;
|
|
62
|
+
}
|
|
63
|
+
function serializeScript(script, cspNonce) {
|
|
64
|
+
if (!script) return "";
|
|
65
|
+
if ("src" in script && script.src) {
|
|
66
|
+
const attrs = [`src="${escapeHtml(script.src)}"`];
|
|
67
|
+
if (script.integrity) attrs.push(`integrity="${escapeHtml(script.integrity)}"`);
|
|
68
|
+
if (script.crossOrigin) attrs.push(`crossorigin="${escapeHtml(script.crossOrigin)}"`);
|
|
69
|
+
if (script.type) attrs.push(`type="${escapeHtml(script.type)}"`);
|
|
70
|
+
if (cspNonce) attrs.push(`nonce="${cspNonce}"`);
|
|
71
|
+
return `<script ${attrs.join(" ")}><\/script>`;
|
|
72
|
+
}
|
|
73
|
+
if ("children" in script) {
|
|
74
|
+
const attrs = [];
|
|
75
|
+
if (script.type) attrs.push(`type="${escapeHtml(script.type)}"`);
|
|
76
|
+
if (cspNonce) attrs.push(`nonce="${cspNonce}"`);
|
|
77
|
+
const content = typeof script.children === "string" ? script.children : JSON.stringify(script.children);
|
|
78
|
+
return `<script${attrs.length ? ` ${attrs.join(" ")}` : ""}>${content}<\/script>`;
|
|
79
|
+
}
|
|
80
|
+
return "";
|
|
81
|
+
}
|
|
82
|
+
function serializeHeadData(headData, cspNonce) {
|
|
83
|
+
return {
|
|
84
|
+
metaHtml: headData.meta.filter(Boolean).map((m) => serializeMeta(m)).join("\n"),
|
|
85
|
+
linkHtml: headData.links.filter(Boolean).map((l) => serializeLink(l)).join("\n"),
|
|
86
|
+
scriptHtml: headData.scripts.filter(Boolean).map((s) => serializeScript(s, cspNonce)).join("\n")
|
|
87
|
+
};
|
|
88
|
+
}
|
|
50
89
|
|
|
51
90
|
//#endregion
|
|
52
91
|
exports.collectHeadData = collectHeadData;
|
|
53
92
|
exports.getLinkKey = getLinkKey;
|
|
54
93
|
exports.getMetaKey = getMetaKey;
|
|
55
94
|
exports.getScriptKey = getScriptKey;
|
|
95
|
+
exports.serializeHeadData = serializeHeadData;
|
|
56
96
|
//# sourceMappingURL=router.cjs.map
|