@akanjs/cli 3.0.1 → 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.build-stamp +1 -1
- package/{CodeAgent-zfab7pkn.js → CodeAgent-szbjv4gv.js} +2 -2
- package/{CodeTui-0zhnr0pw.js → CodeTui-5nw86ab6.js} +1 -1
- package/{agent.command-aja6z9mn.js → agent.command-np1dffkb.js} +5 -5
- package/akanCode.js +2 -2
- package/{application.command-049ehgx3.js → application.command-gk69v1xs.js} +8 -8
- package/{applicationBuildRunner-75n5rpwp.js → applicationBuildRunner-wx09n9g6.js} +3 -3
- package/buildBatch.proc.js +4 -4
- package/{cloud.command-gw4kqxt8.js → cloud.command-tw06613r.js} +10 -10
- package/cloud.script-64gzba8r.js +20 -0
- package/{code.command-x9t6z5nw.js → code.command-hmtx14b2.js} +6 -6
- package/{context.command-yfbe1rtd.js → context.command-6aqvdx43.js} +13 -13
- package/context.runner-hnkvv3z3.js +21 -0
- package/{guideline.command-kq9gp690.js → guideline.command-axvf68gc.js} +2 -2
- package/guidelines/conventions/conventions.instruction.md +89 -17
- package/guidelines/queryRule/queryRule.instruction.md +4 -2
- package/guidelines/runtimeRule/runtimeRule.instruction.md +10 -5
- package/guidelines/transportRule/transportRule.instruction.md +40 -4
- package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +1 -1
- package/incrementalBuilder.proc.js +3 -3
- package/{index-66yspb67.js → index-1bjkfvm9.js} +29 -27
- package/{index-b95yhqjr.js → index-1gs9g12n.js} +3 -3
- package/{index-y7hx1ygz.js → index-3xmzr1p1.js} +2 -2
- package/{index-mzjb6zp4.js → index-50jjwg8y.js} +1 -1
- package/{index-150s07n8.js → index-50wb2a26.js} +313 -93
- package/{index-8b639zes.js → index-6keyf4sg.js} +4 -4
- package/{index-vs8mefhy.js → index-bsv901fd.js} +7 -7
- package/{index-5pvxf7z0.js → index-cb6yc5mb.js} +2 -2
- package/{index-rfcz04w9.js → index-f4e08ptp.js} +4 -4
- package/{index-25fvrxmy.js → index-g38nhv87.js} +1 -1
- package/{index-m3xsb1ms.js → index-gtjgnv36.js} +29 -11
- package/{index-mb59b8x0.js → index-h9ht6s60.js} +1 -1
- package/{index-5g4rkrvt.js → index-hp3stk1m.js} +3 -3
- package/{index-h54yj9wr.js → index-hxnnfy57.js} +6 -5
- package/{index-kn5d4jmg.js → index-j38qkvkk.js} +7 -7
- package/{index-y5ga5w9t.js → index-jb0hmt3k.js} +3 -3
- package/{index-7p4c0yer.js → index-jk9xnck6.js} +33 -11
- package/{index-senscydg.js → index-k9rrten6.js} +6 -1
- package/{index-qe71g4ze.js → index-nwd6qzvv.js} +42 -23
- package/{index-a37by9hn.js → index-q6ft9fkc.js} +4 -4
- package/{index-br8pkrk1.js → index-t91a7339.js} +5 -5
- package/{index-c14nsvnv.js → index-xwprn9nr.js} +1 -1
- package/{index-fkvb79qe.js → index-z750gk1j.js} +15 -11
- package/{index-5q14pwzd.js → index-zwd84m0w.js} +4 -4
- package/{index-8kvy8qb4.js → index-zyw622y1.js} +12 -2
- package/index.js +21 -21
- package/{library.command-keqjevpp.js → library.command-9m2rdwwz.js} +3 -3
- package/{localRegistry.command-pydeq5zf.js → localRegistry.command-kda81jyk.js} +9 -9
- package/{module.command-dkrnqx3v.js → module.command-q63dffya.js} +5 -5
- package/{package.command-wmc0ys5y.js → package.command-y2jh0m99.js} +3 -3
- package/package.json +2 -2
- package/{page.command-tf3erhrv.js → page.command-f3e4cwhh.js} +3 -3
- package/{primitive.command-7hqpegj4.js → primitive.command-r4kq75qj.js} +6 -6
- package/{quality.command-8122axq3.js → quality.command-f7gzh26z.js} +9 -2
- package/{repair.command-mcy12h0n.js → repair.command-0qmyr6qa.js} +5 -5
- package/{scalar.command-vvvbzttc.js → scalar.command-kddn7av4.js} +4 -4
- package/{subspace.command-pzvqfy5h.js → subspace.command-ft65qvc4.js} +5 -7
- package/templates/app/tsconfig.json.template +1 -6
- package/templates/app/ui/Recipe/jellyButton.ts +1 -0
- package/templates/facetIndex/index.ts +21 -6
- package/templates/lib/dict.ts +9 -1
- package/templates/lib/srv.ts +2 -3
- package/templates/libRoot/common/index.ts +2 -7
- package/templates/libRoot/srvkit/index.ts +2 -7
- package/templates/libRoot/ui/index.ts +2 -7
- package/templates/libRoot/webkit/index.ts +2 -7
- package/templates/moduleRoot/index.tsx +3 -3
- package/{tunnel.command-82zz5xnq.js → tunnel.command-b3ymdk4f.js} +2 -2
- package/{workflow.command-y8x3kgjv.js → workflow.command-z1srcdfw.js} +10 -10
- package/{workspace.command-jvsb7brc.js → workspace.command-vp6vmx3z.js} +21 -21
- package/cloud.script-c723cpcb.js +0 -20
- package/context.runner-erfe68j5.js +0 -21
- package/index-bjwxs904.js +0 -77
- package/templates/libRoot/common/commonLogic.ts +0 -14
- package/templates/libRoot/srvkit/backendLogic.ts +0 -13
- package/templates/libRoot/webkit/frontendLogic.ts +0 -13
|
@@ -517,7 +517,7 @@ import {
|
|
|
517
517
|
stat as stat2,
|
|
518
518
|
symlink
|
|
519
519
|
} from "fs/promises";
|
|
520
|
-
import
|
|
520
|
+
import path10 from "path";
|
|
521
521
|
import { pathToFileURL } from "url";
|
|
522
522
|
import {
|
|
523
523
|
capitalize,
|
|
@@ -1044,8 +1044,9 @@ class AkanAppConfig {
|
|
|
1044
1044
|
"activity",
|
|
1045
1045
|
"files"
|
|
1046
1046
|
],
|
|
1047
|
-
desktop: ["indexPath", "server", "recovery", "window", "screenCapture", "entitlements"],
|
|
1047
|
+
desktop: ["indexPath", "server", "recovery", "window", "screenCapture", "entitlements", "dmg"],
|
|
1048
1048
|
desktopServer: ["omit"],
|
|
1049
|
+
dmg: ["background", "background2x", "window", "iconSize", "textSize", "app", "applications"],
|
|
1049
1050
|
deepLinks: ["schemes", "domains"]
|
|
1050
1051
|
};
|
|
1051
1052
|
static #movedKeys = {
|
|
@@ -1074,6 +1075,7 @@ class AkanAppConfig {
|
|
|
1074
1075
|
check(settings.android, AkanAppConfig.#nativeKeys.android, `${where}.android`, "android");
|
|
1075
1076
|
check(settings.desktop, AkanAppConfig.#nativeKeys.desktop, `${where}.desktop`, "desktop");
|
|
1076
1077
|
check(settings.desktop?.server, AkanAppConfig.#nativeKeys.desktopServer, `${where}.desktop.server`, "desktopServer");
|
|
1078
|
+
check(settings.desktop?.dmg, AkanAppConfig.#nativeKeys.dmg, `${where}.desktop.dmg`, "dmg");
|
|
1077
1079
|
check(settings.deepLinks, AkanAppConfig.#nativeKeys.deepLinks, `${where}.deepLinks`, "deepLinks");
|
|
1078
1080
|
}
|
|
1079
1081
|
static #androidFilePattern = /^(?:res\/[^/]+\/[^/]+|assets\/.+)$/;
|
|
@@ -1352,10 +1354,85 @@ var shiftBuildNum = async (app, delta) => {
|
|
|
1352
1354
|
};
|
|
1353
1355
|
var increaseBuildNum = async (app) => await shiftBuildNum(app, 1);
|
|
1354
1356
|
var decreaseBuildNum = async (app) => await shiftBuildNum(app, -1);
|
|
1357
|
+
// pkgs/@akanjs/devkit/jsonFormatter.ts
|
|
1358
|
+
import path6 from "path";
|
|
1359
|
+
|
|
1360
|
+
class JsonFormatter {
|
|
1361
|
+
static lineWidth = 120;
|
|
1362
|
+
static stringify(value, filePath) {
|
|
1363
|
+
const json = JSON.stringify(value, null, 2);
|
|
1364
|
+
if (path6.basename(filePath) === "package.json")
|
|
1365
|
+
return `${json}
|
|
1366
|
+
`;
|
|
1367
|
+
return `${JsonFormatter.#print(JSON.parse(json), 0, { column: 0, trailing: 0 })}
|
|
1368
|
+
`;
|
|
1369
|
+
}
|
|
1370
|
+
static #print(value, depth, placement) {
|
|
1371
|
+
if (Array.isArray(value))
|
|
1372
|
+
return JsonFormatter.#printArray(value, depth, placement);
|
|
1373
|
+
if (value === null || typeof value !== "object")
|
|
1374
|
+
return JSON.stringify(value);
|
|
1375
|
+
const entries = Object.entries(value);
|
|
1376
|
+
if (!entries.length)
|
|
1377
|
+
return "{}";
|
|
1378
|
+
const indent = " ".repeat(depth + 1);
|
|
1379
|
+
const members = entries.map(([key, member], idx) => {
|
|
1380
|
+
const prefix = `${indent}${JSON.stringify(key)}: `;
|
|
1381
|
+
const trailing = idx < entries.length - 1 ? 1 : 0;
|
|
1382
|
+
return `${prefix}${JsonFormatter.#print(member, depth + 1, { column: Bun.stringWidth(prefix), trailing })}`;
|
|
1383
|
+
});
|
|
1384
|
+
return `{
|
|
1385
|
+
${members.join(`,
|
|
1386
|
+
`)}
|
|
1387
|
+
${" ".repeat(depth)}}`;
|
|
1388
|
+
}
|
|
1389
|
+
static #printArray(items, depth, { column, trailing }) {
|
|
1390
|
+
if (!items.length)
|
|
1391
|
+
return "[]";
|
|
1392
|
+
const flat = JsonFormatter.#flat(items);
|
|
1393
|
+
if (flat !== null && column + Bun.stringWidth(flat) + trailing <= JsonFormatter.lineWidth)
|
|
1394
|
+
return flat;
|
|
1395
|
+
const indent = " ".repeat(depth + 1);
|
|
1396
|
+
const isLast = (idx) => idx === items.length - 1;
|
|
1397
|
+
const body = items.every((item) => typeof item === "number") ? JsonFormatter.#fill(items.map((item, idx) => `${JSON.stringify(item)}${isLast(idx) ? "" : ","}`), indent) : items.map((item, idx) => {
|
|
1398
|
+
const placement = { column: indent.length, trailing: isLast(idx) ? 0 : 1 };
|
|
1399
|
+
return `${indent}${JsonFormatter.#print(item, depth + 1, placement)}`;
|
|
1400
|
+
}).join(`,
|
|
1401
|
+
`);
|
|
1402
|
+
return `[
|
|
1403
|
+
${body}
|
|
1404
|
+
${" ".repeat(depth)}]`;
|
|
1405
|
+
}
|
|
1406
|
+
static #fill(tokens, indent) {
|
|
1407
|
+
const lines = [];
|
|
1408
|
+
let line = "";
|
|
1409
|
+
for (const token of tokens) {
|
|
1410
|
+
if (line && Bun.stringWidth(line) + 1 + Bun.stringWidth(token) <= JsonFormatter.lineWidth) {
|
|
1411
|
+
line = `${line} ${token}`;
|
|
1412
|
+
continue;
|
|
1413
|
+
}
|
|
1414
|
+
if (line)
|
|
1415
|
+
lines.push(line);
|
|
1416
|
+
line = `${indent}${token}`;
|
|
1417
|
+
}
|
|
1418
|
+
return [...lines, line].join(`
|
|
1419
|
+
`);
|
|
1420
|
+
}
|
|
1421
|
+
static #flat(value) {
|
|
1422
|
+
if (Array.isArray(value)) {
|
|
1423
|
+
const items = value.map((item) => JsonFormatter.#flat(item));
|
|
1424
|
+
return items.includes(null) ? null : `[${items.join(", ")}]`;
|
|
1425
|
+
}
|
|
1426
|
+
if (value === null || typeof value !== "object")
|
|
1427
|
+
return JSON.stringify(value);
|
|
1428
|
+
return Object.keys(value).length ? null : "{}";
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1355
1432
|
// pkgs/@akanjs/devkit/linter.ts
|
|
1356
1433
|
import { spawn } from "child_process";
|
|
1357
1434
|
import { existsSync, readFileSync } from "fs";
|
|
1358
|
-
import
|
|
1435
|
+
import path7 from "path";
|
|
1359
1436
|
import chalk from "chalk";
|
|
1360
1437
|
var parseBiomeReport = (output) => {
|
|
1361
1438
|
for (let start = output.indexOf("{");start !== -1; start = output.indexOf("{", start + 1)) {
|
|
@@ -1421,13 +1498,13 @@ class Linter {
|
|
|
1421
1498
|
#biomeBin;
|
|
1422
1499
|
constructor(cwdPath) {
|
|
1423
1500
|
this.lintRoot = this.#findBiomeRootPath(cwdPath);
|
|
1424
|
-
this.configPath = Linter.#configPathIn(this.lintRoot) ??
|
|
1425
|
-
const localBiomeBin =
|
|
1501
|
+
this.configPath = Linter.#configPathIn(this.lintRoot) ?? path7.join(this.lintRoot, "biome.json");
|
|
1502
|
+
const localBiomeBin = path7.join(this.lintRoot, "node_modules", ".bin", Linter.biomeBinName);
|
|
1426
1503
|
this.#biomeBin = existsSync(localBiomeBin) ? localBiomeBin : "biome";
|
|
1427
1504
|
}
|
|
1428
1505
|
static #configPathIn(dir) {
|
|
1429
1506
|
for (const fileName of BIOME_CONFIG_FILES) {
|
|
1430
|
-
const configPath =
|
|
1507
|
+
const configPath = path7.join(dir, fileName);
|
|
1431
1508
|
if (existsSync(configPath))
|
|
1432
1509
|
return configPath;
|
|
1433
1510
|
}
|
|
@@ -1436,19 +1513,19 @@ class Linter {
|
|
|
1436
1513
|
#findBiomeRootPath(dir) {
|
|
1437
1514
|
if (Linter.#configPathIn(dir))
|
|
1438
1515
|
return dir;
|
|
1439
|
-
const parentDir =
|
|
1516
|
+
const parentDir = path7.dirname(dir);
|
|
1440
1517
|
if (parentDir === dir)
|
|
1441
1518
|
throw new Error(`biome.json not found from ${dir}`);
|
|
1442
1519
|
return this.#findBiomeRootPath(parentDir);
|
|
1443
1520
|
}
|
|
1444
1521
|
#toBiomePath(filePath) {
|
|
1445
|
-
const relativePath =
|
|
1446
|
-
if (!relativePath.startsWith("..") && !
|
|
1522
|
+
const relativePath = path7.relative(this.lintRoot, filePath);
|
|
1523
|
+
if (!relativePath.startsWith("..") && !path7.isAbsolute(relativePath))
|
|
1447
1524
|
return relativePath;
|
|
1448
1525
|
return filePath;
|
|
1449
1526
|
}
|
|
1450
1527
|
#resolveFilePath(filePath) {
|
|
1451
|
-
return
|
|
1528
|
+
return path7.isAbsolute(filePath) ? filePath : path7.join(this.lintRoot, filePath);
|
|
1452
1529
|
}
|
|
1453
1530
|
async#runBiome(args, input) {
|
|
1454
1531
|
return await new Promise((resolve, reject) => {
|
|
@@ -1473,7 +1550,7 @@ class Linter {
|
|
|
1473
1550
|
const diagnosticPath = diagnostic.location?.path;
|
|
1474
1551
|
if (!diagnosticPath)
|
|
1475
1552
|
return fallbackFilePath;
|
|
1476
|
-
return
|
|
1553
|
+
return path7.isAbsolute(diagnosticPath) ? diagnosticPath : path7.join(this.lintRoot, diagnosticPath);
|
|
1477
1554
|
}
|
|
1478
1555
|
#createLintMessage(diagnostic) {
|
|
1479
1556
|
const start = diagnostic.location?.start;
|
|
@@ -1679,9 +1756,137 @@ ${errorText}, ${warningText} found`];
|
|
|
1679
1756
|
}
|
|
1680
1757
|
}
|
|
1681
1758
|
|
|
1759
|
+
// pkgs/@akanjs/devkit/libSource.ts
|
|
1760
|
+
class LibSource {
|
|
1761
|
+
static manifestKey = "akan";
|
|
1762
|
+
static unhashedDirs = ["env"];
|
|
1763
|
+
#lib;
|
|
1764
|
+
constructor(lib) {
|
|
1765
|
+
this.#lib = lib;
|
|
1766
|
+
}
|
|
1767
|
+
get #prefix() {
|
|
1768
|
+
return `libs/${this.#lib.name}/`;
|
|
1769
|
+
}
|
|
1770
|
+
#isHashed(file) {
|
|
1771
|
+
const relative = file.slice(this.#prefix.length);
|
|
1772
|
+
return !LibSource.unhashedDirs.includes(relative.split("/")[0] ?? "");
|
|
1773
|
+
}
|
|
1774
|
+
static unstamped(manifestContent) {
|
|
1775
|
+
const manifest = JSON.parse(manifestContent);
|
|
1776
|
+
delete manifest[LibSource.manifestKey];
|
|
1777
|
+
return JSON.stringify(manifest);
|
|
1778
|
+
}
|
|
1779
|
+
static async hashFiles(files, manifestFile, read) {
|
|
1780
|
+
const hasher = new Bun.CryptoHasher("sha256");
|
|
1781
|
+
for (const file of files) {
|
|
1782
|
+
const content = await read(file);
|
|
1783
|
+
hasher.update(file);
|
|
1784
|
+
hasher.update("\x00");
|
|
1785
|
+
hasher.update(file === manifestFile ? LibSource.unstamped(content) : content);
|
|
1786
|
+
hasher.update("\x00");
|
|
1787
|
+
}
|
|
1788
|
+
return hasher.digest("hex").slice(0, 32);
|
|
1789
|
+
}
|
|
1790
|
+
async computeHash() {
|
|
1791
|
+
const files = (await this.#lib.workspace.listGitFiles([`libs/${this.#lib.name}`], { untracked: true })).filter((file) => this.#isHashed(file));
|
|
1792
|
+
return await LibSource.hashFiles(files, `${this.#prefix}package.json`, (file) => this.#lib.workspace.readFile(file));
|
|
1793
|
+
}
|
|
1794
|
+
async read() {
|
|
1795
|
+
const manifest = await this.#lib.getPackageJson();
|
|
1796
|
+
const akan = manifest[LibSource.manifestKey];
|
|
1797
|
+
return akan?.source ?? null;
|
|
1798
|
+
}
|
|
1799
|
+
async write({ origin, sha }) {
|
|
1800
|
+
const [manifest, hash] = await Promise.all([this.#lib.getPackageJson(), this.computeHash()]);
|
|
1801
|
+
const akan = manifest[LibSource.manifestKey] ?? {};
|
|
1802
|
+
const stamp = { origin, sha, hash, syncedAt: new Date().toISOString() };
|
|
1803
|
+
await this.#lib.setPackageJson({ ...manifest, [LibSource.manifestKey]: { ...akan, source: stamp } });
|
|
1804
|
+
return stamp;
|
|
1805
|
+
}
|
|
1806
|
+
async syncStamp({ origin, sha }) {
|
|
1807
|
+
const [current, hash] = await Promise.all([this.read(), this.computeHash()]);
|
|
1808
|
+
if (current?.origin === origin && current.sha === sha && current.hash === hash)
|
|
1809
|
+
return { stamp: current, changed: false };
|
|
1810
|
+
return { stamp: await this.write({ origin, sha }), changed: true };
|
|
1811
|
+
}
|
|
1812
|
+
async status() {
|
|
1813
|
+
const [stamp, hash] = await Promise.all([this.read(), this.computeHash()]);
|
|
1814
|
+
const drift = !stamp ? "unstamped" : stamp.hash === hash ? "clean" : "drifted";
|
|
1815
|
+
return { lib: this.#lib.name, drift, stamp, hash };
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1818
|
+
function formatLibStatuses(statuses) {
|
|
1819
|
+
const marks = { clean: "clean ", drifted: "DRIFTED ", unstamped: "unstamped" };
|
|
1820
|
+
const sections = [
|
|
1821
|
+
"Akan Library Source Status",
|
|
1822
|
+
"",
|
|
1823
|
+
...statuses.map((status) => {
|
|
1824
|
+
const origin = status.stamp ? `${status.stamp.origin}@${status.stamp.sha}` : "no akan.source in package.json";
|
|
1825
|
+
return ` ${marks[status.drift]} libs/${status.lib} ${origin}`;
|
|
1826
|
+
}),
|
|
1827
|
+
"",
|
|
1828
|
+
`drifted: ${statuses.filter((status) => status.drift === "drifted").length} / ${statuses.length}`
|
|
1829
|
+
];
|
|
1830
|
+
return sections.join(`
|
|
1831
|
+
`);
|
|
1832
|
+
}
|
|
1833
|
+
|
|
1834
|
+
// pkgs/@akanjs/devkit/manifestDependencies.ts
|
|
1835
|
+
class ManifestDependencies {
|
|
1836
|
+
#root;
|
|
1837
|
+
#runtime;
|
|
1838
|
+
#typeOnly;
|
|
1839
|
+
#isKept;
|
|
1840
|
+
constructor(root, { runtime, typeOnly }, isKept) {
|
|
1841
|
+
this.#root = root;
|
|
1842
|
+
this.#runtime = new Set(runtime);
|
|
1843
|
+
this.#typeOnly = new Set(typeOnly);
|
|
1844
|
+
this.#isKept = isKept;
|
|
1845
|
+
}
|
|
1846
|
+
static keptBy(manifest) {
|
|
1847
|
+
const { keepDependencies } = manifest[LibSource.manifestKey] ?? {};
|
|
1848
|
+
return Array.isArray(keepDependencies) ? keepDependencies.filter((dep) => typeof dep === "string") : [];
|
|
1849
|
+
}
|
|
1850
|
+
realign(manifest) {
|
|
1851
|
+
const removed = [];
|
|
1852
|
+
const unverifiable = [];
|
|
1853
|
+
const dependencies = {};
|
|
1854
|
+
for (const [dep, version] of Object.entries(manifest.dependencies ?? {})) {
|
|
1855
|
+
if (this.#typeOnly.has(dep))
|
|
1856
|
+
continue;
|
|
1857
|
+
const rootVersion = this.#rootVersionOf(dep);
|
|
1858
|
+
if (!rootVersion) {
|
|
1859
|
+
unverifiable.push(dep);
|
|
1860
|
+
dependencies[dep] = version;
|
|
1861
|
+
} else if (this.#runtime.has(dep) || this.#isKept(dep))
|
|
1862
|
+
dependencies[dep] = rootVersion;
|
|
1863
|
+
else
|
|
1864
|
+
removed.push(dep);
|
|
1865
|
+
}
|
|
1866
|
+
const runtimeOfRootDependencies = [...this.#runtime].filter((dep) => this.#root.dependencies?.[dep]);
|
|
1867
|
+
this.#append(dependencies, runtimeOfRootDependencies);
|
|
1868
|
+
const devDependencies = {};
|
|
1869
|
+
for (const [dep, version] of Object.entries(manifest.devDependencies ?? {}))
|
|
1870
|
+
if (!Object.hasOwn(dependencies, dep))
|
|
1871
|
+
devDependencies[dep] = this.#rootVersionOf(dep) ?? version;
|
|
1872
|
+
this.#append(devDependencies, [...this.#typeOnly]);
|
|
1873
|
+
return { dependencies, devDependencies, removed, unverifiable };
|
|
1874
|
+
}
|
|
1875
|
+
#append(map, deps) {
|
|
1876
|
+
for (const dep of deps.filter((dep) => !Object.hasOwn(map, dep)).sort((a, b) => a < b ? -1 : 1)) {
|
|
1877
|
+
const rootVersion = this.#rootVersionOf(dep);
|
|
1878
|
+
if (rootVersion)
|
|
1879
|
+
map[dep] = rootVersion;
|
|
1880
|
+
}
|
|
1881
|
+
}
|
|
1882
|
+
#rootVersionOf(dep) {
|
|
1883
|
+
return this.#root.dependencies?.[dep] ?? this.#root.devDependencies?.[dep];
|
|
1884
|
+
}
|
|
1885
|
+
}
|
|
1886
|
+
|
|
1682
1887
|
// pkgs/@akanjs/devkit/repoIdentity.ts
|
|
1683
1888
|
import { execFileSync } from "child_process";
|
|
1684
|
-
import
|
|
1889
|
+
import path8 from "path";
|
|
1685
1890
|
var resolved = new Map;
|
|
1686
1891
|
var readRemoteName = (workspaceRoot) => {
|
|
1687
1892
|
try {
|
|
@@ -1699,13 +1904,13 @@ var resolveRepoName = (workspaceRoot) => {
|
|
|
1699
1904
|
const cached = resolved.get(workspaceRoot);
|
|
1700
1905
|
if (cached)
|
|
1701
1906
|
return cached;
|
|
1702
|
-
const repoName = readRemoteName(workspaceRoot) ??
|
|
1907
|
+
const repoName = readRemoteName(workspaceRoot) ?? path8.basename(workspaceRoot);
|
|
1703
1908
|
resolved.set(workspaceRoot, repoName);
|
|
1704
1909
|
return repoName;
|
|
1705
1910
|
};
|
|
1706
1911
|
|
|
1707
1912
|
// pkgs/@akanjs/devkit/scanInfo.ts
|
|
1708
|
-
import
|
|
1913
|
+
import path9 from "path";
|
|
1709
1914
|
|
|
1710
1915
|
// pkgs/@akanjs/devkit/workspaceLayout.ts
|
|
1711
1916
|
var appRootAllowedFiles = new Set([
|
|
@@ -1778,6 +1983,14 @@ var libFacetRootAllowedFiles = new Set([
|
|
|
1778
1983
|
]);
|
|
1779
1984
|
var libFacetRootTestPattern = /^[A-Za-z][A-Za-z0-9_-]*\.signal\.(test|spec)\.(ts|tsx)$/;
|
|
1780
1985
|
var isAllowedLibFacetRootFile = (filename) => libFacetRootAllowedFiles.has(filename) || libFacetRootTestPattern.test(filename);
|
|
1986
|
+
var barrelFacetDirs = ["ui", "webkit", "srvkit", "common", "plugin"];
|
|
1987
|
+
var barrelShadowingIndexFiles = new Set(["index.tsx", "index.jsx", "index.mts"]);
|
|
1988
|
+
var facetIndexShadowOf = (sysRelativePath) => {
|
|
1989
|
+
const [facet, filename = "", ...nested] = sysRelativePath.split("/");
|
|
1990
|
+
if (nested.length || !barrelShadowingIndexFiles.has(filename) || !barrelFacetDirs.some((dir) => dir === facet))
|
|
1991
|
+
return null;
|
|
1992
|
+
return `shadows the generated ${facet}/index.ts: Bun loads ${filename} and TypeScript checks index.ts, so a name only ` + `the generated barrel exports typechecks and is undefined at runtime. Delete it, since the generated barrel ` + `re-exports every file and folder in ${facet}/; a namespace it builds belongs in ${facet}/<Folder>/index.tsx`;
|
|
1993
|
+
};
|
|
1781
1994
|
var retiredAppRootEntries = new Set([
|
|
1782
1995
|
"android",
|
|
1783
1996
|
"ios",
|
|
@@ -1786,7 +1999,7 @@ var retiredAppRootEntries = new Set([
|
|
|
1786
1999
|
"capacitor.config.js",
|
|
1787
2000
|
"capacitor.config.json"
|
|
1788
2001
|
]);
|
|
1789
|
-
var rootEntryHintOf = (type, name) => type === "app" && retiredAppRootEntries.has(name) ? "a Capacitor-era entry; the native runtime generates its projects under
|
|
2002
|
+
var rootEntryHintOf = (type, name) => type === "app" && retiredAppRootEntries.has(name) ? "a Capacitor-era entry; the native runtime generates its projects under dist/native/<app>/<target>, so delete it" : null;
|
|
1790
2003
|
var isScannedRootEntry = (type, name) => !name.startsWith(".") || rootAllowedDirs[type].has(name);
|
|
1791
2004
|
|
|
1792
2005
|
// pkgs/@akanjs/devkit/scanInfo.ts
|
|
@@ -1816,9 +2029,9 @@ var moduleUiFileTypes = {
|
|
|
1816
2029
|
scalar: new Set(["Template", "Unit"])
|
|
1817
2030
|
};
|
|
1818
2031
|
var createDependencyScanner = async (exec) => (await import("./dependencyScanner-06z2dmrr.js")).TypeScriptDependencyScanner.from(exec);
|
|
1819
|
-
var getScanPath = (exec, relativePath) =>
|
|
2032
|
+
var getScanPath = (exec, relativePath) => path9.posix.join(`${exec.type}s`, exec.name, relativePath.split(path9.sep).join("/"));
|
|
1820
2033
|
var getModuleNameFromPath = (kind, modulePath) => {
|
|
1821
|
-
const dirname =
|
|
2034
|
+
const dirname = path9.basename(modulePath);
|
|
1822
2035
|
return kind === "service" ? dirname.replace(/^_+/, "") : dirname;
|
|
1823
2036
|
};
|
|
1824
2037
|
async function assertScanConvention(exec, libRoot) {
|
|
@@ -1835,22 +2048,28 @@ async function assertScanConvention(exec, libRoot) {
|
|
|
1835
2048
|
for (const dirname of dirs)
|
|
1836
2049
|
if (!allowedRootDirs.has(dirname))
|
|
1837
2050
|
addViolation(dirname, rootEntryHintOf(exec.type, dirname) ?? `unsupported ${exec.type} root folder`);
|
|
2051
|
+
for (const facet of barrelFacetDirs)
|
|
2052
|
+
for (const filename of await exec.readdir(facet)) {
|
|
2053
|
+
const shadow = facetIndexShadowOf(`${facet}/${filename}`);
|
|
2054
|
+
if (shadow)
|
|
2055
|
+
addViolation(path9.join(facet, filename), shadow);
|
|
2056
|
+
}
|
|
1838
2057
|
if (exec.type === "lib")
|
|
1839
2058
|
for (const { relativePath, reason } of await exec.getPageConventionViolations())
|
|
1840
2059
|
addViolation(relativePath, reason);
|
|
1841
2060
|
for (const filename of libRoot.files)
|
|
1842
2061
|
if (!isAllowedLibFacetRootFile(filename))
|
|
1843
|
-
addViolation(
|
|
2062
|
+
addViolation(path9.join("lib", filename), "unsupported lib facet root file");
|
|
1844
2063
|
for (const dirname of libRoot.dirs)
|
|
1845
2064
|
if (dirname.startsWith("__") && !internalLibDirs.has(dirname))
|
|
1846
|
-
addViolation(
|
|
2065
|
+
addViolation(path9.join("lib", dirname), "unsupported internal lib folder");
|
|
1847
2066
|
const databaseDirs = libRoot.dirs.filter((dirname) => !dirname.startsWith("_"));
|
|
1848
2067
|
const serviceDirs = libRoot.dirs.filter((dirname) => dirname.startsWith("_") && !dirname.startsWith("__"));
|
|
1849
2068
|
const scalarDirs = await exec.readdir("lib/__scalar");
|
|
1850
2069
|
await Promise.all([
|
|
1851
|
-
...databaseDirs.map((dirname) => validateModuleFiles(exec, violations, "database",
|
|
1852
|
-
...serviceDirs.map((dirname) => validateModuleFiles(exec, violations, "service",
|
|
1853
|
-
...scalarDirs.map((dirname) => validateModuleFiles(exec, violations, "scalar",
|
|
2070
|
+
...databaseDirs.map((dirname) => validateModuleFiles(exec, violations, "database", path9.join("lib", dirname))),
|
|
2071
|
+
...serviceDirs.map((dirname) => validateModuleFiles(exec, violations, "service", path9.join("lib", dirname))),
|
|
2072
|
+
...scalarDirs.map((dirname) => validateModuleFiles(exec, violations, "scalar", path9.join("lib/__scalar", dirname)))
|
|
1854
2073
|
]);
|
|
1855
2074
|
if (violations.length > 0) {
|
|
1856
2075
|
throw new Error(`[scan-convention]
|
|
@@ -1862,11 +2081,11 @@ async function validateModuleFiles(exec, violations, kind, modulePath) {
|
|
|
1862
2081
|
const { files, dirs } = await exec.getFilesAndDirs(modulePath);
|
|
1863
2082
|
const moduleName = getModuleNameFromPath(kind, modulePath);
|
|
1864
2083
|
dirs.forEach((dirname) => {
|
|
1865
|
-
violations.push(`${getScanPath(exec,
|
|
2084
|
+
violations.push(`${getScanPath(exec, path9.join(modulePath, dirname))}: unsupported module folder`);
|
|
1866
2085
|
});
|
|
1867
2086
|
const uiModuleName = moduleName[0].toUpperCase() + moduleName.slice(1);
|
|
1868
2087
|
for (const filename of files) {
|
|
1869
|
-
const scanPath = getScanPath(exec,
|
|
2088
|
+
const scanPath = getScanPath(exec, path9.join(modulePath, filename));
|
|
1870
2089
|
if (filename === "index.ts" || filename === "index.tsx" || /\.(test|spec)\.(ts|tsx)$/.test(filename))
|
|
1871
2090
|
continue;
|
|
1872
2091
|
if (filename === `${moduleName}.abstract.md`)
|
|
@@ -1939,16 +2158,16 @@ class ScanInfo {
|
|
|
1939
2158
|
}
|
|
1940
2159
|
};
|
|
1941
2160
|
await Promise.all([
|
|
1942
|
-
...databaseDirs.map((name) => collect(
|
|
1943
|
-
...serviceDirs.map((dirname) => collect(
|
|
1944
|
-
...scalarDirs.map((name) => collect(
|
|
2161
|
+
...databaseDirs.map((name) => collect(path9.join("lib", name), name, "databases")),
|
|
2162
|
+
...serviceDirs.map((dirname) => collect(path9.join("lib", dirname), dirname.slice(1), "services")),
|
|
2163
|
+
...scalarDirs.map((name) => collect(path9.join("lib/__scalar", name), name, "scalars"))
|
|
1945
2164
|
]);
|
|
1946
2165
|
const routes = exec.type === "lib" ? [] : await exec.getPageKeys();
|
|
1947
2166
|
const common = {
|
|
1948
2167
|
name: exec.name,
|
|
1949
2168
|
type: exec.type,
|
|
1950
2169
|
repoName: exec.workspace.repoName,
|
|
1951
|
-
serveDomain: WorkspaceExecutor.getBaseDevEnv(
|
|
2170
|
+
serveDomain: WorkspaceExecutor.getBaseDevEnv(path9.join(exec.workspace.workspaceRoot, ".env")).serveDomain,
|
|
1952
2171
|
files,
|
|
1953
2172
|
libDeps,
|
|
1954
2173
|
pkgDeps,
|
|
@@ -2330,10 +2549,10 @@ class Executor {
|
|
|
2330
2549
|
return this.#settle(proc, target, { redStderr: true }).then(({ code, signal }) => ({ code, signal }));
|
|
2331
2550
|
}
|
|
2332
2551
|
getPath(filePath) {
|
|
2333
|
-
if (
|
|
2552
|
+
if (path10.isAbsolute(filePath))
|
|
2334
2553
|
return filePath;
|
|
2335
2554
|
if (filePath.startsWith("."))
|
|
2336
|
-
return
|
|
2555
|
+
return path10.join(this.cwdPath, filePath);
|
|
2337
2556
|
const baseParts = this.cwdPath.split(/[\\/]/).filter(Boolean);
|
|
2338
2557
|
const targetParts = filePath.split(/[\\/]/).filter(Boolean);
|
|
2339
2558
|
let overlapLength = 0;
|
|
@@ -2347,7 +2566,7 @@ class Executor {
|
|
|
2347
2566
|
if (isOverlap)
|
|
2348
2567
|
overlapLength = i;
|
|
2349
2568
|
}
|
|
2350
|
-
return
|
|
2569
|
+
return path10.join(this.cwdPath, ...targetParts.slice(overlapLength));
|
|
2351
2570
|
}
|
|
2352
2571
|
async mkdir(dirPath) {
|
|
2353
2572
|
const writePath = this.getPath(dirPath);
|
|
@@ -2388,7 +2607,7 @@ class Executor {
|
|
|
2388
2607
|
return this;
|
|
2389
2608
|
}
|
|
2390
2609
|
async removeDir(dirPath) {
|
|
2391
|
-
const readPath =
|
|
2610
|
+
const readPath = path10.join(this.getPath(dirPath), ".");
|
|
2392
2611
|
if (await FileSys2.entryExists(readPath))
|
|
2393
2612
|
await rm3(readPath, { recursive: true, force: true });
|
|
2394
2613
|
this.logger.verbose(`Remove directory ${readPath}`);
|
|
@@ -2396,11 +2615,10 @@ class Executor {
|
|
|
2396
2615
|
}
|
|
2397
2616
|
async writeFile(filePath, content, { overwrite = true, silent = false } = {}) {
|
|
2398
2617
|
const writePath = this.getPath(filePath);
|
|
2399
|
-
const dir =
|
|
2618
|
+
const dir = path10.dirname(writePath);
|
|
2400
2619
|
if (!await FileSys2.dirExists(dir))
|
|
2401
2620
|
await mkdir2(dir, { recursive: true });
|
|
2402
|
-
let contentStr = typeof content === "string" ? content :
|
|
2403
|
-
`;
|
|
2621
|
+
let contentStr = typeof content === "string" ? content : JsonFormatter.stringify(content, writePath);
|
|
2404
2622
|
if (await FileSys2.fileExists(writePath)) {
|
|
2405
2623
|
const currentContent = await FileSys2.readText(writePath);
|
|
2406
2624
|
if (currentContent === contentStr || !overwrite) {
|
|
@@ -2422,7 +2640,7 @@ class Executor {
|
|
|
2422
2640
|
await this.writeFile(filePath, content);
|
|
2423
2641
|
}
|
|
2424
2642
|
async getLocalFile(targetPath) {
|
|
2425
|
-
const filePath =
|
|
2643
|
+
const filePath = path10.isAbsolute(targetPath) ? targetPath : targetPath.replace(this.cwdPath, "");
|
|
2426
2644
|
const content = await this.readFile(filePath);
|
|
2427
2645
|
return { filePath, content };
|
|
2428
2646
|
}
|
|
@@ -2509,9 +2727,9 @@ class Executor {
|
|
|
2509
2727
|
const result = await getContent.default(scanInfo ?? null, dict, options);
|
|
2510
2728
|
if (result === null)
|
|
2511
2729
|
return null;
|
|
2512
|
-
const filename = typeof result === "object" ? result.filename :
|
|
2730
|
+
const filename = typeof result === "object" ? result.filename : path10.basename(targetPath).replace(".js", ".ts");
|
|
2513
2731
|
const content = typeof result === "object" ? result.content : result;
|
|
2514
|
-
const convertedTargetPath = convertPath(`${
|
|
2732
|
+
const convertedTargetPath = convertPath(`${path10.dirname(targetPath)}/${filename}`);
|
|
2515
2733
|
this.logger.verbose(`Apply template ${templatePath} to ${convertedTargetPath}`);
|
|
2516
2734
|
return this.writeFile(convertedTargetPath, content, { overwrite });
|
|
2517
2735
|
} else if (targetPath.endsWith(".template")) {
|
|
@@ -2520,10 +2738,10 @@ class Executor {
|
|
|
2520
2738
|
const convertedContent = Object.entries(dict).reduce((data, [key, value]) => data.replace(new RegExp(`<%= ${key} %>`, "g"), value), content);
|
|
2521
2739
|
this.logger.verbose(`Apply template ${templatePath} to ${convertedTargetPath}`);
|
|
2522
2740
|
return this.writeFile(convertedTargetPath, convertedContent, { overwrite });
|
|
2523
|
-
} else if (staticTemplateFileExtensions.has(
|
|
2741
|
+
} else if (staticTemplateFileExtensions.has(path10.extname(targetPath).toLowerCase())) {
|
|
2524
2742
|
const convertedTargetPath = convertPath(targetPath);
|
|
2525
2743
|
const writePath = this.getPath(convertedTargetPath);
|
|
2526
|
-
const dirname =
|
|
2744
|
+
const dirname = path10.dirname(writePath);
|
|
2527
2745
|
if (!await FileSys2.dirExists(dirname))
|
|
2528
2746
|
await mkdir2(dirname, { recursive: true });
|
|
2529
2747
|
await copyFile(templatePath, writePath);
|
|
@@ -2545,7 +2763,7 @@ class Executor {
|
|
|
2545
2763
|
if ((await stat2(templatePath)).isFile()) {
|
|
2546
2764
|
const fileContent = await this.#applyTemplateFile({
|
|
2547
2765
|
templatePath,
|
|
2548
|
-
targetPath:
|
|
2766
|
+
targetPath: path10.join(basePath, path10.basename(templatePath)),
|
|
2549
2767
|
scanInfo,
|
|
2550
2768
|
overwrite
|
|
2551
2769
|
}, dict, options);
|
|
@@ -2553,19 +2771,19 @@ class Executor {
|
|
|
2553
2771
|
} else {
|
|
2554
2772
|
const subdirs = await readDirEntries(templatePath);
|
|
2555
2773
|
const fileContents = (await Promise.all(subdirs.map(async (subdir) => {
|
|
2556
|
-
const subpath =
|
|
2774
|
+
const subpath = path10.join(templatePath, subdir);
|
|
2557
2775
|
if ((await stat2(subpath)).isFile()) {
|
|
2558
2776
|
const fileContent = await this.#applyTemplateFile({
|
|
2559
2777
|
templatePath: subpath,
|
|
2560
|
-
targetPath:
|
|
2778
|
+
targetPath: path10.join(basePath, subdir),
|
|
2561
2779
|
scanInfo,
|
|
2562
2780
|
overwrite
|
|
2563
2781
|
}, dict, options);
|
|
2564
2782
|
return fileContent ? [fileContent] : [];
|
|
2565
2783
|
} else
|
|
2566
2784
|
return await this._applyTemplate({
|
|
2567
|
-
basePath:
|
|
2568
|
-
template:
|
|
2785
|
+
basePath: path10.join(basePath, subdir),
|
|
2786
|
+
template: path10.join(template, subdir),
|
|
2569
2787
|
scanInfo,
|
|
2570
2788
|
dict,
|
|
2571
2789
|
overwrite,
|
|
@@ -2577,8 +2795,8 @@ class Executor {
|
|
|
2577
2795
|
}
|
|
2578
2796
|
async#resolveTemplateRoot() {
|
|
2579
2797
|
const candidates = [
|
|
2580
|
-
|
|
2581
|
-
|
|
2798
|
+
path10.resolve(getDirname2(import.meta.url), "templates"),
|
|
2799
|
+
path10.resolve(getDirname2(import.meta.url), "../cli/templates")
|
|
2582
2800
|
];
|
|
2583
2801
|
for (const candidate of candidates) {
|
|
2584
2802
|
if (await FileSys2.dirExists(candidate))
|
|
@@ -2646,11 +2864,11 @@ class Executor {
|
|
|
2646
2864
|
async#resolveTypecheckWorkerEntry() {
|
|
2647
2865
|
const dirname = getDirname2(import.meta.url);
|
|
2648
2866
|
const candidates = [
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2867
|
+
path10.join(process.cwd(), "pkgs/@akanjs/devkit/typecheck/typecheck.proc.ts"),
|
|
2868
|
+
path10.join(process.cwd(), "node_modules/@akanjs/devkit/typecheck/typecheck.proc.ts"),
|
|
2869
|
+
path10.join(dirname, "typecheck/typecheck.proc.ts"),
|
|
2870
|
+
path10.join(dirname, "typecheck.proc.js"),
|
|
2871
|
+
path10.join(dirname, "typecheck.proc.ts")
|
|
2654
2872
|
];
|
|
2655
2873
|
for (const candidate of candidates)
|
|
2656
2874
|
if (await Bun.file(candidate).exists())
|
|
@@ -2770,7 +2988,7 @@ class WorkspaceExecutor extends Executor {
|
|
|
2770
2988
|
await Promise.all(dirs.map(async (dir) => {
|
|
2771
2989
|
if (dir.includes("_") || AVOID_DIRS.includes(dir))
|
|
2772
2990
|
return;
|
|
2773
|
-
const dirPath =
|
|
2991
|
+
const dirPath = path10.join(dirname, dir);
|
|
2774
2992
|
if ((await stat2(dirPath)).isDirectory()) {
|
|
2775
2993
|
results.push(`${prefix}${dir}`);
|
|
2776
2994
|
if (maxDepth > 0)
|
|
@@ -2807,9 +3025,9 @@ class WorkspaceExecutor extends Executor {
|
|
|
2807
3025
|
await Promise.all(dirs.map(async (dir) => {
|
|
2808
3026
|
if (AVOID_DIRS.includes(dir))
|
|
2809
3027
|
return;
|
|
2810
|
-
const dirPath =
|
|
3028
|
+
const dirPath = path10.join(dirname, dir);
|
|
2811
3029
|
if (await FileSys2.dirExists(dirPath)) {
|
|
2812
|
-
const hasTargetFile = await FileSys2.fileExists(
|
|
3030
|
+
const hasTargetFile = await FileSys2.fileExists(path10.join(dirPath, targetFilename));
|
|
2813
3031
|
if (hasTargetFile)
|
|
2814
3032
|
results.push(`${prefix}${dir}`);
|
|
2815
3033
|
if (maxDepth > 0)
|
|
@@ -2839,7 +3057,6 @@ class WorkspaceExecutor extends Executor {
|
|
|
2839
3057
|
return await this.#fromEverySys((sys) => sys.getViewsSourceCode());
|
|
2840
3058
|
}
|
|
2841
3059
|
}
|
|
2842
|
-
var scanFacetDirs = ["ui", "webkit", "srvkit", "common", "plugin"];
|
|
2843
3060
|
|
|
2844
3061
|
class SysExecutor extends Executor {
|
|
2845
3062
|
workspace;
|
|
@@ -2869,7 +3086,7 @@ class SysExecutor extends Executor {
|
|
|
2869
3086
|
return [];
|
|
2870
3087
|
const violations = [];
|
|
2871
3088
|
for (const entry of await this.getAllFiles("**/*", { cwd: this.getPath("page") })) {
|
|
2872
|
-
const relativePath = entry.split(
|
|
3089
|
+
const relativePath = entry.split(path10.sep).join("/");
|
|
2873
3090
|
const reason = getPageSourceFileViolation(relativePath);
|
|
2874
3091
|
if (reason)
|
|
2875
3092
|
violations.push({ relativePath: `page/${relativePath}`, reason });
|
|
@@ -2894,7 +3111,7 @@ class SysExecutor extends Executor {
|
|
|
2894
3111
|
this._applyTemplate({ basePath: ".", template: "server.ts", scanInfo }),
|
|
2895
3112
|
this._applyTemplate({ basePath: ".", template: "client.ts", scanInfo }),
|
|
2896
3113
|
this.type === "lib" ? this._applyTemplate({ basePath: ".", template: "index.ts", scanInfo }) : null,
|
|
2897
|
-
...
|
|
3114
|
+
...barrelFacetDirs.map((facet) => this._applyTemplate({
|
|
2898
3115
|
basePath: facet,
|
|
2899
3116
|
template: "facetIndex/index.ts",
|
|
2900
3117
|
scanInfo,
|
|
@@ -2923,11 +3140,9 @@ class SysExecutor extends Executor {
|
|
|
2923
3140
|
await CodegenLock.run(this.workspace.workspaceRoot, `scan:${this.name}`, async () => {
|
|
2924
3141
|
await Promise.all(this.#getScanTemplateTasks(scanInfo));
|
|
2925
3142
|
await this.writeJson(`akan.${this.type}.json`, scanInfo.getScanResult());
|
|
2926
|
-
|
|
2927
|
-
this.#updateDependencies(scanInfo);
|
|
3143
|
+
await this.#updateDependencies(scanInfo);
|
|
2928
3144
|
if (writeLib) {
|
|
2929
3145
|
const libInfos = [...scanInfo.getLibInfos().values()];
|
|
2930
|
-
await this.#updateDependencies(scanInfo);
|
|
2931
3146
|
await Promise.all(libInfos.flatMap((libInfo) => libInfo.exec.#getScanTemplateTasks(libInfo)));
|
|
2932
3147
|
}
|
|
2933
3148
|
await this.syncAgentsIndex(scanInfo);
|
|
@@ -2946,27 +3161,27 @@ class SysExecutor extends Executor {
|
|
|
2946
3161
|
await this.writeFile("CLAUDE.md", renderScopeClaudeMd(scope));
|
|
2947
3162
|
}
|
|
2948
3163
|
async#updateDependencies(scanInfo) {
|
|
2949
|
-
const rootPackageJson = await
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
const
|
|
2954
|
-
const
|
|
2955
|
-
|
|
2956
|
-
...
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
await this.setPackageJson(
|
|
3164
|
+
const [rootPackageJson, packageJson] = await Promise.all([
|
|
3165
|
+
this.workspace.getPackageJson(),
|
|
3166
|
+
this.getPackageJson({ refresh: true })
|
|
3167
|
+
]);
|
|
3168
|
+
const { dependencies: runtime, devDependencies: typeOnly, akanConfig } = scanInfo.getScanResult();
|
|
3169
|
+
const kept = new Set([
|
|
3170
|
+
...ManifestDependencies.keptBy(packageJson),
|
|
3171
|
+
...akanConfig.externalLibs,
|
|
3172
|
+
...akanConfig.trustedDependencies
|
|
3173
|
+
]);
|
|
3174
|
+
const isKept = (dep) => kept.has(dep) || isAkanFrameworkDependency(dep);
|
|
3175
|
+
const { dependencies, devDependencies, removed, unverifiable } = new ManifestDependencies(rootPackageJson, { runtime, typeOnly }, isKept).realign(packageJson);
|
|
3176
|
+
const manifestPath = `${this.type}s/${this.name}/package.json`;
|
|
3177
|
+
if (removed.length)
|
|
3178
|
+
this.logger.info(`Removed from ${manifestPath}, declared by the root and imported nowhere: ${removed.join(", ")} (list one in akan.keepDependencies to keep it)`);
|
|
3179
|
+
if (unverifiable.length)
|
|
3180
|
+
this.logger.warn(`${manifestPath} lists ${unverifiable.join(", ")}, which the root package.json does not declare, so sync cannot tell whether it is used; kept as is`);
|
|
3181
|
+
await this.setPackageJson({ ...packageJson, dependencies, devDependencies });
|
|
2967
3182
|
}
|
|
2968
3183
|
async getLocalFile(targetPath) {
|
|
2969
|
-
const filePath =
|
|
3184
|
+
const filePath = path10.isAbsolute(targetPath) ? targetPath : `${this.type}s/${this.name}/${targetPath}`;
|
|
2970
3185
|
const content = await this.workspace.readFile(filePath);
|
|
2971
3186
|
return { filePath, content };
|
|
2972
3187
|
}
|
|
@@ -3054,14 +3269,19 @@ class AppExecutor extends SysExecutor {
|
|
|
3054
3269
|
static from(executor, name) {
|
|
3055
3270
|
return new AppExecutor({ workspace: executor instanceof WorkspaceExecutor ? executor : executor.workspace, name });
|
|
3056
3271
|
}
|
|
3057
|
-
static #keptOnStart = [
|
|
3272
|
+
static #keptOnStart = [path10.join(".akan", "cache", "bin")];
|
|
3273
|
+
static #legacyNative = path10.join(".akan", "native");
|
|
3058
3274
|
async#removeDevOutput(dir = ".akan") {
|
|
3059
3275
|
const entries = await readDirEntries(this.getPath(dir)).catch(() => []);
|
|
3060
3276
|
await Promise.all(entries.map(async (name) => {
|
|
3061
|
-
const entry =
|
|
3277
|
+
const entry = path10.join(dir, name);
|
|
3278
|
+
if (entry === AppExecutor.#legacyNative) {
|
|
3279
|
+
this.logger.warn(`apps/${this.name}/.akan/native holds native builds from before they moved to dist/native/${this.name}: upload any release waiting in its updates folders, then delete it.`);
|
|
3280
|
+
return;
|
|
3281
|
+
}
|
|
3062
3282
|
if (AppExecutor.#keptOnStart.includes(entry))
|
|
3063
3283
|
return;
|
|
3064
|
-
if (AppExecutor.#keptOnStart.some((kept) => kept.startsWith(`${entry}${
|
|
3284
|
+
if (AppExecutor.#keptOnStart.some((kept) => kept.startsWith(`${entry}${path10.sep}`)))
|
|
3065
3285
|
return await this.#removeDevOutput(entry);
|
|
3066
3286
|
await this.removeDir(entry);
|
|
3067
3287
|
}));
|
|
@@ -3133,10 +3353,10 @@ class AppExecutor extends SysExecutor {
|
|
|
3133
3353
|
});
|
|
3134
3354
|
if (type === "build") {
|
|
3135
3355
|
const buildEnv = { ...env };
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3356
|
+
for (const key of ["AKAN_PUBLIC_CLIENT_PORT", "AKAN_PUBLIC_SERVER_PORT", "AKAN_PUBLIC_OPERATION_MODE"]) {
|
|
3357
|
+
delete buildEnv[key];
|
|
3358
|
+
delete process.env[key];
|
|
3359
|
+
}
|
|
3140
3360
|
Object.assign(process.env, buildEnv);
|
|
3141
3361
|
}
|
|
3142
3362
|
return { env };
|
|
@@ -3185,13 +3405,13 @@ class AppExecutor extends SysExecutor {
|
|
|
3185
3405
|
absolute: false,
|
|
3186
3406
|
onlyFiles: true
|
|
3187
3407
|
})) {
|
|
3188
|
-
const segments = rel.split(
|
|
3408
|
+
const segments = rel.split(path10.sep);
|
|
3189
3409
|
if (segments.some((s) => s === "node_modules"))
|
|
3190
3410
|
continue;
|
|
3191
3411
|
const posix = `${root.keyPrefix}${segments.join("/")}`;
|
|
3192
3412
|
if (!root.keyPrefix && libKeyPrefixes.some((prefix) => posix.startsWith(prefix)))
|
|
3193
3413
|
continue;
|
|
3194
|
-
const absPath =
|
|
3414
|
+
const absPath = path10.join(root.dir, ...segments);
|
|
3195
3415
|
validatePageSourceFile(posix, { filePath: absPath });
|
|
3196
3416
|
if (!isRouteSourceFile(posix))
|
|
3197
3417
|
continue;
|
|
@@ -3332,7 +3552,7 @@ class AppExecutor extends SysExecutor {
|
|
|
3332
3552
|
static async#linkLibAsset(targetPath, linkPath) {
|
|
3333
3553
|
const isWindows = process.platform === "win32";
|
|
3334
3554
|
try {
|
|
3335
|
-
const target = isWindows ? targetPath :
|
|
3555
|
+
const target = isWindows ? targetPath : path10.relative(path10.dirname(linkPath), targetPath);
|
|
3336
3556
|
await symlink(target, linkPath, isWindows ? "junction" : "dir");
|
|
3337
3557
|
} catch (error) {
|
|
3338
3558
|
if (!isWindows)
|
|
@@ -3375,7 +3595,7 @@ class AppExecutor extends SysExecutor {
|
|
|
3375
3595
|
await this.writeFile(rel, content, opts);
|
|
3376
3596
|
},
|
|
3377
3597
|
readEnvClient: async () => {
|
|
3378
|
-
const envClientPath =
|
|
3598
|
+
const envClientPath = path10.join(this.cwdPath, "env", "env.client.ts");
|
|
3379
3599
|
if (!await FileSys2.fileExists(envClientPath))
|
|
3380
3600
|
return null;
|
|
3381
3601
|
try {
|
|
@@ -3469,7 +3689,7 @@ class PkgExecutor extends Executor {
|
|
|
3469
3689
|
return overrideVersion;
|
|
3470
3690
|
try {
|
|
3471
3691
|
const packageJsonPath = `pkgs/${dep}/package.json`;
|
|
3472
|
-
if (!await Bun.file(
|
|
3692
|
+
if (!await Bun.file(path10.join(this.workspace.workspaceRoot, packageJsonPath)).exists())
|
|
3473
3693
|
return;
|
|
3474
3694
|
const packageJson = await this.workspace.readJson(packageJsonPath);
|
|
3475
3695
|
if (packageJson.name === dep)
|
|
@@ -3562,4 +3782,4 @@ class ModuleExecutor extends Executor {
|
|
|
3562
3782
|
}
|
|
3563
3783
|
}
|
|
3564
3784
|
|
|
3565
|
-
export { AGENT_BLOCK_START, AGENT_BLOCK_END, stampBlockVersion, extractBlockVersion, readDevkitVersion, upsertAgentBlock, extractAgentBlock, renderRecipeEntries, collectScopeRecipeSources, renderScopeAgentBlock, CLAUDE_COMMENT_RULE, binPlatforms, AsyncDefaultExportDetector, resolveSsrPageEntriesForApp, CodegenLock, Linter, rootAllowedFiles, rootAllowedDirs, isAllowedLibFacetRootFile, rootEntryHintOf, isScannedRootEntry, AppInfo, Spinner, Executor, WorkspaceExecutor, SysExecutor, AppExecutor, LibExecutor, PkgExecutor, ModuleExecutor };
|
|
3785
|
+
export { AGENT_BLOCK_START, AGENT_BLOCK_END, stampBlockVersion, extractBlockVersion, readDevkitVersion, upsertAgentBlock, extractAgentBlock, renderRecipeEntries, collectScopeRecipeSources, renderScopeAgentBlock, CLAUDE_COMMENT_RULE, binPlatforms, AsyncDefaultExportDetector, resolveSsrPageEntriesForApp, CodegenLock, Linter, LibSource, formatLibStatuses, rootAllowedFiles, rootAllowedDirs, isAllowedLibFacetRootFile, barrelFacetDirs, facetIndexShadowOf, rootEntryHintOf, isScannedRootEntry, AppInfo, Spinner, Executor, WorkspaceExecutor, SysExecutor, AppExecutor, LibExecutor, PkgExecutor, ModuleExecutor };
|