@intentius/behold 0.29.15 → 0.29.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -0
- package/THIRD_PARTY.md +36 -0
- package/dist/cli.js +416 -278
- package/licenses/octicons-LICENSE +21 -0
- package/package.json +1 -1
- package/web/app.js +388 -43
- package/web/forge-mark.js +235 -0
- package/web/forge-mark.test.js +112 -0
- package/web/kiosk-runs.js +47 -2
- package/web/kiosk-vendor.js +24 -5
- package/web/kiosk-vendor.test.js +11 -2
- package/web/kiosk.html +17 -11
- package/web/kiosk.js +30 -3
- package/web/kiosk.test.js +15 -1
- package/web/theme.js +7 -3
- package/web/tool-mark.js +161 -0
- package/web/tool-mark.test.js +85 -0
- package/web/vendors/sql-yodeler-160.png +0 -0
- package/web/vendors/sql-yodeler-44.png +0 -0
package/dist/cli.js
CHANGED
|
@@ -9291,8 +9291,8 @@ __export(tree_exports, {
|
|
|
9291
9291
|
workingTree: () => workingTree
|
|
9292
9292
|
});
|
|
9293
9293
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
9294
|
-
import { readdirSync as
|
|
9295
|
-
import { join as
|
|
9294
|
+
import { readdirSync as readdirSync12, readFileSync as readFileSync22, statSync as statSync9 } from "node:fs";
|
|
9295
|
+
import { join as join29 } from "node:path";
|
|
9296
9296
|
function joinPath(...parts) {
|
|
9297
9297
|
return parts.filter((p) => p !== "" && p !== ".").join("/");
|
|
9298
9298
|
}
|
|
@@ -9301,7 +9301,7 @@ function workingTree(root) {
|
|
|
9301
9301
|
label: "",
|
|
9302
9302
|
stat(path) {
|
|
9303
9303
|
try {
|
|
9304
|
-
const s = statSync9(
|
|
9304
|
+
const s = statSync9(join29(root, path));
|
|
9305
9305
|
return s.isDirectory() ? "dir" : s.isFile() ? "file" : void 0;
|
|
9306
9306
|
} catch {
|
|
9307
9307
|
return void 0;
|
|
@@ -9310,7 +9310,7 @@ function workingTree(root) {
|
|
|
9310
9310
|
list(path) {
|
|
9311
9311
|
let dirents;
|
|
9312
9312
|
try {
|
|
9313
|
-
dirents =
|
|
9313
|
+
dirents = readdirSync12(join29(root, path), { withFileTypes: true });
|
|
9314
9314
|
} catch {
|
|
9315
9315
|
return void 0;
|
|
9316
9316
|
}
|
|
@@ -9319,7 +9319,7 @@ function workingTree(root) {
|
|
|
9319
9319
|
let type = d.isDirectory() ? "dir" : d.isFile() ? "file" : void 0;
|
|
9320
9320
|
if (!type && d.isSymbolicLink()) {
|
|
9321
9321
|
try {
|
|
9322
|
-
const s = statSync9(
|
|
9322
|
+
const s = statSync9(join29(root, path, d.name));
|
|
9323
9323
|
type = s.isDirectory() ? "dir" : s.isFile() ? "file" : void 0;
|
|
9324
9324
|
} catch {
|
|
9325
9325
|
}
|
|
@@ -9329,10 +9329,10 @@ function workingTree(root) {
|
|
|
9329
9329
|
return out;
|
|
9330
9330
|
},
|
|
9331
9331
|
read(path) {
|
|
9332
|
-
return
|
|
9332
|
+
return readFileSync22(join29(root, path), "utf-8");
|
|
9333
9333
|
},
|
|
9334
9334
|
bytes(path) {
|
|
9335
|
-
return
|
|
9335
|
+
return readFileSync22(join29(root, path));
|
|
9336
9336
|
}
|
|
9337
9337
|
};
|
|
9338
9338
|
}
|
|
@@ -9934,12 +9934,12 @@ var init_identity_gate_rule = __esm({
|
|
|
9934
9934
|
});
|
|
9935
9935
|
|
|
9936
9936
|
// node_modules/@intentius/chant/src/workspace/class-data.ts
|
|
9937
|
-
import { existsSync as
|
|
9938
|
-
import { dirname as dirname7, join as
|
|
9937
|
+
import { existsSync as existsSync19, readFileSync as readFileSync23, statSync as statSync10 } from "node:fs";
|
|
9938
|
+
import { dirname as dirname7, join as join30, posix as posix2, resolve as resolve15 } from "node:path";
|
|
9939
9939
|
function diskFiles(dir) {
|
|
9940
9940
|
return (path) => {
|
|
9941
9941
|
try {
|
|
9942
|
-
return
|
|
9942
|
+
return readFileSync23(join30(dir, ...path.split("/")), "utf-8");
|
|
9943
9943
|
} catch {
|
|
9944
9944
|
return void 0;
|
|
9945
9945
|
}
|
|
@@ -9947,9 +9947,9 @@ function diskFiles(dir) {
|
|
|
9947
9947
|
}
|
|
9948
9948
|
function findInstalledPackage(name, fromDir) {
|
|
9949
9949
|
for (let dir = resolve15(fromDir); ; dir = dirname7(dir)) {
|
|
9950
|
-
const candidate =
|
|
9950
|
+
const candidate = join30(dir, "node_modules", ...name.split("/"));
|
|
9951
9951
|
try {
|
|
9952
|
-
if (statSync10(candidate).isDirectory() &&
|
|
9952
|
+
if (statSync10(candidate).isDirectory() && existsSync19(join30(candidate, "package.json"))) return candidate;
|
|
9953
9953
|
} catch {
|
|
9954
9954
|
}
|
|
9955
9955
|
if (dirname7(dir) === dir) return void 0;
|
|
@@ -10399,10 +10399,10 @@ var init_jsonc = __esm({
|
|
|
10399
10399
|
});
|
|
10400
10400
|
|
|
10401
10401
|
// node_modules/@intentius/chant/src/package-version.ts
|
|
10402
|
-
import { readFileSync as
|
|
10402
|
+
import { readFileSync as readFileSync24 } from "node:fs";
|
|
10403
10403
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
10404
10404
|
function readChantPackageVersion() {
|
|
10405
|
-
return JSON.parse(
|
|
10405
|
+
return JSON.parse(readFileSync24(fileURLToPath4(new URL("../package.json", import.meta.url)), "utf-8")).version;
|
|
10406
10406
|
}
|
|
10407
10407
|
var init_package_version = __esm({
|
|
10408
10408
|
"node_modules/@intentius/chant/src/package-version.ts"() {
|
|
@@ -11201,8 +11201,8 @@ var init_declaration = __esm({
|
|
|
11201
11201
|
});
|
|
11202
11202
|
|
|
11203
11203
|
// src/cli.ts
|
|
11204
|
-
import { resolve as resolve35, dirname as dirname21, join as
|
|
11205
|
-
import { realpathSync as realpathSync3, existsSync as
|
|
11204
|
+
import { resolve as resolve35, dirname as dirname21, join as join54 } from "node:path";
|
|
11205
|
+
import { realpathSync as realpathSync3, existsSync as existsSync33, readFileSync as readFileSync42, rmSync as rmSync4 } from "node:fs";
|
|
11206
11206
|
import { fileURLToPath as fileURLToPath12 } from "node:url";
|
|
11207
11207
|
import { spawn as spawn9, spawnSync as spawnSync4 } from "node:child_process";
|
|
11208
11208
|
|
|
@@ -11260,8 +11260,8 @@ import { serve } from "@hono/node-server";
|
|
|
11260
11260
|
import { fileURLToPath as fileURLToPath10 } from "node:url";
|
|
11261
11261
|
import { execFile as execFile5 } from "node:child_process";
|
|
11262
11262
|
import { promisify as promisify3 } from "node:util";
|
|
11263
|
-
import { existsSync as
|
|
11264
|
-
import { basename as basename5, dirname as dirname18, join as
|
|
11263
|
+
import { existsSync as existsSync30, readFileSync as readFileSync38 } from "node:fs";
|
|
11264
|
+
import { basename as basename5, dirname as dirname18, join as join50, relative as relative11, resolve as resolve32, sep as sep10 } from "node:path";
|
|
11265
11265
|
|
|
11266
11266
|
// src/recents.ts
|
|
11267
11267
|
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
|
|
@@ -13667,10 +13667,10 @@ function joinNamespaceBindings(members, isDir = realIsDir) {
|
|
|
13667
13667
|
if (!winner || tied) continue;
|
|
13668
13668
|
const prev = best.get(winner.dir);
|
|
13669
13669
|
if (prev === "ambiguous") continue;
|
|
13670
|
-
const
|
|
13671
|
-
if (!prev) best.set(winner.dir, { score: winner.score, join:
|
|
13670
|
+
const join55 = { dir: winner.dir, namespace: b.namespace, path: b.path, declaredBy: b.declaredBy };
|
|
13671
|
+
if (!prev) best.set(winner.dir, { score: winner.score, join: join55 });
|
|
13672
13672
|
else if (prev.join.namespace !== b.namespace) best.set(winner.dir, "ambiguous");
|
|
13673
|
-
else if (winner.score > prev.score) best.set(winner.dir, { score: winner.score, join:
|
|
13673
|
+
else if (winner.score > prev.score) best.set(winner.dir, { score: winner.score, join: join55 });
|
|
13674
13674
|
}
|
|
13675
13675
|
return [...best.values()].filter((v) => v !== "ambiguous").map((v) => v.join);
|
|
13676
13676
|
}
|
|
@@ -15149,6 +15149,135 @@ function resourcesByRoot(ir, rootOf2) {
|
|
|
15149
15149
|
return byComponent;
|
|
15150
15150
|
}
|
|
15151
15151
|
|
|
15152
|
+
// src/pipeline-marks.ts
|
|
15153
|
+
init_yaml();
|
|
15154
|
+
init_terragrunt_units();
|
|
15155
|
+
import { existsSync as existsSync11, readdirSync as readdirSync9, readFileSync as readFileSync12 } from "node:fs";
|
|
15156
|
+
import { extname, join as join17 } from "node:path";
|
|
15157
|
+
var PIPELINE_FORGES = ["forgejo", "github", "gitlab"];
|
|
15158
|
+
var WORKFLOW_PLACES = [
|
|
15159
|
+
["forgejo", ".forgejo/workflows"],
|
|
15160
|
+
["github", ".github/workflows"],
|
|
15161
|
+
["gitlab", ".gitlab-ci.yml"]
|
|
15162
|
+
];
|
|
15163
|
+
function forgeOfName(name) {
|
|
15164
|
+
const s = typeof name === "string" ? name.trim().toLowerCase() : "";
|
|
15165
|
+
return PIPELINE_FORGES.find((f) => s === f || s.startsWith(`${f} `) || s.startsWith(`${f}-`));
|
|
15166
|
+
}
|
|
15167
|
+
function forgeOfPipelinePath(path) {
|
|
15168
|
+
const p = path.replace(/\\/g, "/").replace(/^\.\/+/, "");
|
|
15169
|
+
if (/(^|\/)\.forgejo\/workflows(\/|$)/.test(p)) return "forgejo";
|
|
15170
|
+
if (/(^|\/)\.github\/workflows(\/|$)/.test(p)) return "github";
|
|
15171
|
+
if (/(^|\/)\.gitlab-ci\.ya?ml$/.test(p)) return "gitlab";
|
|
15172
|
+
return void 0;
|
|
15173
|
+
}
|
|
15174
|
+
function toolOfBinary(binary) {
|
|
15175
|
+
const b = typeof binary === "string" ? binary.trim().toLowerCase().split("/").pop() ?? "" : "";
|
|
15176
|
+
if (b === "tofu" || b === "opentofu") return "opentofu";
|
|
15177
|
+
if (b === "terraform") return "terraform";
|
|
15178
|
+
if (b === "choudoufu") return "choudoufu";
|
|
15179
|
+
return void 0;
|
|
15180
|
+
}
|
|
15181
|
+
function configKeys(file) {
|
|
15182
|
+
if (!file) return {};
|
|
15183
|
+
let text2;
|
|
15184
|
+
try {
|
|
15185
|
+
text2 = readFileSync12(file, "utf8");
|
|
15186
|
+
} catch {
|
|
15187
|
+
return {};
|
|
15188
|
+
}
|
|
15189
|
+
if (extname(file) === ".ts") {
|
|
15190
|
+
const pick = (k) => new RegExp(`(^|[\\s,{])${k}\\s*:\\s*["']([^"']+)["']`).exec(text2)?.[2];
|
|
15191
|
+
const out = {};
|
|
15192
|
+
const forge = pick("forge");
|
|
15193
|
+
const binary = pick("binary");
|
|
15194
|
+
if (forge) out.forge = forge;
|
|
15195
|
+
if (binary) out.binary = binary;
|
|
15196
|
+
return out;
|
|
15197
|
+
}
|
|
15198
|
+
let doc;
|
|
15199
|
+
try {
|
|
15200
|
+
doc = parseYAMLDocument(text2);
|
|
15201
|
+
} catch {
|
|
15202
|
+
return {};
|
|
15203
|
+
}
|
|
15204
|
+
if (!doc || typeof doc !== "object" || Array.isArray(doc)) return {};
|
|
15205
|
+
const d = doc;
|
|
15206
|
+
return {
|
|
15207
|
+
...typeof d.forge === "string" ? { forge: d.forge } : {},
|
|
15208
|
+
...typeof d.binary === "string" ? { binary: d.binary } : {}
|
|
15209
|
+
};
|
|
15210
|
+
}
|
|
15211
|
+
function pipelineForge(decl, dir, config) {
|
|
15212
|
+
const declared = forgeOfName(decl?.pipeline.forge);
|
|
15213
|
+
if (declared) return { forge: declared, from: "declared" };
|
|
15214
|
+
const configured = forgeOfName(configKeys(config).forge);
|
|
15215
|
+
if (configured) return { forge: configured, from: "config" };
|
|
15216
|
+
const byPath = decl?.pipeline.path ? forgeOfPipelinePath(decl.pipeline.path) : void 0;
|
|
15217
|
+
if (byPath) return { forge: byPath, from: "pipeline-path" };
|
|
15218
|
+
const present2 = WORKFLOW_PLACES.filter(([, p]) => existsSync11(join17(dir, p))).map(([f]) => f);
|
|
15219
|
+
return present2.length === 1 ? { forge: present2[0], from: "workflow-dir" } : void 0;
|
|
15220
|
+
}
|
|
15221
|
+
function chantWorkspaceWithMembers(dir) {
|
|
15222
|
+
try {
|
|
15223
|
+
const doc = JSON.parse(readFileSync12(join17(dir, "chant.workspace.json"), "utf8"));
|
|
15224
|
+
return Array.isArray(doc.members) && doc.members.length > 0;
|
|
15225
|
+
} catch {
|
|
15226
|
+
return false;
|
|
15227
|
+
}
|
|
15228
|
+
}
|
|
15229
|
+
function atmosRepo(dir) {
|
|
15230
|
+
if (existsSync11(join17(dir, "atmos.yaml")) || existsSync11(join17(dir, "atmos.yml"))) return true;
|
|
15231
|
+
return existsSync11(join17(dir, "stacks")) && existsSync11(join17(dir, "components", "terraform"));
|
|
15232
|
+
}
|
|
15233
|
+
function sqlYodelerRepo(dir) {
|
|
15234
|
+
if (existsSync11(join17(dir, "yodel.config.ts"))) return true;
|
|
15235
|
+
if (!existsSync11(join17(dir, "migrations"))) return false;
|
|
15236
|
+
try {
|
|
15237
|
+
const pkg = JSON.parse(readFileSync12(join17(dir, "package.json"), "utf8"));
|
|
15238
|
+
return ["dependencies", "devDependencies"].some((k) => !!pkg[k]?.["@intentius/sql-yodeler"]);
|
|
15239
|
+
} catch {
|
|
15240
|
+
return false;
|
|
15241
|
+
}
|
|
15242
|
+
}
|
|
15243
|
+
function repoTools(dir, config, has = {}) {
|
|
15244
|
+
const out = [];
|
|
15245
|
+
if ((has.terragrunt ?? hasTerragruntUnits)(dir)) out.push("terragrunt");
|
|
15246
|
+
else if (existsSync11(join17(dir, "cdktf.json")) || existsSync11(join17(dir, "cdktn.json"))) out.push("cdk-terrain");
|
|
15247
|
+
else if (atmosRepo(dir)) out.push("atmos");
|
|
15248
|
+
else if (chantWorkspaceWithMembers(dir)) out.push("chant");
|
|
15249
|
+
if (sqlYodelerRepo(dir)) out.push("sql-yodeler");
|
|
15250
|
+
const engine = toolOfBinary(configKeys(config).binary);
|
|
15251
|
+
if (engine) out.push(engine);
|
|
15252
|
+
return out;
|
|
15253
|
+
}
|
|
15254
|
+
function sqlYodelerProjectIn(dir) {
|
|
15255
|
+
if (existsSync11(join17(dir, "yodel.config.ts")) || existsSync11(join17(dir, "yodel-waves.json"))) return true;
|
|
15256
|
+
return existsSync11(join17(dir, "migrations")) && (existsSync11(join17(dir, "chant.config.ts")) || sqlYodelerRepo(dir));
|
|
15257
|
+
}
|
|
15258
|
+
var SKIP_DIRS4 = /* @__PURE__ */ new Set(["node_modules", ".terraform", ".terragrunt-cache", ".git"]);
|
|
15259
|
+
function rootTools(repo, rootDir) {
|
|
15260
|
+
const top = join17(repo, rootDir);
|
|
15261
|
+
const dirs = [top];
|
|
15262
|
+
const kids = (d) => {
|
|
15263
|
+
try {
|
|
15264
|
+
return readdirSync9(d, { withFileTypes: true }).filter((e) => e.isDirectory() && !SKIP_DIRS4.has(e.name) && e.name !== "migrations").map((e) => join17(d, e.name));
|
|
15265
|
+
} catch {
|
|
15266
|
+
return [];
|
|
15267
|
+
}
|
|
15268
|
+
};
|
|
15269
|
+
for (const k of kids(top)) dirs.push(k, ...kids(k));
|
|
15270
|
+
return dirs.some(sqlYodelerProjectIn) ? ["sql-yodeler"] : [];
|
|
15271
|
+
}
|
|
15272
|
+
function declaredRootTools(repo, roots) {
|
|
15273
|
+
const out = {};
|
|
15274
|
+
for (const [name, r] of Object.entries(roots)) {
|
|
15275
|
+
const tools = rootTools(repo, r.dir.replace(/^\.\/+/, "").replace(/\/+$/, "") || ".");
|
|
15276
|
+
if (tools.length) out[name] = tools;
|
|
15277
|
+
}
|
|
15278
|
+
return out;
|
|
15279
|
+
}
|
|
15280
|
+
|
|
15152
15281
|
// src/server.ts
|
|
15153
15282
|
init_terragucci_components();
|
|
15154
15283
|
init_terragrunt_units();
|
|
@@ -15238,10 +15367,10 @@ import {
|
|
|
15238
15367
|
} from "@intentius/pinhole";
|
|
15239
15368
|
|
|
15240
15369
|
// src/icon-packs.ts
|
|
15241
|
-
import { readFileSync as
|
|
15242
|
-
import { dirname as dirname5, join as
|
|
15370
|
+
import { readFileSync as readFileSync13 } from "node:fs";
|
|
15371
|
+
import { dirname as dirname5, join as join18 } from "node:path";
|
|
15243
15372
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
15244
|
-
var ICON_ROOT =
|
|
15373
|
+
var ICON_ROOT = join18(dirname5(fileURLToPath3(import.meta.url)), "..", "web", "icons");
|
|
15245
15374
|
var cache4 = /* @__PURE__ */ new Map();
|
|
15246
15375
|
function unprefix(body) {
|
|
15247
15376
|
return body.replace(/\s(?:inkscape|sodipodi):[\w-]+\s*=\s*(["'])[\s\S]*?\1/g, "").replace(/\sxlink:href\s*=/g, " href=");
|
|
@@ -15263,7 +15392,7 @@ function plate(glyph) {
|
|
|
15263
15392
|
function loadIcon(rel) {
|
|
15264
15393
|
const hit = cache4.get(rel);
|
|
15265
15394
|
if (hit) return hit;
|
|
15266
|
-
const raw =
|
|
15395
|
+
const raw = readFileSync13(join18(ICON_ROOT, `${rel}.svg`), "utf8");
|
|
15267
15396
|
const open = raw.indexOf("<svg");
|
|
15268
15397
|
const openEnd = raw.indexOf(">", open);
|
|
15269
15398
|
const close = raw.lastIndexOf("</svg");
|
|
@@ -17398,12 +17527,12 @@ init_carve_manifest();
|
|
|
17398
17527
|
|
|
17399
17528
|
// src/carve-actions.ts
|
|
17400
17529
|
init_chant();
|
|
17401
|
-
import { existsSync as
|
|
17402
|
-
import { isAbsolute as isAbsolute3, join as
|
|
17530
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync5, readFileSync as readFileSync16, readdirSync as readdirSync10, statSync as statSync7 } from "node:fs";
|
|
17531
|
+
import { isAbsolute as isAbsolute3, join as join21, relative as relative5, resolve as resolve12, sep as sep6 } from "node:path";
|
|
17403
17532
|
|
|
17404
17533
|
// src/layout.ts
|
|
17405
|
-
import { existsSync as
|
|
17406
|
-
import { join as
|
|
17534
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync4, readFileSync as readFileSync14, renameSync, rmSync as rmSync2, writeFileSync as writeFileSync4, accessSync, constants } from "node:fs";
|
|
17535
|
+
import { join as join19 } from "node:path";
|
|
17407
17536
|
var LAYOUT_DIR = ".behold";
|
|
17408
17537
|
var LAYOUT_FILE = "layout.json";
|
|
17409
17538
|
var MAX_BODY_BYTES = 64 * 1024;
|
|
@@ -17444,10 +17573,10 @@ function lensFromQuery(params) {
|
|
|
17444
17573
|
return [slug2(zoom), params.get("radial") === "1" ? "radial" : null, stack ? slug2(`stack-${stack}`) : null].filter(Boolean).join("+");
|
|
17445
17574
|
}
|
|
17446
17575
|
function layoutPath(projectDir) {
|
|
17447
|
-
return
|
|
17576
|
+
return join19(projectDir, LAYOUT_DIR, LAYOUT_FILE);
|
|
17448
17577
|
}
|
|
17449
17578
|
function unwritableReason(projectDir) {
|
|
17450
|
-
if (!projectDir || !
|
|
17579
|
+
if (!projectDir || !existsSync12(projectDir)) return `no such project directory: ${projectDir || "(none)"}`;
|
|
17451
17580
|
try {
|
|
17452
17581
|
accessSync(projectDir, constants.W_OK);
|
|
17453
17582
|
} catch {
|
|
@@ -17459,8 +17588,8 @@ function readLayoutFile(projectDir) {
|
|
|
17459
17588
|
const empty = { version: 1, lenses: {} };
|
|
17460
17589
|
const file = layoutPath(projectDir);
|
|
17461
17590
|
try {
|
|
17462
|
-
if (!
|
|
17463
|
-
const raw =
|
|
17591
|
+
if (!existsSync12(file)) return empty;
|
|
17592
|
+
const raw = readFileSync14(file, "utf8");
|
|
17464
17593
|
if (raw.length > MAX_FILE_BYTES) return empty;
|
|
17465
17594
|
const parsed = JSON.parse(raw);
|
|
17466
17595
|
if (!parsed || typeof parsed !== "object" || !parsed.lenses || typeof parsed.lenses !== "object") return empty;
|
|
@@ -17500,7 +17629,7 @@ function writeLens(projectDir, lens, deltas) {
|
|
|
17500
17629
|
}
|
|
17501
17630
|
const body = JSON.stringify({ version: 1, lenses }, null, 2) + "\n";
|
|
17502
17631
|
if (body.length > MAX_FILE_BYTES) throw new LayoutTooLarge(`a layout sidecar is capped at ${MAX_FILE_BYTES} bytes`);
|
|
17503
|
-
mkdirSync4(
|
|
17632
|
+
mkdirSync4(join19(projectDir, LAYOUT_DIR), { recursive: true });
|
|
17504
17633
|
const tmp = `${file}.tmp`;
|
|
17505
17634
|
writeFileSync4(tmp, body, "utf8");
|
|
17506
17635
|
renameSync(tmp, file);
|
|
@@ -17586,8 +17715,8 @@ function reanchorEdges(svg, moved) {
|
|
|
17586
17715
|
// src/carve-live.ts
|
|
17587
17716
|
init_scratch();
|
|
17588
17717
|
import { spawn as spawn4 } from "node:child_process";
|
|
17589
|
-
import { readFileSync as
|
|
17590
|
-
import { join as
|
|
17718
|
+
import { readFileSync as readFileSync15, writeFileSync as writeFileSync5, existsSync as existsSync13 } from "node:fs";
|
|
17719
|
+
import { join as join20 } from "node:path";
|
|
17591
17720
|
var LIVE_CONTAINER = "behold-carve-floci";
|
|
17592
17721
|
var LIVE_PORT = 4602;
|
|
17593
17722
|
var LIVE_IMAGE = "floci/floci:1.5.34";
|
|
@@ -17647,9 +17776,9 @@ async function teardownScratchFloci() {
|
|
|
17647
17776
|
await capture("docker", ["rm", "-f", LIVE_CONTAINER], process.cwd()).catch(() => void 0);
|
|
17648
17777
|
}
|
|
17649
17778
|
async function applyIntoFloci(fromDir, step) {
|
|
17650
|
-
const template =
|
|
17651
|
-
if (!
|
|
17652
|
-
writeFileSync5(
|
|
17779
|
+
const template = join20(fromDir, "floci-override.tf.disabled");
|
|
17780
|
+
if (!existsSync13(template)) return `no floci-override.tf.disabled in ${fromDir} \u2014 this estate wasn't authored for the live tier`;
|
|
17781
|
+
writeFileSync5(join20(fromDir, "floci_override.tf"), armOverride(readFileSync15(template, "utf8"), LIVE_PORT));
|
|
17653
17782
|
const init = await step("terraform", ["init", "-input=false", "-no-color"], fromDir);
|
|
17654
17783
|
if (init !== 0) return `terraform init exited ${init} (provider downloads need network)`;
|
|
17655
17784
|
const apply = await step(
|
|
@@ -17699,7 +17828,7 @@ async function runCarveObserve(demo, select) {
|
|
|
17699
17828
|
"run `behold demo carve --live` (needs docker + terraform)"
|
|
17700
17829
|
);
|
|
17701
17830
|
}
|
|
17702
|
-
if (!
|
|
17831
|
+
if (!existsSync14(join21(demo.out, "src"))) {
|
|
17703
17832
|
return refuse6("carve-action", "nothing has been emitted yet", "run Emit first \u2014 observe reads the carveout emit writes");
|
|
17704
17833
|
}
|
|
17705
17834
|
const args = ["lifecycle", "diff", "prod", "--live", "--json"];
|
|
@@ -17780,7 +17909,7 @@ function carveWriteBlock(demo) {
|
|
|
17780
17909
|
if (!demo) {
|
|
17781
17910
|
return "this server isn't running a carve demo \u2014 the carve actions only exist inside a `behold demo carve` copy";
|
|
17782
17911
|
}
|
|
17783
|
-
if (!
|
|
17912
|
+
if (!existsSync14(demo.from)) return `the demo copy has no Terraform estate at ${demo.from}`;
|
|
17784
17913
|
if (!insideDemo(demo.root, demo.out)) return "the carve output directory is outside the demo copy";
|
|
17785
17914
|
return unwritableReason(demo.root);
|
|
17786
17915
|
}
|
|
@@ -17790,14 +17919,14 @@ function readArtifacts(demo, dir, filter) {
|
|
|
17790
17919
|
if (out.length >= MAX_ARTIFACTS || depth > 2) return;
|
|
17791
17920
|
let entries;
|
|
17792
17921
|
try {
|
|
17793
|
-
entries =
|
|
17922
|
+
entries = readdirSync10(d).sort();
|
|
17794
17923
|
} catch {
|
|
17795
17924
|
return;
|
|
17796
17925
|
}
|
|
17797
17926
|
for (const name of entries) {
|
|
17798
17927
|
if (out.length >= MAX_ARTIFACTS) return;
|
|
17799
17928
|
if (name === "node_modules" || name.startsWith(".")) continue;
|
|
17800
|
-
const full =
|
|
17929
|
+
const full = join21(d, name);
|
|
17801
17930
|
let st;
|
|
17802
17931
|
try {
|
|
17803
17932
|
st = statSync7(full);
|
|
@@ -17812,7 +17941,7 @@ function readArtifacts(demo, dir, filter) {
|
|
|
17812
17941
|
if (!filter(rel)) continue;
|
|
17813
17942
|
let text2 = "";
|
|
17814
17943
|
try {
|
|
17815
|
-
text2 =
|
|
17944
|
+
text2 = readFileSync16(full, "utf8");
|
|
17816
17945
|
} catch {
|
|
17817
17946
|
continue;
|
|
17818
17947
|
}
|
|
@@ -17844,7 +17973,7 @@ async function runCarveEmit(demo, select) {
|
|
|
17844
17973
|
const block = carveWriteBlock(demo);
|
|
17845
17974
|
if (block) return refuse6("read-only", block, "Start the walkthrough with `behold demo carve`.");
|
|
17846
17975
|
mkdirSync5(demo.out, { recursive: true });
|
|
17847
|
-
const reportFile =
|
|
17976
|
+
const reportFile = join21(demo.out, `${carveSlug(select)}-boundary.json`);
|
|
17848
17977
|
const args = [
|
|
17849
17978
|
"carve",
|
|
17850
17979
|
"emit",
|
|
@@ -17873,10 +18002,10 @@ async function runCarveEmit(demo, select) {
|
|
|
17873
18002
|
}
|
|
17874
18003
|
let boundary = null;
|
|
17875
18004
|
try {
|
|
17876
|
-
boundary = JSON.parse(
|
|
18005
|
+
boundary = JSON.parse(readFileSync16(reportFile, "utf8"));
|
|
17877
18006
|
} catch {
|
|
17878
18007
|
}
|
|
17879
|
-
const lintPath = relative5(demo.project,
|
|
18008
|
+
const lintPath = relative5(demo.project, join21(demo.out, "src")).split(sep6).join("/");
|
|
17880
18009
|
const lintArgs = ["lint", lintPath];
|
|
17881
18010
|
const lint = await runChantRaw(lintArgs, demo.project).catch((err) => ({
|
|
17882
18011
|
code: 127,
|
|
@@ -17939,8 +18068,8 @@ async function runCarveBridge(demo, select) {
|
|
|
17939
18068
|
}
|
|
17940
18069
|
|
|
17941
18070
|
// src/ops.ts
|
|
17942
|
-
import { readdirSync as
|
|
17943
|
-
import { join as
|
|
18071
|
+
import { readdirSync as readdirSync11, readFileSync as readFileSync17, existsSync as existsSync15 } from "node:fs";
|
|
18072
|
+
import { join as join22 } from "node:path";
|
|
17944
18073
|
var APPLY_TARGET_LEXICON = {
|
|
17945
18074
|
cloudformation: "aws",
|
|
17946
18075
|
kubectl: "k8s",
|
|
@@ -17962,11 +18091,11 @@ function discoverOps(projectDir) {
|
|
|
17962
18091
|
const seen = /* @__PURE__ */ new Set();
|
|
17963
18092
|
const out = [];
|
|
17964
18093
|
for (const sub of ["ops", "src", "."]) {
|
|
17965
|
-
const dir =
|
|
17966
|
-
if (!
|
|
17967
|
-
for (const f of
|
|
18094
|
+
const dir = join22(projectDir, sub);
|
|
18095
|
+
if (!existsSync15(dir)) continue;
|
|
18096
|
+
for (const f of readdirSync11(dir)) {
|
|
17968
18097
|
if (!f.endsWith(".op.ts")) continue;
|
|
17969
|
-
const content =
|
|
18098
|
+
const content = readFileSync17(join22(dir, f), "utf8");
|
|
17970
18099
|
const name = content.match(/name:\s*["'`]([^"'`]+)["'`]/)?.[1];
|
|
17971
18100
|
if (!name || seen.has(name)) continue;
|
|
17972
18101
|
seen.add(name);
|
|
@@ -17982,25 +18111,25 @@ function discoverOps(projectDir) {
|
|
|
17982
18111
|
...gate ? { gate } : {},
|
|
17983
18112
|
...env ? { env } : {},
|
|
17984
18113
|
...substrate ? { substrate } : {},
|
|
17985
|
-
...
|
|
18114
|
+
...existsSync15(irPath) ? { irPath } : {}
|
|
17986
18115
|
});
|
|
17987
18116
|
}
|
|
17988
18117
|
}
|
|
17989
18118
|
return out.sort((a, b) => a.name.localeCompare(b.name));
|
|
17990
18119
|
}
|
|
17991
18120
|
function opIrPath(projectDir, name) {
|
|
17992
|
-
return
|
|
18121
|
+
return join22(projectDir, "dist", "ops", name, "op.json");
|
|
17993
18122
|
}
|
|
17994
18123
|
function discoverOpIrs(projectDirs) {
|
|
17995
18124
|
const seen = /* @__PURE__ */ new Set();
|
|
17996
18125
|
const out = [];
|
|
17997
18126
|
for (const dir of projectDirs) {
|
|
17998
|
-
const root =
|
|
17999
|
-
if (!
|
|
18000
|
-
for (const name of
|
|
18127
|
+
const root = join22(dir, "dist", "ops");
|
|
18128
|
+
if (!existsSync15(root)) continue;
|
|
18129
|
+
for (const name of readdirSync11(root)) {
|
|
18001
18130
|
if (seen.has(name)) continue;
|
|
18002
18131
|
const path = opIrPath(dir, name);
|
|
18003
|
-
if (!
|
|
18132
|
+
if (!existsSync15(path)) continue;
|
|
18004
18133
|
seen.add(name);
|
|
18005
18134
|
out.push({ name, dir, path });
|
|
18006
18135
|
}
|
|
@@ -18235,11 +18364,11 @@ var RAN = { ok: "ok", fail: "failed", skipped: "skipped" };
|
|
|
18235
18364
|
function tookLabel(ms) {
|
|
18236
18365
|
return ms < 1e3 ? `${ms}ms` : `${(ms / 1e3).toFixed(1)}s`;
|
|
18237
18366
|
}
|
|
18238
|
-
function paintPlayhead(ir,
|
|
18239
|
-
if (!
|
|
18367
|
+
function paintPlayhead(ir, join55, gate) {
|
|
18368
|
+
if (!join55.byNode.size && !join55.at) return ir;
|
|
18240
18369
|
const nodes = ir.nodes.map((node) => {
|
|
18241
|
-
const run3 =
|
|
18242
|
-
const here =
|
|
18370
|
+
const run3 = join55.byNode.get(node.id);
|
|
18371
|
+
const here = join55.at === node.id;
|
|
18243
18372
|
if (!run3 && !here) return node;
|
|
18244
18373
|
const isGate = node.attrs?._step === "gate";
|
|
18245
18374
|
const attrs = { ...node.attrs };
|
|
@@ -18254,7 +18383,7 @@ function paintPlayhead(ir, join54, gate) {
|
|
|
18254
18383
|
if (here) {
|
|
18255
18384
|
attrs._playhead = true;
|
|
18256
18385
|
attrs._status = isGate && gate ? "warn" : "accent";
|
|
18257
|
-
attrs.run = isGate && gate ? `waiting for approval since ${gate.since}` :
|
|
18386
|
+
attrs.run = isGate && gate ? `waiting for approval since ${gate.since}` : join55.atReason ?? "here";
|
|
18258
18387
|
if (isGate && gate?.description) attrs.gateDescription = gate.description;
|
|
18259
18388
|
}
|
|
18260
18389
|
return { ...node, attrs };
|
|
@@ -18276,11 +18405,11 @@ function pendingGateCard(op, gate, ir) {
|
|
|
18276
18405
|
}
|
|
18277
18406
|
};
|
|
18278
18407
|
}
|
|
18279
|
-
function playheadNote(state,
|
|
18408
|
+
function playheadNote(state, join55) {
|
|
18280
18409
|
if (!state.op) {
|
|
18281
18410
|
return "No run state: nothing has been run from this behold session, so every step paints as declared.";
|
|
18282
18411
|
}
|
|
18283
|
-
const settled =
|
|
18412
|
+
const settled = join55 ? join55.byNode.size : state.records.length;
|
|
18284
18413
|
const bits = [];
|
|
18285
18414
|
const head = state.status === "idle" ? `Run state for ${state.op}: no per-step records \u2014 this behold session didn't start the run, so only the gate query answers` : `Run: ${state.op} (${state.mode === "temporal" ? "durable" : "local executor"}) \u2014 ${settled} step${settled === 1 ? "" : "s"} settled`;
|
|
18286
18415
|
if (state.status === "running") {
|
|
@@ -18296,9 +18425,9 @@ function playheadNote(state, join54) {
|
|
|
18296
18425
|
} else if (state.gateNote) {
|
|
18297
18426
|
bits.push(`gate state unavailable \u2014 ${state.gateNote}`);
|
|
18298
18427
|
}
|
|
18299
|
-
if (
|
|
18428
|
+
if (join55?.unplaced.length) {
|
|
18300
18429
|
bits.push(
|
|
18301
|
-
`${
|
|
18430
|
+
`${join55.unplaced.length} record${join55.unplaced.length === 1 ? "" : "s"} matched no declared step and ${join55.unplaced.length === 1 ? "is" : "are"} not painted`
|
|
18302
18431
|
);
|
|
18303
18432
|
}
|
|
18304
18433
|
if (!bits.length) return `${head}.`;
|
|
@@ -18969,8 +19098,8 @@ var OpRunner = class {
|
|
|
18969
19098
|
};
|
|
18970
19099
|
|
|
18971
19100
|
// src/public-mode.ts
|
|
18972
|
-
import { readFileSync as
|
|
18973
|
-
import { join as
|
|
19101
|
+
import { readFileSync as readFileSync18 } from "node:fs";
|
|
19102
|
+
import { join as join23 } from "node:path";
|
|
18974
19103
|
var ReadOnlyRunner = class {
|
|
18975
19104
|
running = null;
|
|
18976
19105
|
applyProgress = initialApplyProgress;
|
|
@@ -19033,7 +19162,7 @@ function publicReadRefusal(path, query) {
|
|
|
19033
19162
|
}
|
|
19034
19163
|
var PUBLIC_FLAG = "<script>window.__BEHOLD_PUBLIC__ = true;</script>";
|
|
19035
19164
|
function publicPage(webRoot2) {
|
|
19036
|
-
const html =
|
|
19165
|
+
const html = readFileSync18(join23(webRoot2, "index.html"), "utf8");
|
|
19037
19166
|
return html.replace("</head>", ` ${PUBLIC_FLAG}
|
|
19038
19167
|
</head>`);
|
|
19039
19168
|
}
|
|
@@ -19050,8 +19179,8 @@ function publicRoutes(app, webRoot2) {
|
|
|
19050
19179
|
|
|
19051
19180
|
// src/substrates.ts
|
|
19052
19181
|
import { spawn as spawn5 } from "node:child_process";
|
|
19053
|
-
import { existsSync as
|
|
19054
|
-
import { join as
|
|
19182
|
+
import { existsSync as existsSync16, readFileSync as readFileSync19 } from "node:fs";
|
|
19183
|
+
import { join as join24 } from "node:path";
|
|
19055
19184
|
import { platform } from "node:os";
|
|
19056
19185
|
var DOCKER_DOWN_DETAIL = "docker is down";
|
|
19057
19186
|
function probe(cmd, args) {
|
|
@@ -19080,11 +19209,11 @@ async function dockerRunning(run3, nameFilter) {
|
|
|
19080
19209
|
return out.split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
|
|
19081
19210
|
}
|
|
19082
19211
|
function scriptBringUp(projectDir, relPath, label) {
|
|
19083
|
-
return
|
|
19212
|
+
return existsSync16(join24(projectDir, relPath)) ? { label, cmd: "bash", args: [relPath] } : void 0;
|
|
19084
19213
|
}
|
|
19085
19214
|
function projectLexicons(projectDir) {
|
|
19086
19215
|
try {
|
|
19087
|
-
const src =
|
|
19216
|
+
const src = readFileSync19(join24(projectDir, "chant.config.ts"), "utf-8");
|
|
19088
19217
|
const m = src.match(/lexicons\s*:\s*\[([^\]]*)\]/);
|
|
19089
19218
|
if (!m) return [];
|
|
19090
19219
|
return [...m[1].matchAll(/["']([^"']+)["']/g)].map((x) => x[1]);
|
|
@@ -19136,7 +19265,7 @@ async function detectSubstrates(projectDir, preview = false, boundContext, probe
|
|
|
19136
19265
|
["forgejo", "Forgejo", ".forgejo", "test/forgejo-runtime-e2e.sh"]
|
|
19137
19266
|
];
|
|
19138
19267
|
for (const [name, label, marker, script] of forges) {
|
|
19139
|
-
if (!
|
|
19268
|
+
if (!existsSync16(join24(projectDir, marker))) continue;
|
|
19140
19269
|
const c = docker ? await dockerRunning(run3, name) : [];
|
|
19141
19270
|
const d = dep(c.length > 0, "container up", "on-demand (pipeline run)");
|
|
19142
19271
|
subs.push({
|
|
@@ -19170,7 +19299,7 @@ async function detectSubstrates(projectDir, preview = false, boundContext, probe
|
|
|
19170
19299
|
detail: endpoint ? `targeting ${endpoint}` : "real Fly (FLY_FLAPS_BASE_URL unset)"
|
|
19171
19300
|
});
|
|
19172
19301
|
}
|
|
19173
|
-
if (
|
|
19302
|
+
if (existsSync16(join24(projectDir, ".github", "workflows"))) {
|
|
19174
19303
|
const gh = await run3("gh", ["auth", "status"]);
|
|
19175
19304
|
const ready = gh.code === 0;
|
|
19176
19305
|
subs.push({
|
|
@@ -19183,7 +19312,7 @@ async function detectSubstrates(projectDir, preview = false, boundContext, probe
|
|
|
19183
19312
|
if (lexicons.includes("temporal")) {
|
|
19184
19313
|
let hasProfiles = false;
|
|
19185
19314
|
try {
|
|
19186
|
-
hasProfiles = /temporal\s*:\s*\{[\s\S]{0,400}?profiles\s*:/.test(
|
|
19315
|
+
hasProfiles = /temporal\s*:\s*\{[\s\S]{0,400}?profiles\s*:/.test(readFileSync19(join24(projectDir, "chant.config.ts"), "utf-8"));
|
|
19187
19316
|
} catch {
|
|
19188
19317
|
}
|
|
19189
19318
|
subs.push({
|
|
@@ -19326,8 +19455,8 @@ function statusVocabulary(kinds) {
|
|
|
19326
19455
|
}
|
|
19327
19456
|
|
|
19328
19457
|
// src/behaviour.ts
|
|
19329
|
-
import { readFileSync as
|
|
19330
|
-
import { join as
|
|
19458
|
+
import { readFileSync as readFileSync20 } from "node:fs";
|
|
19459
|
+
import { join as join25 } from "node:path";
|
|
19331
19460
|
var rec5 = (v) => v && typeof v === "object" && !Array.isArray(v) ? v : void 0;
|
|
19332
19461
|
var str6 = (v) => typeof v === "string" && v.trim().length > 0 ? v : void 0;
|
|
19333
19462
|
var num = (v) => typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
@@ -19434,7 +19563,7 @@ var FIRST_TOTAL_SHOWN = "two members stated an estate total; the first is shown"
|
|
|
19434
19563
|
var behaviourFileName = (env) => `behaviour.${env}.json`;
|
|
19435
19564
|
var realRead = (path) => {
|
|
19436
19565
|
try {
|
|
19437
|
-
return
|
|
19566
|
+
return readFileSync20(path, "utf8");
|
|
19438
19567
|
} catch {
|
|
19439
19568
|
return void 0;
|
|
19440
19569
|
}
|
|
@@ -19492,7 +19621,7 @@ function attachBehaviour(ir, members, env, readFile2 = realRead) {
|
|
|
19492
19621
|
}
|
|
19493
19622
|
const file = behaviourFileName(env);
|
|
19494
19623
|
looked.push(`${label}/${file}`);
|
|
19495
|
-
const raw = readFile2(
|
|
19624
|
+
const raw = readFile2(join25(m.dir, file));
|
|
19496
19625
|
if (raw === void 0) {
|
|
19497
19626
|
sources.set(label, "none");
|
|
19498
19627
|
continue;
|
|
@@ -19928,7 +20057,7 @@ init_choudoufu_live();
|
|
|
19928
20057
|
init_choudoufu_member();
|
|
19929
20058
|
import { mkdtempSync, rmSync as rmSync3 } from "node:fs";
|
|
19930
20059
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
19931
|
-
import { join as
|
|
20060
|
+
import { join as join26 } from "node:path";
|
|
19932
20061
|
var isRecord10 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
19933
20062
|
var refuse7 = (error, remedy) => ({ ok: false, refusal: { error, code: "choudoufu-live-check", remedy } });
|
|
19934
20063
|
var CREDS2 = "Give behold the ambient read-only AWS credentials the estate's `plan` needs (AWS_PROFILE, or AWS_ENDPOINT_URL for an emulator), then re-check live with plan.";
|
|
@@ -20002,8 +20131,8 @@ var planArgv = (out) => ({
|
|
|
20002
20131
|
show: ["show", "-json", out]
|
|
20003
20132
|
});
|
|
20004
20133
|
async function readChoudoufuPlan(dir, run3 = captureChoudoufu) {
|
|
20005
|
-
const scratch = mkdtempSync(
|
|
20006
|
-
const file =
|
|
20134
|
+
const scratch = mkdtempSync(join26(tmpdir2(), "behold-choudoufu-plan-"));
|
|
20135
|
+
const file = join26(scratch, "plan.tfplan");
|
|
20007
20136
|
const argv = planArgv(file);
|
|
20008
20137
|
try {
|
|
20009
20138
|
const planRun = await run3(argv.plan, dir);
|
|
@@ -20035,8 +20164,8 @@ init_choudoufu_refs();
|
|
|
20035
20164
|
// src/choudoufu-moves.ts
|
|
20036
20165
|
init_choudoufu_member();
|
|
20037
20166
|
init_choudoufu_live();
|
|
20038
|
-
import { existsSync as
|
|
20039
|
-
import { join as
|
|
20167
|
+
import { existsSync as existsSync17, readFileSync as readFileSync21 } from "node:fs";
|
|
20168
|
+
import { join as join27, relative as relative6 } from "node:path";
|
|
20040
20169
|
var isRecord11 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
20041
20170
|
var refuse8 = (error, remedy) => ({ ok: false, refusal: { error, code: "choudoufu-live-check", remedy } });
|
|
20042
20171
|
var HOW_TO_GET_ONE2 = "A plan is the live-mv workbench's carve.json: `{from, estates[], moves[{address, from, to}]}` \u2014 the workbench's plan phase writes one, or write it by hand.";
|
|
@@ -20056,7 +20185,7 @@ function parseCarvePlan(value) {
|
|
|
20056
20185
|
}
|
|
20057
20186
|
};
|
|
20058
20187
|
}
|
|
20059
|
-
function readCarvePlan(path, readFile2 = (p) =>
|
|
20188
|
+
function readCarvePlan(path, readFile2 = (p) => readFileSync21(p, "utf8")) {
|
|
20060
20189
|
let text2;
|
|
20061
20190
|
try {
|
|
20062
20191
|
text2 = readFile2(path);
|
|
@@ -20072,8 +20201,8 @@ function readCarvePlan(path, readFile2 = (p) => readFileSync20(p, "utf8")) {
|
|
|
20072
20201
|
function discoverCarvePlans(memberDirs, base) {
|
|
20073
20202
|
const out = [];
|
|
20074
20203
|
for (const dir of memberDirs) {
|
|
20075
|
-
const p =
|
|
20076
|
-
if (
|
|
20204
|
+
const p = join27(dir, "carve.json");
|
|
20205
|
+
if (existsSync17(p)) out.push(relative6(base, p));
|
|
20077
20206
|
}
|
|
20078
20207
|
return out;
|
|
20079
20208
|
}
|
|
@@ -20302,27 +20431,27 @@ function getRuntime() {
|
|
|
20302
20431
|
}
|
|
20303
20432
|
|
|
20304
20433
|
// node_modules/@intentius/chant/src/lifecycle/member-ledger.ts
|
|
20305
|
-
import { existsSync as
|
|
20306
|
-
import { dirname as dirname8, join as
|
|
20434
|
+
import { existsSync as existsSync20 } from "node:fs";
|
|
20435
|
+
import { dirname as dirname8, join as join31, relative as relative7, resolve as resolve16, sep as sep7 } from "node:path";
|
|
20307
20436
|
|
|
20308
20437
|
// node_modules/@intentius/chant/src/project-root.ts
|
|
20309
|
-
import { existsSync as
|
|
20310
|
-
import { dirname as dirname6, join as
|
|
20438
|
+
import { existsSync as existsSync18 } from "fs";
|
|
20439
|
+
import { dirname as dirname6, join as join28, resolve as resolve14 } from "path";
|
|
20311
20440
|
var WORKSPACE_DECLARATION_FILES = ["chant.workspace.json", "chant.workspace.jsonc"];
|
|
20312
20441
|
function findWorkspaceRoot(startDir) {
|
|
20313
20442
|
const start = resolve14(startDir);
|
|
20314
20443
|
let top;
|
|
20315
20444
|
for (let dir = start; ; dir = dirname6(dir)) {
|
|
20316
|
-
if (
|
|
20445
|
+
if (existsSync18(join28(dir, ".git"))) {
|
|
20317
20446
|
top = dir;
|
|
20318
20447
|
break;
|
|
20319
20448
|
}
|
|
20320
20449
|
if (dirname6(dir) === dir) break;
|
|
20321
20450
|
}
|
|
20322
20451
|
for (let dir = start; ; dir = dirname6(dir)) {
|
|
20323
|
-
const [json2, jsonc] = WORKSPACE_DECLARATION_FILES.map((name) =>
|
|
20324
|
-
const hasJson =
|
|
20325
|
-
const hasJsonc =
|
|
20452
|
+
const [json2, jsonc] = WORKSPACE_DECLARATION_FILES.map((name) => join28(dir, name));
|
|
20453
|
+
const hasJson = existsSync18(json2);
|
|
20454
|
+
const hasJsonc = existsSync18(jsonc);
|
|
20326
20455
|
if (hasJson && hasJsonc) return { dir, file: json2, conflicting: jsonc };
|
|
20327
20456
|
if (hasJson) return { dir, file: json2 };
|
|
20328
20457
|
if (hasJsonc) return { dir, file: jsonc };
|
|
@@ -20382,7 +20511,7 @@ async function ledgerIn(root, dir) {
|
|
|
20382
20511
|
}
|
|
20383
20512
|
let outer = FLAT;
|
|
20384
20513
|
const parent = dirname8(root);
|
|
20385
|
-
if (parent !== root && !
|
|
20514
|
+
if (parent !== root && !existsSync20(join31(root, ".git"))) {
|
|
20386
20515
|
const outerFound = findWorkspaceRoot(parent);
|
|
20387
20516
|
if (outerFound) outer = await ledgerIn(outerFound.dir, root);
|
|
20388
20517
|
}
|
|
@@ -20936,8 +21065,8 @@ function decideOverride(input) {
|
|
|
20936
21065
|
}
|
|
20937
21066
|
|
|
20938
21067
|
// src/terragucci-repo.ts
|
|
20939
|
-
import { existsSync as
|
|
20940
|
-
import { dirname as dirname9, join as
|
|
21068
|
+
import { existsSync as existsSync21 } from "node:fs";
|
|
21069
|
+
import { dirname as dirname9, join as join32, resolve as resolve17 } from "node:path";
|
|
20941
21070
|
var TERRAGUCCI_CONFIG_NAMES = ["terragucci.yml", "terragucci.yaml", "terragucci.json", "terragucci.ts"];
|
|
20942
21071
|
function terragucciConfig(dir) {
|
|
20943
21072
|
return walkUp(dir, TERRAGUCCI_CONFIG_NAMES);
|
|
@@ -20946,10 +21075,10 @@ function walkUp(dir, names) {
|
|
|
20946
21075
|
let at2 = resolve17(dir);
|
|
20947
21076
|
for (; ; ) {
|
|
20948
21077
|
for (const name of names) {
|
|
20949
|
-
const file =
|
|
20950
|
-
if (
|
|
21078
|
+
const file = join32(at2, name);
|
|
21079
|
+
if (existsSync21(file)) return file;
|
|
20951
21080
|
}
|
|
20952
|
-
if (
|
|
21081
|
+
if (existsSync21(join32(at2, ".git"))) return void 0;
|
|
20953
21082
|
const up = dirname9(at2);
|
|
20954
21083
|
if (up === at2) return void 0;
|
|
20955
21084
|
at2 = up;
|
|
@@ -21752,8 +21881,8 @@ init_read_stats();
|
|
|
21752
21881
|
init_foreign();
|
|
21753
21882
|
|
|
21754
21883
|
// src/events.ts
|
|
21755
|
-
import { watch, existsSync as
|
|
21756
|
-
import { join as
|
|
21884
|
+
import { watch, existsSync as existsSync22 } from "node:fs";
|
|
21885
|
+
import { join as join33 } from "node:path";
|
|
21757
21886
|
var Broadcaster = class {
|
|
21758
21887
|
listeners = /* @__PURE__ */ new Set();
|
|
21759
21888
|
subscribe(fn) {
|
|
@@ -21771,7 +21900,7 @@ var Broadcaster = class {
|
|
|
21771
21900
|
};
|
|
21772
21901
|
var IGNORE = /(^|[\\/])(node_modules|dist|\.git)([\\/]|$)/;
|
|
21773
21902
|
function watchSource(projectDir, onChange, debounceMs = 200) {
|
|
21774
|
-
const dir =
|
|
21903
|
+
const dir = existsSync22(join33(projectDir, "src")) ? join33(projectDir, "src") : projectDir;
|
|
21775
21904
|
let timer;
|
|
21776
21905
|
const watcher = watch(dir, { recursive: true }, (_event, file) => {
|
|
21777
21906
|
const name = typeof file === "string" ? file : "";
|
|
@@ -22075,27 +22204,27 @@ async function emulatorDown(projectDir) {
|
|
|
22075
22204
|
|
|
22076
22205
|
// src/terragucci-view.ts
|
|
22077
22206
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
22078
|
-
import { dirname as dirname13, join as
|
|
22207
|
+
import { dirname as dirname13, join as join42, relative as relative9, sep as sep8 } from "node:path";
|
|
22079
22208
|
init_terraform_member();
|
|
22080
22209
|
|
|
22081
22210
|
// src/terragucci-reports.ts
|
|
22082
|
-
import { readFileSync as
|
|
22211
|
+
import { readFileSync as readFileSync26, statSync as statSync11 } from "node:fs";
|
|
22083
22212
|
import { createRequire as createRequire4 } from "node:module";
|
|
22084
|
-
import { dirname as dirname10, join as
|
|
22213
|
+
import { dirname as dirname10, join as join36, resolve as resolve21 } from "node:path";
|
|
22085
22214
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
22086
22215
|
import { Ajv2020 } from "ajv/dist/2020.js";
|
|
22087
22216
|
|
|
22088
22217
|
// src/terragucci-lifecycle.ts
|
|
22089
22218
|
import { execFile as execFile4 } from "node:child_process";
|
|
22090
22219
|
import { createHash as createHash8 } from "node:crypto";
|
|
22091
|
-
import { existsSync as
|
|
22220
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync6, readdirSync as readdirSync13 } from "node:fs";
|
|
22092
22221
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
22093
|
-
import { basename as basename3, isAbsolute as isAbsolute4, join as
|
|
22222
|
+
import { basename as basename3, isAbsolute as isAbsolute4, join as join35, resolve as resolve20 } from "node:path";
|
|
22094
22223
|
|
|
22095
22224
|
// node_modules/@intentius/chant/src/gate-decision.ts
|
|
22096
22225
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
22097
|
-
import { readFileSync as
|
|
22098
|
-
import { join as
|
|
22226
|
+
import { readFileSync as readFileSync25 } from "node:fs";
|
|
22227
|
+
import { join as join34, posix as posix4 } from "node:path";
|
|
22099
22228
|
|
|
22100
22229
|
// node_modules/@intentius/chant/src/lifecycle/gate-applied.ts
|
|
22101
22230
|
function appliedGatePath(op) {
|
|
@@ -22204,7 +22333,7 @@ function pinnedClassesAt(repo, base, pins, packages) {
|
|
|
22204
22333
|
}
|
|
22205
22334
|
let installed2;
|
|
22206
22335
|
try {
|
|
22207
|
-
installed2 = JSON.parse(
|
|
22336
|
+
installed2 = JSON.parse(readFileSync25(join34(dir, "package.json"), "utf-8")).version;
|
|
22208
22337
|
} catch {
|
|
22209
22338
|
installed2 = void 0;
|
|
22210
22339
|
}
|
|
@@ -22811,7 +22940,7 @@ var realGit = (args, o = {}) => new Promise((res) => {
|
|
|
22811
22940
|
});
|
|
22812
22941
|
var redact = (s) => s.replace(/(\b[a-z][a-z0-9+.-]*:\/\/)[^/@\s]+@/gi, "$1");
|
|
22813
22942
|
function cacheDir(origin, root = tmpdir3()) {
|
|
22814
|
-
return
|
|
22943
|
+
return join35(root, `${CACHE_PREFIX}${createHash8("sha256").update(origin).digest("hex").slice(0, 16)}`);
|
|
22815
22944
|
}
|
|
22816
22945
|
var inflight = /* @__PURE__ */ new Map();
|
|
22817
22946
|
function serially(key, fn) {
|
|
@@ -22830,8 +22959,8 @@ function fetchable(url, checkout) {
|
|
|
22830
22959
|
async function fetchIntoCache(git3, origin, cache6) {
|
|
22831
22960
|
assertScratch(basename3(cache6));
|
|
22832
22961
|
return serially(cache6, async () => {
|
|
22833
|
-
if (!
|
|
22834
|
-
if (
|
|
22962
|
+
if (!existsSync23(join35(cache6, "HEAD"))) {
|
|
22963
|
+
if (existsSync23(cache6) && readdirSync13(cache6).length > 0) return { ok: false, error: `${cache6} exists and is not behold's lifecycle cache; behold leaves it alone` };
|
|
22835
22964
|
mkdirSync6(cache6, { recursive: true });
|
|
22836
22965
|
const init = await git3(["init", "--bare", "-q", cache6]);
|
|
22837
22966
|
if (init.code !== 0) return { ok: false, error: `could not make the cache ${cache6}: ${init.stderr.trim()}` };
|
|
@@ -23032,7 +23161,7 @@ function structural(name, doc) {
|
|
|
23032
23161
|
var compiledSchemas = /* @__PURE__ */ new Map();
|
|
23033
23162
|
function schemaStamp(dist) {
|
|
23034
23163
|
try {
|
|
23035
|
-
const files = [
|
|
23164
|
+
const files = [join36(dist, "..", "package.json"), ...Object.values(SCHEMA_FILES).map((f) => join36(dist, f))];
|
|
23036
23165
|
return [dist, ...files.map((f) => {
|
|
23037
23166
|
const st = statSync11(f);
|
|
23038
23167
|
return `${st.mtimeMs}:${st.size}`;
|
|
@@ -23042,10 +23171,10 @@ function schemaStamp(dist) {
|
|
|
23042
23171
|
}
|
|
23043
23172
|
}
|
|
23044
23173
|
function compileSchemas(dist) {
|
|
23045
|
-
const version = JSON.parse(
|
|
23174
|
+
const version = JSON.parse(readFileSync26(join36(dist, "..", "package.json"), "utf8")).version ?? "";
|
|
23046
23175
|
const ajv = new Ajv2020({ strict: false, allErrors: false });
|
|
23047
23176
|
const compiled4 = Object.fromEntries(
|
|
23048
|
-
Object.keys(SCHEMA_FILES).map((n) => [n, ajv.compile(JSON.parse(
|
|
23177
|
+
Object.keys(SCHEMA_FILES).map((n) => [n, ajv.compile(JSON.parse(readFileSync26(join36(dist, SCHEMA_FILES[n]), "utf8")))])
|
|
23049
23178
|
);
|
|
23050
23179
|
return {
|
|
23051
23180
|
validation: { by: "schema", terragucci: version },
|
|
@@ -23062,7 +23191,7 @@ function terragucciValidator(dirs = []) {
|
|
|
23062
23191
|
for (const from of [...dirs, dirname10(fileURLToPath5(import.meta.url))]) {
|
|
23063
23192
|
let entry;
|
|
23064
23193
|
try {
|
|
23065
|
-
entry = createRequire4(
|
|
23194
|
+
entry = createRequire4(join36(resolve21(from), "noop.js")).resolve("@intentius/terragucci/report.schema.json");
|
|
23066
23195
|
} catch {
|
|
23067
23196
|
continue;
|
|
23068
23197
|
}
|
|
@@ -23418,11 +23547,11 @@ function joinTerragucci(read, nodes, roots) {
|
|
|
23418
23547
|
// src/terragucci-source.ts
|
|
23419
23548
|
import { spawn as spawn7 } from "node:child_process";
|
|
23420
23549
|
import { readFile } from "node:fs/promises";
|
|
23421
|
-
import { join as
|
|
23550
|
+
import { join as join37, resolve as resolve22 } from "node:path";
|
|
23422
23551
|
|
|
23423
23552
|
// src/s3-object.ts
|
|
23424
23553
|
import { createHash as createHash9, createHmac } from "node:crypto";
|
|
23425
|
-
import { readFileSync as
|
|
23554
|
+
import { readFileSync as readFileSync27 } from "node:fs";
|
|
23426
23555
|
var S3Error = class extends Error {
|
|
23427
23556
|
/** The HTTP status S3 answered, when it answered. */
|
|
23428
23557
|
status;
|
|
@@ -23469,7 +23598,7 @@ function s3FromEnv(bucket, env = process.env) {
|
|
|
23469
23598
|
async function assumeRole(w, fetchFn) {
|
|
23470
23599
|
let token;
|
|
23471
23600
|
try {
|
|
23472
|
-
token =
|
|
23601
|
+
token = readFileSync27(w.tokenFile, "utf8").trim();
|
|
23473
23602
|
} catch (e) {
|
|
23474
23603
|
throw new S3Error(`cannot read the OIDC token in ${w.tokenFile}: ${e.message}`);
|
|
23475
23604
|
}
|
|
@@ -23666,7 +23795,7 @@ function terragucciSource(spec2, opts = {}) {
|
|
|
23666
23795
|
location: dir,
|
|
23667
23796
|
async read(key) {
|
|
23668
23797
|
try {
|
|
23669
|
-
return await readFile(
|
|
23798
|
+
return await readFile(join37(dir, ...trim(key).split("/")), "utf8");
|
|
23670
23799
|
} catch (e) {
|
|
23671
23800
|
if (e.code === "ENOENT") return void 0;
|
|
23672
23801
|
throw e;
|
|
@@ -23676,9 +23805,9 @@ function terragucciSource(spec2, opts = {}) {
|
|
|
23676
23805
|
}
|
|
23677
23806
|
|
|
23678
23807
|
// src/terragucci-timeline.ts
|
|
23679
|
-
import { readFileSync as
|
|
23808
|
+
import { readFileSync as readFileSync28, statSync as statSync12 } from "node:fs";
|
|
23680
23809
|
import { createRequire as createRequire5 } from "node:module";
|
|
23681
|
-
import { dirname as dirname11, join as
|
|
23810
|
+
import { dirname as dirname11, join as join38, resolve as resolve23 } from "node:path";
|
|
23682
23811
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
23683
23812
|
import { Ajv2020 as Ajv20202 } from "ajv/dist/2020.js";
|
|
23684
23813
|
var AUDIT_SCHEMA = "terragucci.audit/v1";
|
|
@@ -23719,12 +23848,12 @@ function auditValidator(dirs = []) {
|
|
|
23719
23848
|
for (const from of [...dirs, dirname11(fileURLToPath6(import.meta.url))]) {
|
|
23720
23849
|
let dist;
|
|
23721
23850
|
try {
|
|
23722
|
-
dist = dirname11(createRequire5(
|
|
23851
|
+
dist = dirname11(createRequire5(join38(resolve23(from), "noop.js")).resolve("@intentius/terragucci/report.schema.json"));
|
|
23723
23852
|
} catch {
|
|
23724
23853
|
continue;
|
|
23725
23854
|
}
|
|
23726
|
-
const pkg =
|
|
23727
|
-
const file =
|
|
23855
|
+
const pkg = join38(dist, "..", "package.json");
|
|
23856
|
+
const file = join38(dist, AUDIT_SCHEMA_FILE);
|
|
23728
23857
|
let stamp;
|
|
23729
23858
|
try {
|
|
23730
23859
|
stamp = [dist, ...[pkg, file].map((f) => {
|
|
@@ -23738,8 +23867,8 @@ function auditValidator(dirs = []) {
|
|
|
23738
23867
|
if (hit) return hit;
|
|
23739
23868
|
let v;
|
|
23740
23869
|
try {
|
|
23741
|
-
const version = JSON.parse(
|
|
23742
|
-
v = compileAuditSchema(JSON.parse(
|
|
23870
|
+
const version = JSON.parse(readFileSync28(pkg, "utf8")).version ?? "";
|
|
23871
|
+
v = compileAuditSchema(JSON.parse(readFileSync28(file, "utf8")), version);
|
|
23743
23872
|
} catch {
|
|
23744
23873
|
continue;
|
|
23745
23874
|
}
|
|
@@ -23935,7 +24064,7 @@ function terragucciTimelineRoute(app, source2, opts = {}) {
|
|
|
23935
24064
|
// src/terragucci-poll.ts
|
|
23936
24065
|
import { createHash as createHash10 } from "node:crypto";
|
|
23937
24066
|
import { stat } from "node:fs/promises";
|
|
23938
|
-
import { join as
|
|
24067
|
+
import { join as join39, resolve as resolve24 } from "node:path";
|
|
23939
24068
|
import { streamSSE } from "hono/streaming";
|
|
23940
24069
|
var TERRAGUCCI_POLL_SECS = 30;
|
|
23941
24070
|
var INDEX_KEY = "index.json";
|
|
@@ -23986,7 +24115,7 @@ function indexProbe(spec2, opts = {}) {
|
|
|
23986
24115
|
return verdict2(prev, etag);
|
|
23987
24116
|
};
|
|
23988
24117
|
}
|
|
23989
|
-
const file =
|
|
24118
|
+
const file = join39(resolve24(opts.cwd ?? process.cwd(), spec2), name);
|
|
23990
24119
|
return async (prev) => {
|
|
23991
24120
|
try {
|
|
23992
24121
|
const s = await stat(file);
|
|
@@ -24141,9 +24270,9 @@ function terragucciLaneRoutes(app, o, base, forget) {
|
|
|
24141
24270
|
}
|
|
24142
24271
|
|
|
24143
24272
|
// src/terragucci-progress.ts
|
|
24144
|
-
import { readFileSync as
|
|
24273
|
+
import { readFileSync as readFileSync29, statSync as statSync13 } from "node:fs";
|
|
24145
24274
|
import { createRequire as createRequire6 } from "node:module";
|
|
24146
|
-
import { dirname as dirname12, join as
|
|
24275
|
+
import { dirname as dirname12, join as join40, resolve as resolve25 } from "node:path";
|
|
24147
24276
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
24148
24277
|
import { Ajv2020 as Ajv20203 } from "ajv/dist/2020.js";
|
|
24149
24278
|
var RUN_SCHEMA = "terragucci.run/v1";
|
|
@@ -24188,12 +24317,12 @@ function runValidator(dirs = []) {
|
|
|
24188
24317
|
for (const from of [...dirs, dirname12(fileURLToPath7(import.meta.url))]) {
|
|
24189
24318
|
let dist;
|
|
24190
24319
|
try {
|
|
24191
|
-
dist = dirname12(createRequire6(
|
|
24320
|
+
dist = dirname12(createRequire6(join40(resolve25(from), "noop.js")).resolve("@intentius/terragucci/report.schema.json"));
|
|
24192
24321
|
} catch {
|
|
24193
24322
|
continue;
|
|
24194
24323
|
}
|
|
24195
|
-
const pkg =
|
|
24196
|
-
const file =
|
|
24324
|
+
const pkg = join40(dist, "..", "package.json");
|
|
24325
|
+
const file = join40(dist, RUN_SCHEMA_FILE);
|
|
24197
24326
|
let stamp;
|
|
24198
24327
|
try {
|
|
24199
24328
|
stamp = [dist, ...[pkg, file].map((f) => {
|
|
@@ -24207,8 +24336,8 @@ function runValidator(dirs = []) {
|
|
|
24207
24336
|
if (hit) return hit;
|
|
24208
24337
|
let v;
|
|
24209
24338
|
try {
|
|
24210
|
-
const version = JSON.parse(
|
|
24211
|
-
v = compileRunSchema(JSON.parse(
|
|
24339
|
+
const version = JSON.parse(readFileSync29(pkg, "utf8")).version ?? "";
|
|
24340
|
+
v = compileRunSchema(JSON.parse(readFileSync29(file, "utf8")), version);
|
|
24212
24341
|
} catch {
|
|
24213
24342
|
continue;
|
|
24214
24343
|
}
|
|
@@ -24501,8 +24630,8 @@ function terragucciProgressRoute(app, progress) {
|
|
|
24501
24630
|
}
|
|
24502
24631
|
|
|
24503
24632
|
// src/terragucci-demo.ts
|
|
24504
|
-
import { readFileSync as
|
|
24505
|
-
import { join as
|
|
24633
|
+
import { readFileSync as readFileSync30 } from "node:fs";
|
|
24634
|
+
import { join as join41 } from "node:path";
|
|
24506
24635
|
var DEMO_KEY = "demo.json";
|
|
24507
24636
|
var DEMO_READ_TTL_MS = 2e3;
|
|
24508
24637
|
var DEMO_STEPS = ["pull-request", "planned", "merged", "applying", "waiting", "approved", "failed", "resumed", "applied", "reset", "stalled"];
|
|
@@ -24591,10 +24720,10 @@ function kioskRoute(app, webRoot2, enabled) {
|
|
|
24591
24720
|
if (!enabled) {
|
|
24592
24721
|
return c.html(disabledPage, 404);
|
|
24593
24722
|
}
|
|
24594
|
-
return new Response(
|
|
24723
|
+
return new Response(readFileSync30(join41(webRoot2, "kiosk.html"), "utf8"), { headers: { "content-type": "text/html; charset=utf-8", "cache-control": "no-cache" } });
|
|
24595
24724
|
});
|
|
24596
24725
|
}
|
|
24597
|
-
var VENDOR_TOOLS = ["terraform", "terragrunt", "cdk-terrain", "choudoufu"];
|
|
24726
|
+
var VENDOR_TOOLS = ["terraform", "terragrunt", "cdk-terrain", "choudoufu", "chant"];
|
|
24598
24727
|
var isVendorTool = (v) => VENDOR_TOOLS.includes(v);
|
|
24599
24728
|
var cycleKey = (tool) => `cycles/${tool}/latest.json`;
|
|
24600
24729
|
var CYCLE_READ_TTL_MS = 1e4;
|
|
@@ -24671,7 +24800,7 @@ function vendorRoutes(app, webRoot2, enabled) {
|
|
|
24671
24800
|
for (const tool of VENDOR_TOOLS) {
|
|
24672
24801
|
app.get(`/${tool}`, (c) => {
|
|
24673
24802
|
if (!enabled) return c.html(disabledPage, 404);
|
|
24674
|
-
const html = vendorPage(
|
|
24803
|
+
const html = vendorPage(readFileSync30(join41(webRoot2, "kiosk.html"), "utf8"), tool);
|
|
24675
24804
|
return new Response(html, { headers: { "content-type": "text/html; charset=utf-8", "cache-control": "no-cache" } });
|
|
24676
24805
|
});
|
|
24677
24806
|
}
|
|
@@ -24837,7 +24966,7 @@ function checkoutRoots(dirs, base = repoBase(dirs)) {
|
|
|
24837
24966
|
for (const m of estateMembers(dirs)) {
|
|
24838
24967
|
if (m.kind !== "terraform") continue;
|
|
24839
24968
|
for (const r of checkoutRootDirs(m.dir)) {
|
|
24840
|
-
const path = relative9(base,
|
|
24969
|
+
const path = relative9(base, join42(m.dir, r.dir)).split(sep8).join("/") || ".";
|
|
24841
24970
|
out.push({ member: m.name, name: r.name, path });
|
|
24842
24971
|
}
|
|
24843
24972
|
}
|
|
@@ -24948,8 +25077,8 @@ function terragucciRoutes(app, opts, dirs) {
|
|
|
24948
25077
|
|
|
24949
25078
|
// src/view-repos.ts
|
|
24950
25079
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
24951
|
-
import { existsSync as
|
|
24952
|
-
import { join as
|
|
25080
|
+
import { existsSync as existsSync24, readdirSync as readdirSync14, readFileSync as readFileSync31 } from "node:fs";
|
|
25081
|
+
import { join as join43, resolve as resolve26 } from "node:path";
|
|
24953
25082
|
var NAME2 = /^[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/;
|
|
24954
25083
|
function repoName(value) {
|
|
24955
25084
|
const v = value.trim().replace(/\.git$/, "");
|
|
@@ -24959,11 +25088,11 @@ function repoName(value) {
|
|
|
24959
25088
|
function listCheckouts(parent) {
|
|
24960
25089
|
let names;
|
|
24961
25090
|
try {
|
|
24962
|
-
names =
|
|
25091
|
+
names = readdirSync14(parent, { withFileTypes: true }).filter((e) => e.isDirectory() && NAME2.test(e.name)).map((e) => e.name).sort();
|
|
24963
25092
|
} catch {
|
|
24964
25093
|
return [];
|
|
24965
25094
|
}
|
|
24966
|
-
return names.map((name) => ({ name, dir: resolve26(parent, name) })).filter((c) =>
|
|
25095
|
+
return names.map((name) => ({ name, dir: resolve26(parent, name) })).filter((c) => existsSync24(join43(c.dir, ".git")));
|
|
24967
25096
|
}
|
|
24968
25097
|
var scope = new AsyncLocalStorage2();
|
|
24969
25098
|
function scopeServedDirs(cfg) {
|
|
@@ -25005,7 +25134,7 @@ var SHA = /^[0-9a-f]{40}([0-9a-f]{24})?$/;
|
|
|
25005
25134
|
function checkoutCommit(dir) {
|
|
25006
25135
|
const read = (f) => {
|
|
25007
25136
|
try {
|
|
25008
|
-
return
|
|
25137
|
+
return readFileSync31(join43(dir, ".git", f), "utf8");
|
|
25009
25138
|
} catch {
|
|
25010
25139
|
return void 0;
|
|
25011
25140
|
}
|
|
@@ -25486,8 +25615,8 @@ function lifecycleHistoryRoute(app, base, opts = {}) {
|
|
|
25486
25615
|
}
|
|
25487
25616
|
|
|
25488
25617
|
// src/lifecycle-releases.ts
|
|
25489
|
-
import { existsSync as
|
|
25490
|
-
import { join as
|
|
25618
|
+
import { existsSync as existsSync25, readFileSync as readFileSync32 } from "node:fs";
|
|
25619
|
+
import { join as join44 } from "node:path";
|
|
25491
25620
|
|
|
25492
25621
|
// node_modules/@intentius/chant/src/lifecycle/legacy-digest.ts
|
|
25493
25622
|
import { resolve as resolve27 } from "node:path";
|
|
@@ -25600,10 +25729,10 @@ function memberNote(l) {
|
|
|
25600
25729
|
// src/lifecycle-releases.ts
|
|
25601
25730
|
var WAVES_SPEC_FILE = "yodel-waves.json";
|
|
25602
25731
|
function waveOrder(checkout) {
|
|
25603
|
-
const p =
|
|
25604
|
-
if (!
|
|
25732
|
+
const p = join44(checkout, WAVES_SPEC_FILE);
|
|
25733
|
+
if (!existsSync25(p)) return void 0;
|
|
25605
25734
|
try {
|
|
25606
|
-
const doc = JSON.parse(
|
|
25735
|
+
const doc = JSON.parse(readFileSync32(p, "utf8"));
|
|
25607
25736
|
const names = (doc.waves ?? []).map((w) => w?.name).filter((n) => typeof n === "string" && n.length > 0);
|
|
25608
25737
|
return names.length ? [...new Set(names)] : void 0;
|
|
25609
25738
|
} catch {
|
|
@@ -25611,7 +25740,7 @@ function waveOrder(checkout) {
|
|
|
25611
25740
|
}
|
|
25612
25741
|
}
|
|
25613
25742
|
function hasReleaseLedgerHint(checkout) {
|
|
25614
|
-
return
|
|
25743
|
+
return existsSync25(join44(checkout, "yodel.config.ts")) || existsSync25(join44(checkout, WAVES_SPEC_FILE));
|
|
25615
25744
|
}
|
|
25616
25745
|
function orderEnvironments(envs, waves) {
|
|
25617
25746
|
const seen = new Set(envs);
|
|
@@ -25653,7 +25782,7 @@ function releaseCells(ledgers, order, sources) {
|
|
|
25653
25782
|
}
|
|
25654
25783
|
async function copyCheckoutRef(git3, checkout, cache6) {
|
|
25655
25784
|
assertScratch(cache6.split(/[\\/]/).pop());
|
|
25656
|
-
if (!
|
|
25785
|
+
if (!existsSync25(join44(cache6, "HEAD"))) {
|
|
25657
25786
|
const init = await git3(["init", "--bare", "-q", cache6]);
|
|
25658
25787
|
if (init.code !== 0) return false;
|
|
25659
25788
|
}
|
|
@@ -25756,8 +25885,8 @@ function releasesRoutes(app, base, opts = {}) {
|
|
|
25756
25885
|
}
|
|
25757
25886
|
|
|
25758
25887
|
// src/sql-yodeler-lane.ts
|
|
25759
|
-
import { existsSync as
|
|
25760
|
-
import { join as
|
|
25888
|
+
import { existsSync as existsSync26, readdirSync as readdirSync15, readFileSync as readFileSync33 } from "node:fs";
|
|
25889
|
+
import { join as join45 } from "node:path";
|
|
25761
25890
|
var YODEL_APPLY_OP = "yodel-apply";
|
|
25762
25891
|
var YODEL_HEAD_PLANS_DIR = headPlansPath(YODEL_APPLY_OP, "").dir;
|
|
25763
25892
|
function parseYodelWaves(text2, path = WAVES_SPEC_FILE) {
|
|
@@ -25789,19 +25918,19 @@ function parseYodelWaves(text2, path = WAVES_SPEC_FILE) {
|
|
|
25789
25918
|
return { path, waves };
|
|
25790
25919
|
}
|
|
25791
25920
|
function readYodelWaves(checkout) {
|
|
25792
|
-
const p =
|
|
25793
|
-
if (!
|
|
25921
|
+
const p = join45(checkout, WAVES_SPEC_FILE);
|
|
25922
|
+
if (!existsSync26(p)) return void 0;
|
|
25794
25923
|
try {
|
|
25795
|
-
return parseYodelWaves(
|
|
25924
|
+
return parseYodelWaves(readFileSync33(p, "utf8"));
|
|
25796
25925
|
} catch (e) {
|
|
25797
25926
|
return { path: WAVES_SPEC_FILE, waves: [], error: e instanceof Error ? e.message : String(e) };
|
|
25798
25927
|
}
|
|
25799
25928
|
}
|
|
25800
25929
|
function migrateOpEnvironments(checkout) {
|
|
25801
|
-
const dir =
|
|
25802
|
-
if (!
|
|
25930
|
+
const dir = join45(checkout, "ops");
|
|
25931
|
+
if (!existsSync26(dir)) return [];
|
|
25803
25932
|
try {
|
|
25804
|
-
return
|
|
25933
|
+
return readdirSync15(dir).map((f) => /^migrate-(.+)\.op\.ts$/.exec(f)?.[1]).filter((e) => !!e).sort();
|
|
25805
25934
|
} catch {
|
|
25806
25935
|
return [];
|
|
25807
25936
|
}
|
|
@@ -25921,20 +26050,20 @@ function sqlYodelerLaneRoute(app, checkout, opts = {}) {
|
|
|
25921
26050
|
|
|
25922
26051
|
// src/terragucci-estate.ts
|
|
25923
26052
|
init_yaml();
|
|
25924
|
-
import { existsSync as
|
|
26053
|
+
import { existsSync as existsSync27, readFileSync as readFileSync34, statSync as statSync14 } from "node:fs";
|
|
25925
26054
|
import { createRequire as createRequire7 } from "node:module";
|
|
25926
|
-
import { dirname as dirname14, extname, join as
|
|
26055
|
+
import { dirname as dirname14, extname as extname2, join as join46, resolve as resolve28 } from "node:path";
|
|
25927
26056
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
25928
26057
|
import { Ajv2020 as Ajv20204 } from "ajv/dist/2020.js";
|
|
25929
26058
|
var RUN_SCHEMA2 = "terragucci.run/v1";
|
|
25930
26059
|
function configProjects(file) {
|
|
25931
26060
|
let text2;
|
|
25932
26061
|
try {
|
|
25933
|
-
text2 =
|
|
26062
|
+
text2 = readFileSync34(file, "utf8");
|
|
25934
26063
|
} catch {
|
|
25935
26064
|
return void 0;
|
|
25936
26065
|
}
|
|
25937
|
-
if (
|
|
26066
|
+
if (extname2(file) === ".ts") return /(^|[\s,{])projects\s*:\s*\{/.test(text2) ? [] : void 0;
|
|
25938
26067
|
let doc;
|
|
25939
26068
|
try {
|
|
25940
26069
|
doc = parseYAMLDocument(text2);
|
|
@@ -25981,16 +26110,16 @@ function runViewValidator(dirs = []) {
|
|
|
25981
26110
|
for (const from of [...dirs, dirname14(fileURLToPath8(import.meta.url))]) {
|
|
25982
26111
|
let entry;
|
|
25983
26112
|
try {
|
|
25984
|
-
entry = createRequire7(
|
|
26113
|
+
entry = createRequire7(join46(resolve28(from), "noop.js")).resolve("@intentius/terragucci/report.schema.json");
|
|
25985
26114
|
} catch {
|
|
25986
26115
|
continue;
|
|
25987
26116
|
}
|
|
25988
26117
|
const dist = dirname14(entry);
|
|
25989
|
-
const schema =
|
|
26118
|
+
const schema = join46(dist, "run.schema.json");
|
|
25990
26119
|
let stamp;
|
|
25991
26120
|
try {
|
|
25992
26121
|
const st = statSync14(schema);
|
|
25993
|
-
const pkg = statSync14(
|
|
26122
|
+
const pkg = statSync14(join46(dist, "..", "package.json"));
|
|
25994
26123
|
stamp = `${schema}\0${st.mtimeMs}:${st.size}\0${pkg.mtimeMs}`;
|
|
25995
26124
|
} catch {
|
|
25996
26125
|
continue;
|
|
@@ -25999,8 +26128,8 @@ function runViewValidator(dirs = []) {
|
|
|
25999
26128
|
if (hit) return hit;
|
|
26000
26129
|
let v;
|
|
26001
26130
|
try {
|
|
26002
|
-
const version = JSON.parse(
|
|
26003
|
-
const validate = new Ajv20204({ strict: false, allErrors: false }).compile(JSON.parse(
|
|
26131
|
+
const version = JSON.parse(readFileSync34(join46(dist, "..", "package.json"), "utf8")).version ?? "";
|
|
26132
|
+
const validate = new Ajv20204({ strict: false, allErrors: false }).compile(JSON.parse(readFileSync34(schema, "utf8")));
|
|
26004
26133
|
v = {
|
|
26005
26134
|
validation: { by: "schema", terragucci: version },
|
|
26006
26135
|
check(doc) {
|
|
@@ -26055,8 +26184,8 @@ function controlEdges(views) {
|
|
|
26055
26184
|
function siblingCheckout(project, base, projectOf = checkoutProject) {
|
|
26056
26185
|
const name = project.split("/").filter(Boolean).pop();
|
|
26057
26186
|
if (!name) return void 0;
|
|
26058
|
-
const dir =
|
|
26059
|
-
if (dir === resolve28(base) || !
|
|
26187
|
+
const dir = join46(dirname14(resolve28(base)), name);
|
|
26188
|
+
if (dir === resolve28(base) || !existsSync27(join46(dir, ".git"))) return void 0;
|
|
26060
26189
|
return projectOf(dir) === project ? dir : void 0;
|
|
26061
26190
|
}
|
|
26062
26191
|
var shellWord = (s) => /^[A-Za-z0-9_./:@%+=,-]+$/.test(s) ? s : `'${s.replace(/'/g, `'\\''`)}'`;
|
|
@@ -26263,9 +26392,9 @@ function controlRepoInfo(dirs) {
|
|
|
26263
26392
|
}
|
|
26264
26393
|
|
|
26265
26394
|
// src/yodel-report.ts
|
|
26266
|
-
import { readdirSync as
|
|
26395
|
+
import { readdirSync as readdirSync16, readFileSync as readFileSync35, statSync as statSync15 } from "node:fs";
|
|
26267
26396
|
import { createRequire as createRequire8 } from "node:module";
|
|
26268
|
-
import { basename as basename4, dirname as dirname15, join as
|
|
26397
|
+
import { basename as basename4, dirname as dirname15, join as join47, resolve as resolve29 } from "node:path";
|
|
26269
26398
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
26270
26399
|
import { Ajv2020 as Ajv20205 } from "ajv/dist/2020.js";
|
|
26271
26400
|
|
|
@@ -26694,13 +26823,13 @@ var installed = /* @__PURE__ */ new Map();
|
|
|
26694
26823
|
function packageRoot(from) {
|
|
26695
26824
|
let entry;
|
|
26696
26825
|
try {
|
|
26697
|
-
entry = createRequire8(
|
|
26826
|
+
entry = createRequire8(join47(resolve29(from), "noop.js")).resolve("@intentius/sql-yodeler");
|
|
26698
26827
|
} catch {
|
|
26699
26828
|
return void 0;
|
|
26700
26829
|
}
|
|
26701
26830
|
for (let d = dirname15(entry); d !== dirname15(d); d = dirname15(d)) {
|
|
26702
26831
|
try {
|
|
26703
|
-
const pkg = JSON.parse(
|
|
26832
|
+
const pkg = JSON.parse(readFileSync35(join47(d, "package.json"), "utf8"));
|
|
26704
26833
|
if (pkg.name === "@intentius/sql-yodeler") return d;
|
|
26705
26834
|
} catch {
|
|
26706
26835
|
}
|
|
@@ -26712,11 +26841,11 @@ function yodelValidator(dirs = []) {
|
|
|
26712
26841
|
const root = packageRoot(from);
|
|
26713
26842
|
if (!root) continue;
|
|
26714
26843
|
try {
|
|
26715
|
-
const version = JSON.parse(
|
|
26844
|
+
const version = JSON.parse(readFileSync35(join47(root, "package.json"), "utf8")).version ?? "";
|
|
26716
26845
|
const key = `${root}\0${version}`;
|
|
26717
26846
|
let v = installed.get(key);
|
|
26718
26847
|
if (!v) {
|
|
26719
|
-
const load2 = (n) => JSON.parse(
|
|
26848
|
+
const load2 = (n) => JSON.parse(readFileSync35(join47(root, "schemas", `${n}.schema.json`), "utf8"));
|
|
26720
26849
|
v = compile({ common: load2("common"), report: load2("report"), drift: load2("drift") }, { by: "schema", from: "package", sqlYodeler: version });
|
|
26721
26850
|
installed.set(key, v);
|
|
26722
26851
|
}
|
|
@@ -26738,7 +26867,7 @@ function filesOf(source2) {
|
|
|
26738
26867
|
return refuse14(`--yodel-report ${source2}: no such file or directory`, "Point --yodel-report at the file `yodel report --json` wrote, or the directory holding it.");
|
|
26739
26868
|
}
|
|
26740
26869
|
const dir = st.isDirectory() ? source2 : dirname15(source2);
|
|
26741
|
-
const files =
|
|
26870
|
+
const files = readdirSync16(dir).filter((f) => f.endsWith(".json")).sort().map((f) => join47(dir, f));
|
|
26742
26871
|
return st.isDirectory() ? { dir, files } : { dir, files, named: resolve29(source2) };
|
|
26743
26872
|
}
|
|
26744
26873
|
function readYodelReport(source2, validator2) {
|
|
@@ -26750,7 +26879,7 @@ function readYodelReport(source2, validator2) {
|
|
|
26750
26879
|
for (const file of files) {
|
|
26751
26880
|
let doc;
|
|
26752
26881
|
try {
|
|
26753
|
-
doc = JSON.parse(
|
|
26882
|
+
doc = JSON.parse(readFileSync35(file, "utf8"));
|
|
26754
26883
|
} catch (e) {
|
|
26755
26884
|
if (file === named) refuse14(`${basename4(file)} is not JSON: ${e instanceof Error ? e.message : String(e)}`, remedy);
|
|
26756
26885
|
ignored.push(basename4(file));
|
|
@@ -26837,15 +26966,15 @@ function yodelReportRoute(app, source2, dirs) {
|
|
|
26837
26966
|
|
|
26838
26967
|
// src/demo-pins.ts
|
|
26839
26968
|
init_terraform_member();
|
|
26840
|
-
import { existsSync as
|
|
26841
|
-
import { dirname as dirname16, join as
|
|
26969
|
+
import { existsSync as existsSync28, lstatSync as lstatSync2, mkdirSync as mkdirSync7, readFileSync as readFileSync36, readlinkSync as readlinkSync2, symlinkSync as symlinkSync2, writeFileSync as writeFileSync6 } from "node:fs";
|
|
26970
|
+
import { dirname as dirname16, join as join48, resolve as resolve30 } from "node:path";
|
|
26842
26971
|
var isRecord21 = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
|
|
26843
26972
|
function linkDemoPins(work, probes = {}) {
|
|
26844
|
-
const file =
|
|
26845
|
-
if (!
|
|
26973
|
+
const file = join48(work, "chant.workspace.json");
|
|
26974
|
+
if (!existsSync28(file)) return { ok: true, linked: [] };
|
|
26846
26975
|
let decl;
|
|
26847
26976
|
try {
|
|
26848
|
-
decl = JSON.parse(
|
|
26977
|
+
decl = JSON.parse(readFileSync36(file, "utf8"));
|
|
26849
26978
|
} catch {
|
|
26850
26979
|
return { ok: true, linked: [] };
|
|
26851
26980
|
}
|
|
@@ -26868,7 +26997,7 @@ function linkDemoPins(work, probes = {}) {
|
|
|
26868
26997
|
remedy: `Install ${pkg} beside behold, then load the demo again.`
|
|
26869
26998
|
};
|
|
26870
26999
|
}
|
|
26871
|
-
const link =
|
|
27000
|
+
const link = join48(work, "node_modules", ...pkg.split("/"));
|
|
26872
27001
|
if (!present(link)) {
|
|
26873
27002
|
mkdirSync7(dirname16(link), { recursive: true });
|
|
26874
27003
|
symlinkSync2(found.dir, link, "junction");
|
|
@@ -26903,13 +27032,13 @@ function linksTo(link, target) {
|
|
|
26903
27032
|
}
|
|
26904
27033
|
|
|
26905
27034
|
// src/demos.ts
|
|
26906
|
-
import { readFileSync as
|
|
26907
|
-
import { dirname as dirname17, isAbsolute as isAbsolute5, join as
|
|
27035
|
+
import { readFileSync as readFileSync37, existsSync as existsSync29, cpSync, mkdirSync as mkdirSync8 } from "node:fs";
|
|
27036
|
+
import { dirname as dirname17, isAbsolute as isAbsolute5, join as join49, relative as relative10, resolve as resolve31, sep as sep9 } from "node:path";
|
|
26908
27037
|
import { spawn as spawn8, spawnSync as spawnSync3 } from "node:child_process";
|
|
26909
27038
|
function readCatalog(file, catalog) {
|
|
26910
27039
|
let raw;
|
|
26911
27040
|
try {
|
|
26912
|
-
raw = JSON.parse(
|
|
27041
|
+
raw = JSON.parse(readFileSync37(file, "utf8"));
|
|
26913
27042
|
} catch {
|
|
26914
27043
|
return [];
|
|
26915
27044
|
}
|
|
@@ -26949,10 +27078,10 @@ function validEntry(e) {
|
|
|
26949
27078
|
return true;
|
|
26950
27079
|
}
|
|
26951
27080
|
function loadDemoRegistry(pkgRoot3) {
|
|
26952
|
-
const merged = readCatalog(
|
|
27081
|
+
const merged = readCatalog(join49(pkgRoot3, "demos.json"), "demos");
|
|
26953
27082
|
const seen = new Set(merged.map((e) => e.name));
|
|
26954
27083
|
const named = process.env.BEHOLD_WORKBENCH;
|
|
26955
|
-
for (const e of [...readCatalog(
|
|
27084
|
+
for (const e of [...readCatalog(join49(pkgRoot3, "workbench.json"), "workbench"), ...named ? readCatalog(resolve31(named), "workbench") : []]) {
|
|
26956
27085
|
if (seen.has(e.name)) {
|
|
26957
27086
|
process.stderr.write(`behold: workbench entry "${e.name}" collides with a demo already in the catalog \u2014 dropped
|
|
26958
27087
|
`);
|
|
@@ -26971,11 +27100,11 @@ function missingRequirements(entry) {
|
|
|
26971
27100
|
const bins = entry.source === "git" && !entry.requires.includes("git") ? [...entry.requires, "git"] : entry.requires;
|
|
26972
27101
|
const finder = process.platform === "win32" ? "where" : "which";
|
|
26973
27102
|
const missing = bins.filter((bin) => {
|
|
26974
|
-
if (bin === "choudoufu" && process.env.CHOUDOUFU_BIN &&
|
|
27103
|
+
if (bin === "choudoufu" && process.env.CHOUDOUFU_BIN && existsSync29(process.env.CHOUDOUFU_BIN)) return false;
|
|
26975
27104
|
return spawnSync3(finder, [bin], { stdio: "ignore" }).status !== 0;
|
|
26976
27105
|
});
|
|
26977
27106
|
const local = demoLocalPath(entry);
|
|
26978
|
-
if (local && !
|
|
27107
|
+
if (local && !existsSync29(local)) missing.push(`${entry.path} (not checked out)`);
|
|
26979
27108
|
return missing;
|
|
26980
27109
|
}
|
|
26981
27110
|
function fetchesFromNetwork(entry) {
|
|
@@ -26985,7 +27114,7 @@ function demoTargetDir(entry, cwd = process.cwd()) {
|
|
|
26985
27114
|
const inPlace = entry.inPlace ? demoLocalPath(entry) : void 0;
|
|
26986
27115
|
if (inPlace) return inPlace;
|
|
26987
27116
|
const legacy = resolve31(cwd, "behold-demo");
|
|
26988
|
-
if (entry.name === "writes" &&
|
|
27117
|
+
if (entry.name === "writes" && existsSync29(legacy)) return legacy;
|
|
26989
27118
|
return resolve31(cwd, "behold-demos", entry.name);
|
|
26990
27119
|
}
|
|
26991
27120
|
async function loadDemo(entry, opts) {
|
|
@@ -26995,12 +27124,12 @@ async function loadDemo(entry, opts) {
|
|
|
26995
27124
|
const inPlace = entry.source === "local" && entry.inPlace;
|
|
26996
27125
|
const work = inPlace ? local : target;
|
|
26997
27126
|
if (inPlace) {
|
|
26998
|
-
if (!
|
|
27127
|
+
if (!existsSync29(work)) return { ok: false, error: `${entry.path} is not checked out (looked in ${work})` };
|
|
26999
27128
|
say(`serving ${work} where it is \u2014 nothing copied`);
|
|
27000
|
-
} else if (!
|
|
27129
|
+
} else if (!existsSync29(target)) {
|
|
27001
27130
|
if (entry.source === "bundled" || entry.source === "local" && local) {
|
|
27002
|
-
const from = entry.source === "bundled" ?
|
|
27003
|
-
if (!
|
|
27131
|
+
const from = entry.source === "bundled" ? join49(pkgRoot3, entry.dir) : local;
|
|
27132
|
+
if (!existsSync29(from)) return { ok: false, error: entry.source === "bundled" ? `this install has no bundled ${entry.dir}` : `${entry.path} is not checked out (looked in ${from})` };
|
|
27004
27133
|
say(`copying to ${target} (it's yours \u2014 edit it)`);
|
|
27005
27134
|
try {
|
|
27006
27135
|
cpSync(from, target, {
|
|
@@ -27031,7 +27160,7 @@ async function loadDemo(entry, opts) {
|
|
|
27031
27160
|
if (!pins.ok) return { ok: false, error: `${pins.error} ${pins.remedy}` };
|
|
27032
27161
|
for (const p of pins.linked) say(`linked ${p.pkg} ${p.version} into the copy${p.was ? ` (the declaration pinned ${p.was}; now ${p.version})` : ""}`);
|
|
27033
27162
|
}
|
|
27034
|
-
if (!inPlace &&
|
|
27163
|
+
if (!inPlace && existsSync29(join49(work, "package.json")) && !existsSync29(join49(work, "node_modules"))) {
|
|
27035
27164
|
say("npm install\u2026");
|
|
27036
27165
|
if (await runStep("npm", ["install"], { cwd: work, shell: process.platform === "win32" }) !== 0) {
|
|
27037
27166
|
return { ok: false, error: `npm install failed in ${work}` };
|
|
@@ -27048,7 +27177,7 @@ async function loadDemo(entry, opts) {
|
|
|
27048
27177
|
return { ok: false, error: `setup failed (${entry.setup})` };
|
|
27049
27178
|
}
|
|
27050
27179
|
}
|
|
27051
|
-
return { ok: true, serveDirs: entry.serve.dirs?.length ? entry.serve.dirs.map((d) =>
|
|
27180
|
+
return { ok: true, serveDirs: entry.serve.dirs?.length ? entry.serve.dirs.map((d) => join49(work, d)) : [work] };
|
|
27052
27181
|
}
|
|
27053
27182
|
function runStep(cmd, args, opts = {}) {
|
|
27054
27183
|
return new Promise((res) => {
|
|
@@ -27059,8 +27188,8 @@ function runStep(cmd, args, opts = {}) {
|
|
|
27059
27188
|
}
|
|
27060
27189
|
|
|
27061
27190
|
// src/server.ts
|
|
27062
|
-
var pkgRoot =
|
|
27063
|
-
var webRoot =
|
|
27191
|
+
var pkgRoot = join50(dirname18(fileURLToPath10(import.meta.url)), "..");
|
|
27192
|
+
var webRoot = join50(pkgRoot, "web");
|
|
27064
27193
|
var execFileP = async (cmd, args) => (await promisify3(execFile5)(cmd, args, { encoding: "utf8", timeout: 1e4 })).stdout;
|
|
27065
27194
|
function optsFromQuery(url, tierEnvVar, projectDir) {
|
|
27066
27195
|
const q = url.searchParams;
|
|
@@ -27111,7 +27240,7 @@ function tierFailure(tier, message2) {
|
|
|
27111
27240
|
function beholdVersion() {
|
|
27112
27241
|
try {
|
|
27113
27242
|
const here = dirname18(fileURLToPath10(import.meta.url));
|
|
27114
|
-
return JSON.parse(
|
|
27243
|
+
return JSON.parse(readFileSync38(join50(here, "..", "package.json"), "utf8")).version ?? "unknown";
|
|
27115
27244
|
} catch {
|
|
27116
27245
|
return "unknown";
|
|
27117
27246
|
}
|
|
@@ -27158,7 +27287,7 @@ async function captureFrame(projectDir, env, frames, broadcaster) {
|
|
|
27158
27287
|
}
|
|
27159
27288
|
}
|
|
27160
27289
|
function carveRoutes(app, reportPath, demo) {
|
|
27161
|
-
const load2 = () => readCarveReport(reportPath, (p) =>
|
|
27290
|
+
const load2 = () => readCarveReport(reportPath, (p) => readFileSync38(p, "utf8"));
|
|
27162
27291
|
const carveDirs = [dirname18(reportPath), ...demo ? [demo.out] : []];
|
|
27163
27292
|
const carveStates = () => readCarveStates(carveDirs, nodeCarveIo, 0);
|
|
27164
27293
|
const emittedNodes = async (states) => {
|
|
@@ -27550,8 +27679,8 @@ function createApp(cfg, broadcaster = new Broadcaster(), frames = new FrameBuffe
|
|
|
27550
27679
|
if (!sub) return c.json({ error: `unknown substrate "${name}"` }, 404);
|
|
27551
27680
|
if (!sub.bringUp) return c.json({ error: `no bring-up available for "${name}"` }, 400);
|
|
27552
27681
|
const { label, cmd, args } = sub.bringUp;
|
|
27553
|
-
const
|
|
27554
|
-
const forge =
|
|
27682
|
+
const PIPELINE_FORGES2 = { "gitlab-ci": "gitlab", forgejo: "forgejo" };
|
|
27683
|
+
const forge = PIPELINE_FORGES2[name];
|
|
27555
27684
|
if (forge) {
|
|
27556
27685
|
const parsed = await ciPipeline(cfg.projectDir, { env: cfg.env }, forge).catch(() => void 0);
|
|
27557
27686
|
if (parsed && parsed.jobs.length > 0) {
|
|
@@ -27567,9 +27696,9 @@ function createApp(cfg, broadcaster = new Broadcaster(), frames = new FrameBuffe
|
|
|
27567
27696
|
return c.json({ started: true, name, ran: label });
|
|
27568
27697
|
});
|
|
27569
27698
|
app.post("/api/local/reset", (c) => {
|
|
27570
|
-
const down =
|
|
27571
|
-
const up =
|
|
27572
|
-
if (!
|
|
27699
|
+
const down = join50(cfg.projectDir, "scripts/local/local-down.sh");
|
|
27700
|
+
const up = join50(cfg.projectDir, "scripts/local/local-up.sh");
|
|
27701
|
+
if (!existsSync30(down) || !existsSync30(up)) {
|
|
27573
27702
|
return c.json({ error: "no local-down.sh / local-up.sh in scripts/local \u2014 reset is only for local emulator projects" }, 400);
|
|
27574
27703
|
}
|
|
27575
27704
|
if (!runner.bringUp("reset local emulator", "bash", ["-c", "bash scripts/local/local-down.sh && bash scripts/local/local-up.sh"], cfg.projectDir)) {
|
|
@@ -27590,7 +27719,7 @@ function createApp(cfg, broadcaster = new Broadcaster(), frames = new FrameBuffe
|
|
|
27590
27719
|
const dirs = [];
|
|
27591
27720
|
const declared = [];
|
|
27592
27721
|
for (const f of discoverOpIrs(estateDirs)) {
|
|
27593
|
-
const parsed = readOpIr(f.path, (p) =>
|
|
27722
|
+
const parsed = readOpIr(f.path, (p) => readFileSync38(p, "utf8"));
|
|
27594
27723
|
if (!parsed.ok) continue;
|
|
27595
27724
|
const mine = declaredConvergeOps([parsed.ir]);
|
|
27596
27725
|
if (!mine.length) continue;
|
|
@@ -27820,7 +27949,9 @@ function createApp(cfg, broadcaster = new Broadcaster(), frames = new FrameBuffe
|
|
|
27820
27949
|
const decl = servedTerragucciComponents();
|
|
27821
27950
|
if (!decl) return {};
|
|
27822
27951
|
const waves = decl.pipeline.jobs.filter((j) => typeof j.wave === "number").map((j) => ({ job: j.name, wave: j.wave, roots: [...j.applies] }));
|
|
27823
|
-
|
|
27952
|
+
const tools = repoTools(cfg.projectDir, tgConfig());
|
|
27953
|
+
const rootTools2 = declaredRootTools(cfg.projectDir, decl.roots);
|
|
27954
|
+
return { terragucciRoots: { roots: Object.keys(decl.roots).sort(), waves, ...tools.length ? { tools } : {}, ...Object.keys(rootTools2).length ? { rootTools: rootTools2 } : {} } };
|
|
27824
27955
|
})(),
|
|
27825
27956
|
// #517: a SQL Yodeler repo is migrated by its pipeline; same contract.
|
|
27826
27957
|
...(() => {
|
|
@@ -27896,8 +28027,8 @@ function createApp(cfg, broadcaster = new Broadcaster(), frames = new FrameBuffe
|
|
|
27896
28027
|
if (cfg.previewMode) return c.json({ error: "switching projects is locked in preview mode" }, 403);
|
|
27897
28028
|
const body = await c.req.json().catch(() => ({}));
|
|
27898
28029
|
const dir = typeof body.dir === "string" && body.dir.trim() ? resolve32(body.dir.trim()) : "";
|
|
27899
|
-
if (!dir || !
|
|
27900
|
-
if (!
|
|
28030
|
+
if (!dir || !existsSync30(dir)) return c.json({ error: `no such directory: ${dir || "(no dir given)"}` }, 400);
|
|
28031
|
+
if (!existsSync30(join50(dir, "chant.config.ts"))) {
|
|
27901
28032
|
return c.json({ error: `${dir} doesn't look like a chant project \u2014 no chant.config.ts` }, 400);
|
|
27902
28033
|
}
|
|
27903
28034
|
switchServedProject([dir]);
|
|
@@ -27948,7 +28079,7 @@ function createApp(cfg, broadcaster = new Broadcaster(), frames = new FrameBuffe
|
|
|
27948
28079
|
fetches: fetchesFromNetwork(e),
|
|
27949
28080
|
...e.repo ? { repo: e.repo } : {},
|
|
27950
28081
|
target,
|
|
27951
|
-
loaded:
|
|
28082
|
+
loaded: existsSync30(target),
|
|
27952
28083
|
satisfiable: missing.length === 0,
|
|
27953
28084
|
// #254: the carve walkthrough runs fine here — it just isn't a project
|
|
27954
28085
|
// to switch INTO. Carve mode claims `/api/graph` and `/api/project` at
|
|
@@ -28164,6 +28295,9 @@ function createApp(cfg, broadcaster = new Broadcaster(), frames = new FrameBuffe
|
|
|
28164
28295
|
const { project } = terraformMemberProject(cfg.projectDir);
|
|
28165
28296
|
const ir = await componentGraphIr(project, tierTargetOpts(opts));
|
|
28166
28297
|
const titles = waveTitles(ir, decl);
|
|
28298
|
+
const forge = pipelineForge(decl, cfg.projectDir, tgConfig());
|
|
28299
|
+
const tools = repoTools(cfg.projectDir, tgConfig());
|
|
28300
|
+
const rootToolsByName = declaredRootTools(cfg.projectDir, decl.roots);
|
|
28167
28301
|
const { svg } = renderGraph(ir, { waveTitles: titles });
|
|
28168
28302
|
const waves = Object.keys(ir.groups.byWave ?? {}).length;
|
|
28169
28303
|
const noun = hasTerragruntUnits(cfg.projectDir) ? "unit" : "root";
|
|
@@ -28181,7 +28315,11 @@ function createApp(cfg, broadcaster = new Broadcaster(), frames = new FrameBuffe
|
|
|
28181
28315
|
// The CI facet's source on a terragucci repo: the declared jobs, not a
|
|
28182
28316
|
// chant-generated pipeline (`/api/ci`, which a public view refuses).
|
|
28183
28317
|
terragucciComponents: {
|
|
28184
|
-
|
|
28318
|
+
// behold#571: the forge, and what said so, for each wave box's mark (web/forge-mark.js).
|
|
28319
|
+
...forge ? { forge: forge.forge, forgeFrom: forge.from } : decl.pipeline.forge ? { forge: decl.pipeline.forge } : {},
|
|
28320
|
+
...tools.length ? { tools } : {},
|
|
28321
|
+
// behold#571: the tools a root carries inside it (a SQL Yodeler project), by root name.
|
|
28322
|
+
...Object.keys(rootToolsByName).length ? { rootTools: rootToolsByName } : {},
|
|
28185
28323
|
...decl.pipeline.path ? { pipeline: decl.pipeline.path } : {},
|
|
28186
28324
|
jobs: Object.values(componentJobs(decl)),
|
|
28187
28325
|
// component -> the root it applies: the live marks' join onto the
|
|
@@ -28245,7 +28383,7 @@ function createApp(cfg, broadcaster = new Broadcaster(), frames = new FrameBuffe
|
|
|
28245
28383
|
}
|
|
28246
28384
|
const parsedOps = [];
|
|
28247
28385
|
for (const f of files) {
|
|
28248
|
-
const parsed = readOpIr(f.path, (p) =>
|
|
28386
|
+
const parsed = readOpIr(f.path, (p) => readFileSync38(p, "utf8"));
|
|
28249
28387
|
if (!parsed.ok) return c.json(parsed.refusal, 422);
|
|
28250
28388
|
parsedOps.push(parsed.ir);
|
|
28251
28389
|
}
|
|
@@ -28258,8 +28396,8 @@ function createApp(cfg, broadcaster = new Broadcaster(), frames = new FrameBuffe
|
|
|
28258
28396
|
}
|
|
28259
28397
|
const runState = runner.runState;
|
|
28260
28398
|
const ranOp = runState.op ? parsedOps.find((o) => o.name === runState.op) : void 0;
|
|
28261
|
-
const
|
|
28262
|
-
const opsIr =
|
|
28399
|
+
const join55 = ranOp ? joinRun(ranOp, runState.records, runState.gate) : null;
|
|
28400
|
+
const opsIr = join55 ? paintPlayhead(declaredIr, join55, runState.gate) : declaredIr;
|
|
28263
28401
|
const { svg: svg2 } = renderGraph(opsIr, { boxes: "byStack" });
|
|
28264
28402
|
const operator = runner.noteDeclaredConvergeOps(declaredConvergeOps(parsedOps));
|
|
28265
28403
|
return c.json({
|
|
@@ -28272,7 +28410,7 @@ function createApp(cfg, broadcaster = new Broadcaster(), frames = new FrameBuffe
|
|
|
28272
28410
|
target: null,
|
|
28273
28411
|
mode: "ops",
|
|
28274
28412
|
ops: parsedOps.length,
|
|
28275
|
-
note: `${opsNote(parsedOps, opsIr)} ${playheadNote(runState,
|
|
28413
|
+
note: `${opsNote(parsedOps, opsIr)} ${playheadNote(runState, join55)} ${operatorNote(operator)}`,
|
|
28276
28414
|
// The operator strip's own model: the ConvergeOps this project
|
|
28277
28415
|
// declares, plus whatever the last status read said. `declared`
|
|
28278
28416
|
// without a `strip` is the honest starting state — a loop exists and
|
|
@@ -28385,7 +28523,7 @@ function createApp(cfg, broadcaster = new Broadcaster(), frames = new FrameBuffe
|
|
|
28385
28523
|
srcCompositeEdgesAttached = 0;
|
|
28386
28524
|
}
|
|
28387
28525
|
}
|
|
28388
|
-
if (!multi && !components && !logical && !opts.lens && !ownKindVia && ir.nodes.length === 0 && !
|
|
28526
|
+
if (!multi && !components && !logical && !opts.lens && !ownKindVia && ir.nodes.length === 0 && !existsSync30(join50(cfg.projectDir, "chant.config.ts"))) {
|
|
28389
28527
|
return c.json(noProjectError(cfg.projectDir), 404);
|
|
28390
28528
|
}
|
|
28391
28529
|
const radial = new URL(c.req.url).searchParams.get("radial") === "1";
|
|
@@ -29024,7 +29162,7 @@ function createApp(cfg, broadcaster = new Broadcaster(), frames = new FrameBuffe
|
|
|
29024
29162
|
if (!c.req.path.startsWith("/api/") && c.res.ok && !c.res.headers.has("cache-control")) c.res.headers.set("cache-control", "no-cache");
|
|
29025
29163
|
});
|
|
29026
29164
|
app.use("/*", serveStatic({ root: rel }));
|
|
29027
|
-
app.get("/", serveStatic({ path:
|
|
29165
|
+
app.get("/", serveStatic({ path: join50(rel, "index.html") }));
|
|
29028
29166
|
if (cfg.terragucci) vendorFallback(app);
|
|
29029
29167
|
return app;
|
|
29030
29168
|
}
|
|
@@ -29054,7 +29192,7 @@ async function bootLocalEmulators(dir, who) {
|
|
|
29054
29192
|
async function startServer(cfg) {
|
|
29055
29193
|
if (cfg.local) cfg.emulators = await bootLocalEmulators(cfg.projectDir, "behold serve --local");
|
|
29056
29194
|
for (const dir of cfg.projectDirs ?? [cfg.projectDir]) {
|
|
29057
|
-
if (
|
|
29195
|
+
if (existsSync30(join50(dir, "chant.config.ts"))) addRecent(dir);
|
|
29058
29196
|
}
|
|
29059
29197
|
const broadcaster = new Broadcaster();
|
|
29060
29198
|
const frames = new FrameBuffer();
|
|
@@ -29229,8 +29367,8 @@ init_chant();
|
|
|
29229
29367
|
|
|
29230
29368
|
// src/workspace-convert.ts
|
|
29231
29369
|
init_chant();
|
|
29232
|
-
import { existsSync as
|
|
29233
|
-
import { basename as basename6, dirname as dirname19, join as
|
|
29370
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync9, readFileSync as readFileSync39, renameSync as renameSync2, writeFileSync as writeFileSync7 } from "node:fs";
|
|
29371
|
+
import { basename as basename6, dirname as dirname19, join as join51, relative as relative12, resolve as resolve33, sep as sep11 } from "node:path";
|
|
29234
29372
|
import { shortStackNames as shortStackNames2 } from "@intentius/pinhole";
|
|
29235
29373
|
init_project();
|
|
29236
29374
|
init_terraform_member();
|
|
@@ -29248,10 +29386,10 @@ function unique(name, taken) {
|
|
|
29248
29386
|
var posix5 = (p) => p.split(sep11).join("/");
|
|
29249
29387
|
function installedVersion(pkg, dir) {
|
|
29250
29388
|
for (let at2 = resolve33(dir); ; at2 = dirname19(at2)) {
|
|
29251
|
-
const manifest =
|
|
29252
|
-
if (
|
|
29389
|
+
const manifest = join51(at2, "node_modules", ...pkg.split("/"), "package.json");
|
|
29390
|
+
if (existsSync31(manifest)) {
|
|
29253
29391
|
try {
|
|
29254
|
-
const v = JSON.parse(
|
|
29392
|
+
const v = JSON.parse(readFileSync39(manifest, "utf8")).version;
|
|
29255
29393
|
return typeof v === "string" ? v : void 0;
|
|
29256
29394
|
} catch {
|
|
29257
29395
|
return void 0;
|
|
@@ -29262,7 +29400,7 @@ function installedVersion(pkg, dir) {
|
|
|
29262
29400
|
}
|
|
29263
29401
|
function planConversion(rootArg) {
|
|
29264
29402
|
const root = resolve33(rootArg);
|
|
29265
|
-
const existing = DECLARATION_FILES.find((f) =>
|
|
29403
|
+
const existing = DECLARATION_FILES.find((f) => existsSync31(join51(root, f)));
|
|
29266
29404
|
if (existing) return { ok: false, error: `${root} already has ${existing}; there is nothing to convert.` };
|
|
29267
29405
|
const shape = detectProjectShape(root);
|
|
29268
29406
|
if (shape.kind !== "estate" || !shape.members?.length || shape.membersFrom === "itself") {
|
|
@@ -29283,10 +29421,10 @@ function planConversion(rootArg) {
|
|
|
29283
29421
|
const scan = discoverTerraformRoots(abs[i]);
|
|
29284
29422
|
for (const r of scan.roots) {
|
|
29285
29423
|
const name2 = unique(declarationName(r.name), taken);
|
|
29286
|
-
members.push({ name: name2, dir: r.dir === "." ? dir : posix5(
|
|
29424
|
+
members.push({ name: name2, dir: r.dir === "." ? dir : posix5(join51(dir, r.dir)), kind: "terraform" });
|
|
29287
29425
|
moves.push({ from: `${short}/${r.name}/`, to: `${name2}/${name2}/` });
|
|
29288
29426
|
}
|
|
29289
|
-
for (const s of scan.skipped) notes.push(`${posix5(
|
|
29427
|
+
for (const s of scan.skipped) notes.push(`${posix5(join51(dir, s.dir))} is not declared: ${s.why}.`);
|
|
29290
29428
|
if (scan.roots.length > 1) notes.push(`${dir} held ${scan.roots.length} Terraform roots; each is its own member now, since a chant terraform member is one root.`);
|
|
29291
29429
|
return;
|
|
29292
29430
|
}
|
|
@@ -29314,7 +29452,7 @@ function planConversion(rootArg) {
|
|
|
29314
29452
|
};
|
|
29315
29453
|
const firstLayout = layoutPath(abs[0]);
|
|
29316
29454
|
moves.sort((a, b) => b.from.length - a.from.length);
|
|
29317
|
-
return { ok: true, plan: { root, from: shape.membersFrom === "behold-config" ? "behold-config" : "workspaces", declaration, moves, ...
|
|
29455
|
+
return { ok: true, plan: { root, from: shape.membersFrom === "behold-config" ? "behold-config" : "workspaces", declaration, moves, ...existsSync31(firstLayout) ? { layoutFrom: firstLayout } : {}, notes } };
|
|
29318
29456
|
}
|
|
29319
29457
|
function moveLayoutIds(file, moves) {
|
|
29320
29458
|
const lenses = {};
|
|
@@ -29329,18 +29467,18 @@ function moveLayoutIds(file, moves) {
|
|
|
29329
29467
|
return { version: 1, lenses };
|
|
29330
29468
|
}
|
|
29331
29469
|
function applyConversion(plan) {
|
|
29332
|
-
const declarationFile =
|
|
29333
|
-
if (
|
|
29470
|
+
const declarationFile = join51(plan.root, DECLARATION_FILES[0]);
|
|
29471
|
+
if (existsSync31(declarationFile)) throw new Error(`${declarationFile} appeared while converting; nothing was written`);
|
|
29334
29472
|
writeFileSync7(declarationFile, `${JSON.stringify(plan.declaration, null, 2)}
|
|
29335
29473
|
`);
|
|
29336
29474
|
let layout;
|
|
29337
29475
|
const target = layoutPath(plan.root);
|
|
29338
29476
|
if (!plan.layoutFrom) layout = { skipped: "no saved layout to move" };
|
|
29339
29477
|
else if (resolve33(plan.layoutFrom) === resolve33(target)) layout = { skipped: "the saved layout is already in the root" };
|
|
29340
|
-
else if (
|
|
29478
|
+
else if (existsSync31(target)) layout = { skipped: `${target} already exists; the layout in ${plan.layoutFrom} was left alone` };
|
|
29341
29479
|
else {
|
|
29342
29480
|
const moved = moveLayoutIds(readLayoutFile(dirname19(dirname19(plan.layoutFrom))), plan.moves);
|
|
29343
|
-
mkdirSync9(
|
|
29481
|
+
mkdirSync9(join51(plan.root, LAYOUT_DIR), { recursive: true });
|
|
29344
29482
|
const tmp = `${target}.tmp`;
|
|
29345
29483
|
writeFileSync7(tmp, `${JSON.stringify(moved, null, 2)}
|
|
29346
29484
|
`);
|
|
@@ -29351,9 +29489,9 @@ function applyConversion(plan) {
|
|
|
29351
29489
|
}
|
|
29352
29490
|
|
|
29353
29491
|
// src/export.ts
|
|
29354
|
-
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync8, copyFileSync, cpSync as cpSync2, readFileSync as
|
|
29492
|
+
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync8, copyFileSync, cpSync as cpSync2, readFileSync as readFileSync40, readdirSync as readdirSync17, existsSync as existsSync32, realpathSync as realpathSync2 } from "node:fs";
|
|
29355
29493
|
import { homedir as homedir3 } from "node:os";
|
|
29356
|
-
import { join as
|
|
29494
|
+
import { join as join52, dirname as dirname20, basename as basename7, relative as relative13, resolve as resolve34, sep as sep12 } from "node:path";
|
|
29357
29495
|
import { createHash as createHash11 } from "node:crypto";
|
|
29358
29496
|
import { fileURLToPath as fileURLToPath11 } from "node:url";
|
|
29359
29497
|
var LENS_PARAMS = ["collapse", "components", "detail", "env", "logical", "ops", "radial", "stacks", "tier"];
|
|
@@ -29410,24 +29548,24 @@ function captureKeys(axes) {
|
|
|
29410
29548
|
return [...keys];
|
|
29411
29549
|
}
|
|
29412
29550
|
function webDir() {
|
|
29413
|
-
return
|
|
29551
|
+
return join52(dirname20(fileURLToPath11(import.meta.url)), "..", "web");
|
|
29414
29552
|
}
|
|
29415
29553
|
function pkgRoot2() {
|
|
29416
|
-
return
|
|
29554
|
+
return join52(dirname20(fileURLToPath11(import.meta.url)), "..");
|
|
29417
29555
|
}
|
|
29418
29556
|
var NOTICE_FILES = ["LICENSE", "THIRD_PARTY.md"];
|
|
29419
29557
|
function copyNotices(outDir, root = pkgRoot2()) {
|
|
29420
29558
|
const copied = [];
|
|
29421
29559
|
for (const f of NOTICE_FILES) {
|
|
29422
|
-
if (!
|
|
29423
|
-
copyFileSync(
|
|
29560
|
+
if (!existsSync32(join52(root, f))) continue;
|
|
29561
|
+
copyFileSync(join52(root, f), join52(outDir, f));
|
|
29424
29562
|
copied.push(f);
|
|
29425
29563
|
}
|
|
29426
|
-
const lic =
|
|
29427
|
-
if (
|
|
29428
|
-
mkdirSync10(
|
|
29429
|
-
for (const f of
|
|
29430
|
-
copyFileSync(
|
|
29564
|
+
const lic = join52(root, "licenses");
|
|
29565
|
+
if (existsSync32(lic)) {
|
|
29566
|
+
mkdirSync10(join52(outDir, "licenses"), { recursive: true });
|
|
29567
|
+
for (const f of readdirSync17(lic)) {
|
|
29568
|
+
copyFileSync(join52(lic, f), join52(outDir, "licenses", f));
|
|
29431
29569
|
copied.push(`licenses/${f}`);
|
|
29432
29570
|
}
|
|
29433
29571
|
}
|
|
@@ -29452,7 +29590,7 @@ async function runExport(cfg, outDir, opts = {}) {
|
|
|
29452
29590
|
...proj.sqlYodeler ? { sqlYodeler: true } : {}
|
|
29453
29591
|
};
|
|
29454
29592
|
const scrub = exportScrubber(cfg);
|
|
29455
|
-
const snapDir =
|
|
29593
|
+
const snapDir = join52(outDir, "snapshots");
|
|
29456
29594
|
mkdirSync10(snapDir, { recursive: true });
|
|
29457
29595
|
const keyToFile = {};
|
|
29458
29596
|
let ok = 0;
|
|
@@ -29461,7 +29599,7 @@ async function runExport(cfg, outDir, opts = {}) {
|
|
|
29461
29599
|
const res = await app.request(`${key}${key.includes("?") ? "&" : "?"}layout=1`);
|
|
29462
29600
|
const body = scrub(shapeSnapshot(key, await res.text(), opts));
|
|
29463
29601
|
const file = slug3(key, body);
|
|
29464
|
-
writeFileSync8(
|
|
29602
|
+
writeFileSync8(join52(snapDir, file), body);
|
|
29465
29603
|
keyToFile[key] = `snapshots/${file}`;
|
|
29466
29604
|
if (res.ok) ok++;
|
|
29467
29605
|
else failed++;
|
|
@@ -29483,29 +29621,29 @@ async function runExport(cfg, outDir, opts = {}) {
|
|
|
29483
29621
|
axes,
|
|
29484
29622
|
keyToFile
|
|
29485
29623
|
};
|
|
29486
|
-
writeFileSync8(
|
|
29487
|
-
const html =
|
|
29624
|
+
writeFileSync8(join52(outDir, "manifest.json"), JSON.stringify(manifest, null, 2));
|
|
29625
|
+
const html = readFileSync40(join52(webDir(), "index.html"), "utf8").replace(
|
|
29488
29626
|
/<\/head>/i,
|
|
29489
29627
|
` <script>window.__BEHOLD_STATIC__ = true;</script>
|
|
29490
29628
|
</head>`
|
|
29491
29629
|
);
|
|
29492
|
-
writeFileSync8(
|
|
29493
|
-
for (const f of
|
|
29630
|
+
writeFileSync8(join52(outDir, "index.html"), html);
|
|
29631
|
+
for (const f of readdirSync17(webDir())) {
|
|
29494
29632
|
if (f === "index.html" || f.endsWith(".test.js")) continue;
|
|
29495
|
-
cpSync2(
|
|
29633
|
+
cpSync2(join52(webDir(), f), join52(outDir, f), { recursive: true });
|
|
29496
29634
|
}
|
|
29497
|
-
writeFileSync8(
|
|
29635
|
+
writeFileSync8(join52(outDir, "README.md"), BUNDLE_README);
|
|
29498
29636
|
copyNotices(outDir);
|
|
29499
29637
|
const name = workerName(cfg.projectDir, opts.name);
|
|
29500
29638
|
writeFileSync8(
|
|
29501
|
-
|
|
29639
|
+
join52(outDir, "wrangler.jsonc"),
|
|
29502
29640
|
JSON.stringify(
|
|
29503
29641
|
{ $schema: "node_modules/wrangler/config-schema.json", name, compatibility_date: "2025-06-01", assets: { directory: "." } },
|
|
29504
29642
|
null,
|
|
29505
29643
|
2
|
|
29506
29644
|
) + "\n"
|
|
29507
29645
|
);
|
|
29508
|
-
writeFileSync8(
|
|
29646
|
+
writeFileSync8(join52(outDir, "manifest.json"), JSON.stringify({ ...manifest, files: bundleFiles(outDir).filter((f) => f !== "manifest.json") }, null, 2));
|
|
29509
29647
|
process.stdout.write(
|
|
29510
29648
|
`behold export \u2192 ${outDir}
|
|
29511
29649
|
${ok} snapshots${failed ? ` (${failed} endpoint error(s) captured as-is)` : ""}
|
|
@@ -29602,7 +29740,7 @@ function manifestFiles(text2) {
|
|
|
29602
29740
|
return Object.values(map).filter((f) => typeof f === "string" && /^snapshots\/[A-Za-z0-9=_.-]+$/.test(f) && !f.includes(".."));
|
|
29603
29741
|
}
|
|
29604
29742
|
function bundleFiles(outDir) {
|
|
29605
|
-
return
|
|
29743
|
+
return readdirSync17(outDir, { recursive: true, withFileTypes: true }).filter((d) => d.isFile()).map((d) => relative13(outDir, join52(d.parentPath, d.name)).split(sep12).join("/")).sort();
|
|
29606
29744
|
}
|
|
29607
29745
|
async function publishBundle(outDir, target, client) {
|
|
29608
29746
|
const files = bundleFiles(outDir);
|
|
@@ -29618,7 +29756,7 @@ async function publishBundle(outDir, target, client) {
|
|
|
29618
29756
|
}
|
|
29619
29757
|
const last = ["manifest.json", "index.html"];
|
|
29620
29758
|
const order = [...files.filter((f) => !last.includes(f)), ...last.filter((f) => files.includes(f))];
|
|
29621
|
-
for (const f of order) await client.put(at2(f),
|
|
29759
|
+
for (const f of order) await client.put(at2(f), readFileSync40(join52(outDir, f)), contentType(f), CONTENT_ADDRESSED.test(f) ? IMMUTABLE : NO_CACHE);
|
|
29622
29760
|
const wrote = new Set(files);
|
|
29623
29761
|
const removed = [];
|
|
29624
29762
|
for (const f of previous) {
|
|
@@ -29670,8 +29808,8 @@ It's just files \u2014 GitHub Pages, S3, nginx, or Cloudflare Pages
|
|
|
29670
29808
|
|
|
29671
29809
|
// src/publish-snapshots.ts
|
|
29672
29810
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
29673
|
-
import { readFileSync as
|
|
29674
|
-
import { join as
|
|
29811
|
+
import { readFileSync as readFileSync41 } from "node:fs";
|
|
29812
|
+
import { join as join53 } from "node:path";
|
|
29675
29813
|
var DEFAULT_KEEP = 30;
|
|
29676
29814
|
var SNAPSHOT_REPORTS_BASE = "../../../";
|
|
29677
29815
|
var COMMIT = /^[0-9a-f]{7,64}$/;
|
|
@@ -29759,7 +29897,7 @@ async function publishSnapshot(outDir, target, commit, client, opts = {}) {
|
|
|
29759
29897
|
const keep = opts.keep ?? DEFAULT_KEEP;
|
|
29760
29898
|
if (!Number.isInteger(keep) || keep < 1) throw new Error(`--keep takes a whole number of at least 1, not ${keep}`);
|
|
29761
29899
|
const at2 = (f) => `${target.prefix}/${f}`;
|
|
29762
|
-
const local = JSON.parse(
|
|
29900
|
+
const local = JSON.parse(readFileSync41(join53(outDir, "manifest.json"), "utf8"));
|
|
29763
29901
|
const generated = local.capturedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
29764
29902
|
const entry = { commit: sha, at: commit.at ?? generated, project: opts.project ?? local.projectDir ?? "", generated };
|
|
29765
29903
|
const bundle = await publishBundle(outDir, { bucket: target.bucket, prefix: at2(sha) }, client);
|
|
@@ -30260,7 +30398,7 @@ function warnIfNotChantProject(dir) {
|
|
|
30260
30398
|
if (shape.kind === "estate") {
|
|
30261
30399
|
process.stderr.write(
|
|
30262
30400
|
`behold: warning \u2014 ${dir} is an estate root, not a chant project itself.
|
|
30263
|
-
Serve its members composed: behold serve ${shape.members.map((m) =>
|
|
30401
|
+
Serve its members composed: behold serve ${shape.members.map((m) => join54(dir, m.dir)).join(" ")}
|
|
30264
30402
|
`
|
|
30265
30403
|
);
|
|
30266
30404
|
return;
|
|
@@ -30296,7 +30434,7 @@ async function runCarve(rest) {
|
|
|
30296
30434
|
process.exit(2);
|
|
30297
30435
|
}
|
|
30298
30436
|
const reportPath = resolve35(fileArg);
|
|
30299
|
-
const parsed = readCarveReport(reportPath, (p) =>
|
|
30437
|
+
const parsed = readCarveReport(reportPath, (p) => readFileSync42(p, "utf8"));
|
|
30300
30438
|
if (!parsed.ok) {
|
|
30301
30439
|
process.stderr.write(`behold carve: ${parsed.refusal.error}
|
|
30302
30440
|
${parsed.refusal.remedy}
|
|
@@ -30325,7 +30463,7 @@ async function runDoctor(rest) {
|
|
|
30325
30463
|
}
|
|
30326
30464
|
}
|
|
30327
30465
|
const dir = dirArg ?? ".";
|
|
30328
|
-
if (!
|
|
30466
|
+
if (!existsSync33(resolve35(dir))) {
|
|
30329
30467
|
process.stderr.write(`behold doctor: no such directory: ${resolve35(dir)}
|
|
30330
30468
|
`);
|
|
30331
30469
|
process.exit(2);
|
|
@@ -30362,7 +30500,7 @@ ${check.stdout || check.stderr}
|
|
|
30362
30500
|
if (check.code !== 0) process.exitCode = 1;
|
|
30363
30501
|
}
|
|
30364
30502
|
async function runDemo(rest) {
|
|
30365
|
-
const pkgRoot3 =
|
|
30503
|
+
const pkgRoot3 = join54(dirname21(fileURLToPath12(import.meta.url)), "..");
|
|
30366
30504
|
const registry2 = loadDemoRegistry(pkgRoot3);
|
|
30367
30505
|
let port = 4600;
|
|
30368
30506
|
let live2 = false;
|
|
@@ -30497,7 +30635,7 @@ async function serveCarveDemo(target, carve, port, live2 = false) {
|
|
|
30497
30635
|
};
|
|
30498
30636
|
process.stdout.write("behold demo carve --live \u2192 the tfstate is real now; the advisor reads what terraform wrote.\n");
|
|
30499
30637
|
}
|
|
30500
|
-
if (
|
|
30638
|
+
if (existsSync33(join54(project, "package.json")) && !existsSync33(join54(project, "node_modules"))) {
|
|
30501
30639
|
process.stdout.write(`behold demo carve \u2192 npm install in ${carve.project}/ (the chant this walkthrough shells)\u2026
|
|
30502
30640
|
`);
|
|
30503
30641
|
const code = await spawnStep("npm", ["install"], project);
|
|
@@ -30508,7 +30646,7 @@ async function serveCarveDemo(target, carve, port, live2 = false) {
|
|
|
30508
30646
|
}
|
|
30509
30647
|
}
|
|
30510
30648
|
let degraded;
|
|
30511
|
-
if (!
|
|
30649
|
+
if (!existsSync33(join54(target, "node_modules", ...HCL_PARSER_PKG.split("/")))) {
|
|
30512
30650
|
process.stdout.write(`behold demo carve \u2192 npm install ${HCL_PARSER_PKG} (chant's HCL parser, ~2MB, once)\u2026
|
|
30513
30651
|
`);
|
|
30514
30652
|
const code = await spawnStep("npm", ["install", "--no-save", "--no-package-lock", HCL_PARSER_PKG], target);
|
|
@@ -30525,7 +30663,7 @@ async function serveCarveDemo(target, carve, port, live2 = false) {
|
|
|
30525
30663
|
);
|
|
30526
30664
|
if (code !== 0) degraded = `chant carve advise exited ${code}`;
|
|
30527
30665
|
}
|
|
30528
|
-
const serving = !degraded &&
|
|
30666
|
+
const serving = !degraded && existsSync33(report) ? report : committed;
|
|
30529
30667
|
if (degraded) {
|
|
30530
30668
|
process.stderr.write(
|
|
30531
30669
|
`behold demo carve: ${degraded}
|
|
@@ -30533,7 +30671,7 @@ async function serveCarveDemo(target, carve, port, live2 = false) {
|
|
|
30533
30671
|
`
|
|
30534
30672
|
);
|
|
30535
30673
|
}
|
|
30536
|
-
if (!
|
|
30674
|
+
if (!existsSync33(serving)) {
|
|
30537
30675
|
process.stderr.write(`behold demo carve: no carve report at ${serving}
|
|
30538
30676
|
`);
|
|
30539
30677
|
process.exit(2);
|
|
@@ -30579,7 +30717,7 @@ async function runPreview(rest) {
|
|
|
30579
30717
|
process.exit(2);
|
|
30580
30718
|
}
|
|
30581
30719
|
const projectDir = resolve35(dirArg ?? process.cwd());
|
|
30582
|
-
if (!
|
|
30720
|
+
if (!existsSync33(projectDir)) {
|
|
30583
30721
|
process.stderr.write(`behold preview: project not found at ${projectDir}
|
|
30584
30722
|
`);
|
|
30585
30723
|
process.exit(2);
|
|
@@ -30670,7 +30808,7 @@ async function runExportCmd(rest) {
|
|
|
30670
30808
|
injectEmulatorEnv(env);
|
|
30671
30809
|
env ??= "local";
|
|
30672
30810
|
}
|
|
30673
|
-
if (!
|
|
30811
|
+
if (!existsSync33(projectDir)) {
|
|
30674
30812
|
process.stderr.write(`behold export: project not found at ${projectDir}
|
|
30675
30813
|
`);
|
|
30676
30814
|
process.exit(2);
|