@akanjs/cli 2.3.13-rc.3 → 2.4.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/incrementalBuilder.proc.js +879 -321
- package/index.js +904 -353
- package/package.json +2 -2
- package/templates/facetIndex/index.ts +3 -9
|
@@ -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 path45 from "path";
|
|
6
6
|
|
|
7
7
|
// pkgs/@akanjs/devkit/aiEditor.ts
|
|
8
8
|
import { input, select } from "@inquirer/prompts";
|
|
@@ -8837,7 +8837,7 @@ Caused by: ${ApplicationBuildReporter.formatError(error.cause)}` : "";
|
|
|
8837
8837
|
}
|
|
8838
8838
|
// pkgs/@akanjs/devkit/applicationBuildRunner.ts
|
|
8839
8839
|
import { mkdir as mkdir8, rm as rm4 } from "fs/promises";
|
|
8840
|
-
import
|
|
8840
|
+
import path38 from "path";
|
|
8841
8841
|
|
|
8842
8842
|
// pkgs/@akanjs/devkit/frontendBuild/allRoutesBuilder.ts
|
|
8843
8843
|
import path22 from "path";
|
|
@@ -10620,14 +10620,538 @@ class AllRoutesBuilder {
|
|
|
10620
10620
|
this.#routeIds.push(routeId);
|
|
10621
10621
|
}
|
|
10622
10622
|
}
|
|
10623
|
+
// pkgs/@akanjs/devkit/frontendBuild/autoImportSync.ts
|
|
10624
|
+
import { readdir as readdir2, readFile, stat as stat3, writeFile } from "fs/promises";
|
|
10625
|
+
import path23 from "path";
|
|
10626
|
+
import ts8 from "typescript";
|
|
10627
|
+
var TEST_FILE_RE = /\.(test|spec)\.(ts|tsx)$/;
|
|
10628
|
+
var AKAN_BASE = {
|
|
10629
|
+
names: ["Int", "Float", "ID", "Any", "Upload", "enumOf", "dayjs"],
|
|
10630
|
+
specifier: "akanjs/base",
|
|
10631
|
+
kind: "named"
|
|
10632
|
+
};
|
|
10633
|
+
var AKAN_BASE_TYPES = { names: ["Dayjs"], specifier: "akanjs/base", kind: "named", typeOnly: true };
|
|
10634
|
+
var CNST_NS = { names: ["cnst"], specifier: "../cnst", kind: "namespace" };
|
|
10635
|
+
var DB_NS = { names: ["db"], specifier: "../db", kind: "namespace" };
|
|
10636
|
+
var SRV_NS = { names: ["srv"], specifier: "../srv", kind: "namespace" };
|
|
10637
|
+
var ERR_DICT = { names: ["Err"], specifier: "../dict", kind: "named" };
|
|
10638
|
+
var RULES = {
|
|
10639
|
+
constant: [AKAN_BASE, AKAN_BASE_TYPES, { names: ["via"], specifier: "akanjs/constant", kind: "named" }],
|
|
10640
|
+
document: [
|
|
10641
|
+
AKAN_BASE,
|
|
10642
|
+
AKAN_BASE_TYPES,
|
|
10643
|
+
CNST_NS,
|
|
10644
|
+
DB_NS,
|
|
10645
|
+
ERR_DICT,
|
|
10646
|
+
{
|
|
10647
|
+
names: ["by", "from", "into", "SchemaOf", "DataInputOf", "DocumentUpdateHelper", "documentQueryHelper", "Mdl"],
|
|
10648
|
+
specifier: "akanjs/document",
|
|
10649
|
+
kind: "named"
|
|
10650
|
+
}
|
|
10651
|
+
],
|
|
10652
|
+
service: [
|
|
10653
|
+
AKAN_BASE,
|
|
10654
|
+
AKAN_BASE_TYPES,
|
|
10655
|
+
DB_NS,
|
|
10656
|
+
SRV_NS,
|
|
10657
|
+
CNST_NS,
|
|
10658
|
+
ERR_DICT,
|
|
10659
|
+
{ names: ["serve"], specifier: "akanjs/service", kind: "named" },
|
|
10660
|
+
{
|
|
10661
|
+
names: ["DataInputOf", "ListQueryOption", "DatabaseRegistry", "getFilterInfoByKey"],
|
|
10662
|
+
specifier: "akanjs/document",
|
|
10663
|
+
kind: "named"
|
|
10664
|
+
}
|
|
10665
|
+
],
|
|
10666
|
+
signal: [
|
|
10667
|
+
AKAN_BASE,
|
|
10668
|
+
AKAN_BASE_TYPES,
|
|
10669
|
+
SRV_NS,
|
|
10670
|
+
CNST_NS,
|
|
10671
|
+
ERR_DICT,
|
|
10672
|
+
{
|
|
10673
|
+
names: ["endpoint", "internal", "slice", "Public", "Req", "Ws", "None", "Res"],
|
|
10674
|
+
specifier: "akanjs/signal",
|
|
10675
|
+
kind: "named"
|
|
10676
|
+
}
|
|
10677
|
+
],
|
|
10678
|
+
dictionary: [
|
|
10679
|
+
{
|
|
10680
|
+
names: ["modelDictionary", "scalarDictionary", "serviceDictionary"],
|
|
10681
|
+
specifier: "akanjs/dictionary",
|
|
10682
|
+
kind: "named"
|
|
10683
|
+
}
|
|
10684
|
+
],
|
|
10685
|
+
srvkit: [
|
|
10686
|
+
AKAN_BASE,
|
|
10687
|
+
AKAN_BASE_TYPES,
|
|
10688
|
+
{ names: ["Logger", "HttpClient", "sleep"], specifier: "akanjs/common", kind: "named" },
|
|
10689
|
+
{ names: ["adapt"], specifier: "akanjs/service", kind: "named" },
|
|
10690
|
+
{ names: ["SignalContext", "Guard", "InternalArg", "Middleware"], specifier: "akanjs/signal", kind: "named" }
|
|
10691
|
+
],
|
|
10692
|
+
common: [AKAN_BASE, AKAN_BASE_TYPES],
|
|
10693
|
+
store: [
|
|
10694
|
+
CNST_NS,
|
|
10695
|
+
{ names: ["store"], specifier: "akanjs/store", kind: "named" },
|
|
10696
|
+
{ names: ["fetch", "usePage", "sig"], specifier: "../useClient", kind: "named" },
|
|
10697
|
+
{ names: ["st"], specifier: "../st", kind: "named" },
|
|
10698
|
+
{ names: ["RootStore"], specifier: "../st", kind: "named", typeOnly: true }
|
|
10699
|
+
],
|
|
10700
|
+
client: [
|
|
10701
|
+
{
|
|
10702
|
+
names: ["cnst", "fetch", "st", "usePage"],
|
|
10703
|
+
specifier: (ctx) => `@${ctx.scope}/${ctx.project}/client`,
|
|
10704
|
+
kind: "named"
|
|
10705
|
+
}
|
|
10706
|
+
]
|
|
10707
|
+
};
|
|
10708
|
+
var PASCAL_CASE_RE = /^[A-Z][A-Za-z0-9]*$/;
|
|
10709
|
+
var DOMAIN_ROLE_KINDS = {
|
|
10710
|
+
constant: ["constant"],
|
|
10711
|
+
dictionary: ["constant", "document", "signal"],
|
|
10712
|
+
common: ["constant"]
|
|
10713
|
+
};
|
|
10714
|
+
var LIB_BARRELS = {
|
|
10715
|
+
Err: { barrel: "dict", kind: "named" },
|
|
10716
|
+
db: { barrel: "db", kind: "namespace" },
|
|
10717
|
+
cnst: { barrel: "cnst", kind: "namespace" },
|
|
10718
|
+
srv: { barrel: "srv", kind: "namespace" }
|
|
10719
|
+
};
|
|
10720
|
+
var DOMAIN_DENYLIST = new Set([
|
|
10721
|
+
"Map",
|
|
10722
|
+
"Set",
|
|
10723
|
+
"WeakMap",
|
|
10724
|
+
"WeakSet",
|
|
10725
|
+
"Date",
|
|
10726
|
+
"Promise",
|
|
10727
|
+
"Array",
|
|
10728
|
+
"Object",
|
|
10729
|
+
"Error",
|
|
10730
|
+
"TypeError",
|
|
10731
|
+
"RangeError",
|
|
10732
|
+
"RegExp",
|
|
10733
|
+
"Symbol",
|
|
10734
|
+
"Proxy",
|
|
10735
|
+
"Reflect",
|
|
10736
|
+
"JSON",
|
|
10737
|
+
"Math",
|
|
10738
|
+
"Number",
|
|
10739
|
+
"BigInt",
|
|
10740
|
+
"Function",
|
|
10741
|
+
"Boolean",
|
|
10742
|
+
"String",
|
|
10743
|
+
"Record",
|
|
10744
|
+
"Partial",
|
|
10745
|
+
"Required",
|
|
10746
|
+
"Readonly",
|
|
10747
|
+
"Pick",
|
|
10748
|
+
"Omit",
|
|
10749
|
+
"Exclude",
|
|
10750
|
+
"Extract",
|
|
10751
|
+
"NonNullable",
|
|
10752
|
+
"ReturnType",
|
|
10753
|
+
"Parameters",
|
|
10754
|
+
"Awaited",
|
|
10755
|
+
"InstanceType"
|
|
10756
|
+
]);
|
|
10757
|
+
|
|
10758
|
+
class AutoImportSync {
|
|
10759
|
+
#workspaceRoot;
|
|
10760
|
+
#domainCache = new Map;
|
|
10761
|
+
constructor({ workspaceRoot }) {
|
|
10762
|
+
this.#workspaceRoot = path23.resolve(workspaceRoot);
|
|
10763
|
+
}
|
|
10764
|
+
async syncForBatch(files) {
|
|
10765
|
+
const changedFiles = [];
|
|
10766
|
+
const errors = [];
|
|
10767
|
+
const seen = new Set;
|
|
10768
|
+
for (const file of files) {
|
|
10769
|
+
const pkgRoot = this.#domainPkgRootOf(file);
|
|
10770
|
+
if (pkgRoot)
|
|
10771
|
+
this.#domainCache.delete(pkgRoot);
|
|
10772
|
+
}
|
|
10773
|
+
for (const file of files) {
|
|
10774
|
+
const abs = path23.resolve(file);
|
|
10775
|
+
if (seen.has(abs))
|
|
10776
|
+
continue;
|
|
10777
|
+
seen.add(abs);
|
|
10778
|
+
const ctx = this.#contextFor(abs);
|
|
10779
|
+
if (!ctx)
|
|
10780
|
+
continue;
|
|
10781
|
+
try {
|
|
10782
|
+
const changed = await this.#syncFile(abs, ctx);
|
|
10783
|
+
if (changed)
|
|
10784
|
+
changedFiles.push(abs);
|
|
10785
|
+
} catch (err) {
|
|
10786
|
+
errors.push(`[auto-import] sync failed for ${file}: ${formatError(err)}`);
|
|
10787
|
+
}
|
|
10788
|
+
}
|
|
10789
|
+
return { changedFiles, errors };
|
|
10790
|
+
}
|
|
10791
|
+
#contextFor(abs) {
|
|
10792
|
+
const rel = path23.relative(this.#workspaceRoot, abs);
|
|
10793
|
+
if (rel.startsWith("..") || path23.isAbsolute(rel))
|
|
10794
|
+
return null;
|
|
10795
|
+
const base = path23.basename(abs);
|
|
10796
|
+
if (TEST_FILE_RE.test(base) || base === "index.ts" || base === "index.tsx" || base.endsWith(".d.ts"))
|
|
10797
|
+
return null;
|
|
10798
|
+
const parts = rel.split(path23.sep).filter(Boolean);
|
|
10799
|
+
const [scope, project, facet] = parts;
|
|
10800
|
+
if (scope !== "apps" && scope !== "libs" || !project || !facet)
|
|
10801
|
+
return null;
|
|
10802
|
+
const role = roleFor(facet, base);
|
|
10803
|
+
if (!role)
|
|
10804
|
+
return null;
|
|
10805
|
+
return { role, scope, project };
|
|
10806
|
+
}
|
|
10807
|
+
async#syncFile(abs, ctx) {
|
|
10808
|
+
const stats = await stat3(abs).catch(() => null);
|
|
10809
|
+
if (!stats?.isFile())
|
|
10810
|
+
return false;
|
|
10811
|
+
const source2 = await readFile(abs, "utf8");
|
|
10812
|
+
const resolveExtra = await this.#extraResolverFor(abs, ctx);
|
|
10813
|
+
const next = transformSource(source2, abs, ctx, resolveExtra);
|
|
10814
|
+
if (next === null || next === source2)
|
|
10815
|
+
return false;
|
|
10816
|
+
await writeFile(abs, next);
|
|
10817
|
+
return true;
|
|
10818
|
+
}
|
|
10819
|
+
async#extraResolverFor(abs, ctx) {
|
|
10820
|
+
const resolvers = [];
|
|
10821
|
+
if (ctx.role === "srvkit" || ctx.role === "common")
|
|
10822
|
+
resolvers.push(await this.#libBarrelResolver(abs, ctx));
|
|
10823
|
+
const kinds = DOMAIN_ROLE_KINDS[ctx.role];
|
|
10824
|
+
if (kinds)
|
|
10825
|
+
resolvers.push(await this.#domainResolver(abs, ctx, kinds));
|
|
10826
|
+
if (resolvers.length === 0)
|
|
10827
|
+
return;
|
|
10828
|
+
return (symbol) => {
|
|
10829
|
+
for (const resolve of resolvers) {
|
|
10830
|
+
const target = resolve(symbol);
|
|
10831
|
+
if (target)
|
|
10832
|
+
return target;
|
|
10833
|
+
}
|
|
10834
|
+
return null;
|
|
10835
|
+
};
|
|
10836
|
+
}
|
|
10837
|
+
async#domainResolver(abs, ctx, kinds) {
|
|
10838
|
+
const index = await this.#domainIndex(path23.join(this.#workspaceRoot, ctx.scope, ctx.project));
|
|
10839
|
+
const fileDir = path23.dirname(abs);
|
|
10840
|
+
return (symbol) => {
|
|
10841
|
+
if (!PASCAL_CASE_RE.test(symbol) || DOMAIN_DENYLIST.has(symbol))
|
|
10842
|
+
return null;
|
|
10843
|
+
const entries = (index.get(symbol) ?? []).filter((entry) => kinds.includes(entry.kind));
|
|
10844
|
+
if (entries.length !== 1)
|
|
10845
|
+
return null;
|
|
10846
|
+
return { specifier: relativeSpecifier(fileDir, entries[0].file), kind: "named" };
|
|
10847
|
+
};
|
|
10848
|
+
}
|
|
10849
|
+
async#libBarrelResolver(abs, ctx) {
|
|
10850
|
+
const fileDir = path23.dirname(abs);
|
|
10851
|
+
const libDir = path23.join(this.#workspaceRoot, ctx.scope, ctx.project, "lib");
|
|
10852
|
+
const available = new Map;
|
|
10853
|
+
for (const [symbol, { barrel, kind }] of Object.entries(LIB_BARRELS)) {
|
|
10854
|
+
if (await fileExists2(path23.join(libDir, `${barrel}.ts`)))
|
|
10855
|
+
available.set(symbol, { specifier: relativeSpecifier(fileDir, path23.join(libDir, barrel)), kind });
|
|
10856
|
+
}
|
|
10857
|
+
return (symbol) => available.get(symbol) ?? null;
|
|
10858
|
+
}
|
|
10859
|
+
async#domainIndex(pkgRoot) {
|
|
10860
|
+
const cached = this.#domainCache.get(pkgRoot);
|
|
10861
|
+
if (cached)
|
|
10862
|
+
return cached;
|
|
10863
|
+
const index = await buildDomainIndex(path23.join(pkgRoot, "lib"));
|
|
10864
|
+
this.#domainCache.set(pkgRoot, index);
|
|
10865
|
+
return index;
|
|
10866
|
+
}
|
|
10867
|
+
#domainPkgRootOf(file) {
|
|
10868
|
+
const rel = path23.relative(this.#workspaceRoot, path23.resolve(file));
|
|
10869
|
+
if (rel.startsWith("..") || path23.isAbsolute(rel))
|
|
10870
|
+
return null;
|
|
10871
|
+
const [scope, project, facet] = rel.split(path23.sep).filter(Boolean);
|
|
10872
|
+
if (scope !== "apps" && scope !== "libs" || !project || facet !== "lib")
|
|
10873
|
+
return null;
|
|
10874
|
+
if (!domainKindOf(path23.basename(file)))
|
|
10875
|
+
return null;
|
|
10876
|
+
return path23.join(this.#workspaceRoot, scope, project);
|
|
10877
|
+
}
|
|
10878
|
+
}
|
|
10879
|
+
var roleFor = (facet, base) => {
|
|
10880
|
+
if (facet === "lib") {
|
|
10881
|
+
if (base.endsWith(".constant.ts"))
|
|
10882
|
+
return "constant";
|
|
10883
|
+
if (base.endsWith(".document.ts"))
|
|
10884
|
+
return "document";
|
|
10885
|
+
if (base.endsWith(".service.ts"))
|
|
10886
|
+
return "service";
|
|
10887
|
+
if (base.endsWith(".signal.ts"))
|
|
10888
|
+
return "signal";
|
|
10889
|
+
if (base.endsWith(".dictionary.ts"))
|
|
10890
|
+
return "dictionary";
|
|
10891
|
+
if (base.endsWith(".store.ts"))
|
|
10892
|
+
return "store";
|
|
10893
|
+
if (base.endsWith(".tsx"))
|
|
10894
|
+
return "client";
|
|
10895
|
+
return null;
|
|
10896
|
+
}
|
|
10897
|
+
if (facet === "ui" || facet === "page")
|
|
10898
|
+
return base.endsWith(".tsx") ? "client" : null;
|
|
10899
|
+
if (facet === "webkit")
|
|
10900
|
+
return base.endsWith(".ts") || base.endsWith(".tsx") ? "client" : null;
|
|
10901
|
+
if (facet === "srvkit")
|
|
10902
|
+
return base.endsWith(".ts") ? "srvkit" : null;
|
|
10903
|
+
if (facet === "common")
|
|
10904
|
+
return base.endsWith(".ts") || base.endsWith(".tsx") ? "common" : null;
|
|
10905
|
+
return null;
|
|
10906
|
+
};
|
|
10907
|
+
var targetFor = (symbol, ctx) => {
|
|
10908
|
+
for (const rule of RULES[ctx.role]) {
|
|
10909
|
+
if (!rule.names.includes(symbol))
|
|
10910
|
+
continue;
|
|
10911
|
+
const specifier = typeof rule.specifier === "function" ? rule.specifier(ctx) : rule.specifier;
|
|
10912
|
+
return { specifier, kind: rule.kind, typeOnly: rule.typeOnly };
|
|
10913
|
+
}
|
|
10914
|
+
return null;
|
|
10915
|
+
};
|
|
10916
|
+
var transformSource = (source2, fileName, ctx, resolveExtra) => {
|
|
10917
|
+
const sf = ts8.createSourceFile(fileName, source2, ts8.ScriptTarget.Latest, true, scriptKindFor(fileName));
|
|
10918
|
+
const bound = collectBoundNames(sf);
|
|
10919
|
+
const used = collectUsedReferences(sf);
|
|
10920
|
+
const namedBySpecifier = new Map;
|
|
10921
|
+
const namespaceImports = [];
|
|
10922
|
+
for (const name of used) {
|
|
10923
|
+
if (bound.has(name))
|
|
10924
|
+
continue;
|
|
10925
|
+
const target = targetFor(name, ctx) ?? resolveExtra?.(name) ?? null;
|
|
10926
|
+
if (!target)
|
|
10927
|
+
continue;
|
|
10928
|
+
if (target.kind === "namespace")
|
|
10929
|
+
namespaceImports.push({ name, specifier: target.specifier });
|
|
10930
|
+
else {
|
|
10931
|
+
const names = namedBySpecifier.get(target.specifier) ?? new Map;
|
|
10932
|
+
names.set(name, target.typeOnly ?? false);
|
|
10933
|
+
namedBySpecifier.set(target.specifier, names);
|
|
10934
|
+
}
|
|
10935
|
+
}
|
|
10936
|
+
if (namedBySpecifier.size === 0 && namespaceImports.length === 0)
|
|
10937
|
+
return null;
|
|
10938
|
+
const importDecls = sf.statements.filter(ts8.isImportDeclaration);
|
|
10939
|
+
const anchor = importDecls.at(-1) ?? null;
|
|
10940
|
+
const namedImportsBySpecifier = collectExistingNamedImports(importDecls);
|
|
10941
|
+
const edits = [];
|
|
10942
|
+
const newStatements = [];
|
|
10943
|
+
for (const [specifier, names] of namedBySpecifier) {
|
|
10944
|
+
const existing = namedImportsBySpecifier.get(specifier);
|
|
10945
|
+
if (existing) {
|
|
10946
|
+
const merged = new Map(existing.names);
|
|
10947
|
+
for (const [name, isType] of names)
|
|
10948
|
+
if (!merged.has(name))
|
|
10949
|
+
merged.set(name, isType);
|
|
10950
|
+
edits.push({
|
|
10951
|
+
start: existing.decl.getStart(sf),
|
|
10952
|
+
end: existing.decl.getEnd(),
|
|
10953
|
+
text: formatNamedImport(specifier, merged)
|
|
10954
|
+
});
|
|
10955
|
+
} else
|
|
10956
|
+
newStatements.push(formatNamedImport(specifier, names));
|
|
10957
|
+
}
|
|
10958
|
+
for (const ns of namespaceImports)
|
|
10959
|
+
newStatements.push(`import * as ${ns.name} from "${ns.specifier}";`);
|
|
10960
|
+
if (newStatements.length > 0) {
|
|
10961
|
+
const anchorEdit = anchor ? edits.find((edit) => edit.start === anchor.getStart(sf)) : undefined;
|
|
10962
|
+
if (anchorEdit)
|
|
10963
|
+
anchorEdit.text = `${anchorEdit.text}
|
|
10964
|
+
${newStatements.join(`
|
|
10965
|
+
`)}`;
|
|
10966
|
+
else if (anchor)
|
|
10967
|
+
edits.push({ start: anchor.getEnd(), end: anchor.getEnd(), text: `
|
|
10968
|
+
${newStatements.join(`
|
|
10969
|
+
`)}` });
|
|
10970
|
+
else {
|
|
10971
|
+
const prologueEnd = directivePrologueEnd(sf);
|
|
10972
|
+
if (prologueEnd >= 0)
|
|
10973
|
+
edits.push({ start: prologueEnd, end: prologueEnd, text: `
|
|
10974
|
+
${newStatements.join(`
|
|
10975
|
+
`)}` });
|
|
10976
|
+
else
|
|
10977
|
+
edits.push({ start: 0, end: 0, text: `${newStatements.join(`
|
|
10978
|
+
`)}
|
|
10979
|
+
|
|
10980
|
+
` });
|
|
10981
|
+
}
|
|
10982
|
+
}
|
|
10983
|
+
if (edits.length === 0)
|
|
10984
|
+
return null;
|
|
10985
|
+
edits.sort((a, b) => b.start - a.start);
|
|
10986
|
+
let out = source2;
|
|
10987
|
+
for (const edit of edits)
|
|
10988
|
+
out = out.slice(0, edit.start) + edit.text + out.slice(edit.end);
|
|
10989
|
+
return out === source2 ? null : out;
|
|
10990
|
+
};
|
|
10991
|
+
var collectBoundNames = (sf) => {
|
|
10992
|
+
const names = new Set;
|
|
10993
|
+
const visit = (node) => {
|
|
10994
|
+
if (ts8.isImportClause(node)) {
|
|
10995
|
+
if (node.name)
|
|
10996
|
+
names.add(node.name.text);
|
|
10997
|
+
const bindings = node.namedBindings;
|
|
10998
|
+
if (bindings && ts8.isNamespaceImport(bindings))
|
|
10999
|
+
names.add(bindings.name.text);
|
|
11000
|
+
if (bindings && ts8.isNamedImports(bindings))
|
|
11001
|
+
for (const el of bindings.elements)
|
|
11002
|
+
names.add(el.name.text);
|
|
11003
|
+
}
|
|
11004
|
+
if ((ts8.isVariableDeclaration(node) || ts8.isFunctionDeclaration(node) || ts8.isClassDeclaration(node) || ts8.isParameter(node) || ts8.isBindingElement(node) || ts8.isEnumDeclaration(node) || ts8.isTypeAliasDeclaration(node) || ts8.isInterfaceDeclaration(node)) && node.name && ts8.isIdentifier(node.name))
|
|
11005
|
+
names.add(node.name.text);
|
|
11006
|
+
ts8.forEachChild(node, visit);
|
|
11007
|
+
};
|
|
11008
|
+
ts8.forEachChild(sf, visit);
|
|
11009
|
+
return names;
|
|
11010
|
+
};
|
|
11011
|
+
var collectUsedReferences = (sf) => {
|
|
11012
|
+
const used = new Set;
|
|
11013
|
+
const visit = (node) => {
|
|
11014
|
+
if (ts8.isIdentifier(node) && isReferencePosition(node))
|
|
11015
|
+
used.add(node.text);
|
|
11016
|
+
ts8.forEachChild(node, visit);
|
|
11017
|
+
};
|
|
11018
|
+
ts8.forEachChild(sf, visit);
|
|
11019
|
+
return used;
|
|
11020
|
+
};
|
|
11021
|
+
var isReferencePosition = (node) => {
|
|
11022
|
+
const parent = node.parent;
|
|
11023
|
+
if (!parent)
|
|
11024
|
+
return true;
|
|
11025
|
+
if (ts8.isPropertyAccessExpression(parent) && parent.name === node)
|
|
11026
|
+
return false;
|
|
11027
|
+
if (ts8.isQualifiedName(parent) && parent.right === node)
|
|
11028
|
+
return false;
|
|
11029
|
+
if (ts8.isPropertyAssignment(parent) && parent.name === node)
|
|
11030
|
+
return false;
|
|
11031
|
+
if (ts8.isPropertySignature(parent) && parent.name === node)
|
|
11032
|
+
return false;
|
|
11033
|
+
if (ts8.isBindingElement(parent) && parent.propertyName === node)
|
|
11034
|
+
return false;
|
|
11035
|
+
if (ts8.isImportSpecifier(parent) || ts8.isExportSpecifier(parent))
|
|
11036
|
+
return false;
|
|
11037
|
+
return true;
|
|
11038
|
+
};
|
|
11039
|
+
var collectExistingNamedImports = (importDecls) => {
|
|
11040
|
+
const map = new Map;
|
|
11041
|
+
for (const decl of importDecls) {
|
|
11042
|
+
const clause = decl.importClause;
|
|
11043
|
+
const bindings = clause?.namedBindings;
|
|
11044
|
+
if (!clause || !bindings || !ts8.isNamedImports(bindings))
|
|
11045
|
+
continue;
|
|
11046
|
+
if (!ts8.isStringLiteral(decl.moduleSpecifier))
|
|
11047
|
+
continue;
|
|
11048
|
+
const specifier = decl.moduleSpecifier.text;
|
|
11049
|
+
if (map.has(specifier))
|
|
11050
|
+
continue;
|
|
11051
|
+
const names = new Map;
|
|
11052
|
+
for (const el of bindings.elements)
|
|
11053
|
+
names.set(el.name.text, clause.isTypeOnly || el.isTypeOnly);
|
|
11054
|
+
map.set(specifier, { decl, names });
|
|
11055
|
+
}
|
|
11056
|
+
return map;
|
|
11057
|
+
};
|
|
11058
|
+
var formatNamedImport = (specifier, names) => {
|
|
11059
|
+
const entries = [...names.entries()].sort((a, b) => compareNames(a[0], b[0]));
|
|
11060
|
+
if (entries.every(([, isType]) => isType))
|
|
11061
|
+
return `import type { ${entries.map(([name]) => name).join(", ")} } from "${specifier}";`;
|
|
11062
|
+
const parts = entries.map(([name, isType]) => isType ? `type ${name}` : name);
|
|
11063
|
+
return `import { ${parts.join(", ")} } from "${specifier}";`;
|
|
11064
|
+
};
|
|
11065
|
+
var directivePrologueEnd = (sf) => {
|
|
11066
|
+
let end = -1;
|
|
11067
|
+
for (const stmt of sf.statements) {
|
|
11068
|
+
if (ts8.isExpressionStatement(stmt) && ts8.isStringLiteral(stmt.expression))
|
|
11069
|
+
end = stmt.getEnd();
|
|
11070
|
+
else
|
|
11071
|
+
break;
|
|
11072
|
+
}
|
|
11073
|
+
return end;
|
|
11074
|
+
};
|
|
11075
|
+
var scriptKindFor = (fileName) => fileName.endsWith(".tsx") ? ts8.ScriptKind.TSX : ts8.ScriptKind.TS;
|
|
11076
|
+
var compareNames = (a, b) => {
|
|
11077
|
+
const [la, lb] = [a.toLowerCase(), b.toLowerCase()];
|
|
11078
|
+
if (la !== lb)
|
|
11079
|
+
return la < lb ? -1 : 1;
|
|
11080
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
11081
|
+
};
|
|
11082
|
+
var formatError = (err) => err instanceof Error ? err.message : String(err);
|
|
11083
|
+
var fileExists2 = async (file) => stat3(file).then((s) => s.isFile()).catch(() => false);
|
|
11084
|
+
var domainKindOf = (base) => {
|
|
11085
|
+
if (base.endsWith(".constant.ts"))
|
|
11086
|
+
return "constant";
|
|
11087
|
+
if (base.endsWith(".document.ts"))
|
|
11088
|
+
return "document";
|
|
11089
|
+
if (base.endsWith(".signal.ts"))
|
|
11090
|
+
return "signal";
|
|
11091
|
+
return null;
|
|
11092
|
+
};
|
|
11093
|
+
var buildDomainIndex = async (libDir) => {
|
|
11094
|
+
const index = new Map;
|
|
11095
|
+
for (const file of await collectDomainFiles(libDir)) {
|
|
11096
|
+
const kind = domainKindOf(path23.basename(file));
|
|
11097
|
+
if (!kind)
|
|
11098
|
+
continue;
|
|
11099
|
+
const src = await readFile(file, "utf8").catch(() => null);
|
|
11100
|
+
if (src === null)
|
|
11101
|
+
continue;
|
|
11102
|
+
for (const name of exportedPascalNames(src, file)) {
|
|
11103
|
+
const entries = index.get(name) ?? [];
|
|
11104
|
+
entries.push({ file, kind });
|
|
11105
|
+
index.set(name, entries);
|
|
11106
|
+
}
|
|
11107
|
+
}
|
|
11108
|
+
return index;
|
|
11109
|
+
};
|
|
11110
|
+
var collectDomainFiles = async (dir) => {
|
|
11111
|
+
const entries = await readdir2(dir, { withFileTypes: true }).catch(() => []);
|
|
11112
|
+
const files = [];
|
|
11113
|
+
for (const entry of entries) {
|
|
11114
|
+
if (entry.name.startsWith(".") || entry.name === "node_modules")
|
|
11115
|
+
continue;
|
|
11116
|
+
const full = path23.join(dir, entry.name);
|
|
11117
|
+
if (entry.isDirectory())
|
|
11118
|
+
files.push(...await collectDomainFiles(full));
|
|
11119
|
+
else if (domainKindOf(entry.name) && !TEST_FILE_RE.test(entry.name))
|
|
11120
|
+
files.push(full);
|
|
11121
|
+
}
|
|
11122
|
+
return files;
|
|
11123
|
+
};
|
|
11124
|
+
var exportedPascalNames = (source2, fileName) => {
|
|
11125
|
+
const sf = ts8.createSourceFile(fileName, source2, ts8.ScriptTarget.Latest, true);
|
|
11126
|
+
const isExported = (node) => ts8.canHaveModifiers(node) && (ts8.getModifiers(node) ?? []).some((m) => m.kind === ts8.SyntaxKind.ExportKeyword);
|
|
11127
|
+
const names = [];
|
|
11128
|
+
for (const stmt of sf.statements) {
|
|
11129
|
+
if ((ts8.isClassDeclaration(stmt) || ts8.isFunctionDeclaration(stmt) || ts8.isEnumDeclaration(stmt)) && stmt.name) {
|
|
11130
|
+
if (isExported(stmt))
|
|
11131
|
+
names.push(stmt.name.text);
|
|
11132
|
+
} else if (ts8.isVariableStatement(stmt) && isExported(stmt)) {
|
|
11133
|
+
for (const decl of stmt.declarationList.declarations)
|
|
11134
|
+
if (ts8.isIdentifier(decl.name))
|
|
11135
|
+
names.push(decl.name.text);
|
|
11136
|
+
} else if (ts8.isExportDeclaration(stmt) && stmt.exportClause && ts8.isNamedExports(stmt.exportClause)) {
|
|
11137
|
+
for (const el of stmt.exportClause.elements)
|
|
11138
|
+
names.push(el.name.text);
|
|
11139
|
+
}
|
|
11140
|
+
}
|
|
11141
|
+
return names.filter((name) => PASCAL_CASE_RE.test(name));
|
|
11142
|
+
};
|
|
11143
|
+
var relativeSpecifier = (fromDir, toFile) => {
|
|
11144
|
+
const rel = path23.relative(fromDir, toFile).replace(/\.tsx?$/, "").split(path23.sep).join("/");
|
|
11145
|
+
return rel.startsWith(".") ? rel : `./${rel}`;
|
|
11146
|
+
};
|
|
10623
11147
|
// pkgs/@akanjs/devkit/frontendBuild/csrArtifactBuilder.ts
|
|
10624
11148
|
import { mkdir as mkdir5, rm as rm2, unlink } from "fs/promises";
|
|
10625
|
-
import
|
|
11149
|
+
import path25 from "path";
|
|
10626
11150
|
|
|
10627
11151
|
// pkgs/@akanjs/devkit/frontendBuild/pagesEntrySourceGenerator.ts
|
|
10628
11152
|
import fs3 from "fs";
|
|
10629
|
-
import
|
|
10630
|
-
import
|
|
11153
|
+
import path24 from "path";
|
|
11154
|
+
import ts9 from "typescript";
|
|
10631
11155
|
|
|
10632
11156
|
class PagesEntrySourceGenerator {
|
|
10633
11157
|
#pageEntries;
|
|
@@ -10669,12 +11193,12 @@ ${entries.join(`
|
|
|
10669
11193
|
`;
|
|
10670
11194
|
}
|
|
10671
11195
|
static #toImportSpecifier(moduleAbsPath) {
|
|
10672
|
-
return
|
|
11196
|
+
return path24.resolve(moduleAbsPath).split(path24.sep).join("/");
|
|
10673
11197
|
}
|
|
10674
11198
|
static #hasAsyncDefaultExport(moduleAbsPath) {
|
|
10675
11199
|
try {
|
|
10676
|
-
const source2 = fs3.readFileSync(
|
|
10677
|
-
const sourceFile2 =
|
|
11200
|
+
const source2 = fs3.readFileSync(path24.resolve(moduleAbsPath), "utf8");
|
|
11201
|
+
const sourceFile2 = ts9.createSourceFile(moduleAbsPath, source2, ts9.ScriptTarget.Latest, true, PagesEntrySourceGenerator.#scriptKind(moduleAbsPath));
|
|
10678
11202
|
return PagesEntrySourceGenerator.#sourceFileHasAsyncDefaultExport(sourceFile2);
|
|
10679
11203
|
} catch {
|
|
10680
11204
|
return false;
|
|
@@ -10684,31 +11208,31 @@ ${entries.join(`
|
|
|
10684
11208
|
const asyncBindings = new Map;
|
|
10685
11209
|
let defaultIdentifier = null;
|
|
10686
11210
|
for (const statement of sourceFile2.statements) {
|
|
10687
|
-
if (
|
|
10688
|
-
if (PagesEntrySourceGenerator.#hasModifier(statement,
|
|
10689
|
-
return PagesEntrySourceGenerator.#hasModifier(statement,
|
|
11211
|
+
if (ts9.isFunctionDeclaration(statement)) {
|
|
11212
|
+
if (PagesEntrySourceGenerator.#hasModifier(statement, ts9.SyntaxKind.DefaultKeyword)) {
|
|
11213
|
+
return PagesEntrySourceGenerator.#hasModifier(statement, ts9.SyntaxKind.AsyncKeyword);
|
|
10690
11214
|
}
|
|
10691
11215
|
if (statement.name) {
|
|
10692
|
-
asyncBindings.set(statement.name.text, PagesEntrySourceGenerator.#hasModifier(statement,
|
|
11216
|
+
asyncBindings.set(statement.name.text, PagesEntrySourceGenerator.#hasModifier(statement, ts9.SyntaxKind.AsyncKeyword));
|
|
10693
11217
|
}
|
|
10694
11218
|
continue;
|
|
10695
11219
|
}
|
|
10696
|
-
if (
|
|
11220
|
+
if (ts9.isVariableStatement(statement)) {
|
|
10697
11221
|
for (const declaration of statement.declarationList.declarations) {
|
|
10698
|
-
if (!
|
|
11222
|
+
if (!ts9.isIdentifier(declaration.name))
|
|
10699
11223
|
continue;
|
|
10700
11224
|
asyncBindings.set(declaration.name.text, PagesEntrySourceGenerator.#isAsyncFunctionExpression(declaration.initializer));
|
|
10701
11225
|
}
|
|
10702
11226
|
continue;
|
|
10703
11227
|
}
|
|
10704
|
-
if (
|
|
11228
|
+
if (ts9.isExportAssignment(statement)) {
|
|
10705
11229
|
if (PagesEntrySourceGenerator.#isAsyncFunctionExpression(statement.expression))
|
|
10706
11230
|
return true;
|
|
10707
|
-
if (
|
|
11231
|
+
if (ts9.isIdentifier(statement.expression))
|
|
10708
11232
|
defaultIdentifier = statement.expression.text;
|
|
10709
11233
|
continue;
|
|
10710
11234
|
}
|
|
10711
|
-
if (
|
|
11235
|
+
if (ts9.isExportDeclaration(statement) && statement.exportClause && ts9.isNamedExports(statement.exportClause)) {
|
|
10712
11236
|
const exportClause = statement.exportClause;
|
|
10713
11237
|
for (const specifier of exportClause.elements) {
|
|
10714
11238
|
if (specifier.name.text !== "default")
|
|
@@ -10720,13 +11244,13 @@ ${entries.join(`
|
|
|
10720
11244
|
return defaultIdentifier ? asyncBindings.get(defaultIdentifier) === true : false;
|
|
10721
11245
|
}
|
|
10722
11246
|
static #hasModifier(node, kind) {
|
|
10723
|
-
return
|
|
11247
|
+
return ts9.canHaveModifiers(node) && (ts9.getModifiers(node)?.some((modifier) => modifier.kind === kind) ?? false);
|
|
10724
11248
|
}
|
|
10725
11249
|
static #isAsyncFunctionExpression(node) {
|
|
10726
|
-
return Boolean(node && (
|
|
11250
|
+
return Boolean(node && (ts9.isArrowFunction(node) || ts9.isFunctionExpression(node)) && PagesEntrySourceGenerator.#hasModifier(node, ts9.SyntaxKind.AsyncKeyword));
|
|
10727
11251
|
}
|
|
10728
11252
|
static #scriptKind(moduleAbsPath) {
|
|
10729
|
-
return moduleAbsPath.endsWith(".tsx") || moduleAbsPath.endsWith(".jsx") ?
|
|
11253
|
+
return moduleAbsPath.endsWith(".tsx") || moduleAbsPath.endsWith(".jsx") ? ts9.ScriptKind.TSX : ts9.ScriptKind.TS;
|
|
10730
11254
|
}
|
|
10731
11255
|
}
|
|
10732
11256
|
|
|
@@ -10752,7 +11276,7 @@ class CsrArtifactBuilder {
|
|
|
10752
11276
|
const csrBasePaths = [...akanConfig2.basePaths];
|
|
10753
11277
|
const htmlEntries = csrBasePaths.length > 0 ? csrBasePaths : ["index"];
|
|
10754
11278
|
await rm2(this.#outputDir, { recursive: true, force: true });
|
|
10755
|
-
await mkdir5(
|
|
11279
|
+
await mkdir5(path25.join(this.#app.cwdPath, ".akan/generated/csr"), { recursive: true });
|
|
10756
11280
|
const generatedHtmlFiles = Object.fromEntries(htmlEntries.map((basePath2) => this.#createHtmlFile(basePath2)));
|
|
10757
11281
|
const result = await Bun.build({
|
|
10758
11282
|
target: "browser",
|
|
@@ -10784,7 +11308,7 @@ ${logs}` : ""}`);
|
|
|
10784
11308
|
return { outputDir: this.#outputDir };
|
|
10785
11309
|
}
|
|
10786
11310
|
get #outputDir() {
|
|
10787
|
-
return
|
|
11311
|
+
return path25.join(this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath, this.#command === "build" ? "csr" : ".akan/artifact/csr");
|
|
10788
11312
|
}
|
|
10789
11313
|
#define() {
|
|
10790
11314
|
const nodeEnv = this.#command === "build" ? "production" : "development";
|
|
@@ -10815,8 +11339,8 @@ ${logs}` : ""}`);
|
|
|
10815
11339
|
];
|
|
10816
11340
|
}
|
|
10817
11341
|
async#loadCsrArtifact() {
|
|
10818
|
-
const artifactDir =
|
|
10819
|
-
const artifactFile = Bun.file(
|
|
11342
|
+
const artifactDir = path25.join(this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath, ".akan/artifact");
|
|
11343
|
+
const artifactFile = Bun.file(path25.join(artifactDir, "base-artifact.json"));
|
|
10820
11344
|
if (!await artifactFile.exists())
|
|
10821
11345
|
return { cssAssets: {} };
|
|
10822
11346
|
const artifact = await artifactFile.json();
|
|
@@ -10829,7 +11353,7 @@ ${logs}` : ""}`);
|
|
|
10829
11353
|
const htmlFile = Bun.file(htmlPath);
|
|
10830
11354
|
if (!await htmlFile.exists())
|
|
10831
11355
|
continue;
|
|
10832
|
-
const basePath2 =
|
|
11356
|
+
const basePath2 = path25.basename(htmlPath, ".html") === "index" ? "" : path25.basename(htmlPath, ".html");
|
|
10833
11357
|
const inlined = await this.#inlineHtmlAssets(await htmlFile.text(), htmlPath, cssAssets[basePath2]);
|
|
10834
11358
|
for (const filePath of inlined.jsFiles)
|
|
10835
11359
|
jsFiles.add(filePath);
|
|
@@ -10871,7 +11395,7 @@ ${remainingAssets.join(`
|
|
|
10871
11395
|
next = CsrArtifactBuilder.injectBeforeHeadEnd(next, style);
|
|
10872
11396
|
}
|
|
10873
11397
|
if (cssAsset) {
|
|
10874
|
-
const cssPath =
|
|
11398
|
+
const cssPath = path25.join(this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath, ".akan/artifact", cssAsset.cssRelPath);
|
|
10875
11399
|
const css = await Bun.file(cssPath).text();
|
|
10876
11400
|
const style = CsrArtifactBuilder.createInlineStyle(css);
|
|
10877
11401
|
if (!next.includes(style))
|
|
@@ -10942,16 +11466,16 @@ ${CsrArtifactBuilder.escapeInlineScript(await loadScript(src))}
|
|
|
10942
11466
|
throw new Error(`[csr-build] cannot inline external script: ${src}`);
|
|
10943
11467
|
}
|
|
10944
11468
|
const normalized = src.startsWith("/") ? src.slice(1) : src;
|
|
10945
|
-
return
|
|
11469
|
+
return path25.resolve(path25.dirname(htmlPath), normalized);
|
|
10946
11470
|
}
|
|
10947
11471
|
}
|
|
10948
11472
|
// pkgs/@akanjs/devkit/frontendBuild/cssCompiler.ts
|
|
10949
|
-
import
|
|
11473
|
+
import path27 from "path";
|
|
10950
11474
|
import { Logger as Logger8 } from "akanjs/common";
|
|
10951
11475
|
import { compile } from "tailwindcss";
|
|
10952
11476
|
|
|
10953
11477
|
// pkgs/@akanjs/devkit/frontendBuild/cssImportResolver.ts
|
|
10954
|
-
import
|
|
11478
|
+
import path26 from "path";
|
|
10955
11479
|
var CSS_IMPORT_EXTS = ["", ".css", "/styles.css", "/index.css"];
|
|
10956
11480
|
|
|
10957
11481
|
class CssImportResolver {
|
|
@@ -11004,7 +11528,7 @@ class CssImportResolver {
|
|
|
11004
11528
|
const exact = this.#paths[id];
|
|
11005
11529
|
if (exact) {
|
|
11006
11530
|
for (const repl of exact) {
|
|
11007
|
-
const resolved = await this.#firstExisting(
|
|
11531
|
+
const resolved = await this.#firstExisting(path26.resolve(this.#workspaceRoot, repl));
|
|
11008
11532
|
if (resolved)
|
|
11009
11533
|
return resolved;
|
|
11010
11534
|
}
|
|
@@ -11015,7 +11539,7 @@ class CssImportResolver {
|
|
|
11015
11539
|
const suffix = id.slice(prefix.length);
|
|
11016
11540
|
for (const repl of replacements) {
|
|
11017
11541
|
const replPath = repl.endsWith("/*") ? repl.slice(0, -1) : repl;
|
|
11018
|
-
const resolved = await this.#firstExisting(
|
|
11542
|
+
const resolved = await this.#firstExisting(path26.resolve(this.#workspaceRoot, replPath + suffix));
|
|
11019
11543
|
if (resolved)
|
|
11020
11544
|
return resolved;
|
|
11021
11545
|
}
|
|
@@ -11045,25 +11569,25 @@ class CssImportResolver {
|
|
|
11045
11569
|
try {
|
|
11046
11570
|
if (!await Bun.file(pkgPath).exists())
|
|
11047
11571
|
return null;
|
|
11048
|
-
const pkgDir =
|
|
11572
|
+
const pkgDir = path26.dirname(pkgPath);
|
|
11049
11573
|
const pkg = await Bun.file(pkgPath).json();
|
|
11050
11574
|
const subpath = id === pkgName ? "." : `.${id.slice(pkgName.length)}`;
|
|
11051
11575
|
const exportValue = pkg.exports?.[subpath];
|
|
11052
11576
|
const styleEntry = (typeof exportValue === "string" ? exportValue : exportValue?.style || exportValue?.import || exportValue?.default) || pkg.exports?.["."]?.style || pkg.style || "index.css";
|
|
11053
|
-
return await this.#firstExisting(
|
|
11577
|
+
return await this.#firstExisting(path26.resolve(pkgDir, styleEntry));
|
|
11054
11578
|
} catch {
|
|
11055
11579
|
return null;
|
|
11056
11580
|
}
|
|
11057
11581
|
}
|
|
11058
11582
|
#resolutionBases(fromBase) {
|
|
11059
|
-
return [fromBase, this.#workspaceRoot,
|
|
11583
|
+
return [fromBase, this.#workspaceRoot, path26.dirname(Bun.main), path26.resolve(path26.dirname(Bun.main), "../..")];
|
|
11060
11584
|
}
|
|
11061
11585
|
#packageJsonCandidates(pkgName) {
|
|
11062
11586
|
return [
|
|
11063
|
-
|
|
11064
|
-
|
|
11065
|
-
|
|
11066
|
-
|
|
11587
|
+
path26.join(this.#workspaceRoot, "pkgs", pkgName, "package.json"),
|
|
11588
|
+
path26.join(this.#workspaceRoot, "node_modules", pkgName, "package.json"),
|
|
11589
|
+
path26.join(path26.dirname(Bun.main), "node_modules", pkgName, "package.json"),
|
|
11590
|
+
path26.join(path26.dirname(Bun.main), "../../", pkgName, "package.json")
|
|
11067
11591
|
];
|
|
11068
11592
|
}
|
|
11069
11593
|
async#firstExisting(basePath2) {
|
|
@@ -11081,7 +11605,7 @@ class CssImportResolver {
|
|
|
11081
11605
|
return parts[0] ?? null;
|
|
11082
11606
|
}
|
|
11083
11607
|
static isCssFile(filePath) {
|
|
11084
|
-
return
|
|
11608
|
+
return path26.extname(filePath) === ".css";
|
|
11085
11609
|
}
|
|
11086
11610
|
}
|
|
11087
11611
|
|
|
@@ -11148,7 +11672,7 @@ class CssCompiler {
|
|
|
11148
11672
|
pageKeys
|
|
11149
11673
|
} = {}) {
|
|
11150
11674
|
pageKeys ??= await this.#app.getPageKeys({ refresh });
|
|
11151
|
-
const seeds = pageKeys.map((key) =>
|
|
11675
|
+
const seeds = pageKeys.map((key) => path27.resolve(this.#app.cwdPath, "page", key));
|
|
11152
11676
|
const cssFiles = new Set;
|
|
11153
11677
|
const sourceFiles = new Set;
|
|
11154
11678
|
const queue = [...seeds];
|
|
@@ -11180,7 +11704,7 @@ class CssCompiler {
|
|
|
11180
11704
|
} catch {
|
|
11181
11705
|
continue;
|
|
11182
11706
|
}
|
|
11183
|
-
const importerDir =
|
|
11707
|
+
const importerDir = path27.dirname(filePath);
|
|
11184
11708
|
for (const imp of imports) {
|
|
11185
11709
|
const spec = imp.path;
|
|
11186
11710
|
if (!spec)
|
|
@@ -11206,7 +11730,7 @@ class CssCompiler {
|
|
|
11206
11730
|
const compileStarted = Date.now();
|
|
11207
11731
|
const compilers = await Promise.all(cssPaths.map(async (cssPath) => {
|
|
11208
11732
|
const css = await Bun.file(cssPath).text();
|
|
11209
|
-
const base =
|
|
11733
|
+
const base = path27.dirname(cssPath);
|
|
11210
11734
|
const compiler = await compile(css, {
|
|
11211
11735
|
base,
|
|
11212
11736
|
loadStylesheet: (id, fromBase) => this.#loadStylesheet(id, fromBase),
|
|
@@ -11237,11 +11761,11 @@ class CssCompiler {
|
|
|
11237
11761
|
async#loadStylesheet(id, fromBase) {
|
|
11238
11762
|
const p = await this.#resolveCssImport(id, fromBase);
|
|
11239
11763
|
const content = await Bun.file(p).text();
|
|
11240
|
-
return { path: p, base:
|
|
11764
|
+
return { path: p, base: path27.dirname(p), content };
|
|
11241
11765
|
}
|
|
11242
11766
|
async#resolveCssImport(id, fromBase) {
|
|
11243
11767
|
if (id.startsWith(".") || id.startsWith("/"))
|
|
11244
|
-
return
|
|
11768
|
+
return path27.resolve(fromBase, id);
|
|
11245
11769
|
const resolver = await this.#getCssImportResolver();
|
|
11246
11770
|
const resolved = await resolver.resolve(id, fromBase);
|
|
11247
11771
|
if (resolved)
|
|
@@ -11257,11 +11781,11 @@ class CssCompiler {
|
|
|
11257
11781
|
async#loadModule(id, fromBase) {
|
|
11258
11782
|
const p = __require.resolve(id, { paths: [fromBase] });
|
|
11259
11783
|
const mod = await import(p);
|
|
11260
|
-
return { path: p, base:
|
|
11784
|
+
return { path: p, base: path27.dirname(p), module: mod.default ?? mod };
|
|
11261
11785
|
}
|
|
11262
11786
|
async#resolveSourceImport(id, fromBase, resolvePackage) {
|
|
11263
11787
|
if (id.startsWith(".") || id.startsWith("/")) {
|
|
11264
|
-
const abs = id.startsWith("/") ? id :
|
|
11788
|
+
const abs = id.startsWith("/") ? id : path27.resolve(fromBase, id);
|
|
11265
11789
|
return resolveSourceFileCandidate(abs);
|
|
11266
11790
|
}
|
|
11267
11791
|
const pkg = await resolvePackage(id);
|
|
@@ -11303,7 +11827,7 @@ async function resolveSourceFileCandidate(absPathNoExt) {
|
|
|
11303
11827
|
return filePath;
|
|
11304
11828
|
}
|
|
11305
11829
|
for (const ext of SOURCE_EXTS3) {
|
|
11306
|
-
const filePath =
|
|
11830
|
+
const filePath = path27.join(absPathNoExt, `index${ext}`);
|
|
11307
11831
|
if (await Bun.file(filePath).exists())
|
|
11308
11832
|
return filePath;
|
|
11309
11833
|
}
|
|
@@ -11326,19 +11850,19 @@ function resolveSourceWithRequire(id, fromBase) {
|
|
|
11326
11850
|
}
|
|
11327
11851
|
}
|
|
11328
11852
|
function isSourceFile(filePath) {
|
|
11329
|
-
return SOURCE_EXTS3.includes(
|
|
11853
|
+
return SOURCE_EXTS3.includes(path27.extname(filePath));
|
|
11330
11854
|
}
|
|
11331
11855
|
function isIgnoredNodeModuleSource(filePath) {
|
|
11332
11856
|
return NODE_MODULES_RE3.test(filePath) && !AKANJS_NODE_MODULE_RE3.test(filePath);
|
|
11333
11857
|
}
|
|
11334
11858
|
function getPageKeyBasePath(pageKey, basePaths) {
|
|
11335
|
-
const normalized = pageKey.split(
|
|
11859
|
+
const normalized = pageKey.split(path27.sep).join("/").replace(/^\.\//, "");
|
|
11336
11860
|
const segments = normalized.split("/");
|
|
11337
11861
|
const firstPublicSegment = segments.find((segment) => segment !== "[lang]" && !/^\(.+\)$/.test(segment));
|
|
11338
11862
|
return firstPublicSegment && basePaths.includes(firstPublicSegment) ? firstPublicSegment : null;
|
|
11339
11863
|
}
|
|
11340
11864
|
// pkgs/@akanjs/devkit/frontendBuild/devChangePlanner.ts
|
|
11341
|
-
import
|
|
11865
|
+
import path28 from "path";
|
|
11342
11866
|
var SOURCE_EXTS4 = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
11343
11867
|
var CONFIG_BASENAMES = new Set(["akan.config.ts", "bunfig.toml", "tsconfig.json", "package.json"]);
|
|
11344
11868
|
var BARREL_FACETS = new Set(["common", "srvkit", "ui", "webkit", "plugin"]);
|
|
@@ -11350,11 +11874,11 @@ var RUNTIME_METADATA_BASENAMES2 = new Set(["dict.ts", "sig.ts", "useClient.ts",
|
|
|
11350
11874
|
class DevChangePlanner {
|
|
11351
11875
|
#workspaceRoot;
|
|
11352
11876
|
constructor({ workspaceRoot }) {
|
|
11353
|
-
this.#workspaceRoot =
|
|
11877
|
+
this.#workspaceRoot = path28.resolve(workspaceRoot);
|
|
11354
11878
|
}
|
|
11355
11879
|
plan({ generation, files, kinds, generatedFiles: generatedFiles2 = [] }) {
|
|
11356
11880
|
const fileList = uniqueResolved([...files, ...generatedFiles2]);
|
|
11357
|
-
const generatedSet = new Set(generatedFiles2.map((file) =>
|
|
11881
|
+
const generatedSet = new Set(generatedFiles2.map((file) => path28.resolve(file)));
|
|
11358
11882
|
const kindSet = new Set(kinds);
|
|
11359
11883
|
const roles = new Set;
|
|
11360
11884
|
const actions = new Set;
|
|
@@ -11371,13 +11895,13 @@ class DevChangePlanner {
|
|
|
11371
11895
|
}
|
|
11372
11896
|
for (const file of fileList) {
|
|
11373
11897
|
const reasons = new Set;
|
|
11374
|
-
const fileRoles = this.#rolesForFile(file, { isGenerated: generatedSet.has(
|
|
11898
|
+
const fileRoles = this.#rolesForFile(file, { isGenerated: generatedSet.has(path28.resolve(file)), reasons });
|
|
11375
11899
|
for (const role of fileRoles)
|
|
11376
11900
|
roles.add(role);
|
|
11377
11901
|
if (reasons.has("runtime-metadata"))
|
|
11378
11902
|
actions.add("restart-builder");
|
|
11379
11903
|
if (reasons.size > 0)
|
|
11380
|
-
reasonByFile[
|
|
11904
|
+
reasonByFile[path28.resolve(file)] = [...reasons].sort();
|
|
11381
11905
|
}
|
|
11382
11906
|
if (roles.has("barrel"))
|
|
11383
11907
|
actions.add("sync-generated");
|
|
@@ -11398,12 +11922,12 @@ class DevChangePlanner {
|
|
|
11398
11922
|
}
|
|
11399
11923
|
#rolesForFile(file, { isGenerated, reasons }) {
|
|
11400
11924
|
const roles = new Set;
|
|
11401
|
-
const abs =
|
|
11402
|
-
const base =
|
|
11403
|
-
const ext =
|
|
11925
|
+
const abs = path28.resolve(file);
|
|
11926
|
+
const base = path28.basename(abs);
|
|
11927
|
+
const ext = path28.extname(abs).toLowerCase();
|
|
11404
11928
|
const isSource = SOURCE_EXTS4.has(ext);
|
|
11405
|
-
const rel =
|
|
11406
|
-
const parts = rel.split(
|
|
11929
|
+
const rel = path28.relative(this.#workspaceRoot, abs);
|
|
11930
|
+
const parts = rel.split(path28.sep).filter(Boolean);
|
|
11407
11931
|
if (CONFIG_BASENAMES.has(base)) {
|
|
11408
11932
|
roles.add("config");
|
|
11409
11933
|
reasons.add("config-file");
|
|
@@ -11444,15 +11968,15 @@ class DevChangePlanner {
|
|
|
11444
11968
|
return roles;
|
|
11445
11969
|
}
|
|
11446
11970
|
#isServerBiased(abs, parts) {
|
|
11447
|
-
const base =
|
|
11971
|
+
const base = path28.basename(abs);
|
|
11448
11972
|
return parts.includes("srvkit") || SERVER_SUFFIXES2.some((suffix) => base.endsWith(suffix)) || base === "main.ts" || base === "server.ts";
|
|
11449
11973
|
}
|
|
11450
11974
|
#isClientBiased(abs, parts) {
|
|
11451
|
-
const base =
|
|
11975
|
+
const base = path28.basename(abs);
|
|
11452
11976
|
return parts.includes("ui") || parts.includes("webkit") || parts.includes("page") || CLIENT_SUFFIXES.some((suffix) => base.endsWith(suffix));
|
|
11453
11977
|
}
|
|
11454
11978
|
#isSharedBiased(abs, parts) {
|
|
11455
|
-
const base =
|
|
11979
|
+
const base = path28.basename(abs);
|
|
11456
11980
|
return parts.includes("common") || SHARED_SUFFIXES2.some((suffix) => base.endsWith(suffix)) || RUNTIME_METADATA_BASENAMES2.has(base);
|
|
11457
11981
|
}
|
|
11458
11982
|
#isRuntimeMetadataFile(parts, base) {
|
|
@@ -11477,16 +12001,16 @@ class DevChangePlanner {
|
|
|
11477
12001
|
return true;
|
|
11478
12002
|
}
|
|
11479
12003
|
#isWorkspaceSource(rel) {
|
|
11480
|
-
if (!rel || rel.startsWith("..") ||
|
|
12004
|
+
if (!rel || rel.startsWith("..") || path28.isAbsolute(rel))
|
|
11481
12005
|
return false;
|
|
11482
|
-
const [scope] = rel.split(
|
|
12006
|
+
const [scope] = rel.split(path28.sep);
|
|
11483
12007
|
return scope === "apps" || scope === "libs" || scope === "pkgs";
|
|
11484
12008
|
}
|
|
11485
12009
|
}
|
|
11486
|
-
var uniqueResolved = (files) => [...new Set(files.map((file) =>
|
|
12010
|
+
var uniqueResolved = (files) => [...new Set(files.map((file) => path28.resolve(file)))].sort();
|
|
11487
12011
|
// pkgs/@akanjs/devkit/frontendBuild/devGeneratedIndexSync.ts
|
|
11488
|
-
import { mkdir as mkdir6, readdir as
|
|
11489
|
-
import
|
|
12012
|
+
import { mkdir as mkdir6, readdir as readdir3, readFile as readFile2, rm as rm3, stat as stat4, writeFile as writeFile2 } from "fs/promises";
|
|
12013
|
+
import path29 from "path";
|
|
11490
12014
|
var BARREL_FACETS2 = new Set(["common", "srvkit", "ui", "webkit", "plugin"]);
|
|
11491
12015
|
var FACET_SOURCE_FILE_RE = /\.(ts|tsx)$/;
|
|
11492
12016
|
var FACET_EXCLUDED_FILE_RE = /(^index\.tsx?$|\.d\.ts$|\.(test|spec)\.(ts|tsx)$|\.css$|\.scss$|\.sass$)/;
|
|
@@ -11499,7 +12023,7 @@ var SCALAR_UI_TYPES = ["Template", "Unit"];
|
|
|
11499
12023
|
class DevGeneratedIndexSync {
|
|
11500
12024
|
#workspaceRoot;
|
|
11501
12025
|
constructor({ workspaceRoot }) {
|
|
11502
|
-
this.#workspaceRoot =
|
|
12026
|
+
this.#workspaceRoot = path29.resolve(workspaceRoot);
|
|
11503
12027
|
}
|
|
11504
12028
|
async syncForBatch(files) {
|
|
11505
12029
|
const indexPaths = new Set;
|
|
@@ -11509,7 +12033,7 @@ class DevGeneratedIndexSync {
|
|
|
11509
12033
|
if (facetIndex)
|
|
11510
12034
|
indexPaths.add(facetIndex);
|
|
11511
12035
|
const moduleIndex2 = await this.#moduleIndexForDirectoryEvent(file).catch((err) => {
|
|
11512
|
-
errors.push(`[generated-index] module detection failed for ${file}: ${
|
|
12036
|
+
errors.push(`[generated-index] module detection failed for ${file}: ${formatError2(err)}`);
|
|
11513
12037
|
return null;
|
|
11514
12038
|
});
|
|
11515
12039
|
if (moduleIndex2)
|
|
@@ -11522,17 +12046,17 @@ class DevGeneratedIndexSync {
|
|
|
11522
12046
|
if (changed)
|
|
11523
12047
|
changedFiles.push(indexPath);
|
|
11524
12048
|
} catch (err) {
|
|
11525
|
-
errors.push(`[generated-index] sync failed for ${indexPath}: ${
|
|
12049
|
+
errors.push(`[generated-index] sync failed for ${indexPath}: ${formatError2(err)}`);
|
|
11526
12050
|
}
|
|
11527
12051
|
}
|
|
11528
12052
|
return { changedFiles, errors };
|
|
11529
12053
|
}
|
|
11530
12054
|
#facetIndexFor(file) {
|
|
11531
|
-
const abs =
|
|
11532
|
-
const rel =
|
|
11533
|
-
if (rel.startsWith("..") ||
|
|
12055
|
+
const abs = path29.resolve(file);
|
|
12056
|
+
const rel = path29.relative(this.#workspaceRoot, abs);
|
|
12057
|
+
if (rel.startsWith("..") || path29.isAbsolute(rel))
|
|
11534
12058
|
return null;
|
|
11535
|
-
const parts = rel.split(
|
|
12059
|
+
const parts = rel.split(path29.sep).filter(Boolean);
|
|
11536
12060
|
if (parts.length < 4)
|
|
11537
12061
|
return null;
|
|
11538
12062
|
const [scope, project, facet, child] = parts;
|
|
@@ -11540,32 +12064,32 @@ class DevGeneratedIndexSync {
|
|
|
11540
12064
|
return null;
|
|
11541
12065
|
if (!child || child.startsWith(".") || child === "index.ts" || child === "index.tsx")
|
|
11542
12066
|
return null;
|
|
11543
|
-
return
|
|
12067
|
+
return path29.join(this.#workspaceRoot, scope, project, facet, "index.ts");
|
|
11544
12068
|
}
|
|
11545
12069
|
async#moduleIndexForDirectoryEvent(file) {
|
|
11546
|
-
const abs =
|
|
11547
|
-
const rel =
|
|
11548
|
-
if (rel.startsWith("..") ||
|
|
12070
|
+
const abs = path29.resolve(file);
|
|
12071
|
+
const rel = path29.relative(this.#workspaceRoot, abs);
|
|
12072
|
+
if (rel.startsWith("..") || path29.isAbsolute(rel))
|
|
11549
12073
|
return null;
|
|
11550
|
-
const parts = rel.split(
|
|
12074
|
+
const parts = rel.split(path29.sep).filter(Boolean);
|
|
11551
12075
|
if (parts.length !== 4 && parts.length !== 5)
|
|
11552
12076
|
return null;
|
|
11553
12077
|
const [scope, project, libSegment, moduleSegment, scalarSegment] = parts;
|
|
11554
12078
|
if (scope !== "apps" && scope !== "libs" || !project || libSegment !== "lib")
|
|
11555
12079
|
return null;
|
|
11556
|
-
const isExistingDirectory = await
|
|
11557
|
-
const looksLikeDeletedDirectory = !
|
|
12080
|
+
const isExistingDirectory = await stat4(abs).then((s) => s.isDirectory()).catch(() => false);
|
|
12081
|
+
const looksLikeDeletedDirectory = !path29.extname(abs);
|
|
11558
12082
|
if (!isExistingDirectory && !looksLikeDeletedDirectory)
|
|
11559
12083
|
return null;
|
|
11560
12084
|
if (moduleSegment === "__scalar" && scalarSegment) {
|
|
11561
|
-
return
|
|
12085
|
+
return path29.join(this.#workspaceRoot, scope, project, "lib", "__scalar", scalarSegment, "index.ts");
|
|
11562
12086
|
}
|
|
11563
12087
|
if (!moduleSegment || moduleSegment === "__scalar")
|
|
11564
12088
|
return null;
|
|
11565
|
-
return
|
|
12089
|
+
return path29.join(this.#workspaceRoot, scope, project, "lib", moduleSegment, "index.ts");
|
|
11566
12090
|
}
|
|
11567
12091
|
async#syncIndex(indexPath) {
|
|
11568
|
-
const dir =
|
|
12092
|
+
const dir = path29.dirname(indexPath);
|
|
11569
12093
|
const content = await this.#contentForIndex(indexPath);
|
|
11570
12094
|
if (content === null) {
|
|
11571
12095
|
if (!await exists(indexPath))
|
|
@@ -11573,23 +12097,23 @@ class DevGeneratedIndexSync {
|
|
|
11573
12097
|
await rm3(indexPath, { force: true });
|
|
11574
12098
|
return true;
|
|
11575
12099
|
}
|
|
11576
|
-
const current = await
|
|
12100
|
+
const current = await readFile2(indexPath, "utf8").catch(() => null);
|
|
11577
12101
|
if (current === content)
|
|
11578
12102
|
return false;
|
|
11579
12103
|
await mkdir6(dir, { recursive: true });
|
|
11580
|
-
await
|
|
12104
|
+
await writeFile2(indexPath, content);
|
|
11581
12105
|
return true;
|
|
11582
12106
|
}
|
|
11583
12107
|
async#contentForIndex(indexPath) {
|
|
11584
|
-
const parts =
|
|
12108
|
+
const parts = path29.relative(this.#workspaceRoot, indexPath).split(path29.sep).filter(Boolean);
|
|
11585
12109
|
const facet = parts.at(-2);
|
|
11586
12110
|
if (facet && BARREL_FACETS2.has(facet))
|
|
11587
|
-
return this.#facetContent(
|
|
11588
|
-
return this.#moduleContent(
|
|
12111
|
+
return this.#facetContent(path29.dirname(indexPath));
|
|
12112
|
+
return this.#moduleContent(path29.dirname(indexPath));
|
|
11589
12113
|
}
|
|
11590
12114
|
async#facetContent(dir) {
|
|
11591
|
-
const nameCasePattern =
|
|
11592
|
-
const entries = await
|
|
12115
|
+
const nameCasePattern = path29.basename(dir) === "ui" ? FACET_PASCAL_CASE_RE : FACET_CAMEL_CASE_RE;
|
|
12116
|
+
const entries = await readdir3(dir, { withFileTypes: true }).catch(() => []);
|
|
11593
12117
|
const exportNames = entries.flatMap((entry) => {
|
|
11594
12118
|
const name = entry.name;
|
|
11595
12119
|
if (name.startsWith("."))
|
|
@@ -11610,8 +12134,8 @@ class DevGeneratedIndexSync {
|
|
|
11610
12134
|
`;
|
|
11611
12135
|
}
|
|
11612
12136
|
async#moduleContent(dir) {
|
|
11613
|
-
const rel =
|
|
11614
|
-
const parts = rel.split(
|
|
12137
|
+
const rel = path29.relative(this.#workspaceRoot, dir);
|
|
12138
|
+
const parts = rel.split(path29.sep).filter(Boolean);
|
|
11615
12139
|
const moduleSegment = parts.at(-1);
|
|
11616
12140
|
if (!moduleSegment)
|
|
11617
12141
|
return null;
|
|
@@ -11623,7 +12147,7 @@ class DevGeneratedIndexSync {
|
|
|
11623
12147
|
const allowedTypes = isScalar ? SCALAR_UI_TYPES : moduleSegment.startsWith("_") ? SERVICE_UI_TYPES : MODULE_UI_TYPES;
|
|
11624
12148
|
const fileTypes = [];
|
|
11625
12149
|
for (const type of allowedTypes) {
|
|
11626
|
-
if (await exists(
|
|
12150
|
+
if (await exists(path29.join(dir, `${modelName}.${type}.tsx`)))
|
|
11627
12151
|
fileTypes.push(type);
|
|
11628
12152
|
}
|
|
11629
12153
|
if (fileTypes.length === 0)
|
|
@@ -11635,12 +12159,12 @@ ${fileTypes.map((type) => `import * as ${type} from "./${modelName}.${type}";`).
|
|
|
11635
12159
|
export const ${modelName} = { ${fileTypes.join(", ")} };`;
|
|
11636
12160
|
}
|
|
11637
12161
|
}
|
|
11638
|
-
var exists = async (file) =>
|
|
12162
|
+
var exists = async (file) => stat4(file).then(() => true).catch(() => false);
|
|
11639
12163
|
var capitalize4 = (value) => `${value.charAt(0).toUpperCase()}${value.slice(1)}`;
|
|
11640
|
-
var
|
|
12164
|
+
var formatError2 = (err) => err instanceof Error ? err.message : String(err);
|
|
11641
12165
|
// pkgs/@akanjs/devkit/frontendBuild/fontOptimizer.ts
|
|
11642
12166
|
import { mkdir as mkdir7 } from "fs/promises";
|
|
11643
|
-
import
|
|
12167
|
+
import path30 from "path";
|
|
11644
12168
|
import {
|
|
11645
12169
|
generateFontFace,
|
|
11646
12170
|
getMetricsForFamily,
|
|
@@ -11649,7 +12173,7 @@ import {
|
|
|
11649
12173
|
} from "fontaine";
|
|
11650
12174
|
import { createFont, woff2 } from "fonteditor-core";
|
|
11651
12175
|
import subsetFont from "subset-font";
|
|
11652
|
-
import
|
|
12176
|
+
import ts10 from "typescript";
|
|
11653
12177
|
var FONT_URL_PREFIX = "/_akan/fonts";
|
|
11654
12178
|
var DEFAULT_FONT_SUBSETS = ["latin"];
|
|
11655
12179
|
|
|
@@ -11664,7 +12188,7 @@ class FontOptimizer {
|
|
|
11664
12188
|
constructor(app, command = "start") {
|
|
11665
12189
|
this.#app = app;
|
|
11666
12190
|
this.#command = command;
|
|
11667
|
-
this.#artifactRoot =
|
|
12191
|
+
this.#artifactRoot = path30.join(command === "build" ? app.dist.cwdPath : app.cwdPath, ".akan/artifact");
|
|
11668
12192
|
}
|
|
11669
12193
|
async optimize() {
|
|
11670
12194
|
const fonts = await this.discoverFonts();
|
|
@@ -11683,7 +12207,7 @@ class FontOptimizer {
|
|
|
11683
12207
|
const pageKeys = await this.#app.getPageKeys();
|
|
11684
12208
|
const fonts = [];
|
|
11685
12209
|
await Promise.all(pageKeys.map(async (key) => {
|
|
11686
|
-
const filePath =
|
|
12210
|
+
const filePath = path30.resolve(this.#app.cwdPath, "page", key);
|
|
11687
12211
|
const file = Bun.file(filePath);
|
|
11688
12212
|
if (!await file.exists())
|
|
11689
12213
|
return;
|
|
@@ -11699,8 +12223,8 @@ class FontOptimizer {
|
|
|
11699
12223
|
this.#app.logger.warn(`[font] source not found: ${face.src}`);
|
|
11700
12224
|
continue;
|
|
11701
12225
|
}
|
|
11702
|
-
const outputPath =
|
|
11703
|
-
await mkdir7(
|
|
12226
|
+
const outputPath = path30.join(this.#artifactRoot, face.optimizedSrc.replace(/^\/_akan\//, ""));
|
|
12227
|
+
await mkdir7(path30.dirname(outputPath), { recursive: true });
|
|
11704
12228
|
const sourceBuffer = Buffer.from(await Bun.file(sourcePath).arrayBuffer());
|
|
11705
12229
|
const outputBuffer = font.subset === false ? await this.#convertToWoff2(sourceBuffer, sourcePath) : await subsetFont(sourceBuffer, await this.#getSubsetText(font), { targetFormat: "woff2" });
|
|
11706
12230
|
await Bun.write(outputPath, outputBuffer);
|
|
@@ -11714,17 +12238,17 @@ class FontOptimizer {
|
|
|
11714
12238
|
this.#cssParts.push(...faceCss, this.#buildRootVariableRule(font));
|
|
11715
12239
|
}
|
|
11716
12240
|
#extractFontsExport(source2, filePath) {
|
|
11717
|
-
const sourceFile2 =
|
|
12241
|
+
const sourceFile2 = ts10.createSourceFile(filePath, source2, ts10.ScriptTarget.Latest, true, ts10.ScriptKind.TSX);
|
|
11718
12242
|
const fonts = [];
|
|
11719
12243
|
for (const statement of sourceFile2.statements) {
|
|
11720
|
-
if (!
|
|
12244
|
+
if (!ts10.isVariableStatement(statement))
|
|
11721
12245
|
continue;
|
|
11722
|
-
const modifiers =
|
|
11723
|
-
const isExported = modifiers?.some((modifier) => modifier.kind ===
|
|
12246
|
+
const modifiers = ts10.canHaveModifiers(statement) ? ts10.getModifiers(statement) : undefined;
|
|
12247
|
+
const isExported = modifiers?.some((modifier) => modifier.kind === ts10.SyntaxKind.ExportKeyword) ?? false;
|
|
11724
12248
|
if (!isExported)
|
|
11725
12249
|
continue;
|
|
11726
12250
|
for (const declaration of statement.declarationList.declarations) {
|
|
11727
|
-
if (!
|
|
12251
|
+
if (!ts10.isIdentifier(declaration.name) || declaration.name.text !== "fonts")
|
|
11728
12252
|
continue;
|
|
11729
12253
|
const value = declaration.initializer ? this.#literalToValue(declaration.initializer) : null;
|
|
11730
12254
|
if (Array.isArray(value)) {
|
|
@@ -11735,20 +12259,20 @@ class FontOptimizer {
|
|
|
11735
12259
|
return fonts;
|
|
11736
12260
|
}
|
|
11737
12261
|
#literalToValue(node) {
|
|
11738
|
-
if (
|
|
12262
|
+
if (ts10.isStringLiteralLike(node))
|
|
11739
12263
|
return node.text;
|
|
11740
|
-
if (
|
|
12264
|
+
if (ts10.isNumericLiteral(node))
|
|
11741
12265
|
return Number(node.text);
|
|
11742
|
-
if (node.kind ===
|
|
12266
|
+
if (node.kind === ts10.SyntaxKind.TrueKeyword)
|
|
11743
12267
|
return true;
|
|
11744
|
-
if (node.kind ===
|
|
12268
|
+
if (node.kind === ts10.SyntaxKind.FalseKeyword)
|
|
11745
12269
|
return false;
|
|
11746
|
-
if (
|
|
12270
|
+
if (ts10.isArrayLiteralExpression(node))
|
|
11747
12271
|
return node.elements.map((element) => this.#literalToValue(element));
|
|
11748
|
-
if (
|
|
12272
|
+
if (ts10.isObjectLiteralExpression(node)) {
|
|
11749
12273
|
const obj = {};
|
|
11750
12274
|
for (const prop of node.properties) {
|
|
11751
|
-
if (!
|
|
12275
|
+
if (!ts10.isPropertyAssignment(prop))
|
|
11752
12276
|
continue;
|
|
11753
12277
|
const name = this.#getPropertyName(prop.name);
|
|
11754
12278
|
if (!name)
|
|
@@ -11757,13 +12281,13 @@ class FontOptimizer {
|
|
|
11757
12281
|
}
|
|
11758
12282
|
return obj;
|
|
11759
12283
|
}
|
|
11760
|
-
if (
|
|
12284
|
+
if (ts10.isAsExpression(node) || ts10.isSatisfiesExpression(node) || ts10.isParenthesizedExpression(node)) {
|
|
11761
12285
|
return this.#literalToValue(node.expression);
|
|
11762
12286
|
}
|
|
11763
12287
|
return;
|
|
11764
12288
|
}
|
|
11765
12289
|
#getPropertyName(name) {
|
|
11766
|
-
if (
|
|
12290
|
+
if (ts10.isIdentifier(name) || ts10.isStringLiteral(name) || ts10.isNumericLiteral(name))
|
|
11767
12291
|
return name.text;
|
|
11768
12292
|
return null;
|
|
11769
12293
|
}
|
|
@@ -11847,8 +12371,8 @@ class FontOptimizer {
|
|
|
11847
12371
|
return null;
|
|
11848
12372
|
const rel = src.replace(/^\//, "");
|
|
11849
12373
|
const candidates = [
|
|
11850
|
-
this.#command === "build" ?
|
|
11851
|
-
|
|
12374
|
+
this.#command === "build" ? path30.join(this.#app.dist.cwdPath, "public", rel) : null,
|
|
12375
|
+
path30.join(this.#app.cwdPath, "public", rel),
|
|
11852
12376
|
this.#resolveWorkspacePublicPath(rel)
|
|
11853
12377
|
].filter(Boolean);
|
|
11854
12378
|
for (const candidate of candidates) {
|
|
@@ -11876,7 +12400,7 @@ class FontOptimizer {
|
|
|
11876
12400
|
return "woff2";
|
|
11877
12401
|
if (signature === "OTTO")
|
|
11878
12402
|
return "otf";
|
|
11879
|
-
const ext =
|
|
12403
|
+
const ext = path30.extname(sourcePath).slice(1).toLowerCase();
|
|
11880
12404
|
if (ext === "otf" || ext === "woff" || ext === "woff2")
|
|
11881
12405
|
return ext;
|
|
11882
12406
|
return "ttf";
|
|
@@ -11885,7 +12409,7 @@ class FontOptimizer {
|
|
|
11885
12409
|
const [root, dep, ...rest] = rel.split("/");
|
|
11886
12410
|
if (root !== "libs" || !dep || rest.length === 0)
|
|
11887
12411
|
return null;
|
|
11888
|
-
return
|
|
12412
|
+
return path30.join(this.#app.workspace.workspaceRoot, "libs", dep, "public", ...rest);
|
|
11889
12413
|
}
|
|
11890
12414
|
async#getSubsetText(font) {
|
|
11891
12415
|
const parts = new Set;
|
|
@@ -11895,7 +12419,7 @@ class FontOptimizer {
|
|
|
11895
12419
|
if (font.subsetText)
|
|
11896
12420
|
parts.add(font.subsetText);
|
|
11897
12421
|
for (const filePath of font.subsetFiles ?? []) {
|
|
11898
|
-
const abs =
|
|
12422
|
+
const abs = path30.isAbsolute(filePath) ? filePath : path30.join(this.#app.cwdPath, filePath);
|
|
11899
12423
|
const file = Bun.file(abs);
|
|
11900
12424
|
if (await file.exists())
|
|
11901
12425
|
parts.add(await file.text());
|
|
@@ -11914,7 +12438,7 @@ class FontOptimizer {
|
|
|
11914
12438
|
return "";
|
|
11915
12439
|
}
|
|
11916
12440
|
async#collectAutoSubsetText() {
|
|
11917
|
-
const roots = ["page", "ui"].map((dir) =>
|
|
12441
|
+
const roots = ["page", "ui"].map((dir) => path30.join(this.#app.cwdPath, dir));
|
|
11918
12442
|
const glob = new Bun.Glob("**/*.{ts,tsx,js,jsx,html,md}");
|
|
11919
12443
|
const parts = [];
|
|
11920
12444
|
await Promise.all(roots.map(async (root) => {
|
|
@@ -12028,7 +12552,7 @@ ${declarations.map(([prop, value]) => ` ${prop}: ${value};`).join(`
|
|
|
12028
12552
|
}
|
|
12029
12553
|
}
|
|
12030
12554
|
// pkgs/@akanjs/devkit/frontendBuild/hmrChangeClassifier.ts
|
|
12031
|
-
import
|
|
12555
|
+
import path31 from "path";
|
|
12032
12556
|
var SOURCE_EXTS5 = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
12033
12557
|
var CSS_EXTS = new Set([".css"]);
|
|
12034
12558
|
var CONFIG_BASENAMES2 = new Set(["akan.config.ts", "bunfig.toml", "tsconfig.json", "package.json"]);
|
|
@@ -12037,10 +12561,10 @@ class HmrChangeClassifier {
|
|
|
12037
12561
|
classify(abs) {
|
|
12038
12562
|
if (this.#isUninteresting(abs))
|
|
12039
12563
|
return "ignore";
|
|
12040
|
-
const base =
|
|
12564
|
+
const base = path31.basename(abs);
|
|
12041
12565
|
if (CONFIG_BASENAMES2.has(base))
|
|
12042
12566
|
return "config";
|
|
12043
|
-
const ext =
|
|
12567
|
+
const ext = path31.extname(abs).toLowerCase();
|
|
12044
12568
|
if (CSS_EXTS.has(ext))
|
|
12045
12569
|
return "css";
|
|
12046
12570
|
if (SOURCE_EXTS5.has(ext))
|
|
@@ -12048,23 +12572,23 @@ class HmrChangeClassifier {
|
|
|
12048
12572
|
return "ignore";
|
|
12049
12573
|
}
|
|
12050
12574
|
#isUninteresting(abs) {
|
|
12051
|
-
const base =
|
|
12575
|
+
const base = path31.basename(abs);
|
|
12052
12576
|
if (!base)
|
|
12053
12577
|
return true;
|
|
12054
12578
|
if (base.startsWith("."))
|
|
12055
12579
|
return true;
|
|
12056
12580
|
if (base.endsWith("~") || base.endsWith(".swp") || base.endsWith(".swx") || base.endsWith(".tmp"))
|
|
12057
12581
|
return true;
|
|
12058
|
-
if (abs.includes(`${
|
|
12582
|
+
if (abs.includes(`${path31.sep}node_modules${path31.sep}`))
|
|
12059
12583
|
return true;
|
|
12060
|
-
if (abs.includes(`${
|
|
12584
|
+
if (abs.includes(`${path31.sep}.akan${path31.sep}`))
|
|
12061
12585
|
return true;
|
|
12062
12586
|
return false;
|
|
12063
12587
|
}
|
|
12064
12588
|
}
|
|
12065
12589
|
// pkgs/@akanjs/devkit/frontendBuild/hmrWatcher.ts
|
|
12066
12590
|
import fs4 from "fs";
|
|
12067
|
-
import
|
|
12591
|
+
import path32 from "path";
|
|
12068
12592
|
class HmrWatcher {
|
|
12069
12593
|
#roots;
|
|
12070
12594
|
#debounceMs;
|
|
@@ -12077,7 +12601,7 @@ class HmrWatcher {
|
|
|
12077
12601
|
#stopped = false;
|
|
12078
12602
|
#flushing = false;
|
|
12079
12603
|
constructor(opts) {
|
|
12080
|
-
this.#roots = [...new Set(opts.roots.map((r) =>
|
|
12604
|
+
this.#roots = [...new Set(opts.roots.map((r) => path32.resolve(r)))];
|
|
12081
12605
|
this.#debounceMs = opts.debounceMs ?? 80;
|
|
12082
12606
|
this.#onBatch = opts.onBatch;
|
|
12083
12607
|
this.#logger = opts.logger;
|
|
@@ -12088,7 +12612,7 @@ class HmrWatcher {
|
|
|
12088
12612
|
const w = fs4.watch(root, { recursive: true, persistent: false }, (_event, filename) => {
|
|
12089
12613
|
if (!filename)
|
|
12090
12614
|
return;
|
|
12091
|
-
const abs =
|
|
12615
|
+
const abs = path32.resolve(root, filename.toString());
|
|
12092
12616
|
this.#queue(abs);
|
|
12093
12617
|
});
|
|
12094
12618
|
this.#watchers.push(w);
|
|
@@ -12146,10 +12670,10 @@ class HmrWatcher {
|
|
|
12146
12670
|
}
|
|
12147
12671
|
}
|
|
12148
12672
|
// pkgs/@akanjs/devkit/frontendBuild/pagesBundleBuilder.ts
|
|
12149
|
-
import
|
|
12673
|
+
import path34 from "path";
|
|
12150
12674
|
|
|
12151
12675
|
// pkgs/@akanjs/devkit/transforms/externalizeFrameworkPlugin.ts
|
|
12152
|
-
import
|
|
12676
|
+
import path33 from "path";
|
|
12153
12677
|
var DEFAULT_INCLUDE = ["akanjs/", "@apps/", "@libs/"];
|
|
12154
12678
|
var DEFAULT_EXCLUDE_EXACT = new Set(["akanjs/webkit", "@akanjs/cli", "@akanjs/devkit"]);
|
|
12155
12679
|
var DEFAULT_EXCLUDE_PREFIX = ["@akanjs/cli/", "@akanjs/devkit/"];
|
|
@@ -12192,7 +12716,7 @@ async function createExternalizeFrameworkPlugin(options) {
|
|
|
12192
12716
|
const replPath = repl?.endsWith("/*") ? repl.slice(0, -1) : repl ?? "";
|
|
12193
12717
|
if (!replPath)
|
|
12194
12718
|
continue;
|
|
12195
|
-
const candidate =
|
|
12719
|
+
const candidate = path33.resolve(workspaceRoot, replPath + suffix);
|
|
12196
12720
|
const hit = await firstExisting(candidate);
|
|
12197
12721
|
if (hit)
|
|
12198
12722
|
return hit;
|
|
@@ -12204,8 +12728,8 @@ async function createExternalizeFrameworkPlugin(options) {
|
|
|
12204
12728
|
if (spec === pkg)
|
|
12205
12729
|
continue;
|
|
12206
12730
|
const suffix = spec.slice(pkg.length + 1);
|
|
12207
|
-
const pkgDir =
|
|
12208
|
-
const candidate =
|
|
12731
|
+
const pkgDir = path33.dirname(path33.resolve(workspaceRoot, entryFile));
|
|
12732
|
+
const candidate = path33.join(pkgDir, suffix);
|
|
12209
12733
|
const hit = await firstExisting(candidate);
|
|
12210
12734
|
if (hit)
|
|
12211
12735
|
return hit;
|
|
@@ -12255,7 +12779,7 @@ async function firstExisting(basePath2) {
|
|
|
12255
12779
|
return candidate;
|
|
12256
12780
|
}
|
|
12257
12781
|
for (const ext of CANDIDATE_EXTS3) {
|
|
12258
|
-
const candidate =
|
|
12782
|
+
const candidate = path33.join(basePath2, `index${ext}`);
|
|
12259
12783
|
if (await Bun.file(candidate).exists())
|
|
12260
12784
|
return candidate;
|
|
12261
12785
|
}
|
|
@@ -12346,11 +12870,11 @@ class PagesBundleBuilder {
|
|
|
12346
12870
|
const entryArtifact = result.outputs.find((a) => a.kind === "entry-point");
|
|
12347
12871
|
if (!entryArtifact)
|
|
12348
12872
|
throw new Error("[PagesBundleBuilder] Bun.build emitted no entry-point artifact");
|
|
12349
|
-
const bundlePath =
|
|
12873
|
+
const bundlePath = path34.resolve(entryArtifact.path);
|
|
12350
12874
|
const buildId = Date.now();
|
|
12351
12875
|
const outputBytes = result.outputs.reduce((sum, output) => sum + output.size, 0);
|
|
12352
12876
|
const chunkCount = result.outputs.filter((output) => output.kind === "chunk").length;
|
|
12353
|
-
this.#app.verbose(`[PagesBundleBuilder] ${
|
|
12877
|
+
this.#app.verbose(`[PagesBundleBuilder] ${path34.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`);
|
|
12354
12878
|
return {
|
|
12355
12879
|
bundlePath,
|
|
12356
12880
|
buildId,
|
|
@@ -12432,11 +12956,11 @@ function loaderFor4(absPath) {
|
|
|
12432
12956
|
}
|
|
12433
12957
|
// pkgs/@akanjs/devkit/frontendBuild/precompressArtifacts.ts
|
|
12434
12958
|
import fs5 from "fs";
|
|
12435
|
-
import
|
|
12959
|
+
import path35 from "path";
|
|
12436
12960
|
var COMPRESSIBLE_EXTS = new Set([".css", ".html", ".js", ".json", ".svg"]);
|
|
12437
12961
|
var MIN_COMPRESS_BYTES = 1024;
|
|
12438
12962
|
async function precompressArtifacts(app) {
|
|
12439
|
-
const roots = [
|
|
12963
|
+
const roots = [path35.join(app.dist.cwdPath, ".akan/artifact/client")];
|
|
12440
12964
|
const result = { files: 0, inputBytes: 0, outputBytes: 0 };
|
|
12441
12965
|
await Promise.all(roots.map((root) => precompressRoot(root, result)));
|
|
12442
12966
|
if (result.files > 0) {
|
|
@@ -12462,7 +12986,7 @@ async function precompressRoot(root, result) {
|
|
|
12462
12986
|
async function shouldPrecompress(filePath) {
|
|
12463
12987
|
if (filePath.endsWith(".gz"))
|
|
12464
12988
|
return false;
|
|
12465
|
-
if (!COMPRESSIBLE_EXTS.has(
|
|
12989
|
+
if (!COMPRESSIBLE_EXTS.has(path35.extname(filePath).toLowerCase()))
|
|
12466
12990
|
return false;
|
|
12467
12991
|
const file = Bun.file(filePath);
|
|
12468
12992
|
if (!await file.exists())
|
|
@@ -12480,7 +13004,7 @@ function formatBytes(bytes) {
|
|
|
12480
13004
|
return `${(bytes / 1024 / 1024).toFixed(1)}MB`;
|
|
12481
13005
|
}
|
|
12482
13006
|
// pkgs/@akanjs/devkit/frontendBuild/ssrBaseArtifactBuilder.ts
|
|
12483
|
-
import
|
|
13007
|
+
import path36 from "path";
|
|
12484
13008
|
import { optimize } from "@tailwindcss/node";
|
|
12485
13009
|
function prepareCssAsset(command, basePath2, cssText) {
|
|
12486
13010
|
return optimize(cssText, { file: `${basePath2 || "root"}.css`, minify: command === "build" }).code;
|
|
@@ -12496,7 +13020,7 @@ class SsrBaseArtifactBuilder {
|
|
|
12496
13020
|
this.#app = app;
|
|
12497
13021
|
this.#command = command;
|
|
12498
13022
|
this.#artifactDir = `${command === "build" ? app.dist.cwdPath : app.cwdPath}/.akan/artifact`;
|
|
12499
|
-
this.#absArtifactDir =
|
|
13023
|
+
this.#absArtifactDir = path36.resolve(this.#artifactDir);
|
|
12500
13024
|
}
|
|
12501
13025
|
async build() {
|
|
12502
13026
|
const akanConfig2 = await this.#app.getConfig();
|
|
@@ -12518,7 +13042,7 @@ class SsrBaseArtifactBuilder {
|
|
|
12518
13042
|
rscRuntimeSsrManifest,
|
|
12519
13043
|
vendorMap,
|
|
12520
13044
|
cssAssets,
|
|
12521
|
-
pagesBundlePath: this.#command === "build" ?
|
|
13045
|
+
pagesBundlePath: this.#command === "build" ? path36.relative(this.#absArtifactDir, pagesBundle.bundlePath) : pagesBundle.bundlePath,
|
|
12522
13046
|
pagesBundleBuildId: pagesBundle.buildId,
|
|
12523
13047
|
domains: [...akanConfig2.domains],
|
|
12524
13048
|
subRoutes: Object.fromEntries(Array.from(akanConfig2.subRoutes.entries()).map(([basePath2, domains]) => [basePath2, [...domains]])),
|
|
@@ -12534,18 +13058,18 @@ class SsrBaseArtifactBuilder {
|
|
|
12534
13058
|
androidSha256CertFingerprints: target.deepLinks?.android?.sha256CertFingerprints
|
|
12535
13059
|
}))
|
|
12536
13060
|
};
|
|
12537
|
-
await Bun.write(
|
|
13061
|
+
await Bun.write(path36.join(this.#absArtifactDir, "base-artifact.json"), `${JSON.stringify(artifact, null, 2)}
|
|
12538
13062
|
`);
|
|
12539
13063
|
this.#app.verbose(`[base-artifact] complete in ${Date.now() - this.#started}ms`);
|
|
12540
13064
|
return { artifact, seedIndex, cssCompiler, optimizedFonts };
|
|
12541
13065
|
}
|
|
12542
13066
|
async#buildRuntimeClientEntries() {
|
|
12543
13067
|
const akanServerPath = await this.#resolveAkanServerPath();
|
|
12544
|
-
const rscClientEntry =
|
|
12545
|
-
const rscSegmentOutletEntry =
|
|
13068
|
+
const rscClientEntry = path36.resolve(akanServerPath, "rscClient.tsx");
|
|
13069
|
+
const rscSegmentOutletEntry = path36.resolve(akanServerPath, "rscSegmentOutlet.tsx");
|
|
12546
13070
|
const vendorEntries = VENDOR_SPECIFIERS.map((specifier) => ({
|
|
12547
13071
|
specifier,
|
|
12548
|
-
absPath:
|
|
13072
|
+
absPath: path36.resolve(akanServerPath, "vendor", `${specifier.replaceAll("/", "-").replaceAll(".", "-")}.ts`)
|
|
12549
13073
|
}));
|
|
12550
13074
|
const entries = [rscClientEntry, rscSegmentOutletEntry, ...vendorEntries.map((v) => v.absPath)];
|
|
12551
13075
|
const clientBundle = await new ClientEntriesBundler({ app: this.#app, entries, command: this.#command }).bundle();
|
|
@@ -12582,15 +13106,15 @@ class SsrBaseArtifactBuilder {
|
|
|
12582
13106
|
async#resolveAkanServerPath() {
|
|
12583
13107
|
const candidates = [];
|
|
12584
13108
|
try {
|
|
12585
|
-
candidates.push(
|
|
13109
|
+
candidates.push(path36.dirname(Bun.resolveSync("akanjs/server", this.#app.workspace.workspaceRoot)));
|
|
12586
13110
|
} catch {}
|
|
12587
|
-
candidates.push(
|
|
13111
|
+
candidates.push(path36.join(this.#app.workspace.workspaceRoot, "pkgs/akanjs/server"), path36.join(this.#app.workspace.workspaceRoot, "node_modules/akanjs/server"));
|
|
12588
13112
|
try {
|
|
12589
|
-
candidates.push(
|
|
13113
|
+
candidates.push(path36.dirname(Bun.resolveSync("akanjs/server", path36.dirname(Bun.main))));
|
|
12590
13114
|
} catch {}
|
|
12591
|
-
candidates.push(
|
|
13115
|
+
candidates.push(path36.join(path36.dirname(Bun.main), "node_modules/akanjs/server"), path36.join(path36.dirname(Bun.main), "../../akanjs/server"), path36.resolve(import.meta.dir, "../../server"), path36.resolve(import.meta.dir, "../server"));
|
|
12592
13116
|
for (const candidate of candidates) {
|
|
12593
|
-
if (await Bun.file(
|
|
13117
|
+
if (await Bun.file(path36.join(candidate, "rscClient.tsx")).exists())
|
|
12594
13118
|
return candidate;
|
|
12595
13119
|
}
|
|
12596
13120
|
throw new Error(`[base-artifact] failed to locate akanjs/server; looked in: ${candidates.join(", ")}`);
|
|
@@ -12619,14 +13143,14 @@ ${preparedCssText}`).toString(36);
|
|
|
12619
13143
|
`styles/${cssAssetName}-${cssHash}.css`,
|
|
12620
13144
|
`/_akan/styles/${cssAssetName}-${cssHash}.css`
|
|
12621
13145
|
];
|
|
12622
|
-
await Bun.write(
|
|
13146
|
+
await Bun.write(path36.join(this.#absArtifactDir, cssRelPath), preparedCssText);
|
|
12623
13147
|
this.#app.verbose(`[base-artifact] wrote ${preparedCssText.length} bytes of CSS for ${basePath2} -> ${cssRelPath}`);
|
|
12624
13148
|
return [basePath2, { cssUrl, cssRelPath }];
|
|
12625
13149
|
}
|
|
12626
13150
|
}
|
|
12627
13151
|
// pkgs/@akanjs/devkit/frontendBuild/watchRootResolver.ts
|
|
12628
13152
|
import fs6 from "fs";
|
|
12629
|
-
import
|
|
13153
|
+
import path37 from "path";
|
|
12630
13154
|
|
|
12631
13155
|
class WatchRootResolver {
|
|
12632
13156
|
#app;
|
|
@@ -12636,15 +13160,15 @@ class WatchRootResolver {
|
|
|
12636
13160
|
async resolve() {
|
|
12637
13161
|
const tsconfig = await this.#app.getTsConfig();
|
|
12638
13162
|
const set = new Set;
|
|
12639
|
-
set.add(
|
|
13163
|
+
set.add(path37.resolve(`${this.#app.cwdPath}/page`));
|
|
12640
13164
|
for (const targets of Object.values(tsconfig.compilerOptions.paths ?? {})) {
|
|
12641
13165
|
for (const target of targets) {
|
|
12642
13166
|
if (!target)
|
|
12643
13167
|
continue;
|
|
12644
|
-
if (
|
|
13168
|
+
if (path37.isAbsolute(target))
|
|
12645
13169
|
continue;
|
|
12646
13170
|
const cleaned = target.replace(/\/?\*+.*$/, "").replace(/\/[^/]+\.[^/]+$/, "");
|
|
12647
|
-
const resolved =
|
|
13171
|
+
const resolved = path37.resolve(this.#app.workspace.workspaceRoot, cleaned);
|
|
12648
13172
|
if (fs6.existsSync(resolved))
|
|
12649
13173
|
set.add(resolved);
|
|
12650
13174
|
}
|
|
@@ -12711,7 +13235,7 @@ class ApplicationBuildRunner {
|
|
|
12711
13235
|
phases: this.#phases,
|
|
12712
13236
|
durationMs: Date.now() - this.#startedAt,
|
|
12713
13237
|
outputDir: this.#app.dist.cwdPath,
|
|
12714
|
-
artifactDir:
|
|
13238
|
+
artifactDir: path38.join(this.#app.dist.cwdPath, ".akan/artifact")
|
|
12715
13239
|
};
|
|
12716
13240
|
}
|
|
12717
13241
|
async typecheck(options = {}) {
|
|
@@ -12719,7 +13243,7 @@ class ApplicationBuildRunner {
|
|
|
12719
13243
|
await this.#app.getPageKeys({ refresh: true });
|
|
12720
13244
|
const { typecheckDir, tsconfigPath } = await this.#writeTypecheckTsconfig({ incremental });
|
|
12721
13245
|
if (clean)
|
|
12722
|
-
await rm4(
|
|
13246
|
+
await rm4(path38.join(typecheckDir, "tsconfig.tsbuildinfo"), { force: true });
|
|
12723
13247
|
await this.#checkProjectInChildProcess(tsconfigPath);
|
|
12724
13248
|
}
|
|
12725
13249
|
async#runPhase(id, label, task, summarize, options = {}) {
|
|
@@ -12791,7 +13315,7 @@ class ApplicationBuildRunner {
|
|
|
12791
13315
|
};
|
|
12792
13316
|
}
|
|
12793
13317
|
async#writeConsoleShim() {
|
|
12794
|
-
await Bun.write(
|
|
13318
|
+
await Bun.write(path38.join(this.#app.dist.cwdPath, "console.js"), `import { cnst, db, dict, option, server, sig, srv } from "./server.js";
|
|
12795
13319
|
import { assertAkanConsoleAllowed, startAkanConsole } from "./console-runtime.js";
|
|
12796
13320
|
|
|
12797
13321
|
const run = async () => {
|
|
@@ -12814,14 +13338,14 @@ void run().catch((error) => {
|
|
|
12814
13338
|
try {
|
|
12815
13339
|
return Bun.resolveSync("akanjs/server/rsc-worker", import.meta.dir);
|
|
12816
13340
|
} catch {
|
|
12817
|
-
return
|
|
13341
|
+
return path38.join(this.#app.workspace.workspaceRoot, "pkgs/akanjs/server/rscWorker.tsx");
|
|
12818
13342
|
}
|
|
12819
13343
|
}
|
|
12820
13344
|
#resolveConsoleRuntimeBuildEntry() {
|
|
12821
13345
|
try {
|
|
12822
|
-
return
|
|
13346
|
+
return path38.join(path38.dirname(Bun.resolveSync("akanjs/server", import.meta.dir)), "console.ts");
|
|
12823
13347
|
} catch {
|
|
12824
|
-
return
|
|
13348
|
+
return path38.join(this.#app.workspace.workspaceRoot, "pkgs/akanjs/server/console.ts");
|
|
12825
13349
|
}
|
|
12826
13350
|
}
|
|
12827
13351
|
async#buildCsr() {
|
|
@@ -12838,7 +13362,7 @@ void run().catch((error) => {
|
|
|
12838
13362
|
return { base, allRoutes };
|
|
12839
13363
|
}
|
|
12840
13364
|
async#writeTypecheckTsconfig({ incremental = true } = {}) {
|
|
12841
|
-
const typecheckDir =
|
|
13365
|
+
const typecheckDir = path38.join(this.#app.cwdPath, ".akan", "typecheck");
|
|
12842
13366
|
await mkdir8(typecheckDir, { recursive: true });
|
|
12843
13367
|
const tsconfig = {
|
|
12844
13368
|
extends: "../../tsconfig.json",
|
|
@@ -12857,7 +13381,7 @@ void run().catch((error) => {
|
|
|
12857
13381
|
],
|
|
12858
13382
|
references: []
|
|
12859
13383
|
};
|
|
12860
|
-
const tsconfigPath =
|
|
13384
|
+
const tsconfigPath = path38.join(typecheckDir, "tsconfig.json");
|
|
12861
13385
|
await Bun.write(tsconfigPath, `${JSON.stringify(tsconfig, null, 2)}
|
|
12862
13386
|
`);
|
|
12863
13387
|
return { typecheckDir, tsconfigPath };
|
|
@@ -12883,10 +13407,10 @@ void run().catch((error) => {
|
|
|
12883
13407
|
}
|
|
12884
13408
|
async#resolveTypecheckWorkerEntry() {
|
|
12885
13409
|
const candidates = [
|
|
12886
|
-
|
|
12887
|
-
|
|
12888
|
-
|
|
12889
|
-
|
|
13410
|
+
path38.join(this.#app.workspace.workspaceRoot, "pkgs/@akanjs/devkit/typecheck/typecheck.proc.ts"),
|
|
13411
|
+
path38.join(this.#app.workspace.workspaceRoot, "node_modules/@akanjs/devkit/typecheck/typecheck.proc.ts"),
|
|
13412
|
+
path38.join(import.meta.dir, "typecheck.proc.js"),
|
|
13413
|
+
path38.join(import.meta.dir, "typecheck.proc.ts")
|
|
12890
13414
|
];
|
|
12891
13415
|
for (const candidate of candidates)
|
|
12892
13416
|
if (await Bun.file(candidate).exists())
|
|
@@ -12920,7 +13444,7 @@ void run().catch((error) => {
|
|
|
12920
13444
|
}
|
|
12921
13445
|
// pkgs/@akanjs/devkit/applicationReleasePackager.ts
|
|
12922
13446
|
import { cp, mkdir as mkdir9, rm as rm5 } from "fs/promises";
|
|
12923
|
-
import
|
|
13447
|
+
import path39 from "path";
|
|
12924
13448
|
|
|
12925
13449
|
// pkgs/@akanjs/devkit/uploadRelease.ts
|
|
12926
13450
|
import { HttpClient as HttpClient2, Logger as Logger9 } from "akanjs/common";
|
|
@@ -13037,7 +13561,7 @@ class ApplicationReleasePackager {
|
|
|
13037
13561
|
await cp(this.#app.dist.cwdPath, buildRoot, { recursive: true });
|
|
13038
13562
|
await rm5(`${buildRoot}/frontend/.next`, { recursive: true, force: true });
|
|
13039
13563
|
const releaseRoot = this.#app.workspace.workspaceRoot;
|
|
13040
|
-
const releaseArchivePath =
|
|
13564
|
+
const releaseArchivePath = path39.relative(releaseRoot, `${releaseRoot}/releases/builds/${this.#app.name}-release.tar.gz`).split(path39.sep).join("/");
|
|
13041
13565
|
await this.#app.workspace.spawn("tar", ["-zcf", releaseArchivePath, "-C", buildRoot, "./"], { cwd: releaseRoot });
|
|
13042
13566
|
await this.#writeCsrZipIfPresent();
|
|
13043
13567
|
return { platformVersion };
|
|
@@ -13059,17 +13583,17 @@ class ApplicationReleasePackager {
|
|
|
13059
13583
|
await cp(this.#app.dist.cwdPath, `${sourceRoot}/apps/${this.#app.name}`, { recursive: true });
|
|
13060
13584
|
const libDeps = ["social", "shared", "platform", "util"];
|
|
13061
13585
|
await Promise.all(libDeps.map((lib) => cp(`${this.#app.workspace.cwdPath}/libs/${lib}`, `${sourceRoot}/libs/${lib}`, { recursive: true })));
|
|
13062
|
-
await Promise.all([".next", "ios", "android", "public/libs"].map(async (
|
|
13063
|
-
const targetPath = `${sourceRoot}/apps/${this.#app.name}/${
|
|
13586
|
+
await Promise.all([".next", "ios", "android", "public/libs"].map(async (path40) => {
|
|
13587
|
+
const targetPath = `${sourceRoot}/apps/${this.#app.name}/${path40}`;
|
|
13064
13588
|
if (await FileSys.dirExists(targetPath))
|
|
13065
13589
|
await rm5(targetPath, { recursive: true, force: true });
|
|
13066
13590
|
}));
|
|
13067
13591
|
const syncPaths = [".husky", ".gitignore", "package.json"];
|
|
13068
|
-
await Promise.all(syncPaths.map((
|
|
13592
|
+
await Promise.all(syncPaths.map((path40) => cp(`${this.#app.workspace.cwdPath}/${path40}`, `${sourceRoot}/${path40}`, { recursive: true })));
|
|
13069
13593
|
await this.#writeSourceTsconfig(sourceRoot, libDeps);
|
|
13070
13594
|
await Bun.write(`${sourceRoot}/README.md`, readme);
|
|
13071
13595
|
const sourceCwd = this.#app.workspace.cwdPath;
|
|
13072
|
-
const sourceArchivePath =
|
|
13596
|
+
const sourceArchivePath = path39.relative(sourceCwd, `${sourceCwd}/releases/sources/${this.#app.name}-source.tar.gz`).split(path39.sep).join("/");
|
|
13073
13597
|
await this.#app.workspace.spawn("tar", ["-zcf", sourceArchivePath, "-C", sourceRoot, "./"], { cwd: sourceCwd });
|
|
13074
13598
|
}
|
|
13075
13599
|
async#resetSourceRoot(sourceRoot) {
|
|
@@ -13152,20 +13676,20 @@ class ApplicationReleasePackager {
|
|
|
13152
13676
|
}
|
|
13153
13677
|
}
|
|
13154
13678
|
// pkgs/@akanjs/devkit/applicationTestPreload.ts
|
|
13155
|
-
import
|
|
13679
|
+
import path40 from "path";
|
|
13156
13680
|
var SIGNAL_TEST_PRELOAD_PATH = "test/signalTest.preload.ts";
|
|
13157
13681
|
async function resolveSignalTestPreloadPath(target) {
|
|
13158
13682
|
const candidates = [];
|
|
13159
13683
|
const addResolvedPackageCandidate = (basePath2) => {
|
|
13160
13684
|
try {
|
|
13161
|
-
candidates.push(
|
|
13685
|
+
candidates.push(path40.join(path40.dirname(Bun.resolveSync("akanjs/package.json", basePath2)), SIGNAL_TEST_PRELOAD_PATH));
|
|
13162
13686
|
} catch {}
|
|
13163
13687
|
};
|
|
13164
13688
|
addResolvedPackageCandidate(target.cwdPath);
|
|
13165
13689
|
addResolvedPackageCandidate(process.cwd());
|
|
13166
|
-
addResolvedPackageCandidate(
|
|
13690
|
+
addResolvedPackageCandidate(path40.dirname(Bun.main));
|
|
13167
13691
|
addResolvedPackageCandidate(import.meta.dir);
|
|
13168
|
-
candidates.push(
|
|
13692
|
+
candidates.push(path40.join(target.cwdPath, "../../node_modules/akanjs", SIGNAL_TEST_PRELOAD_PATH), path40.join(target.cwdPath, "../../pkgs/akanjs", SIGNAL_TEST_PRELOAD_PATH), path40.join(process.cwd(), "node_modules/akanjs", SIGNAL_TEST_PRELOAD_PATH), path40.join(process.cwd(), "pkgs/akanjs", SIGNAL_TEST_PRELOAD_PATH), path40.join(path40.dirname(Bun.main), "../../akanjs", SIGNAL_TEST_PRELOAD_PATH), path40.resolve(import.meta.dir, "../../akanjs", SIGNAL_TEST_PRELOAD_PATH));
|
|
13169
13693
|
const uniqueCandidates = [...new Set(candidates)];
|
|
13170
13694
|
for (const candidate of uniqueCandidates) {
|
|
13171
13695
|
if (await Bun.file(candidate).exists())
|
|
@@ -13179,7 +13703,7 @@ ${uniqueCandidates.map((candidate) => ` - ${candidate}`).join(`
|
|
|
13179
13703
|
// pkgs/@akanjs/devkit/builder.ts
|
|
13180
13704
|
import { existsSync as existsSync2 } from "fs";
|
|
13181
13705
|
import { mkdir as mkdir10 } from "fs/promises";
|
|
13182
|
-
import
|
|
13706
|
+
import path41 from "path";
|
|
13183
13707
|
var SKIP_ENTRY_DIR_SET = new Set(["node_modules", "dist", "build", ".git", ".next"]);
|
|
13184
13708
|
var assetExtensions = [".css", ".md", ".js", ".png", ".ico", ".svg", ".json", ".template"];
|
|
13185
13709
|
var assetLoader = Object.fromEntries(assetExtensions.map((ext) => [ext, "file"]));
|
|
@@ -13196,14 +13720,14 @@ class Builder {
|
|
|
13196
13720
|
#globEntrypoints(cwd, pattern) {
|
|
13197
13721
|
const glob = new Bun.Glob(pattern);
|
|
13198
13722
|
return Array.from(glob.scanSync({ cwd, onlyFiles: true })).filter((relativePath) => {
|
|
13199
|
-
const segments = relativePath.split(
|
|
13723
|
+
const segments = relativePath.split(path41.sep);
|
|
13200
13724
|
return !segments.some((segment) => SKIP_ENTRY_DIR_SET.has(segment));
|
|
13201
|
-
}).map((rel) =>
|
|
13725
|
+
}).map((rel) => path41.join(cwd, rel));
|
|
13202
13726
|
}
|
|
13203
13727
|
#globFiles(cwd, pattern = "**/*.*") {
|
|
13204
13728
|
const glob = new Bun.Glob(pattern);
|
|
13205
13729
|
return Array.from(glob.scanSync({ cwd, onlyFiles: true })).filter((relativePath) => {
|
|
13206
|
-
const segments = relativePath.split(
|
|
13730
|
+
const segments = relativePath.split(path41.sep);
|
|
13207
13731
|
return !segments.some((segment) => SKIP_ENTRY_DIR_SET.has(segment));
|
|
13208
13732
|
});
|
|
13209
13733
|
}
|
|
@@ -13211,17 +13735,17 @@ class Builder {
|
|
|
13211
13735
|
const out = [];
|
|
13212
13736
|
for (const p of additionalEntryPoints) {
|
|
13213
13737
|
if (p.includes("*")) {
|
|
13214
|
-
const rel = p.startsWith(`${cwd}/`) || p.startsWith(`${cwd}${
|
|
13738
|
+
const rel = p.startsWith(`${cwd}/`) || p.startsWith(`${cwd}${path41.sep}`) ? p.slice(cwd.length + 1) : p;
|
|
13215
13739
|
out.push(...this.#globEntrypoints(cwd, rel));
|
|
13216
13740
|
} else
|
|
13217
|
-
out.push(
|
|
13741
|
+
out.push(path41.isAbsolute(p) ? p : path41.join(cwd, p));
|
|
13218
13742
|
}
|
|
13219
13743
|
return out;
|
|
13220
13744
|
}
|
|
13221
13745
|
#getBuildOptions({ bundle = false, additionalEntryPoints = [] } = {}) {
|
|
13222
13746
|
const cwd = this.#executor.cwdPath;
|
|
13223
13747
|
const entrypoints = [
|
|
13224
|
-
...bundle ? [
|
|
13748
|
+
...bundle ? [path41.join(cwd, "index.ts")] : this.#globEntrypoints(cwd, "**/*.{ts,tsx}"),
|
|
13225
13749
|
...this.#resolveAdditionalEntrypoints(cwd, additionalEntryPoints)
|
|
13226
13750
|
];
|
|
13227
13751
|
return {
|
|
@@ -13242,9 +13766,9 @@ class Builder {
|
|
|
13242
13766
|
for (const relativePath of this.#globFiles(cwd)) {
|
|
13243
13767
|
if (relativePath === "package.json")
|
|
13244
13768
|
continue;
|
|
13245
|
-
const sourcePath =
|
|
13246
|
-
const targetPath =
|
|
13247
|
-
await mkdir10(
|
|
13769
|
+
const sourcePath = path41.join(cwd, relativePath);
|
|
13770
|
+
const targetPath = path41.join(this.#distExecutor.cwdPath, relativePath);
|
|
13771
|
+
await mkdir10(path41.dirname(targetPath), { recursive: true });
|
|
13248
13772
|
await Bun.write(targetPath, Bun.file(sourcePath));
|
|
13249
13773
|
}
|
|
13250
13774
|
}
|
|
@@ -13255,13 +13779,13 @@ class Builder {
|
|
|
13255
13779
|
return withoutFormatDir;
|
|
13256
13780
|
if (!hasDotSlash && withoutFormatDir === publishedPath)
|
|
13257
13781
|
return publishedPath;
|
|
13258
|
-
const parsed =
|
|
13782
|
+
const parsed = path41.posix.parse(withoutFormatDir);
|
|
13259
13783
|
if (![".js", ".mjs", ".cjs"].includes(parsed.ext))
|
|
13260
13784
|
return withoutFormatDir;
|
|
13261
|
-
const withoutExt =
|
|
13785
|
+
const withoutExt = path41.posix.join(parsed.dir, parsed.name);
|
|
13262
13786
|
const sourcePath = withoutExt.startsWith("./") ? withoutExt.slice(2) : withoutExt;
|
|
13263
13787
|
const sourceCandidates = [`${sourcePath}.ts`, `${sourcePath}.tsx`];
|
|
13264
|
-
const matchedSource = sourceCandidates.find((candidate) => existsSync2(
|
|
13788
|
+
const matchedSource = sourceCandidates.find((candidate) => existsSync2(path41.join(this.#executor.cwdPath, candidate)));
|
|
13265
13789
|
if (!matchedSource)
|
|
13266
13790
|
return withoutFormatDir;
|
|
13267
13791
|
return hasDotSlash ? `./${matchedSource}` : matchedSource;
|
|
@@ -13310,9 +13834,9 @@ class Builder {
|
|
|
13310
13834
|
}
|
|
13311
13835
|
}
|
|
13312
13836
|
// pkgs/@akanjs/devkit/capacitorApp.ts
|
|
13313
|
-
import { cp as cp2, mkdir as mkdir11, readFile as
|
|
13837
|
+
import { cp as cp2, mkdir as mkdir11, readFile as readFile3, rm as rm6, writeFile as writeFile3 } from "fs/promises";
|
|
13314
13838
|
import os from "os";
|
|
13315
|
-
import
|
|
13839
|
+
import path42 from "path";
|
|
13316
13840
|
import { select as select2 } from "@inquirer/prompts";
|
|
13317
13841
|
import { MobileProject } from "@trapezedev/project";
|
|
13318
13842
|
import { capitalize as capitalize5 } from "akanjs/common";
|
|
@@ -13519,13 +14043,13 @@ var rootCapacitorConfigFilenames = [
|
|
|
13519
14043
|
"capacitor.config.js",
|
|
13520
14044
|
"capacitor.config.json"
|
|
13521
14045
|
];
|
|
13522
|
-
var rootCapacitorConfigPaths = (appRoot) => rootCapacitorConfigFilenames.map((file) =>
|
|
14046
|
+
var rootCapacitorConfigPaths = (appRoot) => rootCapacitorConfigFilenames.map((file) => path42.join(appRoot, file));
|
|
13523
14047
|
async function clearRootCapacitorConfigs(appRoot) {
|
|
13524
14048
|
await Promise.all(rootCapacitorConfigPaths(appRoot).map((file) => rm6(file, { force: true })));
|
|
13525
14049
|
}
|
|
13526
14050
|
async function writeRootCapacitorConfig(appRoot, content) {
|
|
13527
14051
|
await clearRootCapacitorConfigs(appRoot);
|
|
13528
|
-
await Bun.write(
|
|
14052
|
+
await Bun.write(path42.join(appRoot, "capacitor.config.json"), content);
|
|
13529
14053
|
}
|
|
13530
14054
|
var getLocalIP = () => {
|
|
13531
14055
|
const interfaces = os.networkInterfaces();
|
|
@@ -13634,13 +14158,13 @@ function buildIosNativeRunCommand({
|
|
|
13634
14158
|
scheme = "App",
|
|
13635
14159
|
configuration = "Debug"
|
|
13636
14160
|
}) {
|
|
13637
|
-
const derivedDataPath =
|
|
14161
|
+
const derivedDataPath = path42.join(appRoot, "ios/DerivedData", device.id);
|
|
13638
14162
|
const productPlatform = device.kind === "device" ? "iphoneos" : "iphonesimulator";
|
|
13639
14163
|
const destination = device.kind === "device" ? `id=${device.xcodebuildId ?? device.id}` : `platform=iOS Simulator,id=${device.id}`;
|
|
13640
14164
|
return {
|
|
13641
14165
|
configuration,
|
|
13642
14166
|
derivedDataPath,
|
|
13643
|
-
appPath:
|
|
14167
|
+
appPath: path42.join(derivedDataPath, "Build/Products", `${configuration}-${productPlatform}`, "App.app"),
|
|
13644
14168
|
xcodebuildArgs: [
|
|
13645
14169
|
"-project",
|
|
13646
14170
|
"App.xcodeproj",
|
|
@@ -13853,7 +14377,7 @@ function materializeCapacitorConfig(target, { operation, localServerUrl, localIp
|
|
|
13853
14377
|
...capacitorConfig,
|
|
13854
14378
|
appId,
|
|
13855
14379
|
appName,
|
|
13856
|
-
webDir:
|
|
14380
|
+
webDir: path42.posix.join(".akan", "mobile", name, "www"),
|
|
13857
14381
|
plugins: {
|
|
13858
14382
|
CapacitorCookies: { enabled: true },
|
|
13859
14383
|
...pluginsConfig,
|
|
@@ -13917,10 +14441,10 @@ class CapacitorApp {
|
|
|
13917
14441
|
constructor(app, target) {
|
|
13918
14442
|
this.app = app;
|
|
13919
14443
|
this.target = target;
|
|
13920
|
-
this.targetRootPath =
|
|
13921
|
-
this.targetRoot =
|
|
13922
|
-
this.targetWebRoot =
|
|
13923
|
-
this.targetAssetRoot =
|
|
14444
|
+
this.targetRootPath = path42.posix.join(".akan", "mobile", this.target.name);
|
|
14445
|
+
this.targetRoot = path42.join(this.app.cwdPath, this.targetRootPath);
|
|
14446
|
+
this.targetWebRoot = path42.join(this.targetRoot, "www");
|
|
14447
|
+
this.targetAssetRoot = path42.join(this.targetRoot, "assets");
|
|
13924
14448
|
this.project = new MobileProject(this.app.cwdPath, {
|
|
13925
14449
|
android: { path: this.androidRootPath },
|
|
13926
14450
|
ios: { path: this.iosProjectPath }
|
|
@@ -13935,9 +14459,9 @@ class CapacitorApp {
|
|
|
13935
14459
|
await mkdir11(this.targetRoot, { recursive: true });
|
|
13936
14460
|
if (regenerate) {
|
|
13937
14461
|
if (!platform || platform === "ios")
|
|
13938
|
-
await rm6(
|
|
14462
|
+
await rm6(path42.join(this.app.cwdPath, this.iosRootPath), { recursive: true, force: true });
|
|
13939
14463
|
if (!platform || platform === "android")
|
|
13940
|
-
await rm6(
|
|
14464
|
+
await rm6(path42.join(this.app.cwdPath, this.androidRootPath), { recursive: true, force: true });
|
|
13941
14465
|
}
|
|
13942
14466
|
const project = this.project;
|
|
13943
14467
|
await this.project.load();
|
|
@@ -14061,7 +14585,7 @@ ${textError instanceof Error ? textError.message : ""}`);
|
|
|
14061
14585
|
const xcodebuildArgs = noAllowProvisioningUpdates ? command.xcodebuildArgs : [...command.xcodebuildArgs.slice(0, -1), "-allowProvisioningUpdates", ...command.xcodebuildArgs.slice(-1)];
|
|
14062
14586
|
try {
|
|
14063
14587
|
await this.#spawn("xcodebuild", xcodebuildArgs, {
|
|
14064
|
-
cwd:
|
|
14588
|
+
cwd: path42.join(this.app.cwdPath, this.iosProjectPath),
|
|
14065
14589
|
env: mobileEnv
|
|
14066
14590
|
});
|
|
14067
14591
|
const devicectlId = runTarget.devicectlId ?? runTarget.id;
|
|
@@ -14086,7 +14610,7 @@ ${textError instanceof Error ? textError.message : ""}`);
|
|
|
14086
14610
|
return isRecord2(this.target.ios) && typeof this.target.ios.scheme === "string" ? this.target.ios.scheme : "App";
|
|
14087
14611
|
}
|
|
14088
14612
|
async#getIosDevelopmentTeam() {
|
|
14089
|
-
const pbxprojPath =
|
|
14613
|
+
const pbxprojPath = path42.join(this.app.cwdPath, this.iosProjectPath, "App.xcodeproj/project.pbxproj");
|
|
14090
14614
|
if (!await Bun.file(pbxprojPath).exists())
|
|
14091
14615
|
return;
|
|
14092
14616
|
return (await Bun.file(pbxprojPath).text()).match(/DEVELOPMENT_TEAM = ([^;]+);/)?.[1]?.trim();
|
|
@@ -14113,7 +14637,7 @@ ${error.message}`;
|
|
|
14113
14637
|
await this.#setDeepLinksInAndroid(this.target.deepLinks?.schemes ?? [], this.target.deepLinks?.domains ?? []);
|
|
14114
14638
|
}
|
|
14115
14639
|
async#updateAndroidBuildTypes() {
|
|
14116
|
-
const appGradle = await FileEditor.create(
|
|
14640
|
+
const appGradle = await FileEditor.create(path42.join(this.app.cwdPath, this.androidRootPath, "app/build.gradle"));
|
|
14117
14641
|
const buildTypesBlock = `
|
|
14118
14642
|
debug {
|
|
14119
14643
|
applicationIdSuffix ".debug"
|
|
@@ -14157,7 +14681,7 @@ ${error.message}`;
|
|
|
14157
14681
|
const gradleCommand = isWindows ? "gradlew.bat" : "./gradlew";
|
|
14158
14682
|
await this.app.spawn(gradleCommand, [assembleType === "apk" ? "assembleRelease" : "bundleRelease"], {
|
|
14159
14683
|
stdio: "inherit",
|
|
14160
|
-
cwd:
|
|
14684
|
+
cwd: path42.join(this.app.cwdPath, this.androidRootPath),
|
|
14161
14685
|
env: await this.#commandEnv("release", env)
|
|
14162
14686
|
});
|
|
14163
14687
|
}
|
|
@@ -14165,10 +14689,10 @@ ${error.message}`;
|
|
|
14165
14689
|
await this.#spawnMobile("npx", ["cap", "open", "android"], { operation: "local", env: "local" });
|
|
14166
14690
|
}
|
|
14167
14691
|
async#ensureAndroidAssetsDir() {
|
|
14168
|
-
await mkdir11(
|
|
14692
|
+
await mkdir11(path42.join(this.app.cwdPath, this.androidAssetsPath), { recursive: true });
|
|
14169
14693
|
}
|
|
14170
14694
|
async#ensureAndroidDebugKeystore() {
|
|
14171
|
-
const keystorePath =
|
|
14695
|
+
const keystorePath = path42.join(this.app.cwdPath, this.androidRootPath, "app/debug.keystore");
|
|
14172
14696
|
if (await Bun.file(keystorePath).exists())
|
|
14173
14697
|
return;
|
|
14174
14698
|
await this.#spawn("keytool", [
|
|
@@ -14207,7 +14731,7 @@ ${error.message}`;
|
|
|
14207
14731
|
await this.#spawnMobile("npx", args, { operation, env }, { stdio: "inherit" });
|
|
14208
14732
|
}
|
|
14209
14733
|
async#assertAndroidReleaseSigningConfig() {
|
|
14210
|
-
const gradlePropertiesPath =
|
|
14734
|
+
const gradlePropertiesPath = path42.join(this.app.cwdPath, this.androidRootPath, "gradle.properties");
|
|
14211
14735
|
const gradleProperties = await Bun.file(gradlePropertiesPath).exists() ? await Bun.file(gradlePropertiesPath).text() : "";
|
|
14212
14736
|
const missingKeys = getMissingAndroidReleaseSigningKeys({ gradleProperties });
|
|
14213
14737
|
if (missingKeys.length > 0)
|
|
@@ -14234,12 +14758,12 @@ ${error.message}`;
|
|
|
14234
14758
|
await this.#prepareAndroid({ operation: "release", env: "main" });
|
|
14235
14759
|
}
|
|
14236
14760
|
async prepareWww() {
|
|
14237
|
-
const htmlSource =
|
|
14761
|
+
const htmlSource = path42.join(this.app.dist.cwdPath, "csr", targetHtmlFilename(this.target));
|
|
14238
14762
|
if (!await Bun.file(htmlSource).exists())
|
|
14239
14763
|
throw new Error(`CSR html for mobile target '${this.target.name}' not found: ${htmlSource}`);
|
|
14240
14764
|
await rm6(this.targetWebRoot, { recursive: true, force: true });
|
|
14241
14765
|
await mkdir11(this.targetWebRoot, { recursive: true });
|
|
14242
|
-
await Bun.write(
|
|
14766
|
+
await Bun.write(path42.join(this.targetWebRoot, "index.html"), this.#injectMobileTargetMeta(await Bun.file(htmlSource).text()));
|
|
14243
14767
|
}
|
|
14244
14768
|
#injectMobileTargetMeta(html) {
|
|
14245
14769
|
const basePath2 = this.target.basePath?.replace(/^\/+|\/+$/g, "") ?? "";
|
|
@@ -14263,7 +14787,7 @@ ${error.message}`;
|
|
|
14263
14787
|
});
|
|
14264
14788
|
const content = `${JSON.stringify(config, null, 2)}
|
|
14265
14789
|
`;
|
|
14266
|
-
await Bun.write(
|
|
14790
|
+
await Bun.write(path42.join(this.targetRoot, "capacitor.config.json"), content);
|
|
14267
14791
|
return content;
|
|
14268
14792
|
}
|
|
14269
14793
|
async#prepareTargetAssets() {
|
|
@@ -14271,11 +14795,11 @@ ${error.message}`;
|
|
|
14271
14795
|
return;
|
|
14272
14796
|
await mkdir11(this.targetAssetRoot, { recursive: true });
|
|
14273
14797
|
if (this.target.assets.icon)
|
|
14274
|
-
await cp2(
|
|
14798
|
+
await cp2(path42.join(this.app.cwdPath, this.target.assets.icon), path42.join(this.targetAssetRoot, "icon.png"), {
|
|
14275
14799
|
force: true
|
|
14276
14800
|
});
|
|
14277
14801
|
if (this.target.assets.splash)
|
|
14278
|
-
await cp2(
|
|
14802
|
+
await cp2(path42.join(this.app.cwdPath, this.target.assets.splash), path42.join(this.targetAssetRoot, "splash.png"), {
|
|
14279
14803
|
force: true
|
|
14280
14804
|
});
|
|
14281
14805
|
}
|
|
@@ -14283,11 +14807,11 @@ ${error.message}`;
|
|
|
14283
14807
|
const files = this.target.files?.[platform];
|
|
14284
14808
|
if (!files)
|
|
14285
14809
|
return;
|
|
14286
|
-
const platformRoot =
|
|
14810
|
+
const platformRoot = path42.join(this.app.cwdPath, platform === "ios" ? this.iosRootPath : this.androidRootPath);
|
|
14287
14811
|
await Promise.all(Object.entries(files).map(async ([to, from]) => {
|
|
14288
|
-
const targetPath =
|
|
14289
|
-
await mkdir11(
|
|
14290
|
-
await cp2(
|
|
14812
|
+
const targetPath = path42.join(platformRoot, to);
|
|
14813
|
+
await mkdir11(path42.dirname(targetPath), { recursive: true });
|
|
14814
|
+
await cp2(path42.join(this.app.cwdPath, from), targetPath, { force: true });
|
|
14291
14815
|
}));
|
|
14292
14816
|
}
|
|
14293
14817
|
async#generateAssets({ operation, env }) {
|
|
@@ -14297,7 +14821,7 @@ ${error.message}`;
|
|
|
14297
14821
|
"@capacitor/assets",
|
|
14298
14822
|
"generate",
|
|
14299
14823
|
"--assetPath",
|
|
14300
|
-
|
|
14824
|
+
path42.posix.join(this.targetRootPath, "assets"),
|
|
14301
14825
|
"--iosProject",
|
|
14302
14826
|
this.iosProjectPath,
|
|
14303
14827
|
"--androidProject",
|
|
@@ -14331,13 +14855,18 @@ ${error.message}`;
|
|
|
14331
14855
|
}
|
|
14332
14856
|
for (const permission of this.target.permissions ?? []) {
|
|
14333
14857
|
const claimants = nativePlugins.get(permission);
|
|
14334
|
-
if (
|
|
14335
|
-
|
|
14858
|
+
if (claimants?.length) {
|
|
14859
|
+
const ctx = this.#makeNativeContext({ operation, env });
|
|
14860
|
+
for (const plugin of claimants)
|
|
14861
|
+
await plugin.capacitor?.configureNative?.(ctx);
|
|
14336
14862
|
continue;
|
|
14337
14863
|
}
|
|
14338
|
-
|
|
14339
|
-
|
|
14340
|
-
|
|
14864
|
+
if (permission === "camera")
|
|
14865
|
+
await this.addCamera();
|
|
14866
|
+
else if (permission === "contacts")
|
|
14867
|
+
await this.addContact();
|
|
14868
|
+
else if (permission === "location")
|
|
14869
|
+
await this.addLocation();
|
|
14341
14870
|
}
|
|
14342
14871
|
}
|
|
14343
14872
|
#makeNativeContext({ operation, env }) {
|
|
@@ -14454,11 +14983,33 @@ ${error.message}`;
|
|
|
14454
14983
|
await this.#clearRootCapacitorConfigs();
|
|
14455
14984
|
}
|
|
14456
14985
|
}
|
|
14986
|
+
async addCamera() {
|
|
14987
|
+
await this.#setPermissionInIos({
|
|
14988
|
+
cameraUsageDescription: "$(PRODUCT_NAME) requires access to the camera to take photos.",
|
|
14989
|
+
photoAddUsageDescription: "$(PRODUCT_NAME) requires access to the photo library to take photos.",
|
|
14990
|
+
photoUsageDescription: "$(PRODUCT_NAME) requires access to the photo library to take photos."
|
|
14991
|
+
});
|
|
14992
|
+
this.#setPermissionsInAndroid(["READ_MEDIA_IMAGES", "READ_EXTERNAL_STORAGE", "WRITE_EXTERNAL_STORAGE"]);
|
|
14993
|
+
}
|
|
14994
|
+
async addContact() {
|
|
14995
|
+
await this.#setPermissionInIos({
|
|
14996
|
+
contactsUsageDescription: "$(PRODUCT_NAME) requires access to the contacts to add new contacts."
|
|
14997
|
+
});
|
|
14998
|
+
this.#setPermissionsInAndroid(["READ_CONTACTS", "WRITE_CONTACTS"]);
|
|
14999
|
+
}
|
|
15000
|
+
async addLocation() {
|
|
15001
|
+
await this.#setPermissionInIos({
|
|
15002
|
+
locationAlwaysUsageDescription: "$(PRODUCT_NAME) requires access to the location to get the user's location.",
|
|
15003
|
+
locationWhenInUseUsageDescription: "$(PRODUCT_NAME) requires access to the location to get the user's location."
|
|
15004
|
+
});
|
|
15005
|
+
this.#setPermissionsInAndroid(["ACCESS_COARSE_LOCATION", "ACCESS_FINE_LOCATION"]);
|
|
15006
|
+
this.#setFeaturesInAndroid(["android.hardware.location.gps"]);
|
|
15007
|
+
}
|
|
14457
15008
|
#addIosEntitlements(entitlements) {
|
|
14458
15009
|
Object.assign(this.#iosEntitlements, entitlements);
|
|
14459
15010
|
}
|
|
14460
15011
|
async#editIosAppDelegate(transform) {
|
|
14461
|
-
const appDelegatePath =
|
|
15012
|
+
const appDelegatePath = path42.join(this.app.cwdPath, this.iosProjectPath, "App/AppDelegate.swift");
|
|
14462
15013
|
if (!await Bun.file(appDelegatePath).exists())
|
|
14463
15014
|
return;
|
|
14464
15015
|
const editor = await FileEditor.create(appDelegatePath);
|
|
@@ -14500,7 +15051,7 @@ ${error.message}`;
|
|
|
14500
15051
|
if (Object.keys(this.#iosEntitlements).length === 0)
|
|
14501
15052
|
return;
|
|
14502
15053
|
const entitlementsRelPath = "App/App.entitlements";
|
|
14503
|
-
const entitlementsPath =
|
|
15054
|
+
const entitlementsPath = path42.join(this.app.cwdPath, this.iosProjectPath, entitlementsRelPath);
|
|
14504
15055
|
const body = [
|
|
14505
15056
|
'<?xml version="1.0" encoding="UTF-8"?>',
|
|
14506
15057
|
'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">',
|
|
@@ -14514,12 +15065,12 @@ ${error.message}`;
|
|
|
14514
15065
|
`);
|
|
14515
15066
|
const currentBody = await Bun.file(entitlementsPath).exists() ? await Bun.file(entitlementsPath).text() : undefined;
|
|
14516
15067
|
if (currentBody !== body)
|
|
14517
|
-
await
|
|
15068
|
+
await writeFile3(entitlementsPath, body);
|
|
14518
15069
|
await this.#setCodeSignEntitlementsInIos(entitlementsRelPath);
|
|
14519
15070
|
}
|
|
14520
15071
|
async#setCodeSignEntitlementsInIos(entitlementsRelPath) {
|
|
14521
|
-
const pbxprojPath =
|
|
14522
|
-
const lines = (await
|
|
15072
|
+
const pbxprojPath = path42.join(this.app.cwdPath, this.iosProjectPath, "App.xcodeproj/project.pbxproj");
|
|
15073
|
+
const lines = (await readFile3(pbxprojPath, "utf8")).split(`
|
|
14523
15074
|
`);
|
|
14524
15075
|
let changed = false;
|
|
14525
15076
|
for (let index = 0;index < lines.length; index++) {
|
|
@@ -14541,12 +15092,12 @@ ${error.message}`;
|
|
|
14541
15092
|
changed = true;
|
|
14542
15093
|
}
|
|
14543
15094
|
if (changed)
|
|
14544
|
-
await
|
|
15095
|
+
await writeFile3(pbxprojPath, lines.join(`
|
|
14545
15096
|
`));
|
|
14546
15097
|
}
|
|
14547
15098
|
async#setUrlSchemesInAndroid(schemes) {
|
|
14548
|
-
const manifestPath =
|
|
14549
|
-
let manifest = await
|
|
15099
|
+
const manifestPath = path42.join(this.app.cwdPath, this.androidRootPath, "app/src/main/AndroidManifest.xml");
|
|
15100
|
+
let manifest = await readFile3(manifestPath, "utf8");
|
|
14550
15101
|
let changed = false;
|
|
14551
15102
|
for (const scheme of schemes) {
|
|
14552
15103
|
if (manifest.includes(`android:scheme="${scheme}"`))
|
|
@@ -14565,12 +15116,12 @@ ${filter}$1`);
|
|
|
14565
15116
|
changed = true;
|
|
14566
15117
|
}
|
|
14567
15118
|
if (changed)
|
|
14568
|
-
await
|
|
15119
|
+
await writeFile3(manifestPath, manifest);
|
|
14569
15120
|
}
|
|
14570
15121
|
async#setDeepLinksInAndroid(schemes, domains) {
|
|
14571
15122
|
await this.#setUrlSchemesInAndroid(schemes);
|
|
14572
|
-
const manifestPath =
|
|
14573
|
-
let manifest = await
|
|
15123
|
+
const manifestPath = path42.join(this.app.cwdPath, this.androidRootPath, "app/src/main/AndroidManifest.xml");
|
|
15124
|
+
let manifest = await readFile3(manifestPath, "utf8");
|
|
14574
15125
|
let changed = false;
|
|
14575
15126
|
const pathPrefix = resolveMobilePath(this.target, "/");
|
|
14576
15127
|
for (const domain of domains) {
|
|
@@ -14590,7 +15141,7 @@ ${filter}$1`);
|
|
|
14590
15141
|
changed = true;
|
|
14591
15142
|
}
|
|
14592
15143
|
if (changed)
|
|
14593
|
-
await
|
|
15144
|
+
await writeFile3(manifestPath, manifest);
|
|
14594
15145
|
}
|
|
14595
15146
|
#setFeaturesInAndroid(features) {
|
|
14596
15147
|
for (const feature of features) {
|
|
@@ -14671,7 +15222,7 @@ var Pkg = createInternalArgToken("Pkg");
|
|
|
14671
15222
|
var Module = createInternalArgToken("Module");
|
|
14672
15223
|
var Workspace = createInternalArgToken("Workspace");
|
|
14673
15224
|
// pkgs/@akanjs/devkit/commandDecorators/command.ts
|
|
14674
|
-
import
|
|
15225
|
+
import path43 from "path";
|
|
14675
15226
|
import { confirm, input as input2, select as select3 } from "@inquirer/prompts";
|
|
14676
15227
|
import { Logger as Logger10 } from "akanjs/common";
|
|
14677
15228
|
import chalk6 from "chalk";
|
|
@@ -15175,7 +15726,7 @@ var runCommands = async (...commands) => {
|
|
|
15175
15726
|
process.exit(1);
|
|
15176
15727
|
});
|
|
15177
15728
|
const __dirname2 = getDirname(import.meta.url);
|
|
15178
|
-
const packageJsonCandidates = [`${
|
|
15729
|
+
const packageJsonCandidates = [`${path43.dirname(Bun.main)}/package.json`, `${__dirname2}/../package.json`];
|
|
15179
15730
|
let cliPackageJson = null;
|
|
15180
15731
|
for (const packageJsonPath of packageJsonCandidates) {
|
|
15181
15732
|
if (!await FileSys.fileExists(packageJsonPath))
|
|
@@ -15422,7 +15973,7 @@ import { capitalize as capitalize7 } from "akanjs/common";
|
|
|
15422
15973
|
// pkgs/@akanjs/devkit/getRelatedCnsts.ts
|
|
15423
15974
|
import { readFileSync as readFileSync4, realpathSync } from "fs";
|
|
15424
15975
|
import ora2 from "ora";
|
|
15425
|
-
import * as
|
|
15976
|
+
import * as ts11 from "typescript";
|
|
15426
15977
|
var tsTranspiler = new Bun.Transpiler({ loader: "ts" });
|
|
15427
15978
|
var tsxTranspiler = new Bun.Transpiler({ loader: "tsx" });
|
|
15428
15979
|
var getTranspiler = (filePath) => filePath.endsWith(".tsx") ? tsxTranspiler : tsTranspiler;
|
|
@@ -15455,10 +16006,10 @@ var scanModuleSpecifiers = (source2, filePath, includeExports) => {
|
|
|
15455
16006
|
return importSpecifiers;
|
|
15456
16007
|
};
|
|
15457
16008
|
var parseTsConfig = (tsConfigPath = "./tsconfig.json") => {
|
|
15458
|
-
const configFile =
|
|
15459
|
-
return
|
|
16009
|
+
const configFile = ts11.readConfigFile(tsConfigPath, (path44) => {
|
|
16010
|
+
return ts11.sys.readFile(path44);
|
|
15460
16011
|
});
|
|
15461
|
-
return
|
|
16012
|
+
return ts11.parseJsonConfigFileContent(configFile.config, ts11.sys, realpathSync(tsConfigPath).replace(/[^/\\]+$/, ""));
|
|
15462
16013
|
};
|
|
15463
16014
|
var collectImportedFiles = (constantFilePath, parsedConfig) => {
|
|
15464
16015
|
const allFilesToAnalyze = new Set([constantFilePath]);
|
|
@@ -15473,7 +16024,7 @@ var collectImportedFiles = (constantFilePath, parsedConfig) => {
|
|
|
15473
16024
|
for (const importPath of scanModuleSpecifiers(source2, filePath, false)) {
|
|
15474
16025
|
if (!importPath.startsWith("."))
|
|
15475
16026
|
continue;
|
|
15476
|
-
const resolved =
|
|
16027
|
+
const resolved = ts11.resolveModuleName(importPath, filePath, parsedConfig.options, ts11.sys).resolvedModule?.resolvedFileName;
|
|
15477
16028
|
if (resolved && !allFilesToAnalyze.has(resolved)) {
|
|
15478
16029
|
allFilesToAnalyze.add(resolved);
|
|
15479
16030
|
collectImported(resolved);
|
|
@@ -15490,7 +16041,7 @@ var collectImportedFiles = (constantFilePath, parsedConfig) => {
|
|
|
15490
16041
|
var createTsProgram = (filePaths, options) => {
|
|
15491
16042
|
const spinner = ora2("Creating TypeScript program for all files...");
|
|
15492
16043
|
spinner.start();
|
|
15493
|
-
const program2 =
|
|
16044
|
+
const program2 = ts11.createProgram(Array.from(filePaths), options);
|
|
15494
16045
|
const checker = program2.getTypeChecker();
|
|
15495
16046
|
spinner.succeed("TypeScript program created.");
|
|
15496
16047
|
return {
|
|
@@ -15530,17 +16081,17 @@ var analyzeProperties = (filesToAnalyze, program2, checker) => {
|
|
|
15530
16081
|
function visit(node) {
|
|
15531
16082
|
if (!source2)
|
|
15532
16083
|
return;
|
|
15533
|
-
if (
|
|
16084
|
+
if (ts11.isPropertyAccessExpression(node)) {
|
|
15534
16085
|
const left = node.expression;
|
|
15535
16086
|
const right = node.name;
|
|
15536
|
-
const { line } =
|
|
15537
|
-
if (
|
|
16087
|
+
const { line } = ts11.getLineAndCharacterOfPosition(source2, node.getStart());
|
|
16088
|
+
if (ts11.isIdentifier(left) && sourceLines && sourceLines.length > line && sourceLines[line] && (sourceLines[line]?.includes(`@Field.Prop(() => ${left.text}.${right.text}`) || sourceLines[line].includes(`base.Filter(${left.text}.${right.text},`))) {
|
|
15538
16089
|
const symbol = getCachedSymbol(right);
|
|
15539
16090
|
if (symbol?.declarations && symbol.declarations.length > 0) {
|
|
15540
16091
|
const key = symbol.declarations[0]?.getSourceFile().fileName.split("/").pop()?.split(".")[0] ?? "";
|
|
15541
16092
|
const property = propertyMap.get(key);
|
|
15542
16093
|
const isScalar = symbol.declarations[0]?.getSourceFile().fileName.includes("_") ?? false;
|
|
15543
|
-
const symbolFilePath = symbol.declarations[0]?.getSourceFile().fileName.replace(`${
|
|
16094
|
+
const symbolFilePath = symbol.declarations[0]?.getSourceFile().fileName.replace(`${ts11.sys.getCurrentDirectory()}/`, "");
|
|
15544
16095
|
if (!symbolFilePath)
|
|
15545
16096
|
throw new Error(`No symbol file path found for ${left.text}.${right.text}`);
|
|
15546
16097
|
if (property) {
|
|
@@ -15564,10 +16115,10 @@ var analyzeProperties = (filesToAnalyze, program2, checker) => {
|
|
|
15564
16115
|
}
|
|
15565
16116
|
}
|
|
15566
16117
|
}
|
|
15567
|
-
} else if (
|
|
16118
|
+
} else if (ts11.isImportDeclaration(node) && ts11.isStringLiteral(node.moduleSpecifier)) {
|
|
15568
16119
|
const importPath = node.moduleSpecifier.text;
|
|
15569
16120
|
if (importPath.startsWith(".")) {
|
|
15570
|
-
const resolved =
|
|
16121
|
+
const resolved = ts11.resolveModuleName(importPath, filePath, program2.getCompilerOptions(), ts11.sys).resolvedModule?.resolvedFileName;
|
|
15571
16122
|
const moduleName = importPath.split("/").pop()?.split(".")[0] ?? "";
|
|
15572
16123
|
const property = propertyMap.get(moduleName);
|
|
15573
16124
|
const isScalar = importPath.includes("_");
|
|
@@ -15582,7 +16133,7 @@ var analyzeProperties = (filesToAnalyze, program2, checker) => {
|
|
|
15582
16133
|
}
|
|
15583
16134
|
}
|
|
15584
16135
|
}
|
|
15585
|
-
|
|
16136
|
+
ts11.forEachChild(node, visit);
|
|
15586
16137
|
}
|
|
15587
16138
|
visit(source2);
|
|
15588
16139
|
}
|
|
@@ -15674,10 +16225,10 @@ ${document}
|
|
|
15674
16225
|
}
|
|
15675
16226
|
// pkgs/@akanjs/devkit/qualityScanner.ts
|
|
15676
16227
|
import { createHash } from "crypto";
|
|
15677
|
-
import { readdir as
|
|
15678
|
-
import
|
|
16228
|
+
import { readdir as readdir4, readFile as readFile4, stat as stat5 } from "fs/promises";
|
|
16229
|
+
import path44 from "path";
|
|
15679
16230
|
import ignore2 from "ignore";
|
|
15680
|
-
import
|
|
16231
|
+
import ts12 from "typescript";
|
|
15681
16232
|
var MAX_FILE_LINES = 2000;
|
|
15682
16233
|
var PLACEHOLDER_EXPORT_NAMES = new Set([
|
|
15683
16234
|
"aa",
|
|
@@ -15789,7 +16340,7 @@ class AkanQualityScanner {
|
|
|
15789
16340
|
const ignoreFilter = ignore2().add(await this.#readGitIgnore(workspaceRoot));
|
|
15790
16341
|
const files = [];
|
|
15791
16342
|
for (const targetRoot of ["apps", "libs"]) {
|
|
15792
|
-
const absoluteTargetRoot =
|
|
16343
|
+
const absoluteTargetRoot = path44.join(workspaceRoot, targetRoot);
|
|
15793
16344
|
if (!await isDirectory(absoluteTargetRoot))
|
|
15794
16345
|
continue;
|
|
15795
16346
|
await this.#walkTargetFiles(workspaceRoot, absoluteTargetRoot, ignoreFilter, files);
|
|
@@ -15797,16 +16348,16 @@ class AkanQualityScanner {
|
|
|
15797
16348
|
return files.sort();
|
|
15798
16349
|
}
|
|
15799
16350
|
async#readGitIgnore(workspaceRoot) {
|
|
15800
|
-
const gitIgnorePath =
|
|
16351
|
+
const gitIgnorePath = path44.join(workspaceRoot, ".gitignore");
|
|
15801
16352
|
if (!await Bun.file(gitIgnorePath).exists())
|
|
15802
16353
|
return [];
|
|
15803
|
-
return (await
|
|
16354
|
+
return (await readFile4(gitIgnorePath, "utf8")).split(/\r?\n/);
|
|
15804
16355
|
}
|
|
15805
16356
|
async#walkTargetFiles(workspaceRoot, currentPath, ignoreFilter, files) {
|
|
15806
|
-
const entries = await
|
|
16357
|
+
const entries = await readdir4(currentPath, { withFileTypes: true });
|
|
15807
16358
|
for (const entry of entries) {
|
|
15808
|
-
const absolutePath =
|
|
15809
|
-
const relativePath = toPosix(
|
|
16359
|
+
const absolutePath = path44.join(currentPath, entry.name);
|
|
16360
|
+
const relativePath = toPosix(path44.relative(workspaceRoot, absolutePath));
|
|
15810
16361
|
if (shouldSkipPath(relativePath, entry.isDirectory(), ignoreFilter))
|
|
15811
16362
|
continue;
|
|
15812
16363
|
if (entry.isDirectory()) {
|
|
@@ -15819,13 +16370,13 @@ class AkanQualityScanner {
|
|
|
15819
16370
|
}
|
|
15820
16371
|
}
|
|
15821
16372
|
async#readSourceFile(workspaceRoot, file) {
|
|
15822
|
-
const absolutePath =
|
|
15823
|
-
const content = await
|
|
16373
|
+
const absolutePath = path44.join(workspaceRoot, file);
|
|
16374
|
+
const content = await readFile4(absolutePath, "utf8");
|
|
15824
16375
|
return {
|
|
15825
16376
|
file,
|
|
15826
16377
|
absolutePath,
|
|
15827
16378
|
content,
|
|
15828
|
-
sourceFile:
|
|
16379
|
+
sourceFile: ts12.createSourceFile(file, content, ts12.ScriptTarget.Latest, true, getScriptKind(file))
|
|
15829
16380
|
};
|
|
15830
16381
|
}
|
|
15831
16382
|
#scanGlobalQuality(sourceFiles) {
|
|
@@ -15950,7 +16501,7 @@ class AkanQualityScanner {
|
|
|
15950
16501
|
const suffix = CONVENTION_SUFFIXES.find((candidate) => sourceFile2.file.endsWith(candidate));
|
|
15951
16502
|
if (!suffix)
|
|
15952
16503
|
return [];
|
|
15953
|
-
const modelName = toPascalCase(
|
|
16504
|
+
const modelName = toPascalCase(path44.basename(sourceFile2.file, suffix));
|
|
15954
16505
|
const warnings = [];
|
|
15955
16506
|
for (const declaration of getTopLevelDeclarations(sourceFile2)) {
|
|
15956
16507
|
if (isAllowedConventionDeclaration(suffix, modelName, declaration))
|
|
@@ -15961,7 +16512,7 @@ class AkanQualityScanner {
|
|
|
15961
16512
|
severity: "warning",
|
|
15962
16513
|
file: sourceFile2.file,
|
|
15963
16514
|
line: declaration.line,
|
|
15964
|
-
message: `${
|
|
16515
|
+
message: `${path44.basename(sourceFile2.file)} should not declare top-level ${declaration.kind} "${declaration.name}". Allowed declarations: ${getConventionDescription(suffix, modelName)}.`
|
|
15965
16516
|
});
|
|
15966
16517
|
}
|
|
15967
16518
|
return warnings;
|
|
@@ -16033,7 +16584,7 @@ function getExportedFunctionLikes(sourceFile2) {
|
|
|
16033
16584
|
const declarations = [];
|
|
16034
16585
|
const nameExempt = isPageRouteFile(sourceFile2.file) || isUiComponentFile(sourceFile2.file);
|
|
16035
16586
|
for (const statement of sourceFile2.sourceFile.statements) {
|
|
16036
|
-
if (
|
|
16587
|
+
if (ts12.isFunctionDeclaration(statement) && statement.name && isExported(statement)) {
|
|
16037
16588
|
declarations.push({
|
|
16038
16589
|
name: statement.name.text,
|
|
16039
16590
|
kind: "function",
|
|
@@ -16043,7 +16594,7 @@ function getExportedFunctionLikes(sourceFile2) {
|
|
|
16043
16594
|
duplicateNameExempt: nameExempt || isConventionDuplicateNameExempt(sourceFile2.file, false)
|
|
16044
16595
|
});
|
|
16045
16596
|
}
|
|
16046
|
-
if (
|
|
16597
|
+
if (ts12.isClassDeclaration(statement) && statement.name && isExported(statement)) {
|
|
16047
16598
|
declarations.push({
|
|
16048
16599
|
name: statement.name.text,
|
|
16049
16600
|
kind: "class",
|
|
@@ -16053,9 +16604,9 @@ function getExportedFunctionLikes(sourceFile2) {
|
|
|
16053
16604
|
duplicateNameExempt: nameExempt || isConventionDuplicateNameExempt(sourceFile2.file, isEnumClassStatement(sourceFile2.sourceFile, statement))
|
|
16054
16605
|
});
|
|
16055
16606
|
}
|
|
16056
|
-
if (
|
|
16607
|
+
if (ts12.isVariableStatement(statement) && isExported(statement)) {
|
|
16057
16608
|
for (const declaration of statement.declarationList.declarations) {
|
|
16058
|
-
if (!
|
|
16609
|
+
if (!ts12.isIdentifier(declaration.name) || !isFunctionLikeInitializer(declaration.initializer))
|
|
16059
16610
|
continue;
|
|
16060
16611
|
declarations.push({
|
|
16061
16612
|
name: declaration.name.text,
|
|
@@ -16094,14 +16645,14 @@ function isInLibModule(file) {
|
|
|
16094
16645
|
return (segments[0] === "apps" || segments[0] === "libs") && segments.includes("lib");
|
|
16095
16646
|
}
|
|
16096
16647
|
function isEnumClassStatement(sourceFile2, statement) {
|
|
16097
|
-
if (!
|
|
16648
|
+
if (!ts12.isClassDeclaration(statement))
|
|
16098
16649
|
return false;
|
|
16099
|
-
const heritageClause = statement.heritageClauses?.find((clause) => clause.token ===
|
|
16650
|
+
const heritageClause = statement.heritageClauses?.find((clause) => clause.token === ts12.SyntaxKind.ExtendsKeyword);
|
|
16100
16651
|
const expression = heritageClause?.types[0]?.expression;
|
|
16101
16652
|
return !!expression && expression.getText(sourceFile2).startsWith("enumOf(");
|
|
16102
16653
|
}
|
|
16103
16654
|
function getExportedClassNames(sourceFile2) {
|
|
16104
|
-
return sourceFile2.statements.filter((statement) =>
|
|
16655
|
+
return sourceFile2.statements.filter((statement) => ts12.isClassDeclaration(statement) && !!statement.name).filter((statement) => isExported(statement)).map((statement) => statement.name.text);
|
|
16105
16656
|
}
|
|
16106
16657
|
function isComponentDeclarationFile(file) {
|
|
16107
16658
|
if (!file.endsWith(".tsx"))
|
|
@@ -16117,7 +16668,7 @@ function isComponentDeclarationFile(file) {
|
|
|
16117
16668
|
function getComponentFileDeclarations(sourceFile2) {
|
|
16118
16669
|
const reExportedNames = new Set;
|
|
16119
16670
|
for (const statement of sourceFile2.statements) {
|
|
16120
|
-
if (
|
|
16671
|
+
if (ts12.isExportDeclaration(statement) && statement.exportClause && ts12.isNamedExports(statement.exportClause)) {
|
|
16121
16672
|
for (const element of statement.exportClause.elements)
|
|
16122
16673
|
reExportedNames.add((element.propertyName ?? element.name).text);
|
|
16123
16674
|
}
|
|
@@ -16127,19 +16678,19 @@ function getComponentFileDeclarations(sourceFile2) {
|
|
|
16127
16678
|
const isDefaultExport = isDefaultExportStatement(statement);
|
|
16128
16679
|
const inlineExported = isExported(statement);
|
|
16129
16680
|
const add = (name, kind, line) => declarations.push({ name, kind, line, exported: inlineExported || reExportedNames.has(name), isDefaultExport });
|
|
16130
|
-
if (
|
|
16681
|
+
if (ts12.isInterfaceDeclaration(statement))
|
|
16131
16682
|
add(statement.name.text, "interface", getLine(sourceFile2, statement));
|
|
16132
|
-
else if (
|
|
16683
|
+
else if (ts12.isTypeAliasDeclaration(statement))
|
|
16133
16684
|
add(statement.name.text, "type", getLine(sourceFile2, statement));
|
|
16134
|
-
else if (
|
|
16685
|
+
else if (ts12.isEnumDeclaration(statement))
|
|
16135
16686
|
add(statement.name.text, "enum", getLine(sourceFile2, statement));
|
|
16136
|
-
else if (
|
|
16687
|
+
else if (ts12.isFunctionDeclaration(statement) && statement.name)
|
|
16137
16688
|
add(statement.name.text, "function", getLine(sourceFile2, statement));
|
|
16138
|
-
else if (
|
|
16689
|
+
else if (ts12.isClassDeclaration(statement) && statement.name)
|
|
16139
16690
|
add(statement.name.text, "class", getLine(sourceFile2, statement));
|
|
16140
|
-
else if (
|
|
16691
|
+
else if (ts12.isVariableStatement(statement)) {
|
|
16141
16692
|
for (const declaration of statement.declarationList.declarations) {
|
|
16142
|
-
if (!
|
|
16693
|
+
if (!ts12.isIdentifier(declaration.name))
|
|
16143
16694
|
continue;
|
|
16144
16695
|
const kind = isFunctionLikeInitializer(declaration.initializer) ? "function" : "variable";
|
|
16145
16696
|
add(declaration.name.text, kind, getLine(sourceFile2, declaration));
|
|
@@ -16151,15 +16702,15 @@ function getComponentFileDeclarations(sourceFile2) {
|
|
|
16151
16702
|
function getCompoundComponentNames(sourceFile2) {
|
|
16152
16703
|
const names = new Set;
|
|
16153
16704
|
for (const statement of sourceFile2.statements) {
|
|
16154
|
-
if (!
|
|
16705
|
+
if (!ts12.isExpressionStatement(statement))
|
|
16155
16706
|
continue;
|
|
16156
16707
|
const { expression } = statement;
|
|
16157
|
-
if (!
|
|
16708
|
+
if (!ts12.isBinaryExpression(expression) || expression.operatorToken.kind !== ts12.SyntaxKind.EqualsToken)
|
|
16158
16709
|
continue;
|
|
16159
|
-
if (!
|
|
16710
|
+
if (!ts12.isPropertyAccessExpression(expression.left) || !isPascalCaseName(expression.left.name.text))
|
|
16160
16711
|
continue;
|
|
16161
16712
|
names.add(expression.left.name.text);
|
|
16162
|
-
if (
|
|
16713
|
+
if (ts12.isIdentifier(expression.right) && isPascalCaseName(expression.right.text))
|
|
16163
16714
|
names.add(expression.right.text);
|
|
16164
16715
|
}
|
|
16165
16716
|
return names;
|
|
@@ -16179,9 +16730,9 @@ function isPascalCaseName(name) {
|
|
|
16179
16730
|
return /^[A-Z]/.test(name) && !/^[A-Z0-9_]+$/.test(name);
|
|
16180
16731
|
}
|
|
16181
16732
|
function isDefaultExportStatement(statement) {
|
|
16182
|
-
if (
|
|
16733
|
+
if (ts12.isExportAssignment(statement))
|
|
16183
16734
|
return !statement.isExportEquals;
|
|
16184
|
-
return !!(
|
|
16735
|
+
return !!(ts12.getCombinedModifierFlags(statement) & ts12.ModifierFlags.Default);
|
|
16185
16736
|
}
|
|
16186
16737
|
function getPlaceholderExportWarnings(sourceFile2) {
|
|
16187
16738
|
if (!sourceFile2.file.endsWith("/index.ts") && !sourceFile2.file.endsWith("/index.tsx"))
|
|
@@ -16211,7 +16762,7 @@ function getDictionaryTextWarnings(sourceFile2) {
|
|
|
16211
16762
|
function getGlobalMutationWarnings(sourceFile2) {
|
|
16212
16763
|
const warnings = [];
|
|
16213
16764
|
for (const statement of sourceFile2.sourceFile.statements) {
|
|
16214
|
-
if (
|
|
16765
|
+
if (ts12.isModuleDeclaration(statement) && statement.name.getText(sourceFile2.sourceFile) === "global") {
|
|
16215
16766
|
warnings.push({
|
|
16216
16767
|
rule: "akan.file.global-declaration",
|
|
16217
16768
|
scope: "file",
|
|
@@ -16221,7 +16772,7 @@ function getGlobalMutationWarnings(sourceFile2) {
|
|
|
16221
16772
|
message: "Global declarations require an explicit low-level integration allowlist."
|
|
16222
16773
|
});
|
|
16223
16774
|
}
|
|
16224
|
-
if (
|
|
16775
|
+
if (ts12.isInterfaceDeclaration(statement) && statement.name.text === "Window") {
|
|
16225
16776
|
warnings.push({
|
|
16226
16777
|
rule: "akan.file.window-augmentation",
|
|
16227
16778
|
scope: "file",
|
|
@@ -16231,7 +16782,7 @@ function getGlobalMutationWarnings(sourceFile2) {
|
|
|
16231
16782
|
message: "Window augmentation should be isolated to approved browser integration files."
|
|
16232
16783
|
});
|
|
16233
16784
|
}
|
|
16234
|
-
if (
|
|
16785
|
+
if (ts12.isExpressionStatement(statement) && statement.expression.getText(sourceFile2.sourceFile).includes(".prototype.")) {
|
|
16235
16786
|
warnings.push({
|
|
16236
16787
|
rule: "akan.file.prototype-mutation",
|
|
16237
16788
|
scope: "file",
|
|
@@ -16249,23 +16800,23 @@ function getTopLevelDeclarations(sourceFile2) {
|
|
|
16249
16800
|
}
|
|
16250
16801
|
function getTopLevelDeclaration(sourceFile2, statement) {
|
|
16251
16802
|
const line = getLine(sourceFile2, statement);
|
|
16252
|
-
if (
|
|
16803
|
+
if (ts12.isClassDeclaration(statement) && statement.name) {
|
|
16253
16804
|
return [{ name: statement.name.text, kind: "class", line, exported: isExported(statement), node: statement }];
|
|
16254
16805
|
}
|
|
16255
|
-
if (
|
|
16806
|
+
if (ts12.isFunctionDeclaration(statement) && statement.name) {
|
|
16256
16807
|
return [{ name: statement.name.text, kind: "function", line, exported: isExported(statement), node: statement }];
|
|
16257
16808
|
}
|
|
16258
|
-
if (
|
|
16809
|
+
if (ts12.isInterfaceDeclaration(statement)) {
|
|
16259
16810
|
return [{ name: statement.name.text, kind: "interface", line, exported: isExported(statement), node: statement }];
|
|
16260
16811
|
}
|
|
16261
|
-
if (
|
|
16812
|
+
if (ts12.isTypeAliasDeclaration(statement)) {
|
|
16262
16813
|
return [{ name: statement.name.text, kind: "type", line, exported: isExported(statement), node: statement }];
|
|
16263
16814
|
}
|
|
16264
|
-
if (
|
|
16815
|
+
if (ts12.isEnumDeclaration(statement)) {
|
|
16265
16816
|
return [{ name: statement.name.text, kind: "enum", line, exported: isExported(statement), node: statement }];
|
|
16266
16817
|
}
|
|
16267
|
-
if (
|
|
16268
|
-
return statement.declarationList.declarations.filter((declaration) =>
|
|
16818
|
+
if (ts12.isVariableStatement(statement)) {
|
|
16819
|
+
return statement.declarationList.declarations.filter((declaration) => ts12.isIdentifier(declaration.name)).map((declaration) => ({
|
|
16269
16820
|
name: declaration.name.text,
|
|
16270
16821
|
kind: "variable",
|
|
16271
16822
|
line: getLine(sourceFile2, declaration),
|
|
@@ -16273,7 +16824,7 @@ function getTopLevelDeclaration(sourceFile2, statement) {
|
|
|
16273
16824
|
node: statement
|
|
16274
16825
|
}));
|
|
16275
16826
|
}
|
|
16276
|
-
if (
|
|
16827
|
+
if (ts12.isExportDeclaration(statement)) {
|
|
16277
16828
|
return [{ name: "export declaration", kind: "export", line, exported: true, node: statement }];
|
|
16278
16829
|
}
|
|
16279
16830
|
return [];
|
|
@@ -16298,9 +16849,9 @@ function isAllowedConstantDeclaration(modelName, declaration) {
|
|
|
16298
16849
|
return false;
|
|
16299
16850
|
if ([`${modelName}Input`, `${modelName}Object`, modelName, `Light${modelName}`, `${modelName}Insight`].includes(declaration.name))
|
|
16300
16851
|
return true;
|
|
16301
|
-
if (!
|
|
16852
|
+
if (!ts12.isClassDeclaration(declaration.node))
|
|
16302
16853
|
return false;
|
|
16303
|
-
const heritageClause = declaration.node.heritageClauses?.find((clause) => clause.token ===
|
|
16854
|
+
const heritageClause = declaration.node.heritageClauses?.find((clause) => clause.token === ts12.SyntaxKind.ExtendsKeyword);
|
|
16304
16855
|
const expression = heritageClause?.types[0]?.expression;
|
|
16305
16856
|
return !!expression && expression.getText().startsWith("enumOf(");
|
|
16306
16857
|
}
|
|
@@ -16366,13 +16917,13 @@ function getModuleInfo(file) {
|
|
|
16366
16917
|
return { moduleName, fileName, kind: "database" };
|
|
16367
16918
|
}
|
|
16368
16919
|
function isExportedConst(declaration) {
|
|
16369
|
-
return declaration.exported &&
|
|
16920
|
+
return declaration.exported && ts12.isVariableStatement(declaration.node) && (declaration.node.declarationList.flags & ts12.NodeFlags.Const) !== 0;
|
|
16370
16921
|
}
|
|
16371
16922
|
function isExported(node) {
|
|
16372
|
-
return !!
|
|
16923
|
+
return !!ts12.getCombinedModifierFlags(node) && !!(ts12.getCombinedModifierFlags(node) & ts12.ModifierFlags.Export);
|
|
16373
16924
|
}
|
|
16374
16925
|
function isFunctionLikeInitializer(node) {
|
|
16375
|
-
return !!node && (
|
|
16926
|
+
return !!node && (ts12.isArrowFunction(node) || ts12.isFunctionExpression(node));
|
|
16376
16927
|
}
|
|
16377
16928
|
function getBodyFingerprint(sourceFile2, node) {
|
|
16378
16929
|
if (!node)
|
|
@@ -16388,13 +16939,13 @@ function shouldSkipPath(relativePath, isDirectory, ignoreFilter) {
|
|
|
16388
16939
|
}
|
|
16389
16940
|
async function isDirectory(absolutePath) {
|
|
16390
16941
|
try {
|
|
16391
|
-
return (await
|
|
16942
|
+
return (await stat5(absolutePath)).isDirectory();
|
|
16392
16943
|
} catch {
|
|
16393
16944
|
return false;
|
|
16394
16945
|
}
|
|
16395
16946
|
}
|
|
16396
16947
|
function getScriptKind(file) {
|
|
16397
|
-
return file.endsWith(".tsx") ?
|
|
16948
|
+
return file.endsWith(".tsx") ? ts12.ScriptKind.TSX : ts12.ScriptKind.TS;
|
|
16398
16949
|
}
|
|
16399
16950
|
function getLine(sourceFile2, node) {
|
|
16400
16951
|
return sourceFile2.getLineAndCharacterOfPosition(node.getStart(sourceFile2)).line + 1;
|
|
@@ -16415,7 +16966,7 @@ function toPascalCase(value) {
|
|
|
16415
16966
|
return value.replace(/(^|[-_./])([a-zA-Z0-9])/g, (_, __, char) => char.toUpperCase()).replace(/[-_./]/g, "");
|
|
16416
16967
|
}
|
|
16417
16968
|
function toPosix(value) {
|
|
16418
|
-
return value.split(
|
|
16969
|
+
return value.split(path44.sep).join("/");
|
|
16419
16970
|
}
|
|
16420
16971
|
function groupBy(items, getKey) {
|
|
16421
16972
|
const grouped = new Map;
|
|
@@ -16464,6 +17015,7 @@ class IncrementalBuilder {
|
|
|
16464
17015
|
#discovery;
|
|
16465
17016
|
#changePlanner;
|
|
16466
17017
|
#generatedIndexSync;
|
|
17018
|
+
#autoImportSync;
|
|
16467
17019
|
#generation = 0;
|
|
16468
17020
|
#workQueue = Promise.resolve();
|
|
16469
17021
|
#cssRebuildQueue = Promise.resolve();
|
|
@@ -16478,6 +17030,7 @@ class IncrementalBuilder {
|
|
|
16478
17030
|
this.#discovery = options.discovery;
|
|
16479
17031
|
this.#changePlanner = new DevChangePlanner({ workspaceRoot: options.app.workspace.workspaceRoot });
|
|
16480
17032
|
this.#generatedIndexSync = new DevGeneratedIndexSync({ workspaceRoot: options.app.workspace.workspaceRoot });
|
|
17033
|
+
this.#autoImportSync = new AutoImportSync({ workspaceRoot: options.app.workspace.workspaceRoot });
|
|
16481
17034
|
}
|
|
16482
17035
|
async handleBuildRoute(msg) {
|
|
16483
17036
|
return this.#enqueueWork(`build-route:${msg.routeId}`, async () => this.#handleBuildRoute(msg));
|
|
@@ -16545,10 +17098,10 @@ class IncrementalBuilder {
|
|
|
16545
17098
|
}
|
|
16546
17099
|
}
|
|
16547
17100
|
batchTouchesPagesTree(appDir, batch) {
|
|
16548
|
-
const absAppDir =
|
|
17101
|
+
const absAppDir = path45.resolve(appDir);
|
|
16549
17102
|
for (const f of batch.files) {
|
|
16550
|
-
const abs =
|
|
16551
|
-
if (!abs.startsWith(`${absAppDir}${
|
|
17103
|
+
const abs = path45.resolve(f);
|
|
17104
|
+
if (!abs.startsWith(`${absAppDir}${path45.sep}`) && abs !== absAppDir)
|
|
16552
17105
|
continue;
|
|
16553
17106
|
if (/\.(tsx|ts|jsx|js)$/.test(abs))
|
|
16554
17107
|
return true;
|
|
@@ -16556,15 +17109,15 @@ class IncrementalBuilder {
|
|
|
16556
17109
|
return false;
|
|
16557
17110
|
}
|
|
16558
17111
|
async batchMayChangePageKeys(appDir, batch) {
|
|
16559
|
-
const absAppDir =
|
|
16560
|
-
const pageKeys = new Set((await this.#app.getPageKeys()).map((key) =>
|
|
17112
|
+
const absAppDir = path45.resolve(appDir);
|
|
17113
|
+
const pageKeys = new Set((await this.#app.getPageKeys()).map((key) => path45.normalize(key)));
|
|
16561
17114
|
for (const f of batch.files) {
|
|
16562
|
-
const abs =
|
|
16563
|
-
if (!abs.startsWith(`${absAppDir}${
|
|
17115
|
+
const abs = path45.resolve(f);
|
|
17116
|
+
if (!abs.startsWith(`${absAppDir}${path45.sep}`) && abs !== absAppDir)
|
|
16564
17117
|
continue;
|
|
16565
17118
|
if (!/\.(tsx|ts|jsx|js)$/.test(abs))
|
|
16566
17119
|
continue;
|
|
16567
|
-
const rel =
|
|
17120
|
+
const rel = path45.normalize(path45.relative(absAppDir, abs));
|
|
16568
17121
|
if (!await Bun.file(abs).exists() || !pageKeys.has(rel))
|
|
16569
17122
|
return true;
|
|
16570
17123
|
}
|
|
@@ -16592,7 +17145,7 @@ class IncrementalBuilder {
|
|
|
16592
17145
|
${cssText}`).toString(36);
|
|
16593
17146
|
const cssRelPath = `styles/${cssAssetName}-${cssHash}.css`;
|
|
16594
17147
|
const cssUrl = `/_akan/styles/${cssAssetName}-${cssHash}.css`;
|
|
16595
|
-
await Bun.write(
|
|
17148
|
+
await Bun.write(path45.join(artifactDir, cssRelPath), cssText);
|
|
16596
17149
|
cssAssetEntries.push([basePath2, { cssUrl, cssRelPath }]);
|
|
16597
17150
|
cssBase64ByUrl[cssUrl] = Buffer.from(new TextEncoder().encode(cssText)).toString("base64");
|
|
16598
17151
|
})()
|
|
@@ -16660,10 +17213,10 @@ ${cssText}`).toString(36);
|
|
|
16660
17213
|
if (changedFiles.length === 0)
|
|
16661
17214
|
return false;
|
|
16662
17215
|
return changedFiles.some((file) => {
|
|
16663
|
-
const normalized =
|
|
17216
|
+
const normalized = path45.resolve(file);
|
|
16664
17217
|
if (/\.(woff2?|ttf|otf)$/i.test(normalized))
|
|
16665
17218
|
return true;
|
|
16666
|
-
return this.#optimizedFonts.files.some((fontFile) =>
|
|
17219
|
+
return this.#optimizedFonts.files.some((fontFile) => path45.resolve(fontFile) === normalized);
|
|
16667
17220
|
});
|
|
16668
17221
|
}
|
|
16669
17222
|
async installWatcher() {
|
|
@@ -16684,6 +17237,11 @@ ${cssText}`).toString(36);
|
|
|
16684
17237
|
if (rawKinds.size === 0)
|
|
16685
17238
|
return;
|
|
16686
17239
|
const generation = ++this.#generation;
|
|
17240
|
+
const autoImport = await this.#autoImportSync.syncForBatch(batch.files);
|
|
17241
|
+
for (const error of autoImport.errors)
|
|
17242
|
+
this.#logger.error(error);
|
|
17243
|
+
if (autoImport.changedFiles.length > 0)
|
|
17244
|
+
this.#logger.verbose(`[auto-import] inserted imports into ${autoImport.changedFiles.length} file(s)`);
|
|
16687
17245
|
const indexSync = await this.#generatedIndexSync.syncForBatch(batch.files);
|
|
16688
17246
|
const { files, kinds, expandedBatch, event, hasSyncErrors } = prepareDevWatchBatch({
|
|
16689
17247
|
generation,
|