@akanjs/cli 2.2.10 → 2.2.12
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 +15 -0
- package/guidelines/moduleOverview/moduleOverview.instruction.md +5 -1
- package/incrementalBuilder.proc.js +532 -253
- package/index.js +1039 -339
- package/package.json +2 -2
- package/templates/__scalar/__model__/__model__.abstract.md +28 -0
- package/templates/module/__model__.abstract.md +28 -0
- package/templates/service/__model__.abstract.md +28 -0
- package/templates/workspaceRoot/.cursor/rules/akan.mdc.template +26 -0
- package/templates/workspaceRoot/AGENTS.md.template +88 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
var __require = import.meta.require;
|
|
3
3
|
|
|
4
4
|
// pkgs/@akanjs/devkit/incrementalBuilder/incrementalBuilder.proc.ts
|
|
5
|
-
import
|
|
5
|
+
import path38 from "path";
|
|
6
6
|
|
|
7
7
|
// pkgs/@akanjs/devkit/aiEditor.ts
|
|
8
8
|
import { input, select } from "@inquirer/prompts";
|
|
@@ -1723,6 +1723,10 @@ var rootSignalTestFilePattern = /^[A-Za-z][A-Za-z0-9_-]*\.signal\.(test|spec)\.(
|
|
|
1723
1723
|
var isAllowedTestFile = (filename) => testFilePattern.test(filename);
|
|
1724
1724
|
var isAllowedLibRootFile = (filename) => libRootAllowedFiles.has(filename) || rootSignalTestFilePattern.test(filename);
|
|
1725
1725
|
var getScanPath = (exec, relativePath) => path5.posix.join(`${exec.type}s`, exec.name, relativePath.split(path5.sep).join("/"));
|
|
1726
|
+
var getModuleNameFromPath = (kind, modulePath) => {
|
|
1727
|
+
const dirname = path5.basename(modulePath);
|
|
1728
|
+
return kind === "service" ? dirname.replace(/^_+/, "") : dirname;
|
|
1729
|
+
};
|
|
1726
1730
|
async function assertScanConvention(exec, libRoot) {
|
|
1727
1731
|
const violations = [];
|
|
1728
1732
|
const addViolation = (relativePath, reason) => {
|
|
@@ -1759,6 +1763,7 @@ ${violations.sort().map((violation) => `- ${violation}`).join(`
|
|
|
1759
1763
|
}
|
|
1760
1764
|
async function validateModuleFiles(exec, violations, kind, modulePath) {
|
|
1761
1765
|
const { files, dirs } = await exec.getFilesAndDirs(modulePath);
|
|
1766
|
+
const moduleName = getModuleNameFromPath(kind, modulePath);
|
|
1762
1767
|
dirs.forEach((dirname) => {
|
|
1763
1768
|
violations.push(`${getScanPath(exec, path5.join(modulePath, dirname))}: unsupported module folder`);
|
|
1764
1769
|
});
|
|
@@ -1766,6 +1771,8 @@ async function validateModuleFiles(exec, violations, kind, modulePath) {
|
|
|
1766
1771
|
const filePath = path5.join(modulePath, filename);
|
|
1767
1772
|
if (filename === "index.ts" || filename === "index.tsx" || isAllowedTestFile(filename))
|
|
1768
1773
|
return;
|
|
1774
|
+
if (filename === `${moduleName}.abstract.md`)
|
|
1775
|
+
return;
|
|
1769
1776
|
const uiMatch = filename.match(/\.([A-Z][A-Za-z0-9]*)\.tsx$/);
|
|
1770
1777
|
if (uiMatch) {
|
|
1771
1778
|
const fileType = uiMatch[1];
|
|
@@ -2110,7 +2117,7 @@ class PkgInfo {
|
|
|
2110
2117
|
exec;
|
|
2111
2118
|
name;
|
|
2112
2119
|
scanResult;
|
|
2113
|
-
static async
|
|
2120
|
+
static async scanExecutor(exec) {
|
|
2114
2121
|
const [tsconfig, rootPackageJson] = await Promise.all([exec.getTsConfig(), exec.workspace.getPackageJson()]);
|
|
2115
2122
|
const scanner = await TypeScriptDependencyScanner.from(exec);
|
|
2116
2123
|
const npmSet = new Set(Object.keys({ ...rootPackageJson.dependencies, ...rootPackageJson.devDependencies }));
|
|
@@ -2132,7 +2139,7 @@ class PkgInfo {
|
|
|
2132
2139
|
const existingPkgInfo = PkgInfo.#pkgInfos.get(exec.name);
|
|
2133
2140
|
if (existingPkgInfo && !options.refresh)
|
|
2134
2141
|
return existingPkgInfo;
|
|
2135
|
-
const scanResult = await PkgInfo.
|
|
2142
|
+
const scanResult = await PkgInfo.scanExecutor(exec);
|
|
2136
2143
|
const pkgInfo = new PkgInfo(exec, scanResult);
|
|
2137
2144
|
PkgInfo.#pkgInfos.set(exec.name, pkgInfo);
|
|
2138
2145
|
return pkgInfo;
|
|
@@ -4460,6 +4467,240 @@ class AkanAppHost {
|
|
|
4460
4467
|
this.#builder = null;
|
|
4461
4468
|
}
|
|
4462
4469
|
}
|
|
4470
|
+
// pkgs/@akanjs/devkit/akanContext.ts
|
|
4471
|
+
import { readdir } from "fs/promises";
|
|
4472
|
+
import path10 from "path";
|
|
4473
|
+
import { capitalize as capitalize2 } from "akanjs/common";
|
|
4474
|
+
var generatedFiles = [
|
|
4475
|
+
"cnst.ts",
|
|
4476
|
+
"db.ts",
|
|
4477
|
+
"dict.ts",
|
|
4478
|
+
"option.ts",
|
|
4479
|
+
"sig.ts",
|
|
4480
|
+
"srv.ts",
|
|
4481
|
+
"st.ts",
|
|
4482
|
+
"useClient.ts",
|
|
4483
|
+
"useServer.ts"
|
|
4484
|
+
];
|
|
4485
|
+
var appRootAllowFiles = new Set([
|
|
4486
|
+
"akan.app.json",
|
|
4487
|
+
"akan.config.ts",
|
|
4488
|
+
"capacitor.config.ts",
|
|
4489
|
+
"client.ts",
|
|
4490
|
+
"main.ts",
|
|
4491
|
+
"package.json",
|
|
4492
|
+
"server.ts",
|
|
4493
|
+
"tsconfig.json"
|
|
4494
|
+
]);
|
|
4495
|
+
var appRootAllowDirs = new Set([
|
|
4496
|
+
".akan",
|
|
4497
|
+
"android",
|
|
4498
|
+
"common",
|
|
4499
|
+
"env",
|
|
4500
|
+
"ios",
|
|
4501
|
+
"lib",
|
|
4502
|
+
"page",
|
|
4503
|
+
"private",
|
|
4504
|
+
"public",
|
|
4505
|
+
"script",
|
|
4506
|
+
"srvkit",
|
|
4507
|
+
"ui",
|
|
4508
|
+
"webkit"
|
|
4509
|
+
]);
|
|
4510
|
+
var safeReadDir = async (dirPath) => {
|
|
4511
|
+
try {
|
|
4512
|
+
return (await readdir(dirPath, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name));
|
|
4513
|
+
} catch {
|
|
4514
|
+
return [];
|
|
4515
|
+
}
|
|
4516
|
+
};
|
|
4517
|
+
var safeReadText = async (filePath) => {
|
|
4518
|
+
try {
|
|
4519
|
+
return await FileSys.readText(filePath);
|
|
4520
|
+
} catch {
|
|
4521
|
+
return null;
|
|
4522
|
+
}
|
|
4523
|
+
};
|
|
4524
|
+
var safeReadJson = async (filePath) => {
|
|
4525
|
+
try {
|
|
4526
|
+
return await FileSys.readJson(filePath);
|
|
4527
|
+
} catch {
|
|
4528
|
+
return null;
|
|
4529
|
+
}
|
|
4530
|
+
};
|
|
4531
|
+
var parseAbstractSummary = (relativePath, content, includeContent) => {
|
|
4532
|
+
if (content === null)
|
|
4533
|
+
return { path: relativePath, exists: false, headings: [] };
|
|
4534
|
+
const headings = content.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.startsWith("#")).map((line) => line.replace(/^#+\s*/, "").trim()).filter(Boolean);
|
|
4535
|
+
return {
|
|
4536
|
+
path: relativePath,
|
|
4537
|
+
exists: true,
|
|
4538
|
+
title: headings[0],
|
|
4539
|
+
headings: headings.slice(0, 8),
|
|
4540
|
+
...includeContent ? { content } : {}
|
|
4541
|
+
};
|
|
4542
|
+
};
|
|
4543
|
+
var readFiles = async (dirPath) => (await safeReadDir(dirPath)).filter((entry) => entry.isFile()).map((entry) => entry.name).sort();
|
|
4544
|
+
var getRelative = (workspace, absolutePath) => path10.relative(workspace.workspaceRoot, absolutePath).replaceAll(path10.sep, "/");
|
|
4545
|
+
var createModuleContext = async (workspace, sys2, kind, folderName, moduleName, includeAbstractContent) => {
|
|
4546
|
+
const modulePath = kind === "scalar" ? path10.join(sys2.cwdPath, "lib", "__scalar", moduleName) : path10.join(sys2.cwdPath, "lib", folderName);
|
|
4547
|
+
const relativePath = getRelative(workspace, modulePath);
|
|
4548
|
+
const abstractPath = `${relativePath}/${moduleName}.abstract.md`;
|
|
4549
|
+
const abstractContent = await safeReadText(path10.join(workspace.workspaceRoot, abstractPath));
|
|
4550
|
+
return {
|
|
4551
|
+
kind,
|
|
4552
|
+
name: moduleName,
|
|
4553
|
+
folderName,
|
|
4554
|
+
sysName: sys2.name,
|
|
4555
|
+
sysType: sys2.type,
|
|
4556
|
+
path: relativePath,
|
|
4557
|
+
abstract: parseAbstractSummary(abstractPath, abstractContent, includeAbstractContent),
|
|
4558
|
+
files: await readFiles(modulePath)
|
|
4559
|
+
};
|
|
4560
|
+
};
|
|
4561
|
+
var getSysModules = async (workspace, sys2, {
|
|
4562
|
+
includeAbstractContent = false,
|
|
4563
|
+
module: moduleFilter
|
|
4564
|
+
} = {}) => {
|
|
4565
|
+
const libPath = path10.join(sys2.cwdPath, "lib");
|
|
4566
|
+
const entries = await safeReadDir(libPath);
|
|
4567
|
+
const modules = [];
|
|
4568
|
+
for (const entry of entries) {
|
|
4569
|
+
if (!entry.isDirectory())
|
|
4570
|
+
continue;
|
|
4571
|
+
if (entry.name === "__scalar")
|
|
4572
|
+
continue;
|
|
4573
|
+
if (entry.name.startsWith("__"))
|
|
4574
|
+
continue;
|
|
4575
|
+
if (entry.name.startsWith("_")) {
|
|
4576
|
+
const serviceName = entry.name.replace(/^_+/, "");
|
|
4577
|
+
if (moduleFilter && moduleFilter !== serviceName && moduleFilter !== entry.name)
|
|
4578
|
+
continue;
|
|
4579
|
+
if (!await FileSys.fileExists(path10.join(libPath, entry.name, `${serviceName}.service.ts`)))
|
|
4580
|
+
continue;
|
|
4581
|
+
modules.push(await createModuleContext(workspace, sys2, "service", entry.name, serviceName, includeAbstractContent));
|
|
4582
|
+
} else {
|
|
4583
|
+
if (moduleFilter && moduleFilter !== entry.name)
|
|
4584
|
+
continue;
|
|
4585
|
+
if (!await FileSys.fileExists(path10.join(libPath, entry.name, `${entry.name}.constant.ts`)))
|
|
4586
|
+
continue;
|
|
4587
|
+
modules.push(await createModuleContext(workspace, sys2, "domain", entry.name, entry.name, includeAbstractContent));
|
|
4588
|
+
}
|
|
4589
|
+
}
|
|
4590
|
+
const scalarRoot = path10.join(libPath, "__scalar");
|
|
4591
|
+
for (const entry of await safeReadDir(scalarRoot)) {
|
|
4592
|
+
if (!entry.isDirectory() || entry.name.startsWith("_"))
|
|
4593
|
+
continue;
|
|
4594
|
+
if (moduleFilter && moduleFilter !== entry.name)
|
|
4595
|
+
continue;
|
|
4596
|
+
if (!await FileSys.fileExists(path10.join(scalarRoot, entry.name, `${entry.name}.constant.ts`)))
|
|
4597
|
+
continue;
|
|
4598
|
+
modules.push(await createModuleContext(workspace, sys2, "scalar", entry.name, entry.name, includeAbstractContent));
|
|
4599
|
+
}
|
|
4600
|
+
return modules.sort((a, b) => `${a.sysName}:${a.path}`.localeCompare(`${b.sysName}:${b.path}`));
|
|
4601
|
+
};
|
|
4602
|
+
var getSysContext = async (workspace, type, name, options) => {
|
|
4603
|
+
const sys2 = type === "app" ? AppExecutor.from(workspace, name) : LibExecutor.from(workspace, name);
|
|
4604
|
+
return {
|
|
4605
|
+
type,
|
|
4606
|
+
name,
|
|
4607
|
+
path: `${type}s/${name}`,
|
|
4608
|
+
hasConfig: await FileSys.fileExists(path10.join(sys2.cwdPath, "akan.config.ts")),
|
|
4609
|
+
modules: await getSysModules(workspace, sys2, {
|
|
4610
|
+
includeAbstractContent: options.includeAbstractContent,
|
|
4611
|
+
module: options.module
|
|
4612
|
+
})
|
|
4613
|
+
};
|
|
4614
|
+
};
|
|
4615
|
+
|
|
4616
|
+
class AkanContextAnalyzer {
|
|
4617
|
+
static async analyze(workspace, options = {}) {
|
|
4618
|
+
const [appNames, libNames, pkgNames] = await workspace.getExecs();
|
|
4619
|
+
const rootPackageJson = await safeReadJson(path10.join(workspace.workspaceRoot, "package.json"));
|
|
4620
|
+
const filteredApps = options.app ? appNames.filter((name) => name === options.app) : appNames;
|
|
4621
|
+
const [apps, libs, pkgs] = await Promise.all([
|
|
4622
|
+
Promise.all(filteredApps.map((name) => getSysContext(workspace, "app", name, options))),
|
|
4623
|
+
Promise.all(libNames.map((name) => getSysContext(workspace, "lib", name, options))),
|
|
4624
|
+
Promise.all(pkgNames.map(async (name) => {
|
|
4625
|
+
const packageJson = await safeReadJson(path10.join(workspace.workspaceRoot, "pkgs", name, "package.json"));
|
|
4626
|
+
return {
|
|
4627
|
+
name,
|
|
4628
|
+
path: `pkgs/${name}`,
|
|
4629
|
+
...packageJson?.version ? { version: packageJson.version } : {}
|
|
4630
|
+
};
|
|
4631
|
+
}))
|
|
4632
|
+
]);
|
|
4633
|
+
return {
|
|
4634
|
+
schemaVersion: 1,
|
|
4635
|
+
repoName: workspace.repoName,
|
|
4636
|
+
root: workspace.workspaceRoot,
|
|
4637
|
+
packageVersion: rootPackageJson?.dependencies?.akanjs ?? rootPackageJson?.devDependencies?.["@akanjs/devkit"],
|
|
4638
|
+
apps,
|
|
4639
|
+
libs,
|
|
4640
|
+
pkgs,
|
|
4641
|
+
generatedFiles,
|
|
4642
|
+
validationCommands: ["akan lint <app-or-lib-or-pkg>", "akan build <app-name>", "akan start <app-name>"]
|
|
4643
|
+
};
|
|
4644
|
+
}
|
|
4645
|
+
static async doctor(workspace, { strict = false } = {}) {
|
|
4646
|
+
const context = await AkanContextAnalyzer.analyze(workspace);
|
|
4647
|
+
const diagnostics = [];
|
|
4648
|
+
for (const app of context.apps) {
|
|
4649
|
+
const appPath = path10.join(workspace.workspaceRoot, app.path);
|
|
4650
|
+
for (const entry of await safeReadDir(appPath)) {
|
|
4651
|
+
const allowed = entry.isDirectory() ? appRootAllowDirs.has(entry.name) : appRootAllowFiles.has(entry.name);
|
|
4652
|
+
if (!allowed) {
|
|
4653
|
+
diagnostics.push({
|
|
4654
|
+
severity: "warning",
|
|
4655
|
+
code: "app-root-unknown-entry",
|
|
4656
|
+
path: `${app.path}/${entry.name}`,
|
|
4657
|
+
message: `Unexpected ${entry.isDirectory() ? "folder" : "file"} in app root: ${app.path}/${entry.name}`
|
|
4658
|
+
});
|
|
4659
|
+
}
|
|
4660
|
+
}
|
|
4661
|
+
}
|
|
4662
|
+
for (const sys2 of [...context.apps, ...context.libs]) {
|
|
4663
|
+
for (const module of sys2.modules) {
|
|
4664
|
+
if (!module.abstract.exists) {
|
|
4665
|
+
diagnostics.push({
|
|
4666
|
+
severity: strict ? "error" : "warning",
|
|
4667
|
+
code: "module-abstract-missing",
|
|
4668
|
+
path: module.abstract.path,
|
|
4669
|
+
message: `${capitalize2(module.kind)} module ${sys2.name}:${module.name} should include ${module.abstract.path}`
|
|
4670
|
+
});
|
|
4671
|
+
}
|
|
4672
|
+
}
|
|
4673
|
+
}
|
|
4674
|
+
return { schemaVersion: 1, strict, diagnostics };
|
|
4675
|
+
}
|
|
4676
|
+
static findModules(context, moduleName) {
|
|
4677
|
+
const modules = [...context.apps, ...context.libs].flatMap((sys2) => sys2.modules);
|
|
4678
|
+
return moduleName ? modules.filter((module) => module.name === moduleName || module.folderName === moduleName) : modules;
|
|
4679
|
+
}
|
|
4680
|
+
static renderMarkdown(context, { module: moduleName } = {}) {
|
|
4681
|
+
const lines = [`# Akan Workspace Context`, "", `- Repo: ${context.repoName}`, `- Root: ${context.root}`];
|
|
4682
|
+
if (context.packageVersion)
|
|
4683
|
+
lines.push(`- Akan version: ${context.packageVersion}`);
|
|
4684
|
+
lines.push("", "## Apps", ...context.apps.map((app) => `- ${app.name}: ${app.modules.length} module(s)`));
|
|
4685
|
+
lines.push("", "## Libraries", ...context.libs.map((lib) => `- ${lib.name}: ${lib.modules.length} module(s)`));
|
|
4686
|
+
lines.push("", "## Packages", ...context.pkgs.map((pkg) => `- ${pkg.name}${pkg.version ? ` (${pkg.version})` : ""}`));
|
|
4687
|
+
const modules = AkanContextAnalyzer.findModules(context, moduleName);
|
|
4688
|
+
lines.push("", "## Modules");
|
|
4689
|
+
for (const module of modules) {
|
|
4690
|
+
lines.push("", `### ${module.sysName}:${module.name} (${module.kind})`, `- Path: ${module.path}`);
|
|
4691
|
+
lines.push(`- Abstract: ${module.abstract.exists ? module.abstract.path : "missing"}`);
|
|
4692
|
+
if (module.abstract.exists && module.abstract.content)
|
|
4693
|
+
lines.push("", module.abstract.content.trim(), "");
|
|
4694
|
+
else if (module.abstract.headings.length)
|
|
4695
|
+
lines.push(`- Abstract headings: ${module.abstract.headings.join(", ")}`);
|
|
4696
|
+
lines.push(`- Files: ${module.files.join(", ") || "none"}`);
|
|
4697
|
+
}
|
|
4698
|
+
lines.push("", "## Validation", ...context.validationCommands.map((command) => `- \`${command}\``));
|
|
4699
|
+
return `${lines.join(`
|
|
4700
|
+
`)}
|
|
4701
|
+
`;
|
|
4702
|
+
}
|
|
4703
|
+
}
|
|
4463
4704
|
// pkgs/@akanjs/devkit/applicationBuildReporter.ts
|
|
4464
4705
|
import { Logger as Logger6 } from "akanjs/common";
|
|
4465
4706
|
|
|
@@ -4506,20 +4747,20 @@ Caused by: ${ApplicationBuildReporter.formatError(error.cause)}` : "";
|
|
|
4506
4747
|
}
|
|
4507
4748
|
// pkgs/@akanjs/devkit/applicationBuildRunner.ts
|
|
4508
4749
|
import { mkdir as mkdir7, rm as rm2 } from "fs/promises";
|
|
4509
|
-
import
|
|
4750
|
+
import path33 from "path";
|
|
4510
4751
|
|
|
4511
4752
|
// pkgs/@akanjs/devkit/frontendBuild/allRoutesBuilder.ts
|
|
4512
|
-
import
|
|
4753
|
+
import path20 from "path";
|
|
4513
4754
|
|
|
4514
4755
|
// pkgs/@akanjs/devkit/artifact/implicitRootLayout.ts
|
|
4515
4756
|
import { mkdir as mkdir3 } from "fs/promises";
|
|
4516
|
-
import
|
|
4757
|
+
import path11 from "path";
|
|
4517
4758
|
var LAYOUT_KEY_RE = /^\.\/(.+\/)?_layout\.(tsx|ts|jsx|js)$/;
|
|
4518
4759
|
async function appHasStModule(appCwdPath) {
|
|
4519
|
-
return Bun.file(
|
|
4760
|
+
return Bun.file(path11.join(appCwdPath, "lib", "st.ts")).exists();
|
|
4520
4761
|
}
|
|
4521
|
-
var IMPLICIT_LAYOUT_DIR =
|
|
4522
|
-
var IMPLICIT_DICT_DIR =
|
|
4762
|
+
var IMPLICIT_LAYOUT_DIR = path11.join(".akan", "generated", "root-layouts");
|
|
4763
|
+
var IMPLICIT_DICT_DIR = path11.join(".akan", "generated", "dict");
|
|
4523
4764
|
function getRootBoundarySegments(key) {
|
|
4524
4765
|
const match = LAYOUT_KEY_RE.exec(key);
|
|
4525
4766
|
if (!match)
|
|
@@ -4534,10 +4775,10 @@ function implicitRootLayoutKey(segments) {
|
|
|
4534
4775
|
}
|
|
4535
4776
|
function implicitRootLayoutAbsPath(appCwdPath, segments) {
|
|
4536
4777
|
const filename = segments.length ? `${segments.join("__")}__root_layout.tsx` : "__root_layout.tsx";
|
|
4537
|
-
return
|
|
4778
|
+
return path11.join(path11.resolve(appCwdPath), IMPLICIT_LAYOUT_DIR, filename);
|
|
4538
4779
|
}
|
|
4539
4780
|
function implicitDictionaryMacroAbsPath(appCwdPath) {
|
|
4540
|
-
return
|
|
4781
|
+
return path11.join(path11.resolve(appCwdPath), IMPLICIT_DICT_DIR, "useDict.ts");
|
|
4541
4782
|
}
|
|
4542
4783
|
function isRootBoundarySegments(segments, basePaths) {
|
|
4543
4784
|
const firstVisibleIndex = segments.findIndex((segment) => !/^\(.+\)$/.test(segment));
|
|
@@ -4560,7 +4801,7 @@ function findRootBoundaries(pageKeys, appCwdPath, basePaths) {
|
|
|
4560
4801
|
const id = segments.join("/");
|
|
4561
4802
|
boundaries.set(id, {
|
|
4562
4803
|
sourceKey: key,
|
|
4563
|
-
sourceAbsPath:
|
|
4804
|
+
sourceAbsPath: path11.resolve(appCwdPath, "page", key.replace(/^\.\//, "")),
|
|
4564
4805
|
segments
|
|
4565
4806
|
});
|
|
4566
4807
|
}
|
|
@@ -4578,21 +4819,21 @@ function findExplicitRootLayoutAbsPath(pageKeys, appCwdPath) {
|
|
|
4578
4819
|
const segments = getRootBoundarySegments(key);
|
|
4579
4820
|
return segments !== null && segments.length === 0;
|
|
4580
4821
|
});
|
|
4581
|
-
return rootLayoutKey ?
|
|
4822
|
+
return rootLayoutKey ? path11.resolve(appCwdPath, "page", rootLayoutKey.replace(/^\.\//, "")) : null;
|
|
4582
4823
|
}
|
|
4583
4824
|
function routePrefixForSegments(segments) {
|
|
4584
4825
|
const visible = segments.filter((segment) => !/^\(.+\)$/.test(segment));
|
|
4585
4826
|
return visible[0] ?? null;
|
|
4586
4827
|
}
|
|
4587
4828
|
async function assertEnvClientConvention(appCwdPath, appName) {
|
|
4588
|
-
const envPath =
|
|
4829
|
+
const envPath = path11.join(appCwdPath, "env", "env.client.ts");
|
|
4589
4830
|
if (!await Bun.file(envPath).exists()) {
|
|
4590
4831
|
throw new Error(`[route-convention] app "${appName}" must provide env/env.client.ts exporting "env" for generated System.Provider`);
|
|
4591
4832
|
}
|
|
4592
4833
|
}
|
|
4593
4834
|
async function writeGeneratedDictionaryMacroFile(appCwdPath, appName) {
|
|
4594
4835
|
const absPath = implicitDictionaryMacroAbsPath(appCwdPath);
|
|
4595
|
-
await mkdir3(
|
|
4836
|
+
await mkdir3(path11.dirname(absPath), { recursive: true });
|
|
4596
4837
|
await Bun.write(absPath, `import { getAllDictionary } from "@apps/${appName}/lib/dict" with { type: "macro" };
|
|
4597
4838
|
|
|
4598
4839
|
export const allDictionary = getAllDictionary();
|
|
@@ -4603,13 +4844,13 @@ async function writeGeneratedRootLayoutFile(opts) {
|
|
|
4603
4844
|
await assertEnvClientConvention(opts.appCwdPath, opts.appName);
|
|
4604
4845
|
const dictMacroAbsPath = opts.includeSystemProvider ? await writeGeneratedDictionaryMacroFile(opts.appCwdPath, opts.appName) : null;
|
|
4605
4846
|
const absPath = implicitRootLayoutAbsPath(opts.appCwdPath, opts.boundary.segments);
|
|
4606
|
-
await mkdir3(
|
|
4607
|
-
const dictMacroRel = dictMacroAbsPath ?
|
|
4847
|
+
await mkdir3(path11.dirname(absPath), { recursive: true });
|
|
4848
|
+
const dictMacroRel = dictMacroAbsPath ? path11.relative(path11.dirname(absPath), dictMacroAbsPath).split(path11.sep).join("/") : null;
|
|
4608
4849
|
const dictMacroSpecifier = dictMacroRel ? dictMacroRel.startsWith(".") ? dictMacroRel : `./${dictMacroRel}` : null;
|
|
4609
|
-
const sourceRel = opts.boundary.sourceAbsPath ?
|
|
4850
|
+
const sourceRel = opts.boundary.sourceAbsPath ? path11.relative(path11.dirname(absPath), opts.boundary.sourceAbsPath).split(path11.sep).join("/") : null;
|
|
4610
4851
|
const sourceSpecifier = sourceRel ? sourceRel.startsWith(".") ? sourceRel : `./${sourceRel}` : null;
|
|
4611
4852
|
const inheritedSourceAbsPath = opts.rootSourceAbsPath && opts.rootSourceAbsPath !== opts.boundary.sourceAbsPath ? opts.rootSourceAbsPath : null;
|
|
4612
|
-
const inheritedSourceRel = inheritedSourceAbsPath ?
|
|
4853
|
+
const inheritedSourceRel = inheritedSourceAbsPath ? path11.relative(path11.dirname(absPath), inheritedSourceAbsPath).split(path11.sep).join("/") : null;
|
|
4613
4854
|
const inheritedSourceSpecifier = inheritedSourceRel ? inheritedSourceRel.startsWith(".") ? inheritedSourceRel : `./${inheritedSourceRel}` : null;
|
|
4614
4855
|
const clientImport = opts.includeStInit ? `import { st } from "@apps/${opts.appName}/client";
|
|
4615
4856
|
void st;
|
|
@@ -4687,7 +4928,7 @@ export default function GeneratedLayout({ children, params, searchParams }: Layo
|
|
|
4687
4928
|
return absPath;
|
|
4688
4929
|
}
|
|
4689
4930
|
async function resolveSsrPageEntries(opts) {
|
|
4690
|
-
const absPageDir =
|
|
4931
|
+
const absPageDir = path11.resolve(opts.appCwdPath, "page");
|
|
4691
4932
|
const hasSt = await appHasStModule(opts.appCwdPath);
|
|
4692
4933
|
const basePaths = opts.basePaths ?? [];
|
|
4693
4934
|
const rootSourceAbsPath = findExplicitRootLayoutAbsPath(opts.pageKeys, opts.appCwdPath);
|
|
@@ -4698,7 +4939,7 @@ async function resolveSsrPageEntries(opts) {
|
|
|
4698
4939
|
}));
|
|
4699
4940
|
const base = opts.pageKeys.filter((key) => !rootLayoutKeys.has(key)).map((key) => ({
|
|
4700
4941
|
key,
|
|
4701
|
-
moduleAbsPath:
|
|
4942
|
+
moduleAbsPath: path11.resolve(absPageDir, key)
|
|
4702
4943
|
}));
|
|
4703
4944
|
const generated = await Promise.all(rootBoundaries.map(async (boundary) => ({
|
|
4704
4945
|
key: implicitRootLayoutKey(boundary.segments),
|
|
@@ -4722,14 +4963,14 @@ async function resolveSsrPageEntriesForApp(app, pageKeys) {
|
|
|
4722
4963
|
}
|
|
4723
4964
|
|
|
4724
4965
|
// pkgs/@akanjs/devkit/artifact/routeSeedIndex.ts
|
|
4725
|
-
import
|
|
4966
|
+
import path12 from "path";
|
|
4726
4967
|
import { assertUniqueRoutePatterns, compareRouteSpecificity, parseRouteModuleKey as parseRouteModuleKey2 } from "akanjs/common";
|
|
4727
4968
|
function computeRouteSeedIndex(pageEntries) {
|
|
4728
4969
|
const layoutsByPrefix = new Map;
|
|
4729
4970
|
const pagesBySegments = [];
|
|
4730
4971
|
for (const { key, moduleAbsPath, seedAbsPaths } of pageEntries) {
|
|
4731
4972
|
const parsed = parseRouteModuleKey2(key);
|
|
4732
|
-
const files = [
|
|
4973
|
+
const files = [path12.resolve(moduleAbsPath), ...(seedAbsPaths ?? []).map((seed) => path12.resolve(seed))];
|
|
4733
4974
|
if (parsed.kind === "layout") {
|
|
4734
4975
|
const prefix = parsed.routeSegments.join("/");
|
|
4735
4976
|
const prev = layoutsByPrefix.get(prefix) ?? [];
|
|
@@ -4766,7 +5007,7 @@ function computeRouteSeedIndex(pageEntries) {
|
|
|
4766
5007
|
}
|
|
4767
5008
|
var ROUTE_SEED_INDEX_JSON = "route-seed-index.json";
|
|
4768
5009
|
function serializeRouteSeedIndexForArtifact(index, artifactDir, options = {}) {
|
|
4769
|
-
const normalizedArtifactDir =
|
|
5010
|
+
const normalizedArtifactDir = path12.resolve(artifactDir);
|
|
4770
5011
|
if (options.production) {
|
|
4771
5012
|
return {
|
|
4772
5013
|
entries: index.entries.map((entry) => ({ routeId: entry.routeId }))
|
|
@@ -4781,22 +5022,22 @@ function serializeRouteSeedIndexForArtifact(index, artifactDir, options = {}) {
|
|
|
4781
5022
|
};
|
|
4782
5023
|
}
|
|
4783
5024
|
async function saveRouteSeedIndex(artifactDir, index, options = {}) {
|
|
4784
|
-
const absPath =
|
|
5025
|
+
const absPath = path12.join(path12.resolve(artifactDir), ROUTE_SEED_INDEX_JSON);
|
|
4785
5026
|
await Bun.write(absPath, `${JSON.stringify(serializeRouteSeedIndexForArtifact(index, artifactDir, options), null, 2)}
|
|
4786
5027
|
`);
|
|
4787
5028
|
return absPath;
|
|
4788
5029
|
}
|
|
4789
5030
|
function serializeArtifactPath(artifactPath, artifactDir) {
|
|
4790
|
-
if (!
|
|
5031
|
+
if (!path12.isAbsolute(artifactPath))
|
|
4791
5032
|
return artifactPath;
|
|
4792
|
-
return
|
|
5033
|
+
return path12.relative(artifactDir, artifactPath).split(path12.sep).join("/");
|
|
4793
5034
|
}
|
|
4794
5035
|
|
|
4795
5036
|
// pkgs/@akanjs/devkit/frontendBuild/clientEntryDiscovery.ts
|
|
4796
|
-
import
|
|
5037
|
+
import path15 from "path";
|
|
4797
5038
|
|
|
4798
5039
|
// pkgs/@akanjs/devkit/transforms/barrelAnalyzer.ts
|
|
4799
|
-
import
|
|
5040
|
+
import path13 from "path";
|
|
4800
5041
|
import { Logger as Logger7 } from "akanjs/common";
|
|
4801
5042
|
var REEXPORT_RE = /(?:^|\n)\s*export\s+(?:type\s+)?(?:(\*)(?:\s+as\s+(\w+))?|\{\s*([^}]*?)\s*\})\s+from\s+(["'])([^"']+)\4;?/g;
|
|
4802
5043
|
var LOCAL_NAMED_RE = /(?:^|\n)\s*export\s+\{\s*([^}]*?)\s*\}(?!\s*from)/g;
|
|
@@ -4919,7 +5160,7 @@ class BarrelAnalyzer {
|
|
|
4919
5160
|
}
|
|
4920
5161
|
#scanExports(source, absFile) {
|
|
4921
5162
|
try {
|
|
4922
|
-
const transpiler = [".tsx", ".jsx"].includes(
|
|
5163
|
+
const transpiler = [".tsx", ".jsx"].includes(path13.extname(absFile)) ? this.#tsxTranspiler : this.#tsTranspiler;
|
|
4923
5164
|
const { exports } = transpiler.scan(source);
|
|
4924
5165
|
return new Set(exports);
|
|
4925
5166
|
} catch (err) {
|
|
@@ -4928,16 +5169,16 @@ class BarrelAnalyzer {
|
|
|
4928
5169
|
}
|
|
4929
5170
|
}
|
|
4930
5171
|
#subpathFor(pkg, absFile) {
|
|
4931
|
-
const rel =
|
|
4932
|
-
if (!rel || rel.startsWith("..") ||
|
|
5172
|
+
const rel = path13.relative(pkg.pkgDir, absFile);
|
|
5173
|
+
if (!rel || rel.startsWith("..") || path13.isAbsolute(rel))
|
|
4933
5174
|
return null;
|
|
4934
5175
|
if (pkg.preserveFilePath)
|
|
4935
|
-
return `${pkg.pkgName}/${rel.split(
|
|
5176
|
+
return `${pkg.pkgName}/${rel.split(path13.sep).join("/")}`;
|
|
4936
5177
|
const noExt = stripKnownExt(rel);
|
|
4937
5178
|
const tail = collapseIndex(noExt);
|
|
4938
5179
|
if (tail === "")
|
|
4939
5180
|
return pkg.pkgName;
|
|
4940
|
-
return `${pkg.pkgName}/${tail.split(
|
|
5181
|
+
return `${pkg.pkgName}/${tail.split(path13.sep).join("/")}`;
|
|
4941
5182
|
}
|
|
4942
5183
|
async#resolveRel(fromFile, relSpec) {
|
|
4943
5184
|
if (this.#opts.resolveRelative)
|
|
@@ -4978,9 +5219,9 @@ var readIfExists = async (absFile) => {
|
|
|
4978
5219
|
return file.text();
|
|
4979
5220
|
};
|
|
4980
5221
|
var defaultResolveRelative = async (fromFile, relSpec) => {
|
|
4981
|
-
const baseDir =
|
|
4982
|
-
const joined =
|
|
4983
|
-
if (
|
|
5222
|
+
const baseDir = path13.dirname(fromFile);
|
|
5223
|
+
const joined = path13.resolve(baseDir, relSpec);
|
|
5224
|
+
if (path13.extname(joined)) {
|
|
4984
5225
|
if (await Bun.file(joined).exists())
|
|
4985
5226
|
return joined;
|
|
4986
5227
|
return null;
|
|
@@ -4991,7 +5232,7 @@ var defaultResolveRelative = async (fromFile, relSpec) => {
|
|
|
4991
5232
|
return cand;
|
|
4992
5233
|
}
|
|
4993
5234
|
for (const ext of CANDIDATE_EXTS) {
|
|
4994
|
-
const cand =
|
|
5235
|
+
const cand = path13.join(joined, `index${ext}`);
|
|
4995
5236
|
if (await Bun.file(cand).exists())
|
|
4996
5237
|
return cand;
|
|
4997
5238
|
}
|
|
@@ -5005,14 +5246,14 @@ var stripKnownExt = (relPath) => {
|
|
|
5005
5246
|
return relPath;
|
|
5006
5247
|
};
|
|
5007
5248
|
var collapseIndex = (relPathNoExt) => {
|
|
5008
|
-
const parts = relPathNoExt.split(
|
|
5249
|
+
const parts = relPathNoExt.split(path13.sep);
|
|
5009
5250
|
if (parts[parts.length - 1] === "index")
|
|
5010
5251
|
parts.pop();
|
|
5011
|
-
return parts.join(
|
|
5252
|
+
return parts.join(path13.sep);
|
|
5012
5253
|
};
|
|
5013
5254
|
|
|
5014
5255
|
// pkgs/@akanjs/devkit/transforms/barrelImportsPlugin.ts
|
|
5015
|
-
import
|
|
5256
|
+
import path14 from "path";
|
|
5016
5257
|
import ts4 from "typescript";
|
|
5017
5258
|
var createBarrelImportsPlugin = async (app, { skipPath = defaultSkipPath, pipeAfter } = {}) => {
|
|
5018
5259
|
const akanConfig2 = await app.getConfig();
|
|
@@ -5071,10 +5312,10 @@ var createTsconfigPackageResolver = async (app) => {
|
|
|
5071
5312
|
const raw = exact[0];
|
|
5072
5313
|
if (!raw)
|
|
5073
5314
|
return null;
|
|
5074
|
-
const entryFile =
|
|
5315
|
+
const entryFile = path14.resolve(app.workspace.workspaceRoot, raw);
|
|
5075
5316
|
if (!await Bun.file(entryFile).exists())
|
|
5076
5317
|
return null;
|
|
5077
|
-
const parsed =
|
|
5318
|
+
const parsed = path14.parse(entryFile);
|
|
5078
5319
|
const lastSlash = pkgName.lastIndexOf("/");
|
|
5079
5320
|
if (parsed.name !== "index" && lastSlash !== -1) {
|
|
5080
5321
|
const facet = pkgName.slice(lastSlash + 1);
|
|
@@ -5083,7 +5324,7 @@ var createTsconfigPackageResolver = async (app) => {
|
|
|
5083
5324
|
return { pkgName: parentSpec, entryFile, pkgDir: parsed.dir };
|
|
5084
5325
|
}
|
|
5085
5326
|
}
|
|
5086
|
-
return { pkgName, entryFile, pkgDir:
|
|
5327
|
+
return { pkgName, entryFile, pkgDir: path14.dirname(entryFile) };
|
|
5087
5328
|
}
|
|
5088
5329
|
for (const { prefix, replacements } of wildcardEntries) {
|
|
5089
5330
|
if (!pkgName.startsWith(prefix))
|
|
@@ -5093,7 +5334,7 @@ var createTsconfigPackageResolver = async (app) => {
|
|
|
5093
5334
|
if (!repl)
|
|
5094
5335
|
continue;
|
|
5095
5336
|
const replPath = repl.endsWith("/*") ? repl.slice(0, -1) : repl;
|
|
5096
|
-
const candidate =
|
|
5337
|
+
const candidate = path14.resolve(app.workspace.workspaceRoot, replPath + suffix);
|
|
5097
5338
|
for (const ext of CANDIDATE_EXTS2) {
|
|
5098
5339
|
const file = `${candidate}${ext}`;
|
|
5099
5340
|
if (await Bun.file(file).exists()) {
|
|
@@ -5101,14 +5342,14 @@ var createTsconfigPackageResolver = async (app) => {
|
|
|
5101
5342
|
if (lastSlash !== -1) {
|
|
5102
5343
|
const parentSpec = pkgName.slice(0, lastSlash);
|
|
5103
5344
|
if (parentSpec.length > 0) {
|
|
5104
|
-
return { pkgName: parentSpec, entryFile: file, pkgDir:
|
|
5345
|
+
return { pkgName: parentSpec, entryFile: file, pkgDir: path14.dirname(file) };
|
|
5105
5346
|
}
|
|
5106
5347
|
}
|
|
5107
|
-
return { pkgName, entryFile: file, pkgDir:
|
|
5348
|
+
return { pkgName, entryFile: file, pkgDir: path14.dirname(file) };
|
|
5108
5349
|
}
|
|
5109
5350
|
}
|
|
5110
5351
|
for (const ext of CANDIDATE_EXTS2) {
|
|
5111
|
-
const file =
|
|
5352
|
+
const file = path14.join(candidate, `index${ext}`);
|
|
5112
5353
|
if (await Bun.file(file).exists()) {
|
|
5113
5354
|
return { pkgName, entryFile: file, pkgDir: candidate };
|
|
5114
5355
|
}
|
|
@@ -5119,16 +5360,16 @@ var createTsconfigPackageResolver = async (app) => {
|
|
|
5119
5360
|
const exported = await resolveNodePackageExport(app.workspace.workspaceRoot, pkgName);
|
|
5120
5361
|
if (exported)
|
|
5121
5362
|
return exported;
|
|
5122
|
-
const pkgJsonPath =
|
|
5363
|
+
const pkgJsonPath = path14.join(app.workspace.workspaceRoot, "node_modules", pkgName, "package.json");
|
|
5123
5364
|
if (!await Bun.file(pkgJsonPath).exists())
|
|
5124
5365
|
return null;
|
|
5125
5366
|
try {
|
|
5126
5367
|
const pkgJson = JSON.parse(await Bun.file(pkgJsonPath).text());
|
|
5127
5368
|
const rel = pkgJson.module ?? pkgJson.main ?? "index.js";
|
|
5128
|
-
const entryFile =
|
|
5369
|
+
const entryFile = path14.resolve(path14.dirname(pkgJsonPath), rel);
|
|
5129
5370
|
if (!await Bun.file(entryFile).exists())
|
|
5130
5371
|
return null;
|
|
5131
|
-
return { pkgName, entryFile, pkgDir:
|
|
5372
|
+
return { pkgName, entryFile, pkgDir: path14.dirname(pkgJsonPath) };
|
|
5132
5373
|
} catch {
|
|
5133
5374
|
return null;
|
|
5134
5375
|
}
|
|
@@ -5142,22 +5383,22 @@ var resolveNodePackageExport = async (workspaceRoot, specifier) => {
|
|
|
5142
5383
|
const packageName = getPackageName(specifier);
|
|
5143
5384
|
if (!packageName)
|
|
5144
5385
|
return null;
|
|
5145
|
-
const pkgJsonPath =
|
|
5386
|
+
const pkgJsonPath = path14.join(workspaceRoot, "node_modules", packageName, "package.json");
|
|
5146
5387
|
if (!await Bun.file(pkgJsonPath).exists())
|
|
5147
5388
|
return null;
|
|
5148
5389
|
try {
|
|
5149
|
-
const pkgDir =
|
|
5390
|
+
const pkgDir = path14.dirname(pkgJsonPath);
|
|
5150
5391
|
const pkgJson = JSON.parse(await Bun.file(pkgJsonPath).text());
|
|
5151
5392
|
const subpath = specifier === packageName ? "." : `.${specifier.slice(packageName.length)}`;
|
|
5152
5393
|
const exported = resolvePackageExport(pkgJson.exports, subpath);
|
|
5153
5394
|
const rel = exported ?? (subpath === "." ? pkgJson.module ?? pkgJson.main ?? "index.js" : null);
|
|
5154
5395
|
if (!rel || !rel.startsWith("."))
|
|
5155
5396
|
return null;
|
|
5156
|
-
const entryFile = await resolveFileCandidate(
|
|
5397
|
+
const entryFile = await resolveFileCandidate(path14.resolve(pkgDir, rel));
|
|
5157
5398
|
if (!entryFile)
|
|
5158
5399
|
return null;
|
|
5159
5400
|
const pkgEntryName = specifier;
|
|
5160
|
-
return { pkgName: pkgEntryName, entryFile, pkgDir:
|
|
5401
|
+
return { pkgName: pkgEntryName, entryFile, pkgDir: path14.dirname(entryFile), preserveFilePath: true };
|
|
5161
5402
|
} catch {
|
|
5162
5403
|
return null;
|
|
5163
5404
|
}
|
|
@@ -5214,7 +5455,7 @@ var getPackageName = (specifier) => {
|
|
|
5214
5455
|
var resolveFileCandidate = async (candidate) => {
|
|
5215
5456
|
if (await Bun.file(candidate).exists())
|
|
5216
5457
|
return candidate;
|
|
5217
|
-
if (
|
|
5458
|
+
if (path14.extname(candidate))
|
|
5218
5459
|
return null;
|
|
5219
5460
|
for (const ext of CANDIDATE_EXTS2) {
|
|
5220
5461
|
const file = `${candidate}${ext}`;
|
|
@@ -5222,7 +5463,7 @@ var resolveFileCandidate = async (candidate) => {
|
|
|
5222
5463
|
return file;
|
|
5223
5464
|
}
|
|
5224
5465
|
for (const ext of CANDIDATE_EXTS2) {
|
|
5225
|
-
const file =
|
|
5466
|
+
const file = path14.join(candidate, `index${ext}`);
|
|
5226
5467
|
if (await Bun.file(file).exists())
|
|
5227
5468
|
return file;
|
|
5228
5469
|
}
|
|
@@ -5436,7 +5677,7 @@ class GraphClientEntryDiscovery {
|
|
|
5436
5677
|
}
|
|
5437
5678
|
invalidate(files) {
|
|
5438
5679
|
for (const file of files) {
|
|
5439
|
-
const absPath =
|
|
5680
|
+
const absPath = path15.resolve(file);
|
|
5440
5681
|
this.#readCache.delete(absPath);
|
|
5441
5682
|
this.#rewriteCache.delete(absPath);
|
|
5442
5683
|
this.#importCache.delete(absPath);
|
|
@@ -5446,7 +5687,7 @@ class GraphClientEntryDiscovery {
|
|
|
5446
5687
|
this.#reachableEntriesCache.clear();
|
|
5447
5688
|
}
|
|
5448
5689
|
async#fileExists(p) {
|
|
5449
|
-
const absPath =
|
|
5690
|
+
const absPath = path15.resolve(p);
|
|
5450
5691
|
let cached = this.#fileExistsCache.get(absPath);
|
|
5451
5692
|
if (!cached) {
|
|
5452
5693
|
cached = Bun.file(absPath).exists();
|
|
@@ -5455,7 +5696,7 @@ class GraphClientEntryDiscovery {
|
|
|
5455
5696
|
return cached;
|
|
5456
5697
|
}
|
|
5457
5698
|
#readFile(file) {
|
|
5458
|
-
const absPath =
|
|
5699
|
+
const absPath = path15.resolve(file);
|
|
5459
5700
|
let cached = this.#readCache.get(absPath);
|
|
5460
5701
|
if (!cached) {
|
|
5461
5702
|
cached = Bun.file(absPath).text().catch(() => null);
|
|
@@ -5464,7 +5705,7 @@ class GraphClientEntryDiscovery {
|
|
|
5464
5705
|
return cached;
|
|
5465
5706
|
}
|
|
5466
5707
|
async#resolveFileCandidate(absPathNoExt) {
|
|
5467
|
-
const cacheKey =
|
|
5708
|
+
const cacheKey = path15.resolve(absPathNoExt);
|
|
5468
5709
|
let cached = this.#resolvedFileCache.get(cacheKey);
|
|
5469
5710
|
if (cached)
|
|
5470
5711
|
return cached;
|
|
@@ -5477,7 +5718,7 @@ class GraphClientEntryDiscovery {
|
|
|
5477
5718
|
return f;
|
|
5478
5719
|
}
|
|
5479
5720
|
for (const ext of SOURCE_EXTS2) {
|
|
5480
|
-
const f =
|
|
5721
|
+
const f = path15.join(cacheKey, `index${ext}`);
|
|
5481
5722
|
if (await this.#fileExists(f))
|
|
5482
5723
|
return f;
|
|
5483
5724
|
}
|
|
@@ -5493,7 +5734,7 @@ class GraphClientEntryDiscovery {
|
|
|
5493
5734
|
return cached;
|
|
5494
5735
|
cached = (async () => {
|
|
5495
5736
|
if (spec.startsWith(".") || spec.startsWith("/")) {
|
|
5496
|
-
const abs = spec.startsWith("/") ? spec :
|
|
5737
|
+
const abs = spec.startsWith("/") ? spec : path15.resolve(importerDir, spec);
|
|
5497
5738
|
return this.#resolveFileCandidate(abs);
|
|
5498
5739
|
}
|
|
5499
5740
|
const pkg = await this.#resolvePackage(spec);
|
|
@@ -5505,7 +5746,7 @@ class GraphClientEntryDiscovery {
|
|
|
5505
5746
|
return cached;
|
|
5506
5747
|
}
|
|
5507
5748
|
async#getRewrittenSource(file, content) {
|
|
5508
|
-
const absPath =
|
|
5749
|
+
const absPath = path15.resolve(file);
|
|
5509
5750
|
let cached = this.#rewriteCache.get(absPath);
|
|
5510
5751
|
if (!cached) {
|
|
5511
5752
|
cached = (async () => {
|
|
@@ -5522,7 +5763,7 @@ class GraphClientEntryDiscovery {
|
|
|
5522
5763
|
return cached;
|
|
5523
5764
|
}
|
|
5524
5765
|
async#getImports(file, source) {
|
|
5525
|
-
const absPath =
|
|
5766
|
+
const absPath = path15.resolve(file);
|
|
5526
5767
|
let cached = this.#importCache.get(absPath);
|
|
5527
5768
|
if (!cached) {
|
|
5528
5769
|
cached = Promise.resolve().then(() => {
|
|
@@ -5537,7 +5778,7 @@ class GraphClientEntryDiscovery {
|
|
|
5537
5778
|
return cached;
|
|
5538
5779
|
}
|
|
5539
5780
|
async#discoverFromFile(file, visiting) {
|
|
5540
|
-
const absPath =
|
|
5781
|
+
const absPath = path15.resolve(file);
|
|
5541
5782
|
const cached = this.#reachableEntriesCache.get(absPath);
|
|
5542
5783
|
if (cached)
|
|
5543
5784
|
return new Set(cached);
|
|
@@ -5554,7 +5795,7 @@ class GraphClientEntryDiscovery {
|
|
|
5554
5795
|
}
|
|
5555
5796
|
const source = await this.#getRewrittenSource(absPath, content);
|
|
5556
5797
|
const imports = await this.#getImports(absPath, source);
|
|
5557
|
-
const importerDir =
|
|
5798
|
+
const importerDir = path15.dirname(absPath);
|
|
5558
5799
|
for (const imp of imports) {
|
|
5559
5800
|
const spec = imp.path;
|
|
5560
5801
|
if (!spec)
|
|
@@ -5580,14 +5821,14 @@ class GraphClientEntryDiscovery {
|
|
|
5580
5821
|
|
|
5581
5822
|
// pkgs/@akanjs/devkit/frontendBuild/routeClientBuilder.ts
|
|
5582
5823
|
import { mkdir as mkdir4 } from "fs/promises";
|
|
5583
|
-
import
|
|
5824
|
+
import path18 from "path";
|
|
5584
5825
|
|
|
5585
5826
|
// pkgs/@akanjs/devkit/transforms/rscUseClientTransform.ts
|
|
5586
|
-
import
|
|
5827
|
+
import path16 from "path";
|
|
5587
5828
|
var USE_CLIENT_RE2 = /^\s*(?:\/\*[\s\S]*?\*\/\s*|\/\/[^\n]*\n\s*)*["']use client["']/;
|
|
5588
5829
|
var IMPLICIT_ROOT_LAYOUT_RE = /[/\\]\.akan[/\\]generated[/\\](?:implicit-root-layout|root-layouts[/\\].*__root_layout)\.(tsx|ts|jsx|js)$/;
|
|
5589
5830
|
function toClientReferencePath(absPath, workspaceRoot) {
|
|
5590
|
-
return
|
|
5831
|
+
return path16.relative(path16.resolve(workspaceRoot), path16.resolve(absPath)).split(path16.sep).join("/");
|
|
5591
5832
|
}
|
|
5592
5833
|
function transformUseClient(source, args) {
|
|
5593
5834
|
if (!USE_CLIENT_RE2.test(source))
|
|
@@ -5623,7 +5864,7 @@ function loaderFor2(absPath) {
|
|
|
5623
5864
|
|
|
5624
5865
|
// pkgs/@akanjs/devkit/frontendBuild/clientEntriesBundler.ts
|
|
5625
5866
|
import fs2 from "fs";
|
|
5626
|
-
import
|
|
5867
|
+
import path17 from "path";
|
|
5627
5868
|
|
|
5628
5869
|
// pkgs/@akanjs/devkit/frontendBuild/clientBuildTypes.ts
|
|
5629
5870
|
var CLIENT_BUNDLE_NAMING = {
|
|
@@ -5712,23 +5953,23 @@ class ClientEntriesBundler {
|
|
|
5712
5953
|
};
|
|
5713
5954
|
}
|
|
5714
5955
|
async#createOpaqueEntryAliases() {
|
|
5715
|
-
const aliasDir =
|
|
5956
|
+
const aliasDir = path17.join(this.#app.cwdPath, ".akan", "generated", "client-entry-alias", this.#outputSubdir);
|
|
5716
5957
|
fs2.mkdirSync(aliasDir, { recursive: true });
|
|
5717
5958
|
const originalByAlias = new Map;
|
|
5718
5959
|
const aliasedEntries = await Promise.all(this.#entries.map(async (entry) => {
|
|
5719
|
-
const absEntry =
|
|
5960
|
+
const absEntry = path17.resolve(entry);
|
|
5720
5961
|
const hash = Bun.hash(`${this.#app.name}
|
|
5721
5962
|
${this.#outputSubdir}
|
|
5722
5963
|
${absEntry}`).toString(36);
|
|
5723
|
-
const aliasPath =
|
|
5964
|
+
const aliasPath = path17.join(aliasDir, `${hash}.tsx`);
|
|
5724
5965
|
await Bun.write(aliasPath, this.#createOpaqueEntryAliasSource(absEntry, await this.#scanEntryExportNames(absEntry)));
|
|
5725
|
-
originalByAlias.set(
|
|
5966
|
+
originalByAlias.set(path17.resolve(aliasPath), absEntry);
|
|
5726
5967
|
return aliasPath;
|
|
5727
5968
|
}));
|
|
5728
5969
|
return { entries: aliasedEntries, originalByAlias, aliasDir };
|
|
5729
5970
|
}
|
|
5730
5971
|
#createOpaqueEntryAliasSource(absEntry, exportNames) {
|
|
5731
|
-
const entryLit = JSON.stringify(
|
|
5972
|
+
const entryLit = JSON.stringify(path17.resolve(absEntry));
|
|
5732
5973
|
if (exportNames.length === 0)
|
|
5733
5974
|
return `export * from ${entryLit};
|
|
5734
5975
|
`;
|
|
@@ -5811,16 +6052,16 @@ ${absEntry}`).toString(36);
|
|
|
5811
6052
|
return rewritten;
|
|
5812
6053
|
}
|
|
5813
6054
|
#toServeUrl(absOutPath) {
|
|
5814
|
-
const rel =
|
|
6055
|
+
const rel = path17.relative(this.#outdir, absOutPath).split(path17.sep).join("/");
|
|
5815
6056
|
return `${this.#servePrefix}/${rel}`;
|
|
5816
6057
|
}
|
|
5817
6058
|
#absFromOutdir(p) {
|
|
5818
|
-
return
|
|
6059
|
+
return path17.isAbsolute(p) ? p : path17.resolve(this.#outdir, p);
|
|
5819
6060
|
}
|
|
5820
6061
|
#absFromEntryPoint(p) {
|
|
5821
|
-
if (
|
|
5822
|
-
return
|
|
5823
|
-
const candidates = [
|
|
6062
|
+
if (path17.isAbsolute(p))
|
|
6063
|
+
return path17.resolve(p);
|
|
6064
|
+
const candidates = [path17.resolve(process.cwd(), p), path17.resolve(this.#app.cwdPath, p)];
|
|
5824
6065
|
return candidates.find((candidate) => fs2.existsSync(candidate)) ?? candidates[0];
|
|
5825
6066
|
}
|
|
5826
6067
|
#collectChunkUrls(absOutPath, visited = new Set) {
|
|
@@ -5970,13 +6211,13 @@ class RouteClientBuilder {
|
|
|
5970
6211
|
ssrModuleMap[row.id][row.name] = { id: ssrOutput, chunks: [ssrOutput, ssrOutput], name: row.name, async: true };
|
|
5971
6212
|
}
|
|
5972
6213
|
for (const entry of bootstrapEntries.buildEntries) {
|
|
5973
|
-
const buildEntry =
|
|
5974
|
-
const originalEntry =
|
|
6214
|
+
const buildEntry = path18.resolve(entry);
|
|
6215
|
+
const originalEntry = path18.resolve(bootstrapEntries.originalByBuildEntry.get(buildEntry) ?? buildEntry);
|
|
5975
6216
|
if (!acceptedEntries.has(originalEntry))
|
|
5976
6217
|
continue;
|
|
5977
6218
|
const deps = new Set([originalEntry]);
|
|
5978
6219
|
for (const dep of browserBundle.entryDepsByAbsPath.get(buildEntry) ?? [])
|
|
5979
|
-
deps.add(
|
|
6220
|
+
deps.add(path18.resolve(dep));
|
|
5980
6221
|
const sortedDeps = [...deps].sort();
|
|
5981
6222
|
clientDepsByEntry[originalEntry] = sortedDeps;
|
|
5982
6223
|
for (const dep of sortedDeps)
|
|
@@ -6028,25 +6269,25 @@ class RouteClientBuilder {
|
|
|
6028
6269
|
}).bundle();
|
|
6029
6270
|
}
|
|
6030
6271
|
async#createBootstrapEntries(entries) {
|
|
6031
|
-
if (!await Bun.file(
|
|
6272
|
+
if (!await Bun.file(path18.join(this.#app.cwdPath, "lib", "st.ts")).exists()) {
|
|
6032
6273
|
return { buildEntries: entries, originalByBuildEntry: new Map };
|
|
6033
6274
|
}
|
|
6034
|
-
const outdir =
|
|
6275
|
+
const outdir = path18.join(this.#app.cwdPath, ".akan", "generated", "client-entry-bootstrap");
|
|
6035
6276
|
await mkdir4(outdir, { recursive: true });
|
|
6036
6277
|
const originalByBuildEntry = new Map;
|
|
6037
6278
|
const buildEntries = await Promise.all(entries.map(async (entry) => {
|
|
6038
|
-
const absEntry =
|
|
6279
|
+
const absEntry = path18.resolve(entry);
|
|
6039
6280
|
const hash = Bun.hash(`${this.#app.name}
|
|
6040
6281
|
${absEntry}`).toString(36);
|
|
6041
|
-
const base =
|
|
6042
|
-
const wrapperEntry =
|
|
6282
|
+
const base = path18.basename(absEntry).replace(/[^A-Za-z0-9._-]/g, "_");
|
|
6283
|
+
const wrapperEntry = path18.join(outdir, `${base}-${hash}.tsx`);
|
|
6043
6284
|
const exportNames = await this.#scanExportNames(absEntry);
|
|
6044
6285
|
await Bun.write(wrapperEntry, RouteClientBuilder.createStoreBootstrapEntrySource({
|
|
6045
6286
|
appName: this.#app.name,
|
|
6046
6287
|
originalEntry: absEntry,
|
|
6047
6288
|
exportNames
|
|
6048
6289
|
}));
|
|
6049
|
-
originalByBuildEntry.set(
|
|
6290
|
+
originalByBuildEntry.set(path18.resolve(wrapperEntry), absEntry);
|
|
6050
6291
|
return wrapperEntry;
|
|
6051
6292
|
}));
|
|
6052
6293
|
return { buildEntries, originalByBuildEntry };
|
|
@@ -6098,11 +6339,11 @@ ${defaultNames.map((name) => `export default ${name};`).join(`
|
|
|
6098
6339
|
try {
|
|
6099
6340
|
return Bun.resolveSync("akanjs/server", import.meta.dir);
|
|
6100
6341
|
} catch {
|
|
6101
|
-
return
|
|
6342
|
+
return path18.resolve(import.meta.dir, "../../../server/index.ts");
|
|
6102
6343
|
}
|
|
6103
6344
|
}
|
|
6104
6345
|
static createStoreBootstrapEntrySource(args) {
|
|
6105
|
-
const originalEntry = JSON.stringify(
|
|
6346
|
+
const originalEntry = JSON.stringify(path18.resolve(args.originalEntry));
|
|
6106
6347
|
const namedExports = args.exportNames.filter((name) => name !== "default");
|
|
6107
6348
|
const lines = [
|
|
6108
6349
|
`import ${JSON.stringify(`@apps/${args.appName}/client`)};`,
|
|
@@ -6128,7 +6369,7 @@ ${defaultNames.map((name) => `export default ${name};`).join(`
|
|
|
6128
6369
|
}
|
|
6129
6370
|
|
|
6130
6371
|
// pkgs/@akanjs/devkit/frontendBuild/routesManifestArtifactSerializer.ts
|
|
6131
|
-
import
|
|
6372
|
+
import path19 from "path";
|
|
6132
6373
|
|
|
6133
6374
|
class RoutesManifestArtifactSerializer {
|
|
6134
6375
|
#manifest;
|
|
@@ -6136,7 +6377,7 @@ class RoutesManifestArtifactSerializer {
|
|
|
6136
6377
|
#production;
|
|
6137
6378
|
constructor(manifest, artifactDir, options = {}) {
|
|
6138
6379
|
this.#manifest = manifest;
|
|
6139
|
-
this.#artifactDir =
|
|
6380
|
+
this.#artifactDir = path19.resolve(artifactDir);
|
|
6140
6381
|
this.#production = options.production ?? false;
|
|
6141
6382
|
}
|
|
6142
6383
|
static serialize(manifest, artifactDir, options = {}) {
|
|
@@ -6169,9 +6410,9 @@ class RoutesManifestArtifactSerializer {
|
|
|
6169
6410
|
};
|
|
6170
6411
|
}
|
|
6171
6412
|
#serializeArtifactPath(artifactPath) {
|
|
6172
|
-
if (!
|
|
6413
|
+
if (!path19.isAbsolute(artifactPath))
|
|
6173
6414
|
return artifactPath;
|
|
6174
|
-
return
|
|
6415
|
+
return path19.relative(this.#artifactDir, artifactPath).split(path19.sep).join("/");
|
|
6175
6416
|
}
|
|
6176
6417
|
}
|
|
6177
6418
|
|
|
@@ -6211,7 +6452,7 @@ class AllRoutesBuilder {
|
|
|
6211
6452
|
routeIds: this.#routeIds,
|
|
6212
6453
|
...this.#merged
|
|
6213
6454
|
};
|
|
6214
|
-
const manifestPath =
|
|
6455
|
+
const manifestPath = path20.join(path20.resolve(this.#artifactDir), "routes-manifest.json");
|
|
6215
6456
|
await Bun.write(manifestPath, `${JSON.stringify(RoutesManifestArtifactSerializer.serialize(manifest, this.#artifactDir, {
|
|
6216
6457
|
production: this.#command === "build"
|
|
6217
6458
|
}), null, 2)}
|
|
@@ -6248,11 +6489,11 @@ class AllRoutesBuilder {
|
|
|
6248
6489
|
}
|
|
6249
6490
|
// pkgs/@akanjs/devkit/frontendBuild/csrArtifactBuilder.ts
|
|
6250
6491
|
import { mkdir as mkdir5, rm, unlink } from "fs/promises";
|
|
6251
|
-
import
|
|
6492
|
+
import path22 from "path";
|
|
6252
6493
|
|
|
6253
6494
|
// pkgs/@akanjs/devkit/frontendBuild/pagesEntrySourceGenerator.ts
|
|
6254
6495
|
import fs3 from "fs";
|
|
6255
|
-
import
|
|
6496
|
+
import path21 from "path";
|
|
6256
6497
|
import ts5 from "typescript";
|
|
6257
6498
|
|
|
6258
6499
|
class PagesEntrySourceGenerator {
|
|
@@ -6265,7 +6506,7 @@ class PagesEntrySourceGenerator {
|
|
|
6265
6506
|
}
|
|
6266
6507
|
generate() {
|
|
6267
6508
|
const lines = this.#pageEntries.map(({ key, moduleAbsPath }) => {
|
|
6268
|
-
const absPath =
|
|
6509
|
+
const absPath = path21.resolve(moduleAbsPath);
|
|
6269
6510
|
return ` ${JSON.stringify(key)}: () => import(${JSON.stringify(absPath)}),`;
|
|
6270
6511
|
});
|
|
6271
6512
|
return `export const pages = {
|
|
@@ -6279,7 +6520,7 @@ ${lines.join(`
|
|
|
6279
6520
|
}
|
|
6280
6521
|
generateStatic() {
|
|
6281
6522
|
const imports = this.#pageEntries.map(({ moduleAbsPath }, index) => {
|
|
6282
|
-
const absPath =
|
|
6523
|
+
const absPath = path21.resolve(moduleAbsPath);
|
|
6283
6524
|
return `import * as page${index} from ${JSON.stringify(absPath)};`;
|
|
6284
6525
|
});
|
|
6285
6526
|
const entries = this.#pageEntries.map(({ key, moduleAbsPath }, index) => {
|
|
@@ -6296,7 +6537,7 @@ ${entries.join(`
|
|
|
6296
6537
|
}
|
|
6297
6538
|
static #hasAsyncDefaultExport(moduleAbsPath) {
|
|
6298
6539
|
try {
|
|
6299
|
-
const source = fs3.readFileSync(
|
|
6540
|
+
const source = fs3.readFileSync(path21.resolve(moduleAbsPath), "utf8");
|
|
6300
6541
|
const sourceFile = ts5.createSourceFile(moduleAbsPath, source, ts5.ScriptTarget.Latest, true, PagesEntrySourceGenerator.#scriptKind(moduleAbsPath));
|
|
6301
6542
|
return PagesEntrySourceGenerator.#sourceFileHasAsyncDefaultExport(sourceFile);
|
|
6302
6543
|
} catch {
|
|
@@ -6375,7 +6616,7 @@ class CsrArtifactBuilder {
|
|
|
6375
6616
|
const csrBasePaths = [...akanConfig2.basePaths];
|
|
6376
6617
|
const htmlEntries = csrBasePaths.length > 0 ? csrBasePaths : ["index"];
|
|
6377
6618
|
await rm(this.#outputDir, { recursive: true, force: true });
|
|
6378
|
-
await mkdir5(
|
|
6619
|
+
await mkdir5(path22.join(this.#app.cwdPath, ".akan/generated/csr"), { recursive: true });
|
|
6379
6620
|
const generatedHtmlFiles = Object.fromEntries(htmlEntries.map((basePath2) => this.#createHtmlFile(basePath2)));
|
|
6380
6621
|
const result = await Bun.build({
|
|
6381
6622
|
target: "browser",
|
|
@@ -6407,7 +6648,7 @@ ${logs}` : ""}`);
|
|
|
6407
6648
|
return { outputDir: this.#outputDir };
|
|
6408
6649
|
}
|
|
6409
6650
|
get #outputDir() {
|
|
6410
|
-
return
|
|
6651
|
+
return path22.join(this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath, this.#command === "build" ? "csr" : ".akan/artifact/csr");
|
|
6411
6652
|
}
|
|
6412
6653
|
#define() {
|
|
6413
6654
|
const nodeEnv = this.#command === "build" ? "production" : "development";
|
|
@@ -6438,8 +6679,8 @@ ${logs}` : ""}`);
|
|
|
6438
6679
|
];
|
|
6439
6680
|
}
|
|
6440
6681
|
async#loadCsrArtifact() {
|
|
6441
|
-
const artifactDir =
|
|
6442
|
-
const artifactFile = Bun.file(
|
|
6682
|
+
const artifactDir = path22.join(this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath, ".akan/artifact");
|
|
6683
|
+
const artifactFile = Bun.file(path22.join(artifactDir, "base-artifact.json"));
|
|
6443
6684
|
if (!await artifactFile.exists())
|
|
6444
6685
|
return { cssAssets: {} };
|
|
6445
6686
|
const artifact = await artifactFile.json();
|
|
@@ -6452,7 +6693,7 @@ ${logs}` : ""}`);
|
|
|
6452
6693
|
const htmlFile = Bun.file(htmlPath);
|
|
6453
6694
|
if (!await htmlFile.exists())
|
|
6454
6695
|
continue;
|
|
6455
|
-
const basePath2 =
|
|
6696
|
+
const basePath2 = path22.basename(htmlPath, ".html") === "index" ? "" : path22.basename(htmlPath, ".html");
|
|
6456
6697
|
const inlined = await this.#inlineHtmlAssets(await htmlFile.text(), htmlPath, cssAssets[basePath2]);
|
|
6457
6698
|
for (const filePath of inlined.jsFiles)
|
|
6458
6699
|
jsFiles.add(filePath);
|
|
@@ -6494,7 +6735,7 @@ ${remainingAssets.join(`
|
|
|
6494
6735
|
next = CsrArtifactBuilder.injectBeforeHeadEnd(next, style);
|
|
6495
6736
|
}
|
|
6496
6737
|
if (cssAsset) {
|
|
6497
|
-
const cssPath =
|
|
6738
|
+
const cssPath = path22.join(this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath, ".akan/artifact", cssAsset.cssRelPath);
|
|
6498
6739
|
const css = await Bun.file(cssPath).text();
|
|
6499
6740
|
const style = CsrArtifactBuilder.createInlineStyle(css);
|
|
6500
6741
|
if (!next.includes(style))
|
|
@@ -6565,16 +6806,16 @@ ${CsrArtifactBuilder.escapeInlineScript(await loadScript(src))}
|
|
|
6565
6806
|
throw new Error(`[csr-build] cannot inline external script: ${src}`);
|
|
6566
6807
|
}
|
|
6567
6808
|
const normalized = src.startsWith("/") ? src.slice(1) : src;
|
|
6568
|
-
return
|
|
6809
|
+
return path22.resolve(path22.dirname(htmlPath), normalized);
|
|
6569
6810
|
}
|
|
6570
6811
|
}
|
|
6571
6812
|
// pkgs/@akanjs/devkit/frontendBuild/cssCompiler.ts
|
|
6572
|
-
import
|
|
6813
|
+
import path24 from "path";
|
|
6573
6814
|
import { Logger as Logger8 } from "akanjs/common";
|
|
6574
6815
|
import { compile } from "tailwindcss";
|
|
6575
6816
|
|
|
6576
6817
|
// pkgs/@akanjs/devkit/frontendBuild/cssImportResolver.ts
|
|
6577
|
-
import
|
|
6818
|
+
import path23 from "path";
|
|
6578
6819
|
var CSS_IMPORT_EXTS = ["", ".css", "/styles.css", "/index.css"];
|
|
6579
6820
|
|
|
6580
6821
|
class CssImportResolver {
|
|
@@ -6627,7 +6868,7 @@ class CssImportResolver {
|
|
|
6627
6868
|
const exact = this.#paths[id];
|
|
6628
6869
|
if (exact) {
|
|
6629
6870
|
for (const repl of exact) {
|
|
6630
|
-
const resolved = await this.#firstExisting(
|
|
6871
|
+
const resolved = await this.#firstExisting(path23.resolve(this.#workspaceRoot, repl));
|
|
6631
6872
|
if (resolved)
|
|
6632
6873
|
return resolved;
|
|
6633
6874
|
}
|
|
@@ -6638,7 +6879,7 @@ class CssImportResolver {
|
|
|
6638
6879
|
const suffix = id.slice(prefix.length);
|
|
6639
6880
|
for (const repl of replacements) {
|
|
6640
6881
|
const replPath = repl.endsWith("/*") ? repl.slice(0, -1) : repl;
|
|
6641
|
-
const resolved = await this.#firstExisting(
|
|
6882
|
+
const resolved = await this.#firstExisting(path23.resolve(this.#workspaceRoot, replPath + suffix));
|
|
6642
6883
|
if (resolved)
|
|
6643
6884
|
return resolved;
|
|
6644
6885
|
}
|
|
@@ -6668,25 +6909,25 @@ class CssImportResolver {
|
|
|
6668
6909
|
try {
|
|
6669
6910
|
if (!await Bun.file(pkgPath).exists())
|
|
6670
6911
|
return null;
|
|
6671
|
-
const pkgDir =
|
|
6912
|
+
const pkgDir = path23.dirname(pkgPath);
|
|
6672
6913
|
const pkg = await Bun.file(pkgPath).json();
|
|
6673
6914
|
const subpath = id === pkgName ? "." : `.${id.slice(pkgName.length)}`;
|
|
6674
6915
|
const exportValue = pkg.exports?.[subpath];
|
|
6675
6916
|
const styleEntry = (typeof exportValue === "string" ? exportValue : exportValue?.style || exportValue?.import || exportValue?.default) || pkg.exports?.["."]?.style || pkg.style || "index.css";
|
|
6676
|
-
return await this.#firstExisting(
|
|
6917
|
+
return await this.#firstExisting(path23.resolve(pkgDir, styleEntry));
|
|
6677
6918
|
} catch {
|
|
6678
6919
|
return null;
|
|
6679
6920
|
}
|
|
6680
6921
|
}
|
|
6681
6922
|
#resolutionBases(fromBase) {
|
|
6682
|
-
return [fromBase, this.#workspaceRoot,
|
|
6923
|
+
return [fromBase, this.#workspaceRoot, path23.dirname(Bun.main), path23.resolve(path23.dirname(Bun.main), "../..")];
|
|
6683
6924
|
}
|
|
6684
6925
|
#packageJsonCandidates(pkgName) {
|
|
6685
6926
|
return [
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6927
|
+
path23.join(this.#workspaceRoot, "pkgs", pkgName, "package.json"),
|
|
6928
|
+
path23.join(this.#workspaceRoot, "node_modules", pkgName, "package.json"),
|
|
6929
|
+
path23.join(path23.dirname(Bun.main), "node_modules", pkgName, "package.json"),
|
|
6930
|
+
path23.join(path23.dirname(Bun.main), "../../", pkgName, "package.json")
|
|
6690
6931
|
];
|
|
6691
6932
|
}
|
|
6692
6933
|
async#firstExisting(basePath2) {
|
|
@@ -6704,7 +6945,7 @@ class CssImportResolver {
|
|
|
6704
6945
|
return parts[0] ?? null;
|
|
6705
6946
|
}
|
|
6706
6947
|
static isCssFile(filePath) {
|
|
6707
|
-
return
|
|
6948
|
+
return path23.extname(filePath) === ".css";
|
|
6708
6949
|
}
|
|
6709
6950
|
}
|
|
6710
6951
|
|
|
@@ -6771,7 +7012,7 @@ class CssCompiler {
|
|
|
6771
7012
|
pageKeys
|
|
6772
7013
|
} = {}) {
|
|
6773
7014
|
pageKeys ??= await this.#app.getPageKeys({ refresh });
|
|
6774
|
-
const seeds = pageKeys.map((key) =>
|
|
7015
|
+
const seeds = pageKeys.map((key) => path24.resolve(this.#app.cwdPath, "page", key));
|
|
6775
7016
|
const cssFiles = new Set;
|
|
6776
7017
|
const sourceFiles = new Set;
|
|
6777
7018
|
const queue = [...seeds];
|
|
@@ -6803,7 +7044,7 @@ class CssCompiler {
|
|
|
6803
7044
|
} catch {
|
|
6804
7045
|
continue;
|
|
6805
7046
|
}
|
|
6806
|
-
const importerDir =
|
|
7047
|
+
const importerDir = path24.dirname(filePath);
|
|
6807
7048
|
for (const imp of imports) {
|
|
6808
7049
|
const spec = imp.path;
|
|
6809
7050
|
if (!spec)
|
|
@@ -6829,7 +7070,7 @@ class CssCompiler {
|
|
|
6829
7070
|
const compileStarted = Date.now();
|
|
6830
7071
|
const compilers = await Promise.all(cssPaths.map(async (cssPath) => {
|
|
6831
7072
|
const css = await Bun.file(cssPath).text();
|
|
6832
|
-
const base =
|
|
7073
|
+
const base = path24.dirname(cssPath);
|
|
6833
7074
|
const compiler = await compile(css, {
|
|
6834
7075
|
base,
|
|
6835
7076
|
loadStylesheet: (id, fromBase) => this.#loadStylesheet(id, fromBase),
|
|
@@ -6860,11 +7101,11 @@ class CssCompiler {
|
|
|
6860
7101
|
async#loadStylesheet(id, fromBase) {
|
|
6861
7102
|
const p = await this.#resolveCssImport(id, fromBase);
|
|
6862
7103
|
const content = await Bun.file(p).text();
|
|
6863
|
-
return { path: p, base:
|
|
7104
|
+
return { path: p, base: path24.dirname(p), content };
|
|
6864
7105
|
}
|
|
6865
7106
|
async#resolveCssImport(id, fromBase) {
|
|
6866
7107
|
if (id.startsWith(".") || id.startsWith("/"))
|
|
6867
|
-
return
|
|
7108
|
+
return path24.resolve(fromBase, id);
|
|
6868
7109
|
const resolver = await this.#getCssImportResolver();
|
|
6869
7110
|
const resolved = await resolver.resolve(id, fromBase);
|
|
6870
7111
|
if (resolved)
|
|
@@ -6880,11 +7121,11 @@ class CssCompiler {
|
|
|
6880
7121
|
async#loadModule(id, fromBase) {
|
|
6881
7122
|
const p = __require.resolve(id, { paths: [fromBase] });
|
|
6882
7123
|
const mod = await import(p);
|
|
6883
|
-
return { path: p, base:
|
|
7124
|
+
return { path: p, base: path24.dirname(p), module: mod.default ?? mod };
|
|
6884
7125
|
}
|
|
6885
7126
|
async#resolveSourceImport(id, fromBase, resolvePackage) {
|
|
6886
7127
|
if (id.startsWith(".") || id.startsWith("/")) {
|
|
6887
|
-
const abs = id.startsWith("/") ? id :
|
|
7128
|
+
const abs = id.startsWith("/") ? id : path24.resolve(fromBase, id);
|
|
6888
7129
|
return resolveSourceFileCandidate(abs);
|
|
6889
7130
|
}
|
|
6890
7131
|
const pkg = await resolvePackage(id);
|
|
@@ -6926,7 +7167,7 @@ async function resolveSourceFileCandidate(absPathNoExt) {
|
|
|
6926
7167
|
return filePath;
|
|
6927
7168
|
}
|
|
6928
7169
|
for (const ext of SOURCE_EXTS3) {
|
|
6929
|
-
const filePath =
|
|
7170
|
+
const filePath = path24.join(absPathNoExt, `index${ext}`);
|
|
6930
7171
|
if (await Bun.file(filePath).exists())
|
|
6931
7172
|
return filePath;
|
|
6932
7173
|
}
|
|
@@ -6949,20 +7190,20 @@ function resolveSourceWithRequire(id, fromBase) {
|
|
|
6949
7190
|
}
|
|
6950
7191
|
}
|
|
6951
7192
|
function isSourceFile(filePath) {
|
|
6952
|
-
return SOURCE_EXTS3.includes(
|
|
7193
|
+
return SOURCE_EXTS3.includes(path24.extname(filePath));
|
|
6953
7194
|
}
|
|
6954
7195
|
function isIgnoredNodeModuleSource(filePath) {
|
|
6955
7196
|
return NODE_MODULES_RE3.test(filePath) && !AKANJS_NODE_MODULE_RE3.test(filePath);
|
|
6956
7197
|
}
|
|
6957
7198
|
function getPageKeyBasePath(pageKey, basePaths) {
|
|
6958
|
-
const normalized = pageKey.split(
|
|
7199
|
+
const normalized = pageKey.split(path24.sep).join("/").replace(/^\.\//, "");
|
|
6959
7200
|
const segments = normalized.split("/");
|
|
6960
7201
|
const firstPublicSegment = segments.find((segment) => segment !== "[lang]" && !/^\(.+\)$/.test(segment));
|
|
6961
7202
|
return firstPublicSegment && basePaths.includes(firstPublicSegment) ? firstPublicSegment : null;
|
|
6962
7203
|
}
|
|
6963
7204
|
// pkgs/@akanjs/devkit/frontendBuild/fontOptimizer.ts
|
|
6964
7205
|
import { mkdir as mkdir6 } from "fs/promises";
|
|
6965
|
-
import
|
|
7206
|
+
import path25 from "path";
|
|
6966
7207
|
import {
|
|
6967
7208
|
generateFontFace,
|
|
6968
7209
|
getMetricsForFamily,
|
|
@@ -6986,7 +7227,7 @@ class FontOptimizer {
|
|
|
6986
7227
|
constructor(app, command = "start") {
|
|
6987
7228
|
this.#app = app;
|
|
6988
7229
|
this.#command = command;
|
|
6989
|
-
this.#artifactRoot =
|
|
7230
|
+
this.#artifactRoot = path25.join(command === "build" ? app.dist.cwdPath : app.cwdPath, ".akan/artifact");
|
|
6990
7231
|
}
|
|
6991
7232
|
async optimize() {
|
|
6992
7233
|
const fonts = await this.discoverFonts();
|
|
@@ -7005,7 +7246,7 @@ class FontOptimizer {
|
|
|
7005
7246
|
const pageKeys = await this.#app.getPageKeys();
|
|
7006
7247
|
const fonts = [];
|
|
7007
7248
|
await Promise.all(pageKeys.map(async (key) => {
|
|
7008
|
-
const filePath =
|
|
7249
|
+
const filePath = path25.resolve(this.#app.cwdPath, "page", key);
|
|
7009
7250
|
const file = Bun.file(filePath);
|
|
7010
7251
|
if (!await file.exists())
|
|
7011
7252
|
return;
|
|
@@ -7021,8 +7262,8 @@ class FontOptimizer {
|
|
|
7021
7262
|
this.#app.logger.warn(`[font] source not found: ${face.src}`);
|
|
7022
7263
|
continue;
|
|
7023
7264
|
}
|
|
7024
|
-
const outputPath =
|
|
7025
|
-
await mkdir6(
|
|
7265
|
+
const outputPath = path25.join(this.#artifactRoot, face.optimizedSrc.replace(/^\/_akan\//, ""));
|
|
7266
|
+
await mkdir6(path25.dirname(outputPath), { recursive: true });
|
|
7026
7267
|
const sourceBuffer = Buffer.from(await Bun.file(sourcePath).arrayBuffer());
|
|
7027
7268
|
const outputBuffer = font.subset === false ? await this.#convertToWoff2(sourceBuffer, sourcePath) : await subsetFont(sourceBuffer, await this.#getSubsetText(font), { targetFormat: "woff2" });
|
|
7028
7269
|
await Bun.write(outputPath, outputBuffer);
|
|
@@ -7169,8 +7410,8 @@ class FontOptimizer {
|
|
|
7169
7410
|
return null;
|
|
7170
7411
|
const rel = src.replace(/^\//, "");
|
|
7171
7412
|
const candidates = [
|
|
7172
|
-
this.#command === "build" ?
|
|
7173
|
-
|
|
7413
|
+
this.#command === "build" ? path25.join(this.#app.dist.cwdPath, "public", rel) : null,
|
|
7414
|
+
path25.join(this.#app.cwdPath, "public", rel),
|
|
7174
7415
|
this.#resolveWorkspacePublicPath(rel)
|
|
7175
7416
|
].filter(Boolean);
|
|
7176
7417
|
for (const candidate of candidates) {
|
|
@@ -7198,7 +7439,7 @@ class FontOptimizer {
|
|
|
7198
7439
|
return "woff2";
|
|
7199
7440
|
if (signature === "OTTO")
|
|
7200
7441
|
return "otf";
|
|
7201
|
-
const ext =
|
|
7442
|
+
const ext = path25.extname(sourcePath).slice(1).toLowerCase();
|
|
7202
7443
|
if (ext === "otf" || ext === "woff" || ext === "woff2")
|
|
7203
7444
|
return ext;
|
|
7204
7445
|
return "ttf";
|
|
@@ -7207,7 +7448,7 @@ class FontOptimizer {
|
|
|
7207
7448
|
const [root, dep, ...rest] = rel.split("/");
|
|
7208
7449
|
if (root !== "libs" || !dep || rest.length === 0)
|
|
7209
7450
|
return null;
|
|
7210
|
-
return
|
|
7451
|
+
return path25.join(this.#app.workspace.workspaceRoot, "libs", dep, "public", ...rest);
|
|
7211
7452
|
}
|
|
7212
7453
|
async#getSubsetText(font) {
|
|
7213
7454
|
const parts = new Set;
|
|
@@ -7217,7 +7458,7 @@ class FontOptimizer {
|
|
|
7217
7458
|
if (font.subsetText)
|
|
7218
7459
|
parts.add(font.subsetText);
|
|
7219
7460
|
for (const filePath of font.subsetFiles ?? []) {
|
|
7220
|
-
const abs =
|
|
7461
|
+
const abs = path25.isAbsolute(filePath) ? filePath : path25.join(this.#app.cwdPath, filePath);
|
|
7221
7462
|
const file = Bun.file(abs);
|
|
7222
7463
|
if (await file.exists())
|
|
7223
7464
|
parts.add(await file.text());
|
|
@@ -7236,7 +7477,7 @@ class FontOptimizer {
|
|
|
7236
7477
|
return "";
|
|
7237
7478
|
}
|
|
7238
7479
|
async#collectAutoSubsetText() {
|
|
7239
|
-
const roots = ["page", "ui"].map((dir) =>
|
|
7480
|
+
const roots = ["page", "ui"].map((dir) => path25.join(this.#app.cwdPath, dir));
|
|
7240
7481
|
const glob = new Bun.Glob("**/*.{ts,tsx,js,jsx,html,md}");
|
|
7241
7482
|
const parts = [];
|
|
7242
7483
|
await Promise.all(roots.map(async (root) => {
|
|
@@ -7350,7 +7591,7 @@ ${declarations.map(([prop, value]) => ` ${prop}: ${value};`).join(`
|
|
|
7350
7591
|
}
|
|
7351
7592
|
}
|
|
7352
7593
|
// pkgs/@akanjs/devkit/frontendBuild/hmrChangeClassifier.ts
|
|
7353
|
-
import
|
|
7594
|
+
import path26 from "path";
|
|
7354
7595
|
var SOURCE_EXTS4 = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
7355
7596
|
var CSS_EXTS = new Set([".css"]);
|
|
7356
7597
|
var CONFIG_BASENAMES = new Set(["akan.config.ts", "bunfig.toml", "tsconfig.json", "package.json"]);
|
|
@@ -7359,10 +7600,10 @@ class HmrChangeClassifier {
|
|
|
7359
7600
|
classify(abs) {
|
|
7360
7601
|
if (this.#isUninteresting(abs))
|
|
7361
7602
|
return "ignore";
|
|
7362
|
-
const base =
|
|
7603
|
+
const base = path26.basename(abs);
|
|
7363
7604
|
if (CONFIG_BASENAMES.has(base))
|
|
7364
7605
|
return "config";
|
|
7365
|
-
const ext =
|
|
7606
|
+
const ext = path26.extname(abs).toLowerCase();
|
|
7366
7607
|
if (CSS_EXTS.has(ext))
|
|
7367
7608
|
return "css";
|
|
7368
7609
|
if (SOURCE_EXTS4.has(ext))
|
|
@@ -7370,23 +7611,23 @@ class HmrChangeClassifier {
|
|
|
7370
7611
|
return "ignore";
|
|
7371
7612
|
}
|
|
7372
7613
|
#isUninteresting(abs) {
|
|
7373
|
-
const base =
|
|
7614
|
+
const base = path26.basename(abs);
|
|
7374
7615
|
if (!base)
|
|
7375
7616
|
return true;
|
|
7376
7617
|
if (base.startsWith("."))
|
|
7377
7618
|
return true;
|
|
7378
7619
|
if (base.endsWith("~") || base.endsWith(".swp") || base.endsWith(".swx") || base.endsWith(".tmp"))
|
|
7379
7620
|
return true;
|
|
7380
|
-
if (abs.includes(`${
|
|
7621
|
+
if (abs.includes(`${path26.sep}node_modules${path26.sep}`))
|
|
7381
7622
|
return true;
|
|
7382
|
-
if (abs.includes(`${
|
|
7623
|
+
if (abs.includes(`${path26.sep}.akan${path26.sep}`))
|
|
7383
7624
|
return true;
|
|
7384
7625
|
return false;
|
|
7385
7626
|
}
|
|
7386
7627
|
}
|
|
7387
7628
|
// pkgs/@akanjs/devkit/frontendBuild/hmrWatcher.ts
|
|
7388
7629
|
import fs4 from "fs";
|
|
7389
|
-
import
|
|
7630
|
+
import path27 from "path";
|
|
7390
7631
|
class HmrWatcher {
|
|
7391
7632
|
#roots;
|
|
7392
7633
|
#debounceMs;
|
|
@@ -7399,7 +7640,7 @@ class HmrWatcher {
|
|
|
7399
7640
|
#stopped = false;
|
|
7400
7641
|
#flushing = false;
|
|
7401
7642
|
constructor(opts) {
|
|
7402
|
-
this.#roots = [...new Set(opts.roots.map((r) =>
|
|
7643
|
+
this.#roots = [...new Set(opts.roots.map((r) => path27.resolve(r)))];
|
|
7403
7644
|
this.#debounceMs = opts.debounceMs ?? 80;
|
|
7404
7645
|
this.#onBatch = opts.onBatch;
|
|
7405
7646
|
this.#logger = opts.logger;
|
|
@@ -7410,7 +7651,7 @@ class HmrWatcher {
|
|
|
7410
7651
|
const w = fs4.watch(root, { recursive: true, persistent: false }, (_event, filename) => {
|
|
7411
7652
|
if (!filename)
|
|
7412
7653
|
return;
|
|
7413
|
-
const abs =
|
|
7654
|
+
const abs = path27.resolve(root, filename.toString());
|
|
7414
7655
|
this.#queue(abs);
|
|
7415
7656
|
});
|
|
7416
7657
|
this.#watchers.push(w);
|
|
@@ -7468,10 +7709,10 @@ class HmrWatcher {
|
|
|
7468
7709
|
}
|
|
7469
7710
|
}
|
|
7470
7711
|
// pkgs/@akanjs/devkit/frontendBuild/pagesBundleBuilder.ts
|
|
7471
|
-
import
|
|
7712
|
+
import path29 from "path";
|
|
7472
7713
|
|
|
7473
7714
|
// pkgs/@akanjs/devkit/transforms/externalizeFrameworkPlugin.ts
|
|
7474
|
-
import
|
|
7715
|
+
import path28 from "path";
|
|
7475
7716
|
var DEFAULT_INCLUDE = ["akanjs/", "@apps/", "@libs/"];
|
|
7476
7717
|
var DEFAULT_EXCLUDE_EXACT = new Set(["akanjs/webkit", "akanjs/server", "@akanjs/cli", "@akanjs/devkit"]);
|
|
7477
7718
|
var DEFAULT_EXCLUDE_PREFIX = ["akanjs/server/", "@akanjs/cli/", "@akanjs/devkit/"];
|
|
@@ -7506,7 +7747,7 @@ async function createExternalizeFrameworkPlugin(options) {
|
|
|
7506
7747
|
const replPath = repl?.endsWith("/*") ? repl.slice(0, -1) : repl ?? "";
|
|
7507
7748
|
if (!replPath)
|
|
7508
7749
|
continue;
|
|
7509
|
-
const candidate =
|
|
7750
|
+
const candidate = path28.resolve(workspaceRoot, replPath + suffix);
|
|
7510
7751
|
const hit = await firstExisting(candidate);
|
|
7511
7752
|
if (hit)
|
|
7512
7753
|
return hit;
|
|
@@ -7518,8 +7759,8 @@ async function createExternalizeFrameworkPlugin(options) {
|
|
|
7518
7759
|
if (spec === pkg)
|
|
7519
7760
|
continue;
|
|
7520
7761
|
const suffix = spec.slice(pkg.length + 1);
|
|
7521
|
-
const pkgDir =
|
|
7522
|
-
const candidate =
|
|
7762
|
+
const pkgDir = path28.dirname(path28.resolve(workspaceRoot, entryFile));
|
|
7763
|
+
const candidate = path28.join(pkgDir, suffix);
|
|
7523
7764
|
const hit = await firstExisting(candidate);
|
|
7524
7765
|
if (hit)
|
|
7525
7766
|
return hit;
|
|
@@ -7567,7 +7808,7 @@ async function firstExisting(basePath2) {
|
|
|
7567
7808
|
return candidate;
|
|
7568
7809
|
}
|
|
7569
7810
|
for (const ext of CANDIDATE_EXTS3) {
|
|
7570
|
-
const candidate =
|
|
7811
|
+
const candidate = path28.join(basePath2, `index${ext}`);
|
|
7571
7812
|
if (await Bun.file(candidate).exists())
|
|
7572
7813
|
return candidate;
|
|
7573
7814
|
}
|
|
@@ -7656,11 +7897,11 @@ class PagesBundleBuilder {
|
|
|
7656
7897
|
const entryArtifact = result.outputs.find((a) => a.kind === "entry-point");
|
|
7657
7898
|
if (!entryArtifact)
|
|
7658
7899
|
throw new Error("[PagesBundleBuilder] Bun.build emitted no entry-point artifact");
|
|
7659
|
-
const bundlePath =
|
|
7900
|
+
const bundlePath = path29.resolve(entryArtifact.path);
|
|
7660
7901
|
const buildId = Date.now();
|
|
7661
7902
|
const outputBytes = result.outputs.reduce((sum, output) => sum + output.size, 0);
|
|
7662
7903
|
const chunkCount = result.outputs.filter((output) => output.kind === "chunk").length;
|
|
7663
|
-
this.#app.verbose(`[PagesBundleBuilder] ${
|
|
7904
|
+
this.#app.verbose(`[PagesBundleBuilder] ${path29.basename(bundlePath)} emitted in ${Date.now() - this.#started}ms splitting=${this.#splitting} entry=${entryArtifact.size} bytes outputs=${result.outputs.length} chunks=${chunkCount} total=${outputBytes} bytes`);
|
|
7664
7905
|
return {
|
|
7665
7906
|
bundlePath,
|
|
7666
7907
|
buildId,
|
|
@@ -7703,11 +7944,11 @@ class PagesBundleBuilder {
|
|
|
7703
7944
|
}
|
|
7704
7945
|
// pkgs/@akanjs/devkit/frontendBuild/precompressArtifacts.ts
|
|
7705
7946
|
import fs5 from "fs";
|
|
7706
|
-
import
|
|
7947
|
+
import path30 from "path";
|
|
7707
7948
|
var COMPRESSIBLE_EXTS = new Set([".css", ".html", ".js", ".json", ".svg"]);
|
|
7708
7949
|
var MIN_COMPRESS_BYTES = 1024;
|
|
7709
7950
|
async function precompressArtifacts(app) {
|
|
7710
|
-
const roots = [
|
|
7951
|
+
const roots = [path30.join(app.dist.cwdPath, ".akan/artifact/client")];
|
|
7711
7952
|
const result = { files: 0, inputBytes: 0, outputBytes: 0 };
|
|
7712
7953
|
await Promise.all(roots.map((root) => precompressRoot(root, result)));
|
|
7713
7954
|
if (result.files > 0) {
|
|
@@ -7733,7 +7974,7 @@ async function precompressRoot(root, result) {
|
|
|
7733
7974
|
async function shouldPrecompress(filePath) {
|
|
7734
7975
|
if (filePath.endsWith(".gz"))
|
|
7735
7976
|
return false;
|
|
7736
|
-
if (!COMPRESSIBLE_EXTS.has(
|
|
7977
|
+
if (!COMPRESSIBLE_EXTS.has(path30.extname(filePath).toLowerCase()))
|
|
7737
7978
|
return false;
|
|
7738
7979
|
const file = Bun.file(filePath);
|
|
7739
7980
|
if (!await file.exists())
|
|
@@ -7751,7 +7992,7 @@ function formatBytes(bytes) {
|
|
|
7751
7992
|
return `${(bytes / 1024 / 1024).toFixed(1)}MB`;
|
|
7752
7993
|
}
|
|
7753
7994
|
// pkgs/@akanjs/devkit/frontendBuild/ssrBaseArtifactBuilder.ts
|
|
7754
|
-
import
|
|
7995
|
+
import path31 from "path";
|
|
7755
7996
|
import { optimize } from "@tailwindcss/node";
|
|
7756
7997
|
function prepareCssAsset(command, basePath2, cssText) {
|
|
7757
7998
|
return optimize(cssText, { file: `${basePath2 || "root"}.css`, minify: command === "build" }).code;
|
|
@@ -7767,7 +8008,7 @@ class SsrBaseArtifactBuilder {
|
|
|
7767
8008
|
this.#app = app;
|
|
7768
8009
|
this.#command = command;
|
|
7769
8010
|
this.#artifactDir = `${command === "build" ? app.dist.cwdPath : app.cwdPath}/.akan/artifact`;
|
|
7770
|
-
this.#absArtifactDir =
|
|
8011
|
+
this.#absArtifactDir = path31.resolve(this.#artifactDir);
|
|
7771
8012
|
}
|
|
7772
8013
|
async build() {
|
|
7773
8014
|
const akanConfig2 = await this.#app.getConfig();
|
|
@@ -7787,7 +8028,7 @@ class SsrBaseArtifactBuilder {
|
|
|
7787
8028
|
rscClientUrl,
|
|
7788
8029
|
vendorMap,
|
|
7789
8030
|
cssAssets,
|
|
7790
|
-
pagesBundlePath: this.#command === "build" ?
|
|
8031
|
+
pagesBundlePath: this.#command === "build" ? path31.relative(this.#absArtifactDir, pagesBundle.bundlePath) : pagesBundle.bundlePath,
|
|
7791
8032
|
pagesBundleBuildId: pagesBundle.buildId,
|
|
7792
8033
|
domains: [...akanConfig2.domains],
|
|
7793
8034
|
subRoutes: Object.fromEntries(Array.from(akanConfig2.subRoutes.entries()).map(([basePath2, domains]) => [basePath2, [...domains]])),
|
|
@@ -7796,7 +8037,7 @@ class SsrBaseArtifactBuilder {
|
|
|
7796
8037
|
i18n: akanConfig2.i18n,
|
|
7797
8038
|
imageConfig: akanConfig2.images
|
|
7798
8039
|
};
|
|
7799
|
-
await Bun.write(
|
|
8040
|
+
await Bun.write(path31.join(this.#absArtifactDir, "base-artifact.json"), `${JSON.stringify(artifact, null, 2)}
|
|
7800
8041
|
`);
|
|
7801
8042
|
this.#app.verbose(`[base-artifact] complete in ${Date.now() - this.#started}ms`);
|
|
7802
8043
|
return { artifact, seedIndex, cssCompiler, optimizedFonts };
|
|
@@ -7818,15 +8059,15 @@ class SsrBaseArtifactBuilder {
|
|
|
7818
8059
|
async#resolveAkanServerPath() {
|
|
7819
8060
|
const candidates = [];
|
|
7820
8061
|
try {
|
|
7821
|
-
candidates.push(
|
|
8062
|
+
candidates.push(path31.dirname(Bun.resolveSync("akanjs/server", this.#app.workspace.workspaceRoot)));
|
|
7822
8063
|
} catch {}
|
|
7823
|
-
candidates.push(
|
|
8064
|
+
candidates.push(path31.join(this.#app.workspace.workspaceRoot, "pkgs/akanjs/server"), path31.join(this.#app.workspace.workspaceRoot, "node_modules/akanjs/server"));
|
|
7824
8065
|
try {
|
|
7825
|
-
candidates.push(
|
|
8066
|
+
candidates.push(path31.dirname(Bun.resolveSync("akanjs/server", path31.dirname(Bun.main))));
|
|
7826
8067
|
} catch {}
|
|
7827
|
-
candidates.push(
|
|
8068
|
+
candidates.push(path31.join(path31.dirname(Bun.main), "node_modules/akanjs/server"), path31.join(path31.dirname(Bun.main), "../../akanjs/server"), path31.resolve(import.meta.dir, "../../server"), path31.resolve(import.meta.dir, "../server"));
|
|
7828
8069
|
for (const candidate of candidates) {
|
|
7829
|
-
if (await Bun.file(
|
|
8070
|
+
if (await Bun.file(path31.join(candidate, "rscClient.tsx")).exists())
|
|
7830
8071
|
return candidate;
|
|
7831
8072
|
}
|
|
7832
8073
|
throw new Error(`[base-artifact] failed to locate akanjs/server; looked in: ${candidates.join(", ")}`);
|
|
@@ -7855,14 +8096,14 @@ ${preparedCssText}`).toString(36);
|
|
|
7855
8096
|
`styles/${cssAssetName}-${cssHash}.css`,
|
|
7856
8097
|
`/_akan/styles/${cssAssetName}-${cssHash}.css`
|
|
7857
8098
|
];
|
|
7858
|
-
await Bun.write(
|
|
8099
|
+
await Bun.write(path31.join(this.#absArtifactDir, cssRelPath), preparedCssText);
|
|
7859
8100
|
this.#app.verbose(`[base-artifact] wrote ${preparedCssText.length} bytes of CSS for ${basePath2} -> ${cssRelPath}`);
|
|
7860
8101
|
return [basePath2, { cssUrl, cssRelPath }];
|
|
7861
8102
|
}
|
|
7862
8103
|
}
|
|
7863
8104
|
// pkgs/@akanjs/devkit/frontendBuild/watchRootResolver.ts
|
|
7864
8105
|
import fs6 from "fs";
|
|
7865
|
-
import
|
|
8106
|
+
import path32 from "path";
|
|
7866
8107
|
|
|
7867
8108
|
class WatchRootResolver {
|
|
7868
8109
|
#app;
|
|
@@ -7872,15 +8113,15 @@ class WatchRootResolver {
|
|
|
7872
8113
|
async resolve() {
|
|
7873
8114
|
const tsconfig = await this.#app.getTsConfig();
|
|
7874
8115
|
const set = new Set;
|
|
7875
|
-
set.add(
|
|
8116
|
+
set.add(path32.resolve(`${this.#app.cwdPath}/page`));
|
|
7876
8117
|
for (const targets of Object.values(tsconfig.compilerOptions.paths ?? {})) {
|
|
7877
8118
|
for (const target of targets) {
|
|
7878
8119
|
if (!target)
|
|
7879
8120
|
continue;
|
|
7880
|
-
if (
|
|
8121
|
+
if (path32.isAbsolute(target))
|
|
7881
8122
|
continue;
|
|
7882
8123
|
const cleaned = target.replace(/\/?\*+.*$/, "").replace(/\/[^/]+\.[^/]+$/, "");
|
|
7883
|
-
const resolved =
|
|
8124
|
+
const resolved = path32.resolve(this.#app.workspace.workspaceRoot, cleaned);
|
|
7884
8125
|
if (fs6.existsSync(resolved))
|
|
7885
8126
|
set.add(resolved);
|
|
7886
8127
|
}
|
|
@@ -7947,7 +8188,7 @@ class ApplicationBuildRunner {
|
|
|
7947
8188
|
phases: this.#phases,
|
|
7948
8189
|
durationMs: Date.now() - this.#startedAt,
|
|
7949
8190
|
outputDir: this.#app.dist.cwdPath,
|
|
7950
|
-
artifactDir:
|
|
8191
|
+
artifactDir: path33.join(this.#app.dist.cwdPath, ".akan/artifact")
|
|
7951
8192
|
};
|
|
7952
8193
|
}
|
|
7953
8194
|
async typecheck(options = {}) {
|
|
@@ -7955,7 +8196,7 @@ class ApplicationBuildRunner {
|
|
|
7955
8196
|
await this.#app.getPageKeys({ refresh: true });
|
|
7956
8197
|
const { typecheckDir, tsconfigPath } = await this.#writeTypecheckTsconfig({ incremental });
|
|
7957
8198
|
if (clean)
|
|
7958
|
-
await rm2(
|
|
8199
|
+
await rm2(path33.join(typecheckDir, "tsconfig.tsbuildinfo"), { force: true });
|
|
7959
8200
|
await this.#checkProjectInChildProcess(tsconfigPath);
|
|
7960
8201
|
}
|
|
7961
8202
|
async#runPhase(id, label, task, summarize, options = {}) {
|
|
@@ -7998,6 +8239,7 @@ class ApplicationBuildRunner {
|
|
|
7998
8239
|
outdir: this.#app.dist.cwdPath,
|
|
7999
8240
|
target: "bun",
|
|
8000
8241
|
minify: true,
|
|
8242
|
+
naming: { entry: "[name].[ext]", chunk: "chunk-[hash].[ext]" },
|
|
8001
8243
|
define: { "process.env.NODE_ENV": JSON.stringify("production") },
|
|
8002
8244
|
plugins: backendExternals.length > 0 ? [this.#createExternalSpecifiersPlugin(backendExternals)] : []
|
|
8003
8245
|
});
|
|
@@ -8011,16 +8253,52 @@ class ApplicationBuildRunner {
|
|
|
8011
8253
|
define: { "process.env.NODE_ENV": JSON.stringify("production") },
|
|
8012
8254
|
plugins: backendExternals.length > 0 ? [this.#createExternalSpecifiersPlugin(backendExternals)] : []
|
|
8013
8255
|
});
|
|
8256
|
+
const consoleRuntimeResult = await this.#buildOrThrow("console-runtime", {
|
|
8257
|
+
entrypoints: [this.#resolveConsoleRuntimeBuildEntry()],
|
|
8258
|
+
outdir: this.#app.dist.cwdPath,
|
|
8259
|
+
target: "bun",
|
|
8260
|
+
minify: true,
|
|
8261
|
+
naming: { entry: "console-runtime.[ext]", chunk: "chunk-[hash].[ext]" },
|
|
8262
|
+
define: { "process.env.NODE_ENV": JSON.stringify("production") }
|
|
8263
|
+
});
|
|
8264
|
+
await this.#writeConsoleShim();
|
|
8014
8265
|
return {
|
|
8015
|
-
entrypoints: backendEntryPoints.length +
|
|
8016
|
-
outputs: backendResult.outputs.length + rscWorkerResult.outputs.length
|
|
8266
|
+
entrypoints: backendEntryPoints.length + 2,
|
|
8267
|
+
outputs: backendResult.outputs.length + rscWorkerResult.outputs.length + consoleRuntimeResult.outputs.length + 1
|
|
8017
8268
|
};
|
|
8018
8269
|
}
|
|
8270
|
+
async#writeConsoleShim() {
|
|
8271
|
+
await Bun.write(path33.join(this.#app.dist.cwdPath, "console.js"), `import { cnst, db, dict, option, server, sig, srv } from "./server.js";
|
|
8272
|
+
import { assertAkanConsoleAllowed, startAkanConsole } from "./console-runtime.js";
|
|
8273
|
+
|
|
8274
|
+
const run = async () => {
|
|
8275
|
+
assertAkanConsoleAllowed(server.env);
|
|
8276
|
+
await server.start({ listen: false, web: false });
|
|
8277
|
+
try {
|
|
8278
|
+
await startAkanConsole(server, { globals: { cnst, db, dict, option, sig, srv } });
|
|
8279
|
+
} finally {
|
|
8280
|
+
await server.stop();
|
|
8281
|
+
}
|
|
8282
|
+
};
|
|
8283
|
+
|
|
8284
|
+
void run().catch((error) => {
|
|
8285
|
+
console.error(error);
|
|
8286
|
+
process.exit(1);
|
|
8287
|
+
});
|
|
8288
|
+
`);
|
|
8289
|
+
}
|
|
8019
8290
|
#resolveRscWorkerBuildEntry() {
|
|
8020
8291
|
try {
|
|
8021
8292
|
return Bun.resolveSync("akanjs/server/rsc-worker", import.meta.dir);
|
|
8022
8293
|
} catch {
|
|
8023
|
-
return
|
|
8294
|
+
return path33.join(this.#app.workspace.workspaceRoot, "pkgs/akanjs/server/rscWorker.tsx");
|
|
8295
|
+
}
|
|
8296
|
+
}
|
|
8297
|
+
#resolveConsoleRuntimeBuildEntry() {
|
|
8298
|
+
try {
|
|
8299
|
+
return path33.join(path33.dirname(Bun.resolveSync("akanjs/server", import.meta.dir)), "console.ts");
|
|
8300
|
+
} catch {
|
|
8301
|
+
return path33.join(this.#app.workspace.workspaceRoot, "pkgs/akanjs/server/console.ts");
|
|
8024
8302
|
}
|
|
8025
8303
|
}
|
|
8026
8304
|
async#buildCsr() {
|
|
@@ -8037,7 +8315,7 @@ class ApplicationBuildRunner {
|
|
|
8037
8315
|
return { base, allRoutes };
|
|
8038
8316
|
}
|
|
8039
8317
|
async#writeTypecheckTsconfig({ incremental = true } = {}) {
|
|
8040
|
-
const typecheckDir =
|
|
8318
|
+
const typecheckDir = path33.join(this.#app.cwdPath, ".akan", "typecheck");
|
|
8041
8319
|
await mkdir7(typecheckDir, { recursive: true });
|
|
8042
8320
|
const tsconfig = {
|
|
8043
8321
|
extends: "../../tsconfig.json",
|
|
@@ -8056,7 +8334,7 @@ class ApplicationBuildRunner {
|
|
|
8056
8334
|
],
|
|
8057
8335
|
references: []
|
|
8058
8336
|
};
|
|
8059
|
-
const tsconfigPath =
|
|
8337
|
+
const tsconfigPath = path33.join(typecheckDir, "tsconfig.json");
|
|
8060
8338
|
await Bun.write(tsconfigPath, `${JSON.stringify(tsconfig, null, 2)}
|
|
8061
8339
|
`);
|
|
8062
8340
|
return { typecheckDir, tsconfigPath };
|
|
@@ -8082,10 +8360,10 @@ class ApplicationBuildRunner {
|
|
|
8082
8360
|
}
|
|
8083
8361
|
async#resolveTypecheckWorkerEntry() {
|
|
8084
8362
|
const candidates = [
|
|
8085
|
-
|
|
8086
|
-
|
|
8087
|
-
|
|
8088
|
-
|
|
8363
|
+
path33.join(this.#app.workspace.workspaceRoot, "pkgs/@akanjs/devkit/typecheck/typecheck.proc.ts"),
|
|
8364
|
+
path33.join(this.#app.workspace.workspaceRoot, "node_modules/@akanjs/devkit/typecheck/typecheck.proc.ts"),
|
|
8365
|
+
path33.join(import.meta.dir, "typecheck.proc.js"),
|
|
8366
|
+
path33.join(import.meta.dir, "typecheck.proc.ts")
|
|
8089
8367
|
];
|
|
8090
8368
|
for (const candidate of candidates)
|
|
8091
8369
|
if (await Bun.file(candidate).exists())
|
|
@@ -8261,13 +8539,13 @@ class ApplicationReleasePackager {
|
|
|
8261
8539
|
await cp(this.#app.dist.cwdPath, `${sourceRoot}/apps/${this.#app.name}`, { recursive: true });
|
|
8262
8540
|
const libDeps = ["social", "shared", "platform", "util"];
|
|
8263
8541
|
await Promise.all(libDeps.map((lib) => cp(`${this.#app.workspace.cwdPath}/libs/${lib}`, `${sourceRoot}/libs/${lib}`, { recursive: true })));
|
|
8264
|
-
await Promise.all([".next", "ios", "android", "public/libs"].map(async (
|
|
8265
|
-
const targetPath = `${sourceRoot}/apps/${this.#app.name}/${
|
|
8542
|
+
await Promise.all([".next", "ios", "android", "public/libs"].map(async (path34) => {
|
|
8543
|
+
const targetPath = `${sourceRoot}/apps/${this.#app.name}/${path34}`;
|
|
8266
8544
|
if (await FileSys.dirExists(targetPath))
|
|
8267
8545
|
await rm3(targetPath, { recursive: true, force: true });
|
|
8268
8546
|
}));
|
|
8269
8547
|
const syncPaths = [".husky", ".gitignore", "package.json"];
|
|
8270
|
-
await Promise.all(syncPaths.map((
|
|
8548
|
+
await Promise.all(syncPaths.map((path34) => cp(`${this.#app.workspace.cwdPath}/${path34}`, `${sourceRoot}/${path34}`, { recursive: true })));
|
|
8271
8549
|
await this.#writeSourceTsconfig(sourceRoot, libDeps);
|
|
8272
8550
|
await Bun.write(`${sourceRoot}/README.md`, readme);
|
|
8273
8551
|
await this.#app.workspace.spawn("tar", [
|
|
@@ -8358,20 +8636,20 @@ class ApplicationReleasePackager {
|
|
|
8358
8636
|
}
|
|
8359
8637
|
}
|
|
8360
8638
|
// pkgs/@akanjs/devkit/applicationTestPreload.ts
|
|
8361
|
-
import
|
|
8639
|
+
import path34 from "path";
|
|
8362
8640
|
var SIGNAL_TEST_PRELOAD_PATH = "test/signalTest.preload.ts";
|
|
8363
8641
|
async function resolveSignalTestPreloadPath(target) {
|
|
8364
8642
|
const candidates = [];
|
|
8365
8643
|
const addResolvedPackageCandidate = (basePath2) => {
|
|
8366
8644
|
try {
|
|
8367
|
-
candidates.push(
|
|
8645
|
+
candidates.push(path34.join(path34.dirname(Bun.resolveSync("akanjs/package.json", basePath2)), SIGNAL_TEST_PRELOAD_PATH));
|
|
8368
8646
|
} catch {}
|
|
8369
8647
|
};
|
|
8370
8648
|
addResolvedPackageCandidate(target.cwdPath);
|
|
8371
8649
|
addResolvedPackageCandidate(process.cwd());
|
|
8372
|
-
addResolvedPackageCandidate(
|
|
8650
|
+
addResolvedPackageCandidate(path34.dirname(Bun.main));
|
|
8373
8651
|
addResolvedPackageCandidate(import.meta.dir);
|
|
8374
|
-
candidates.push(
|
|
8652
|
+
candidates.push(path34.join(target.cwdPath, "../../node_modules/akanjs", SIGNAL_TEST_PRELOAD_PATH), path34.join(target.cwdPath, "../../pkgs/akanjs", SIGNAL_TEST_PRELOAD_PATH), path34.join(process.cwd(), "node_modules/akanjs", SIGNAL_TEST_PRELOAD_PATH), path34.join(process.cwd(), "pkgs/akanjs", SIGNAL_TEST_PRELOAD_PATH), path34.join(path34.dirname(Bun.main), "../../akanjs", SIGNAL_TEST_PRELOAD_PATH), path34.resolve(import.meta.dir, "../../akanjs", SIGNAL_TEST_PRELOAD_PATH));
|
|
8375
8653
|
for (const candidate of [...new Set(candidates)]) {
|
|
8376
8654
|
if (await Bun.file(candidate).exists())
|
|
8377
8655
|
return candidate;
|
|
@@ -8381,7 +8659,7 @@ async function resolveSignalTestPreloadPath(target) {
|
|
|
8381
8659
|
// pkgs/@akanjs/devkit/builder.ts
|
|
8382
8660
|
import { existsSync as existsSync2 } from "fs";
|
|
8383
8661
|
import { mkdir as mkdir9 } from "fs/promises";
|
|
8384
|
-
import
|
|
8662
|
+
import path35 from "path";
|
|
8385
8663
|
var SKIP_ENTRY_DIR_SET = new Set(["node_modules", "dist", "build", ".git", ".next"]);
|
|
8386
8664
|
var assetExtensions = [".css", ".md", ".js", ".png", ".ico", ".svg", ".json", ".template"];
|
|
8387
8665
|
var assetLoader = Object.fromEntries(assetExtensions.map((ext) => [ext, "file"]));
|
|
@@ -8398,14 +8676,14 @@ class Builder {
|
|
|
8398
8676
|
#globEntrypoints(cwd, pattern) {
|
|
8399
8677
|
const glob = new Bun.Glob(pattern);
|
|
8400
8678
|
return Array.from(glob.scanSync({ cwd, onlyFiles: true })).filter((relativePath) => {
|
|
8401
|
-
const segments = relativePath.split(
|
|
8679
|
+
const segments = relativePath.split(path35.sep);
|
|
8402
8680
|
return !segments.some((segment) => SKIP_ENTRY_DIR_SET.has(segment));
|
|
8403
|
-
}).map((rel) =>
|
|
8681
|
+
}).map((rel) => path35.join(cwd, rel));
|
|
8404
8682
|
}
|
|
8405
8683
|
#globFiles(cwd, pattern = "**/*.*") {
|
|
8406
8684
|
const glob = new Bun.Glob(pattern);
|
|
8407
8685
|
return Array.from(glob.scanSync({ cwd, onlyFiles: true })).filter((relativePath) => {
|
|
8408
|
-
const segments = relativePath.split(
|
|
8686
|
+
const segments = relativePath.split(path35.sep);
|
|
8409
8687
|
return !segments.some((segment) => SKIP_ENTRY_DIR_SET.has(segment));
|
|
8410
8688
|
});
|
|
8411
8689
|
}
|
|
@@ -8413,17 +8691,17 @@ class Builder {
|
|
|
8413
8691
|
const out = [];
|
|
8414
8692
|
for (const p of additionalEntryPoints) {
|
|
8415
8693
|
if (p.includes("*")) {
|
|
8416
|
-
const rel = p.startsWith(`${cwd}/`) || p.startsWith(`${cwd}${
|
|
8694
|
+
const rel = p.startsWith(`${cwd}/`) || p.startsWith(`${cwd}${path35.sep}`) ? p.slice(cwd.length + 1) : p;
|
|
8417
8695
|
out.push(...this.#globEntrypoints(cwd, rel));
|
|
8418
8696
|
} else
|
|
8419
|
-
out.push(
|
|
8697
|
+
out.push(path35.isAbsolute(p) ? p : path35.join(cwd, p));
|
|
8420
8698
|
}
|
|
8421
8699
|
return out;
|
|
8422
8700
|
}
|
|
8423
8701
|
#getBuildOptions({ bundle = false, additionalEntryPoints = [] } = {}) {
|
|
8424
8702
|
const cwd = this.#executor.cwdPath;
|
|
8425
8703
|
const entrypoints = [
|
|
8426
|
-
...bundle ? [
|
|
8704
|
+
...bundle ? [path35.join(cwd, "index.ts")] : this.#globEntrypoints(cwd, "**/*.{ts,tsx}"),
|
|
8427
8705
|
...this.#resolveAdditionalEntrypoints(cwd, additionalEntryPoints)
|
|
8428
8706
|
];
|
|
8429
8707
|
return {
|
|
@@ -8444,9 +8722,9 @@ class Builder {
|
|
|
8444
8722
|
for (const relativePath of this.#globFiles(cwd)) {
|
|
8445
8723
|
if (relativePath === "package.json")
|
|
8446
8724
|
continue;
|
|
8447
|
-
const sourcePath =
|
|
8448
|
-
const targetPath =
|
|
8449
|
-
await mkdir9(
|
|
8725
|
+
const sourcePath = path35.join(cwd, relativePath);
|
|
8726
|
+
const targetPath = path35.join(this.#distExecutor.cwdPath, relativePath);
|
|
8727
|
+
await mkdir9(path35.dirname(targetPath), { recursive: true });
|
|
8450
8728
|
await Bun.write(targetPath, Bun.file(sourcePath));
|
|
8451
8729
|
}
|
|
8452
8730
|
}
|
|
@@ -8457,13 +8735,13 @@ class Builder {
|
|
|
8457
8735
|
return withoutFormatDir;
|
|
8458
8736
|
if (!hasDotSlash && withoutFormatDir === publishedPath)
|
|
8459
8737
|
return publishedPath;
|
|
8460
|
-
const parsed =
|
|
8738
|
+
const parsed = path35.posix.parse(withoutFormatDir);
|
|
8461
8739
|
if (![".js", ".mjs", ".cjs"].includes(parsed.ext))
|
|
8462
8740
|
return withoutFormatDir;
|
|
8463
|
-
const withoutExt =
|
|
8741
|
+
const withoutExt = path35.posix.join(parsed.dir, parsed.name);
|
|
8464
8742
|
const sourcePath = withoutExt.startsWith("./") ? withoutExt.slice(2) : withoutExt;
|
|
8465
8743
|
const sourceCandidates = [`${sourcePath}.ts`, `${sourcePath}.tsx`];
|
|
8466
|
-
const matchedSource = sourceCandidates.find((candidate) => existsSync2(
|
|
8744
|
+
const matchedSource = sourceCandidates.find((candidate) => existsSync2(path35.join(this.#executor.cwdPath, candidate)));
|
|
8467
8745
|
if (!matchedSource)
|
|
8468
8746
|
return withoutFormatDir;
|
|
8469
8747
|
return hasDotSlash ? `./${matchedSource}` : matchedSource;
|
|
@@ -8513,9 +8791,9 @@ class Builder {
|
|
|
8513
8791
|
}
|
|
8514
8792
|
// pkgs/@akanjs/devkit/capacitorApp.ts
|
|
8515
8793
|
import { cp as cp2, mkdir as mkdir10, rm as rm4 } from "fs/promises";
|
|
8516
|
-
import
|
|
8794
|
+
import path36 from "path";
|
|
8517
8795
|
import { MobileProject } from "@trapezedev/project";
|
|
8518
|
-
import { capitalize as
|
|
8796
|
+
import { capitalize as capitalize3 } from "akanjs/common";
|
|
8519
8797
|
|
|
8520
8798
|
// pkgs/@akanjs/devkit/fileEditor.ts
|
|
8521
8799
|
class FileEditor {
|
|
@@ -8708,10 +8986,10 @@ class CapacitorApp {
|
|
|
8708
8986
|
constructor(app, target) {
|
|
8709
8987
|
this.app = app;
|
|
8710
8988
|
this.target = target;
|
|
8711
|
-
this.targetRootPath =
|
|
8712
|
-
this.targetRoot =
|
|
8713
|
-
this.targetWebRoot =
|
|
8714
|
-
this.targetAssetRoot =
|
|
8989
|
+
this.targetRootPath = path36.posix.join(".akan", "mobile", this.target.name);
|
|
8990
|
+
this.targetRoot = path36.join(this.app.cwdPath, this.targetRootPath);
|
|
8991
|
+
this.targetWebRoot = path36.join(this.targetRoot, "www");
|
|
8992
|
+
this.targetAssetRoot = path36.join(this.targetRoot, "assets");
|
|
8715
8993
|
this.project = new MobileProject(this.app.cwdPath, {
|
|
8716
8994
|
android: { path: this.androidRootPath },
|
|
8717
8995
|
ios: { path: this.iosProjectPath }
|
|
@@ -8727,9 +9005,9 @@ class CapacitorApp {
|
|
|
8727
9005
|
await this.#writeCapacitorConfig();
|
|
8728
9006
|
if (regenerate) {
|
|
8729
9007
|
if (!platform || platform === "ios")
|
|
8730
|
-
await rm4(
|
|
9008
|
+
await rm4(path36.join(this.app.cwdPath, this.iosRootPath), { recursive: true, force: true });
|
|
8731
9009
|
if (!platform || platform === "android")
|
|
8732
|
-
await rm4(
|
|
9010
|
+
await rm4(path36.join(this.app.cwdPath, this.androidRootPath), { recursive: true, force: true });
|
|
8733
9011
|
}
|
|
8734
9012
|
const project = this.project;
|
|
8735
9013
|
await this.project.load();
|
|
@@ -8793,7 +9071,7 @@ class CapacitorApp {
|
|
|
8793
9071
|
await this.#spawnMobile("npx", ["cap", "sync", "android"], { operation, env });
|
|
8794
9072
|
}
|
|
8795
9073
|
async#updateAndroidBuildTypes() {
|
|
8796
|
-
const appGradle = await FileEditor.create(
|
|
9074
|
+
const appGradle = await FileEditor.create(path36.join(this.app.cwdPath, this.androidRootPath, "app/build.gradle"));
|
|
8797
9075
|
const buildTypesBlock = `
|
|
8798
9076
|
debug {
|
|
8799
9077
|
applicationIdSuffix ".debug"
|
|
@@ -8836,7 +9114,7 @@ class CapacitorApp {
|
|
|
8836
9114
|
const gradleCommand = isWindows ? "gradlew.bat" : "./gradlew";
|
|
8837
9115
|
await this.app.spawn(gradleCommand, [assembleType === "apk" ? "assembleRelease" : "bundleRelease"], {
|
|
8838
9116
|
stdio: "inherit",
|
|
8839
|
-
cwd:
|
|
9117
|
+
cwd: path36.join(this.app.cwdPath, this.androidRootPath),
|
|
8840
9118
|
env: await this.#commandEnv("release", env)
|
|
8841
9119
|
});
|
|
8842
9120
|
}
|
|
@@ -8844,10 +9122,10 @@ class CapacitorApp {
|
|
|
8844
9122
|
await this.#spawnMobile("npx", ["cap", "open", "android"], { operation: "local", env: "local" });
|
|
8845
9123
|
}
|
|
8846
9124
|
async#ensureAndroidAssetsDir() {
|
|
8847
|
-
await mkdir10(
|
|
9125
|
+
await mkdir10(path36.join(this.app.cwdPath, this.androidAssetsPath), { recursive: true });
|
|
8848
9126
|
}
|
|
8849
9127
|
async#ensureAndroidDebugKeystore() {
|
|
8850
|
-
const keystorePath =
|
|
9128
|
+
const keystorePath = path36.join(this.app.cwdPath, this.androidRootPath, "app/debug.keystore");
|
|
8851
9129
|
if (await Bun.file(keystorePath).exists())
|
|
8852
9130
|
return;
|
|
8853
9131
|
await this.#spawn("keytool", [
|
|
@@ -8893,12 +9171,12 @@ class CapacitorApp {
|
|
|
8893
9171
|
await this.#prepareAndroid({ operation: "release", env: "main" });
|
|
8894
9172
|
}
|
|
8895
9173
|
async prepareWww() {
|
|
8896
|
-
const htmlSource =
|
|
9174
|
+
const htmlSource = path36.join(this.app.dist.cwdPath, "csr", targetHtmlFilename(this.target));
|
|
8897
9175
|
if (!await Bun.file(htmlSource).exists())
|
|
8898
9176
|
throw new Error(`CSR html for mobile target '${this.target.name}' not found: ${htmlSource}`);
|
|
8899
9177
|
await rm4(this.targetWebRoot, { recursive: true, force: true });
|
|
8900
9178
|
await mkdir10(this.targetWebRoot, { recursive: true });
|
|
8901
|
-
await Bun.write(
|
|
9179
|
+
await Bun.write(path36.join(this.targetWebRoot, "index.html"), this.#injectMobileTargetMeta(await Bun.file(htmlSource).text()));
|
|
8902
9180
|
}
|
|
8903
9181
|
#injectMobileTargetMeta(html) {
|
|
8904
9182
|
const basePath2 = this.target.basePath?.replace(/^\/+|\/+$/g, "") ?? "";
|
|
@@ -8910,7 +9188,7 @@ class CapacitorApp {
|
|
|
8910
9188
|
}
|
|
8911
9189
|
async#writeCapacitorConfig() {
|
|
8912
9190
|
await mkdir10(this.targetRoot, { recursive: true });
|
|
8913
|
-
const appInfoPath =
|
|
9191
|
+
const appInfoPath = path36.relative(this.app.cwdPath, path36.join(this.app.cwdPath, "akan.app.json")).split(path36.sep).join("/");
|
|
8914
9192
|
const content = `import type { AppScanResult } from "akanjs";
|
|
8915
9193
|
import { withBase } from "${process.env.USE_AKANJS_PKGS === "true" ? "../../pkgs/" : ""}akanjs/capacitor.base.config";
|
|
8916
9194
|
import appInfo from "${appInfoPath.startsWith(".") ? appInfoPath : `./${appInfoPath}`}";
|
|
@@ -8931,18 +9209,18 @@ export default withBase(
|
|
|
8931
9209
|
appInfo as AppScanResult,
|
|
8932
9210
|
);
|
|
8933
9211
|
`;
|
|
8934
|
-
await Bun.write(
|
|
9212
|
+
await Bun.write(path36.join(this.app.cwdPath, "capacitor.config.ts"), content);
|
|
8935
9213
|
}
|
|
8936
9214
|
async#prepareTargetAssets() {
|
|
8937
9215
|
if (!this.target.assets)
|
|
8938
9216
|
return;
|
|
8939
9217
|
await mkdir10(this.targetAssetRoot, { recursive: true });
|
|
8940
9218
|
if (this.target.assets.icon)
|
|
8941
|
-
await cp2(
|
|
9219
|
+
await cp2(path36.join(this.app.cwdPath, this.target.assets.icon), path36.join(this.targetAssetRoot, "icon.png"), {
|
|
8942
9220
|
force: true
|
|
8943
9221
|
});
|
|
8944
9222
|
if (this.target.assets.splash)
|
|
8945
|
-
await cp2(
|
|
9223
|
+
await cp2(path36.join(this.app.cwdPath, this.target.assets.splash), path36.join(this.targetAssetRoot, "splash.png"), {
|
|
8946
9224
|
force: true
|
|
8947
9225
|
});
|
|
8948
9226
|
}
|
|
@@ -8950,11 +9228,11 @@ export default withBase(
|
|
|
8950
9228
|
const files = this.target.files?.[platform];
|
|
8951
9229
|
if (!files)
|
|
8952
9230
|
return;
|
|
8953
|
-
const platformRoot =
|
|
9231
|
+
const platformRoot = path36.join(this.app.cwdPath, platform === "ios" ? this.iosRootPath : this.androidRootPath);
|
|
8954
9232
|
await Promise.all(Object.entries(files).map(async ([to, from]) => {
|
|
8955
|
-
const targetPath =
|
|
8956
|
-
await mkdir10(
|
|
8957
|
-
await cp2(
|
|
9233
|
+
const targetPath = path36.join(platformRoot, to);
|
|
9234
|
+
await mkdir10(path36.dirname(targetPath), { recursive: true });
|
|
9235
|
+
await cp2(path36.join(this.app.cwdPath, from), targetPath, { force: true });
|
|
8958
9236
|
}));
|
|
8959
9237
|
}
|
|
8960
9238
|
async#generateAssets({ operation, env }) {
|
|
@@ -8964,7 +9242,7 @@ export default withBase(
|
|
|
8964
9242
|
"@capacitor/assets",
|
|
8965
9243
|
"generate",
|
|
8966
9244
|
"--assetPath",
|
|
8967
|
-
|
|
9245
|
+
path36.posix.join(this.targetRootPath, "assets"),
|
|
8968
9246
|
"--iosProject",
|
|
8969
9247
|
this.iosProjectPath,
|
|
8970
9248
|
"--androidProject",
|
|
@@ -9066,7 +9344,7 @@ export default withBase(
|
|
|
9066
9344
|
this.#setPermissionsInAndroid(["POST_NOTIFICATIONS"]);
|
|
9067
9345
|
}
|
|
9068
9346
|
async#setPermissionInIos(permissions) {
|
|
9069
|
-
const updateNs = Object.fromEntries(Object.entries(permissions).map(([key, value]) => [`NS${
|
|
9347
|
+
const updateNs = Object.fromEntries(Object.entries(permissions).map(([key, value]) => [`NS${capitalize3(key)}`, value]));
|
|
9070
9348
|
await Promise.all([
|
|
9071
9349
|
this.project.ios.updateInfoPlist(this.iosTargetName, "Debug", updateNs),
|
|
9072
9350
|
this.project.ios.updateInfoPlist(this.iosTargetName, "Release", updateNs)
|
|
@@ -9151,15 +9429,15 @@ var Pkg = createInternalArgToken("Pkg");
|
|
|
9151
9429
|
var Module = createInternalArgToken("Module");
|
|
9152
9430
|
var Workspace = createInternalArgToken("Workspace");
|
|
9153
9431
|
// pkgs/@akanjs/devkit/commandDecorators/command.ts
|
|
9154
|
-
import
|
|
9432
|
+
import path37 from "path";
|
|
9155
9433
|
import { confirm, input as input2, select as select2 } from "@inquirer/prompts";
|
|
9156
9434
|
import { Logger as Logger10 } from "akanjs/common";
|
|
9157
9435
|
import chalk6 from "chalk";
|
|
9158
9436
|
import { program } from "commander";
|
|
9159
9437
|
|
|
9160
9438
|
// pkgs/@akanjs/devkit/commandDecorators/dependencyBuilder.ts
|
|
9161
|
-
var
|
|
9162
|
-
var createDependencyKey = (refName, kind) => `${refName}${
|
|
9439
|
+
var capitalize4 = (value) => value.slice(0, 1).toUpperCase() + value.slice(1);
|
|
9440
|
+
var createDependencyKey = (refName, kind) => `${refName}${capitalize4(kind)}`;
|
|
9163
9441
|
|
|
9164
9442
|
class CommandContainer {
|
|
9165
9443
|
static #instances = new Map;
|
|
@@ -9651,7 +9929,7 @@ var runCommands = async (...commands) => {
|
|
|
9651
9929
|
process.exit(1);
|
|
9652
9930
|
});
|
|
9653
9931
|
const __dirname2 = getDirname(import.meta.url);
|
|
9654
|
-
const packageJsonCandidates = [`${
|
|
9932
|
+
const packageJsonCandidates = [`${path37.dirname(Bun.main)}/package.json`, `${__dirname2}/../package.json`];
|
|
9655
9933
|
let cliPackageJson = null;
|
|
9656
9934
|
for (const packageJsonPath of packageJsonCandidates) {
|
|
9657
9935
|
if (!await FileSys.fileExists(packageJsonPath))
|
|
@@ -9927,8 +10205,8 @@ var scanModuleSpecifiers = (source, filePath, includeExports) => {
|
|
|
9927
10205
|
return importSpecifiers;
|
|
9928
10206
|
};
|
|
9929
10207
|
var parseTsConfig = (tsConfigPath = "./tsconfig.json") => {
|
|
9930
|
-
const configFile = ts7.readConfigFile(tsConfigPath, (
|
|
9931
|
-
return ts7.sys.readFile(
|
|
10208
|
+
const configFile = ts7.readConfigFile(tsConfigPath, (path38) => {
|
|
10209
|
+
return ts7.sys.readFile(path38);
|
|
9932
10210
|
});
|
|
9933
10211
|
return ts7.parseJsonConfigFileContent(configFile.config, ts7.sys, realpathSync(tsConfigPath).replace(/[^/\\]+$/, ""));
|
|
9934
10212
|
};
|
|
@@ -10077,10 +10355,7 @@ import { input as input3, select as select3 } from "@inquirer/prompts";
|
|
|
10077
10355
|
class Prompter {
|
|
10078
10356
|
static async#getGuidelineRoot() {
|
|
10079
10357
|
const dirname2 = getDirname(import.meta.url);
|
|
10080
|
-
const candidates = [
|
|
10081
|
-
`${dirname2}/guidelines`,
|
|
10082
|
-
`${dirname2}/../cli/guidelines`
|
|
10083
|
-
];
|
|
10358
|
+
const candidates = [`${dirname2}/guidelines`, `${dirname2}/../cli/guidelines`];
|
|
10084
10359
|
for (const candidate of candidates) {
|
|
10085
10360
|
try {
|
|
10086
10361
|
await fsPromise.access(candidate);
|
|
@@ -10091,12 +10366,16 @@ class Prompter {
|
|
|
10091
10366
|
}
|
|
10092
10367
|
static async selectGuideline() {
|
|
10093
10368
|
const guidelineRoot = await Prompter.#getGuidelineRoot();
|
|
10094
|
-
const guideNames =
|
|
10369
|
+
const guideNames = await Prompter.listGuidelines();
|
|
10095
10370
|
return await select3({
|
|
10096
10371
|
message: "Select a guideline",
|
|
10097
10372
|
choices: guideNames.map((name) => ({ name, value: name }))
|
|
10098
10373
|
});
|
|
10099
10374
|
}
|
|
10375
|
+
static async listGuidelines() {
|
|
10376
|
+
const guidelineRoot = await Prompter.#getGuidelineRoot();
|
|
10377
|
+
return (await fsPromise.readdir(guidelineRoot)).filter((name) => !name.startsWith("_")).sort();
|
|
10378
|
+
}
|
|
10100
10379
|
static async getGuideJson(guideName) {
|
|
10101
10380
|
const guidelineRoot = await Prompter.#getGuidelineRoot();
|
|
10102
10381
|
const filePath = `${guidelineRoot}/${guideName}/${guideName}.generate.json`;
|
|
@@ -10241,10 +10520,10 @@ class IncrementalBuilder {
|
|
|
10241
10520
|
}
|
|
10242
10521
|
}
|
|
10243
10522
|
batchTouchesPagesTree(appDir, batch) {
|
|
10244
|
-
const absAppDir =
|
|
10523
|
+
const absAppDir = path38.resolve(appDir);
|
|
10245
10524
|
for (const f of batch.files) {
|
|
10246
|
-
const abs =
|
|
10247
|
-
if (!abs.startsWith(`${absAppDir}${
|
|
10525
|
+
const abs = path38.resolve(f);
|
|
10526
|
+
if (!abs.startsWith(`${absAppDir}${path38.sep}`) && abs !== absAppDir)
|
|
10248
10527
|
continue;
|
|
10249
10528
|
if (/\.(tsx|ts|jsx|js)$/.test(abs))
|
|
10250
10529
|
return true;
|
|
@@ -10252,15 +10531,15 @@ class IncrementalBuilder {
|
|
|
10252
10531
|
return false;
|
|
10253
10532
|
}
|
|
10254
10533
|
async batchMayChangePageKeys(appDir, batch) {
|
|
10255
|
-
const absAppDir =
|
|
10256
|
-
const pageKeys = new Set((await this.#app.getPageKeys()).map((key) =>
|
|
10534
|
+
const absAppDir = path38.resolve(appDir);
|
|
10535
|
+
const pageKeys = new Set((await this.#app.getPageKeys()).map((key) => path38.normalize(key)));
|
|
10257
10536
|
for (const f of batch.files) {
|
|
10258
|
-
const abs =
|
|
10259
|
-
if (!abs.startsWith(`${absAppDir}${
|
|
10537
|
+
const abs = path38.resolve(f);
|
|
10538
|
+
if (!abs.startsWith(`${absAppDir}${path38.sep}`) && abs !== absAppDir)
|
|
10260
10539
|
continue;
|
|
10261
10540
|
if (!/\.(tsx|ts|jsx|js)$/.test(abs))
|
|
10262
10541
|
continue;
|
|
10263
|
-
const rel =
|
|
10542
|
+
const rel = path38.normalize(path38.relative(absAppDir, abs));
|
|
10264
10543
|
if (!await Bun.file(abs).exists() || !pageKeys.has(rel))
|
|
10265
10544
|
return true;
|
|
10266
10545
|
}
|
|
@@ -10288,7 +10567,7 @@ class IncrementalBuilder {
|
|
|
10288
10567
|
${cssText}`).toString(36);
|
|
10289
10568
|
const cssRelPath = `styles/${cssAssetName}-${cssHash}.css`;
|
|
10290
10569
|
const cssUrl = `/_akan/styles/${cssAssetName}-${cssHash}.css`;
|
|
10291
|
-
await Bun.write(
|
|
10570
|
+
await Bun.write(path38.join(artifactDir, cssRelPath), cssText);
|
|
10292
10571
|
cssAssetEntries.push([basePath2, { cssUrl, cssRelPath }]);
|
|
10293
10572
|
cssBase64ByUrl[cssUrl] = Buffer.from(new TextEncoder().encode(cssText)).toString("base64");
|
|
10294
10573
|
})()
|
|
@@ -10348,10 +10627,10 @@ ${cssText}`).toString(36);
|
|
|
10348
10627
|
if (changedFiles.length === 0)
|
|
10349
10628
|
return false;
|
|
10350
10629
|
return changedFiles.some((file) => {
|
|
10351
|
-
const normalized =
|
|
10630
|
+
const normalized = path38.resolve(file);
|
|
10352
10631
|
if (/\.(woff2?|ttf|otf)$/i.test(normalized))
|
|
10353
10632
|
return true;
|
|
10354
|
-
return this.#optimizedFonts.files.some((fontFile) =>
|
|
10633
|
+
return this.#optimizedFonts.files.some((fontFile) => path38.resolve(fontFile) === normalized);
|
|
10355
10634
|
});
|
|
10356
10635
|
}
|
|
10357
10636
|
async installWatcher() {
|