@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
package/index.js
CHANGED
|
@@ -8835,7 +8835,7 @@ Caused by: ${ApplicationBuildReporter.formatError(error.cause)}` : "";
|
|
|
8835
8835
|
}
|
|
8836
8836
|
// pkgs/@akanjs/devkit/applicationBuildRunner.ts
|
|
8837
8837
|
import { mkdir as mkdir8, rm as rm4 } from "fs/promises";
|
|
8838
|
-
import
|
|
8838
|
+
import path38 from "path";
|
|
8839
8839
|
|
|
8840
8840
|
// pkgs/@akanjs/devkit/frontendBuild/allRoutesBuilder.ts
|
|
8841
8841
|
import path22 from "path";
|
|
@@ -10618,14 +10618,538 @@ class AllRoutesBuilder {
|
|
|
10618
10618
|
this.#routeIds.push(routeId);
|
|
10619
10619
|
}
|
|
10620
10620
|
}
|
|
10621
|
+
// pkgs/@akanjs/devkit/frontendBuild/autoImportSync.ts
|
|
10622
|
+
import { readdir as readdir2, readFile, stat as stat3, writeFile } from "fs/promises";
|
|
10623
|
+
import path23 from "path";
|
|
10624
|
+
import ts8 from "typescript";
|
|
10625
|
+
var TEST_FILE_RE = /\.(test|spec)\.(ts|tsx)$/;
|
|
10626
|
+
var AKAN_BASE = {
|
|
10627
|
+
names: ["Int", "Float", "ID", "Any", "Upload", "enumOf", "dayjs"],
|
|
10628
|
+
specifier: "akanjs/base",
|
|
10629
|
+
kind: "named"
|
|
10630
|
+
};
|
|
10631
|
+
var AKAN_BASE_TYPES = { names: ["Dayjs"], specifier: "akanjs/base", kind: "named", typeOnly: true };
|
|
10632
|
+
var CNST_NS = { names: ["cnst"], specifier: "../cnst", kind: "namespace" };
|
|
10633
|
+
var DB_NS = { names: ["db"], specifier: "../db", kind: "namespace" };
|
|
10634
|
+
var SRV_NS = { names: ["srv"], specifier: "../srv", kind: "namespace" };
|
|
10635
|
+
var ERR_DICT = { names: ["Err"], specifier: "../dict", kind: "named" };
|
|
10636
|
+
var RULES = {
|
|
10637
|
+
constant: [AKAN_BASE, AKAN_BASE_TYPES, { names: ["via"], specifier: "akanjs/constant", kind: "named" }],
|
|
10638
|
+
document: [
|
|
10639
|
+
AKAN_BASE,
|
|
10640
|
+
AKAN_BASE_TYPES,
|
|
10641
|
+
CNST_NS,
|
|
10642
|
+
DB_NS,
|
|
10643
|
+
ERR_DICT,
|
|
10644
|
+
{
|
|
10645
|
+
names: ["by", "from", "into", "SchemaOf", "DataInputOf", "DocumentUpdateHelper", "documentQueryHelper", "Mdl"],
|
|
10646
|
+
specifier: "akanjs/document",
|
|
10647
|
+
kind: "named"
|
|
10648
|
+
}
|
|
10649
|
+
],
|
|
10650
|
+
service: [
|
|
10651
|
+
AKAN_BASE,
|
|
10652
|
+
AKAN_BASE_TYPES,
|
|
10653
|
+
DB_NS,
|
|
10654
|
+
SRV_NS,
|
|
10655
|
+
CNST_NS,
|
|
10656
|
+
ERR_DICT,
|
|
10657
|
+
{ names: ["serve"], specifier: "akanjs/service", kind: "named" },
|
|
10658
|
+
{
|
|
10659
|
+
names: ["DataInputOf", "ListQueryOption", "DatabaseRegistry", "getFilterInfoByKey"],
|
|
10660
|
+
specifier: "akanjs/document",
|
|
10661
|
+
kind: "named"
|
|
10662
|
+
}
|
|
10663
|
+
],
|
|
10664
|
+
signal: [
|
|
10665
|
+
AKAN_BASE,
|
|
10666
|
+
AKAN_BASE_TYPES,
|
|
10667
|
+
SRV_NS,
|
|
10668
|
+
CNST_NS,
|
|
10669
|
+
ERR_DICT,
|
|
10670
|
+
{
|
|
10671
|
+
names: ["endpoint", "internal", "slice", "Public", "Req", "Ws", "None", "Res"],
|
|
10672
|
+
specifier: "akanjs/signal",
|
|
10673
|
+
kind: "named"
|
|
10674
|
+
}
|
|
10675
|
+
],
|
|
10676
|
+
dictionary: [
|
|
10677
|
+
{
|
|
10678
|
+
names: ["modelDictionary", "scalarDictionary", "serviceDictionary"],
|
|
10679
|
+
specifier: "akanjs/dictionary",
|
|
10680
|
+
kind: "named"
|
|
10681
|
+
}
|
|
10682
|
+
],
|
|
10683
|
+
srvkit: [
|
|
10684
|
+
AKAN_BASE,
|
|
10685
|
+
AKAN_BASE_TYPES,
|
|
10686
|
+
{ names: ["Logger", "HttpClient", "sleep"], specifier: "akanjs/common", kind: "named" },
|
|
10687
|
+
{ names: ["adapt"], specifier: "akanjs/service", kind: "named" },
|
|
10688
|
+
{ names: ["SignalContext", "Guard", "InternalArg", "Middleware"], specifier: "akanjs/signal", kind: "named" }
|
|
10689
|
+
],
|
|
10690
|
+
common: [AKAN_BASE, AKAN_BASE_TYPES],
|
|
10691
|
+
store: [
|
|
10692
|
+
CNST_NS,
|
|
10693
|
+
{ names: ["store"], specifier: "akanjs/store", kind: "named" },
|
|
10694
|
+
{ names: ["fetch", "usePage", "sig"], specifier: "../useClient", kind: "named" },
|
|
10695
|
+
{ names: ["st"], specifier: "../st", kind: "named" },
|
|
10696
|
+
{ names: ["RootStore"], specifier: "../st", kind: "named", typeOnly: true }
|
|
10697
|
+
],
|
|
10698
|
+
client: [
|
|
10699
|
+
{
|
|
10700
|
+
names: ["cnst", "fetch", "st", "usePage"],
|
|
10701
|
+
specifier: (ctx) => `@${ctx.scope}/${ctx.project}/client`,
|
|
10702
|
+
kind: "named"
|
|
10703
|
+
}
|
|
10704
|
+
]
|
|
10705
|
+
};
|
|
10706
|
+
var PASCAL_CASE_RE = /^[A-Z][A-Za-z0-9]*$/;
|
|
10707
|
+
var DOMAIN_ROLE_KINDS = {
|
|
10708
|
+
constant: ["constant"],
|
|
10709
|
+
dictionary: ["constant", "document", "signal"],
|
|
10710
|
+
common: ["constant"]
|
|
10711
|
+
};
|
|
10712
|
+
var LIB_BARRELS = {
|
|
10713
|
+
Err: { barrel: "dict", kind: "named" },
|
|
10714
|
+
db: { barrel: "db", kind: "namespace" },
|
|
10715
|
+
cnst: { barrel: "cnst", kind: "namespace" },
|
|
10716
|
+
srv: { barrel: "srv", kind: "namespace" }
|
|
10717
|
+
};
|
|
10718
|
+
var DOMAIN_DENYLIST = new Set([
|
|
10719
|
+
"Map",
|
|
10720
|
+
"Set",
|
|
10721
|
+
"WeakMap",
|
|
10722
|
+
"WeakSet",
|
|
10723
|
+
"Date",
|
|
10724
|
+
"Promise",
|
|
10725
|
+
"Array",
|
|
10726
|
+
"Object",
|
|
10727
|
+
"Error",
|
|
10728
|
+
"TypeError",
|
|
10729
|
+
"RangeError",
|
|
10730
|
+
"RegExp",
|
|
10731
|
+
"Symbol",
|
|
10732
|
+
"Proxy",
|
|
10733
|
+
"Reflect",
|
|
10734
|
+
"JSON",
|
|
10735
|
+
"Math",
|
|
10736
|
+
"Number",
|
|
10737
|
+
"BigInt",
|
|
10738
|
+
"Function",
|
|
10739
|
+
"Boolean",
|
|
10740
|
+
"String",
|
|
10741
|
+
"Record",
|
|
10742
|
+
"Partial",
|
|
10743
|
+
"Required",
|
|
10744
|
+
"Readonly",
|
|
10745
|
+
"Pick",
|
|
10746
|
+
"Omit",
|
|
10747
|
+
"Exclude",
|
|
10748
|
+
"Extract",
|
|
10749
|
+
"NonNullable",
|
|
10750
|
+
"ReturnType",
|
|
10751
|
+
"Parameters",
|
|
10752
|
+
"Awaited",
|
|
10753
|
+
"InstanceType"
|
|
10754
|
+
]);
|
|
10755
|
+
|
|
10756
|
+
class AutoImportSync {
|
|
10757
|
+
#workspaceRoot;
|
|
10758
|
+
#domainCache = new Map;
|
|
10759
|
+
constructor({ workspaceRoot }) {
|
|
10760
|
+
this.#workspaceRoot = path23.resolve(workspaceRoot);
|
|
10761
|
+
}
|
|
10762
|
+
async syncForBatch(files) {
|
|
10763
|
+
const changedFiles = [];
|
|
10764
|
+
const errors = [];
|
|
10765
|
+
const seen = new Set;
|
|
10766
|
+
for (const file of files) {
|
|
10767
|
+
const pkgRoot = this.#domainPkgRootOf(file);
|
|
10768
|
+
if (pkgRoot)
|
|
10769
|
+
this.#domainCache.delete(pkgRoot);
|
|
10770
|
+
}
|
|
10771
|
+
for (const file of files) {
|
|
10772
|
+
const abs = path23.resolve(file);
|
|
10773
|
+
if (seen.has(abs))
|
|
10774
|
+
continue;
|
|
10775
|
+
seen.add(abs);
|
|
10776
|
+
const ctx = this.#contextFor(abs);
|
|
10777
|
+
if (!ctx)
|
|
10778
|
+
continue;
|
|
10779
|
+
try {
|
|
10780
|
+
const changed = await this.#syncFile(abs, ctx);
|
|
10781
|
+
if (changed)
|
|
10782
|
+
changedFiles.push(abs);
|
|
10783
|
+
} catch (err) {
|
|
10784
|
+
errors.push(`[auto-import] sync failed for ${file}: ${formatError(err)}`);
|
|
10785
|
+
}
|
|
10786
|
+
}
|
|
10787
|
+
return { changedFiles, errors };
|
|
10788
|
+
}
|
|
10789
|
+
#contextFor(abs) {
|
|
10790
|
+
const rel = path23.relative(this.#workspaceRoot, abs);
|
|
10791
|
+
if (rel.startsWith("..") || path23.isAbsolute(rel))
|
|
10792
|
+
return null;
|
|
10793
|
+
const base = path23.basename(abs);
|
|
10794
|
+
if (TEST_FILE_RE.test(base) || base === "index.ts" || base === "index.tsx" || base.endsWith(".d.ts"))
|
|
10795
|
+
return null;
|
|
10796
|
+
const parts = rel.split(path23.sep).filter(Boolean);
|
|
10797
|
+
const [scope, project, facet] = parts;
|
|
10798
|
+
if (scope !== "apps" && scope !== "libs" || !project || !facet)
|
|
10799
|
+
return null;
|
|
10800
|
+
const role = roleFor(facet, base);
|
|
10801
|
+
if (!role)
|
|
10802
|
+
return null;
|
|
10803
|
+
return { role, scope, project };
|
|
10804
|
+
}
|
|
10805
|
+
async#syncFile(abs, ctx) {
|
|
10806
|
+
const stats = await stat3(abs).catch(() => null);
|
|
10807
|
+
if (!stats?.isFile())
|
|
10808
|
+
return false;
|
|
10809
|
+
const source2 = await readFile(abs, "utf8");
|
|
10810
|
+
const resolveExtra = await this.#extraResolverFor(abs, ctx);
|
|
10811
|
+
const next = transformSource(source2, abs, ctx, resolveExtra);
|
|
10812
|
+
if (next === null || next === source2)
|
|
10813
|
+
return false;
|
|
10814
|
+
await writeFile(abs, next);
|
|
10815
|
+
return true;
|
|
10816
|
+
}
|
|
10817
|
+
async#extraResolverFor(abs, ctx) {
|
|
10818
|
+
const resolvers = [];
|
|
10819
|
+
if (ctx.role === "srvkit" || ctx.role === "common")
|
|
10820
|
+
resolvers.push(await this.#libBarrelResolver(abs, ctx));
|
|
10821
|
+
const kinds = DOMAIN_ROLE_KINDS[ctx.role];
|
|
10822
|
+
if (kinds)
|
|
10823
|
+
resolvers.push(await this.#domainResolver(abs, ctx, kinds));
|
|
10824
|
+
if (resolvers.length === 0)
|
|
10825
|
+
return;
|
|
10826
|
+
return (symbol) => {
|
|
10827
|
+
for (const resolve of resolvers) {
|
|
10828
|
+
const target = resolve(symbol);
|
|
10829
|
+
if (target)
|
|
10830
|
+
return target;
|
|
10831
|
+
}
|
|
10832
|
+
return null;
|
|
10833
|
+
};
|
|
10834
|
+
}
|
|
10835
|
+
async#domainResolver(abs, ctx, kinds) {
|
|
10836
|
+
const index = await this.#domainIndex(path23.join(this.#workspaceRoot, ctx.scope, ctx.project));
|
|
10837
|
+
const fileDir = path23.dirname(abs);
|
|
10838
|
+
return (symbol) => {
|
|
10839
|
+
if (!PASCAL_CASE_RE.test(symbol) || DOMAIN_DENYLIST.has(symbol))
|
|
10840
|
+
return null;
|
|
10841
|
+
const entries = (index.get(symbol) ?? []).filter((entry) => kinds.includes(entry.kind));
|
|
10842
|
+
if (entries.length !== 1)
|
|
10843
|
+
return null;
|
|
10844
|
+
return { specifier: relativeSpecifier(fileDir, entries[0].file), kind: "named" };
|
|
10845
|
+
};
|
|
10846
|
+
}
|
|
10847
|
+
async#libBarrelResolver(abs, ctx) {
|
|
10848
|
+
const fileDir = path23.dirname(abs);
|
|
10849
|
+
const libDir = path23.join(this.#workspaceRoot, ctx.scope, ctx.project, "lib");
|
|
10850
|
+
const available = new Map;
|
|
10851
|
+
for (const [symbol, { barrel, kind }] of Object.entries(LIB_BARRELS)) {
|
|
10852
|
+
if (await fileExists2(path23.join(libDir, `${barrel}.ts`)))
|
|
10853
|
+
available.set(symbol, { specifier: relativeSpecifier(fileDir, path23.join(libDir, barrel)), kind });
|
|
10854
|
+
}
|
|
10855
|
+
return (symbol) => available.get(symbol) ?? null;
|
|
10856
|
+
}
|
|
10857
|
+
async#domainIndex(pkgRoot) {
|
|
10858
|
+
const cached = this.#domainCache.get(pkgRoot);
|
|
10859
|
+
if (cached)
|
|
10860
|
+
return cached;
|
|
10861
|
+
const index = await buildDomainIndex(path23.join(pkgRoot, "lib"));
|
|
10862
|
+
this.#domainCache.set(pkgRoot, index);
|
|
10863
|
+
return index;
|
|
10864
|
+
}
|
|
10865
|
+
#domainPkgRootOf(file) {
|
|
10866
|
+
const rel = path23.relative(this.#workspaceRoot, path23.resolve(file));
|
|
10867
|
+
if (rel.startsWith("..") || path23.isAbsolute(rel))
|
|
10868
|
+
return null;
|
|
10869
|
+
const [scope, project, facet] = rel.split(path23.sep).filter(Boolean);
|
|
10870
|
+
if (scope !== "apps" && scope !== "libs" || !project || facet !== "lib")
|
|
10871
|
+
return null;
|
|
10872
|
+
if (!domainKindOf(path23.basename(file)))
|
|
10873
|
+
return null;
|
|
10874
|
+
return path23.join(this.#workspaceRoot, scope, project);
|
|
10875
|
+
}
|
|
10876
|
+
}
|
|
10877
|
+
var roleFor = (facet, base) => {
|
|
10878
|
+
if (facet === "lib") {
|
|
10879
|
+
if (base.endsWith(".constant.ts"))
|
|
10880
|
+
return "constant";
|
|
10881
|
+
if (base.endsWith(".document.ts"))
|
|
10882
|
+
return "document";
|
|
10883
|
+
if (base.endsWith(".service.ts"))
|
|
10884
|
+
return "service";
|
|
10885
|
+
if (base.endsWith(".signal.ts"))
|
|
10886
|
+
return "signal";
|
|
10887
|
+
if (base.endsWith(".dictionary.ts"))
|
|
10888
|
+
return "dictionary";
|
|
10889
|
+
if (base.endsWith(".store.ts"))
|
|
10890
|
+
return "store";
|
|
10891
|
+
if (base.endsWith(".tsx"))
|
|
10892
|
+
return "client";
|
|
10893
|
+
return null;
|
|
10894
|
+
}
|
|
10895
|
+
if (facet === "ui" || facet === "page")
|
|
10896
|
+
return base.endsWith(".tsx") ? "client" : null;
|
|
10897
|
+
if (facet === "webkit")
|
|
10898
|
+
return base.endsWith(".ts") || base.endsWith(".tsx") ? "client" : null;
|
|
10899
|
+
if (facet === "srvkit")
|
|
10900
|
+
return base.endsWith(".ts") ? "srvkit" : null;
|
|
10901
|
+
if (facet === "common")
|
|
10902
|
+
return base.endsWith(".ts") || base.endsWith(".tsx") ? "common" : null;
|
|
10903
|
+
return null;
|
|
10904
|
+
};
|
|
10905
|
+
var targetFor = (symbol, ctx) => {
|
|
10906
|
+
for (const rule of RULES[ctx.role]) {
|
|
10907
|
+
if (!rule.names.includes(symbol))
|
|
10908
|
+
continue;
|
|
10909
|
+
const specifier = typeof rule.specifier === "function" ? rule.specifier(ctx) : rule.specifier;
|
|
10910
|
+
return { specifier, kind: rule.kind, typeOnly: rule.typeOnly };
|
|
10911
|
+
}
|
|
10912
|
+
return null;
|
|
10913
|
+
};
|
|
10914
|
+
var transformSource = (source2, fileName, ctx, resolveExtra) => {
|
|
10915
|
+
const sf = ts8.createSourceFile(fileName, source2, ts8.ScriptTarget.Latest, true, scriptKindFor(fileName));
|
|
10916
|
+
const bound = collectBoundNames(sf);
|
|
10917
|
+
const used = collectUsedReferences(sf);
|
|
10918
|
+
const namedBySpecifier = new Map;
|
|
10919
|
+
const namespaceImports = [];
|
|
10920
|
+
for (const name of used) {
|
|
10921
|
+
if (bound.has(name))
|
|
10922
|
+
continue;
|
|
10923
|
+
const target = targetFor(name, ctx) ?? resolveExtra?.(name) ?? null;
|
|
10924
|
+
if (!target)
|
|
10925
|
+
continue;
|
|
10926
|
+
if (target.kind === "namespace")
|
|
10927
|
+
namespaceImports.push({ name, specifier: target.specifier });
|
|
10928
|
+
else {
|
|
10929
|
+
const names = namedBySpecifier.get(target.specifier) ?? new Map;
|
|
10930
|
+
names.set(name, target.typeOnly ?? false);
|
|
10931
|
+
namedBySpecifier.set(target.specifier, names);
|
|
10932
|
+
}
|
|
10933
|
+
}
|
|
10934
|
+
if (namedBySpecifier.size === 0 && namespaceImports.length === 0)
|
|
10935
|
+
return null;
|
|
10936
|
+
const importDecls = sf.statements.filter(ts8.isImportDeclaration);
|
|
10937
|
+
const anchor = importDecls.at(-1) ?? null;
|
|
10938
|
+
const namedImportsBySpecifier = collectExistingNamedImports(importDecls);
|
|
10939
|
+
const edits = [];
|
|
10940
|
+
const newStatements = [];
|
|
10941
|
+
for (const [specifier, names] of namedBySpecifier) {
|
|
10942
|
+
const existing = namedImportsBySpecifier.get(specifier);
|
|
10943
|
+
if (existing) {
|
|
10944
|
+
const merged = new Map(existing.names);
|
|
10945
|
+
for (const [name, isType] of names)
|
|
10946
|
+
if (!merged.has(name))
|
|
10947
|
+
merged.set(name, isType);
|
|
10948
|
+
edits.push({
|
|
10949
|
+
start: existing.decl.getStart(sf),
|
|
10950
|
+
end: existing.decl.getEnd(),
|
|
10951
|
+
text: formatNamedImport(specifier, merged)
|
|
10952
|
+
});
|
|
10953
|
+
} else
|
|
10954
|
+
newStatements.push(formatNamedImport(specifier, names));
|
|
10955
|
+
}
|
|
10956
|
+
for (const ns of namespaceImports)
|
|
10957
|
+
newStatements.push(`import * as ${ns.name} from "${ns.specifier}";`);
|
|
10958
|
+
if (newStatements.length > 0) {
|
|
10959
|
+
const anchorEdit = anchor ? edits.find((edit) => edit.start === anchor.getStart(sf)) : undefined;
|
|
10960
|
+
if (anchorEdit)
|
|
10961
|
+
anchorEdit.text = `${anchorEdit.text}
|
|
10962
|
+
${newStatements.join(`
|
|
10963
|
+
`)}`;
|
|
10964
|
+
else if (anchor)
|
|
10965
|
+
edits.push({ start: anchor.getEnd(), end: anchor.getEnd(), text: `
|
|
10966
|
+
${newStatements.join(`
|
|
10967
|
+
`)}` });
|
|
10968
|
+
else {
|
|
10969
|
+
const prologueEnd = directivePrologueEnd(sf);
|
|
10970
|
+
if (prologueEnd >= 0)
|
|
10971
|
+
edits.push({ start: prologueEnd, end: prologueEnd, text: `
|
|
10972
|
+
${newStatements.join(`
|
|
10973
|
+
`)}` });
|
|
10974
|
+
else
|
|
10975
|
+
edits.push({ start: 0, end: 0, text: `${newStatements.join(`
|
|
10976
|
+
`)}
|
|
10977
|
+
|
|
10978
|
+
` });
|
|
10979
|
+
}
|
|
10980
|
+
}
|
|
10981
|
+
if (edits.length === 0)
|
|
10982
|
+
return null;
|
|
10983
|
+
edits.sort((a, b) => b.start - a.start);
|
|
10984
|
+
let out = source2;
|
|
10985
|
+
for (const edit of edits)
|
|
10986
|
+
out = out.slice(0, edit.start) + edit.text + out.slice(edit.end);
|
|
10987
|
+
return out === source2 ? null : out;
|
|
10988
|
+
};
|
|
10989
|
+
var collectBoundNames = (sf) => {
|
|
10990
|
+
const names = new Set;
|
|
10991
|
+
const visit = (node) => {
|
|
10992
|
+
if (ts8.isImportClause(node)) {
|
|
10993
|
+
if (node.name)
|
|
10994
|
+
names.add(node.name.text);
|
|
10995
|
+
const bindings = node.namedBindings;
|
|
10996
|
+
if (bindings && ts8.isNamespaceImport(bindings))
|
|
10997
|
+
names.add(bindings.name.text);
|
|
10998
|
+
if (bindings && ts8.isNamedImports(bindings))
|
|
10999
|
+
for (const el of bindings.elements)
|
|
11000
|
+
names.add(el.name.text);
|
|
11001
|
+
}
|
|
11002
|
+
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))
|
|
11003
|
+
names.add(node.name.text);
|
|
11004
|
+
ts8.forEachChild(node, visit);
|
|
11005
|
+
};
|
|
11006
|
+
ts8.forEachChild(sf, visit);
|
|
11007
|
+
return names;
|
|
11008
|
+
};
|
|
11009
|
+
var collectUsedReferences = (sf) => {
|
|
11010
|
+
const used = new Set;
|
|
11011
|
+
const visit = (node) => {
|
|
11012
|
+
if (ts8.isIdentifier(node) && isReferencePosition(node))
|
|
11013
|
+
used.add(node.text);
|
|
11014
|
+
ts8.forEachChild(node, visit);
|
|
11015
|
+
};
|
|
11016
|
+
ts8.forEachChild(sf, visit);
|
|
11017
|
+
return used;
|
|
11018
|
+
};
|
|
11019
|
+
var isReferencePosition = (node) => {
|
|
11020
|
+
const parent = node.parent;
|
|
11021
|
+
if (!parent)
|
|
11022
|
+
return true;
|
|
11023
|
+
if (ts8.isPropertyAccessExpression(parent) && parent.name === node)
|
|
11024
|
+
return false;
|
|
11025
|
+
if (ts8.isQualifiedName(parent) && parent.right === node)
|
|
11026
|
+
return false;
|
|
11027
|
+
if (ts8.isPropertyAssignment(parent) && parent.name === node)
|
|
11028
|
+
return false;
|
|
11029
|
+
if (ts8.isPropertySignature(parent) && parent.name === node)
|
|
11030
|
+
return false;
|
|
11031
|
+
if (ts8.isBindingElement(parent) && parent.propertyName === node)
|
|
11032
|
+
return false;
|
|
11033
|
+
if (ts8.isImportSpecifier(parent) || ts8.isExportSpecifier(parent))
|
|
11034
|
+
return false;
|
|
11035
|
+
return true;
|
|
11036
|
+
};
|
|
11037
|
+
var collectExistingNamedImports = (importDecls) => {
|
|
11038
|
+
const map = new Map;
|
|
11039
|
+
for (const decl of importDecls) {
|
|
11040
|
+
const clause = decl.importClause;
|
|
11041
|
+
const bindings = clause?.namedBindings;
|
|
11042
|
+
if (!clause || !bindings || !ts8.isNamedImports(bindings))
|
|
11043
|
+
continue;
|
|
11044
|
+
if (!ts8.isStringLiteral(decl.moduleSpecifier))
|
|
11045
|
+
continue;
|
|
11046
|
+
const specifier = decl.moduleSpecifier.text;
|
|
11047
|
+
if (map.has(specifier))
|
|
11048
|
+
continue;
|
|
11049
|
+
const names = new Map;
|
|
11050
|
+
for (const el of bindings.elements)
|
|
11051
|
+
names.set(el.name.text, clause.isTypeOnly || el.isTypeOnly);
|
|
11052
|
+
map.set(specifier, { decl, names });
|
|
11053
|
+
}
|
|
11054
|
+
return map;
|
|
11055
|
+
};
|
|
11056
|
+
var formatNamedImport = (specifier, names) => {
|
|
11057
|
+
const entries = [...names.entries()].sort((a, b) => compareNames(a[0], b[0]));
|
|
11058
|
+
if (entries.every(([, isType]) => isType))
|
|
11059
|
+
return `import type { ${entries.map(([name]) => name).join(", ")} } from "${specifier}";`;
|
|
11060
|
+
const parts = entries.map(([name, isType]) => isType ? `type ${name}` : name);
|
|
11061
|
+
return `import { ${parts.join(", ")} } from "${specifier}";`;
|
|
11062
|
+
};
|
|
11063
|
+
var directivePrologueEnd = (sf) => {
|
|
11064
|
+
let end = -1;
|
|
11065
|
+
for (const stmt of sf.statements) {
|
|
11066
|
+
if (ts8.isExpressionStatement(stmt) && ts8.isStringLiteral(stmt.expression))
|
|
11067
|
+
end = stmt.getEnd();
|
|
11068
|
+
else
|
|
11069
|
+
break;
|
|
11070
|
+
}
|
|
11071
|
+
return end;
|
|
11072
|
+
};
|
|
11073
|
+
var scriptKindFor = (fileName) => fileName.endsWith(".tsx") ? ts8.ScriptKind.TSX : ts8.ScriptKind.TS;
|
|
11074
|
+
var compareNames = (a, b) => {
|
|
11075
|
+
const [la, lb] = [a.toLowerCase(), b.toLowerCase()];
|
|
11076
|
+
if (la !== lb)
|
|
11077
|
+
return la < lb ? -1 : 1;
|
|
11078
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
11079
|
+
};
|
|
11080
|
+
var formatError = (err) => err instanceof Error ? err.message : String(err);
|
|
11081
|
+
var fileExists2 = async (file) => stat3(file).then((s) => s.isFile()).catch(() => false);
|
|
11082
|
+
var domainKindOf = (base) => {
|
|
11083
|
+
if (base.endsWith(".constant.ts"))
|
|
11084
|
+
return "constant";
|
|
11085
|
+
if (base.endsWith(".document.ts"))
|
|
11086
|
+
return "document";
|
|
11087
|
+
if (base.endsWith(".signal.ts"))
|
|
11088
|
+
return "signal";
|
|
11089
|
+
return null;
|
|
11090
|
+
};
|
|
11091
|
+
var buildDomainIndex = async (libDir) => {
|
|
11092
|
+
const index = new Map;
|
|
11093
|
+
for (const file of await collectDomainFiles(libDir)) {
|
|
11094
|
+
const kind = domainKindOf(path23.basename(file));
|
|
11095
|
+
if (!kind)
|
|
11096
|
+
continue;
|
|
11097
|
+
const src = await readFile(file, "utf8").catch(() => null);
|
|
11098
|
+
if (src === null)
|
|
11099
|
+
continue;
|
|
11100
|
+
for (const name of exportedPascalNames(src, file)) {
|
|
11101
|
+
const entries = index.get(name) ?? [];
|
|
11102
|
+
entries.push({ file, kind });
|
|
11103
|
+
index.set(name, entries);
|
|
11104
|
+
}
|
|
11105
|
+
}
|
|
11106
|
+
return index;
|
|
11107
|
+
};
|
|
11108
|
+
var collectDomainFiles = async (dir) => {
|
|
11109
|
+
const entries = await readdir2(dir, { withFileTypes: true }).catch(() => []);
|
|
11110
|
+
const files = [];
|
|
11111
|
+
for (const entry of entries) {
|
|
11112
|
+
if (entry.name.startsWith(".") || entry.name === "node_modules")
|
|
11113
|
+
continue;
|
|
11114
|
+
const full = path23.join(dir, entry.name);
|
|
11115
|
+
if (entry.isDirectory())
|
|
11116
|
+
files.push(...await collectDomainFiles(full));
|
|
11117
|
+
else if (domainKindOf(entry.name) && !TEST_FILE_RE.test(entry.name))
|
|
11118
|
+
files.push(full);
|
|
11119
|
+
}
|
|
11120
|
+
return files;
|
|
11121
|
+
};
|
|
11122
|
+
var exportedPascalNames = (source2, fileName) => {
|
|
11123
|
+
const sf = ts8.createSourceFile(fileName, source2, ts8.ScriptTarget.Latest, true);
|
|
11124
|
+
const isExported = (node) => ts8.canHaveModifiers(node) && (ts8.getModifiers(node) ?? []).some((m) => m.kind === ts8.SyntaxKind.ExportKeyword);
|
|
11125
|
+
const names = [];
|
|
11126
|
+
for (const stmt of sf.statements) {
|
|
11127
|
+
if ((ts8.isClassDeclaration(stmt) || ts8.isFunctionDeclaration(stmt) || ts8.isEnumDeclaration(stmt)) && stmt.name) {
|
|
11128
|
+
if (isExported(stmt))
|
|
11129
|
+
names.push(stmt.name.text);
|
|
11130
|
+
} else if (ts8.isVariableStatement(stmt) && isExported(stmt)) {
|
|
11131
|
+
for (const decl of stmt.declarationList.declarations)
|
|
11132
|
+
if (ts8.isIdentifier(decl.name))
|
|
11133
|
+
names.push(decl.name.text);
|
|
11134
|
+
} else if (ts8.isExportDeclaration(stmt) && stmt.exportClause && ts8.isNamedExports(stmt.exportClause)) {
|
|
11135
|
+
for (const el of stmt.exportClause.elements)
|
|
11136
|
+
names.push(el.name.text);
|
|
11137
|
+
}
|
|
11138
|
+
}
|
|
11139
|
+
return names.filter((name) => PASCAL_CASE_RE.test(name));
|
|
11140
|
+
};
|
|
11141
|
+
var relativeSpecifier = (fromDir, toFile) => {
|
|
11142
|
+
const rel = path23.relative(fromDir, toFile).replace(/\.tsx?$/, "").split(path23.sep).join("/");
|
|
11143
|
+
return rel.startsWith(".") ? rel : `./${rel}`;
|
|
11144
|
+
};
|
|
10621
11145
|
// pkgs/@akanjs/devkit/frontendBuild/csrArtifactBuilder.ts
|
|
10622
11146
|
import { mkdir as mkdir5, rm as rm2, unlink } from "fs/promises";
|
|
10623
|
-
import
|
|
11147
|
+
import path25 from "path";
|
|
10624
11148
|
|
|
10625
11149
|
// pkgs/@akanjs/devkit/frontendBuild/pagesEntrySourceGenerator.ts
|
|
10626
11150
|
import fs3 from "fs";
|
|
10627
|
-
import
|
|
10628
|
-
import
|
|
11151
|
+
import path24 from "path";
|
|
11152
|
+
import ts9 from "typescript";
|
|
10629
11153
|
|
|
10630
11154
|
class PagesEntrySourceGenerator {
|
|
10631
11155
|
#pageEntries;
|
|
@@ -10667,12 +11191,12 @@ ${entries.join(`
|
|
|
10667
11191
|
`;
|
|
10668
11192
|
}
|
|
10669
11193
|
static #toImportSpecifier(moduleAbsPath) {
|
|
10670
|
-
return
|
|
11194
|
+
return path24.resolve(moduleAbsPath).split(path24.sep).join("/");
|
|
10671
11195
|
}
|
|
10672
11196
|
static #hasAsyncDefaultExport(moduleAbsPath) {
|
|
10673
11197
|
try {
|
|
10674
|
-
const source2 = fs3.readFileSync(
|
|
10675
|
-
const sourceFile2 =
|
|
11198
|
+
const source2 = fs3.readFileSync(path24.resolve(moduleAbsPath), "utf8");
|
|
11199
|
+
const sourceFile2 = ts9.createSourceFile(moduleAbsPath, source2, ts9.ScriptTarget.Latest, true, PagesEntrySourceGenerator.#scriptKind(moduleAbsPath));
|
|
10676
11200
|
return PagesEntrySourceGenerator.#sourceFileHasAsyncDefaultExport(sourceFile2);
|
|
10677
11201
|
} catch {
|
|
10678
11202
|
return false;
|
|
@@ -10682,31 +11206,31 @@ ${entries.join(`
|
|
|
10682
11206
|
const asyncBindings = new Map;
|
|
10683
11207
|
let defaultIdentifier = null;
|
|
10684
11208
|
for (const statement of sourceFile2.statements) {
|
|
10685
|
-
if (
|
|
10686
|
-
if (PagesEntrySourceGenerator.#hasModifier(statement,
|
|
10687
|
-
return PagesEntrySourceGenerator.#hasModifier(statement,
|
|
11209
|
+
if (ts9.isFunctionDeclaration(statement)) {
|
|
11210
|
+
if (PagesEntrySourceGenerator.#hasModifier(statement, ts9.SyntaxKind.DefaultKeyword)) {
|
|
11211
|
+
return PagesEntrySourceGenerator.#hasModifier(statement, ts9.SyntaxKind.AsyncKeyword);
|
|
10688
11212
|
}
|
|
10689
11213
|
if (statement.name) {
|
|
10690
|
-
asyncBindings.set(statement.name.text, PagesEntrySourceGenerator.#hasModifier(statement,
|
|
11214
|
+
asyncBindings.set(statement.name.text, PagesEntrySourceGenerator.#hasModifier(statement, ts9.SyntaxKind.AsyncKeyword));
|
|
10691
11215
|
}
|
|
10692
11216
|
continue;
|
|
10693
11217
|
}
|
|
10694
|
-
if (
|
|
11218
|
+
if (ts9.isVariableStatement(statement)) {
|
|
10695
11219
|
for (const declaration of statement.declarationList.declarations) {
|
|
10696
|
-
if (!
|
|
11220
|
+
if (!ts9.isIdentifier(declaration.name))
|
|
10697
11221
|
continue;
|
|
10698
11222
|
asyncBindings.set(declaration.name.text, PagesEntrySourceGenerator.#isAsyncFunctionExpression(declaration.initializer));
|
|
10699
11223
|
}
|
|
10700
11224
|
continue;
|
|
10701
11225
|
}
|
|
10702
|
-
if (
|
|
11226
|
+
if (ts9.isExportAssignment(statement)) {
|
|
10703
11227
|
if (PagesEntrySourceGenerator.#isAsyncFunctionExpression(statement.expression))
|
|
10704
11228
|
return true;
|
|
10705
|
-
if (
|
|
11229
|
+
if (ts9.isIdentifier(statement.expression))
|
|
10706
11230
|
defaultIdentifier = statement.expression.text;
|
|
10707
11231
|
continue;
|
|
10708
11232
|
}
|
|
10709
|
-
if (
|
|
11233
|
+
if (ts9.isExportDeclaration(statement) && statement.exportClause && ts9.isNamedExports(statement.exportClause)) {
|
|
10710
11234
|
const exportClause = statement.exportClause;
|
|
10711
11235
|
for (const specifier of exportClause.elements) {
|
|
10712
11236
|
if (specifier.name.text !== "default")
|
|
@@ -10718,13 +11242,13 @@ ${entries.join(`
|
|
|
10718
11242
|
return defaultIdentifier ? asyncBindings.get(defaultIdentifier) === true : false;
|
|
10719
11243
|
}
|
|
10720
11244
|
static #hasModifier(node, kind) {
|
|
10721
|
-
return
|
|
11245
|
+
return ts9.canHaveModifiers(node) && (ts9.getModifiers(node)?.some((modifier) => modifier.kind === kind) ?? false);
|
|
10722
11246
|
}
|
|
10723
11247
|
static #isAsyncFunctionExpression(node) {
|
|
10724
|
-
return Boolean(node && (
|
|
11248
|
+
return Boolean(node && (ts9.isArrowFunction(node) || ts9.isFunctionExpression(node)) && PagesEntrySourceGenerator.#hasModifier(node, ts9.SyntaxKind.AsyncKeyword));
|
|
10725
11249
|
}
|
|
10726
11250
|
static #scriptKind(moduleAbsPath) {
|
|
10727
|
-
return moduleAbsPath.endsWith(".tsx") || moduleAbsPath.endsWith(".jsx") ?
|
|
11251
|
+
return moduleAbsPath.endsWith(".tsx") || moduleAbsPath.endsWith(".jsx") ? ts9.ScriptKind.TSX : ts9.ScriptKind.TS;
|
|
10728
11252
|
}
|
|
10729
11253
|
}
|
|
10730
11254
|
|
|
@@ -10750,7 +11274,7 @@ class CsrArtifactBuilder {
|
|
|
10750
11274
|
const csrBasePaths = [...akanConfig2.basePaths];
|
|
10751
11275
|
const htmlEntries = csrBasePaths.length > 0 ? csrBasePaths : ["index"];
|
|
10752
11276
|
await rm2(this.#outputDir, { recursive: true, force: true });
|
|
10753
|
-
await mkdir5(
|
|
11277
|
+
await mkdir5(path25.join(this.#app.cwdPath, ".akan/generated/csr"), { recursive: true });
|
|
10754
11278
|
const generatedHtmlFiles = Object.fromEntries(htmlEntries.map((basePath2) => this.#createHtmlFile(basePath2)));
|
|
10755
11279
|
const result = await Bun.build({
|
|
10756
11280
|
target: "browser",
|
|
@@ -10782,7 +11306,7 @@ ${logs}` : ""}`);
|
|
|
10782
11306
|
return { outputDir: this.#outputDir };
|
|
10783
11307
|
}
|
|
10784
11308
|
get #outputDir() {
|
|
10785
|
-
return
|
|
11309
|
+
return path25.join(this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath, this.#command === "build" ? "csr" : ".akan/artifact/csr");
|
|
10786
11310
|
}
|
|
10787
11311
|
#define() {
|
|
10788
11312
|
const nodeEnv = this.#command === "build" ? "production" : "development";
|
|
@@ -10813,8 +11337,8 @@ ${logs}` : ""}`);
|
|
|
10813
11337
|
];
|
|
10814
11338
|
}
|
|
10815
11339
|
async#loadCsrArtifact() {
|
|
10816
|
-
const artifactDir =
|
|
10817
|
-
const artifactFile = Bun.file(
|
|
11340
|
+
const artifactDir = path25.join(this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath, ".akan/artifact");
|
|
11341
|
+
const artifactFile = Bun.file(path25.join(artifactDir, "base-artifact.json"));
|
|
10818
11342
|
if (!await artifactFile.exists())
|
|
10819
11343
|
return { cssAssets: {} };
|
|
10820
11344
|
const artifact = await artifactFile.json();
|
|
@@ -10827,7 +11351,7 @@ ${logs}` : ""}`);
|
|
|
10827
11351
|
const htmlFile = Bun.file(htmlPath);
|
|
10828
11352
|
if (!await htmlFile.exists())
|
|
10829
11353
|
continue;
|
|
10830
|
-
const basePath2 =
|
|
11354
|
+
const basePath2 = path25.basename(htmlPath, ".html") === "index" ? "" : path25.basename(htmlPath, ".html");
|
|
10831
11355
|
const inlined = await this.#inlineHtmlAssets(await htmlFile.text(), htmlPath, cssAssets[basePath2]);
|
|
10832
11356
|
for (const filePath of inlined.jsFiles)
|
|
10833
11357
|
jsFiles.add(filePath);
|
|
@@ -10869,7 +11393,7 @@ ${remainingAssets.join(`
|
|
|
10869
11393
|
next = CsrArtifactBuilder.injectBeforeHeadEnd(next, style);
|
|
10870
11394
|
}
|
|
10871
11395
|
if (cssAsset) {
|
|
10872
|
-
const cssPath =
|
|
11396
|
+
const cssPath = path25.join(this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath, ".akan/artifact", cssAsset.cssRelPath);
|
|
10873
11397
|
const css = await Bun.file(cssPath).text();
|
|
10874
11398
|
const style = CsrArtifactBuilder.createInlineStyle(css);
|
|
10875
11399
|
if (!next.includes(style))
|
|
@@ -10940,16 +11464,16 @@ ${CsrArtifactBuilder.escapeInlineScript(await loadScript(src))}
|
|
|
10940
11464
|
throw new Error(`[csr-build] cannot inline external script: ${src}`);
|
|
10941
11465
|
}
|
|
10942
11466
|
const normalized = src.startsWith("/") ? src.slice(1) : src;
|
|
10943
|
-
return
|
|
11467
|
+
return path25.resolve(path25.dirname(htmlPath), normalized);
|
|
10944
11468
|
}
|
|
10945
11469
|
}
|
|
10946
11470
|
// pkgs/@akanjs/devkit/frontendBuild/cssCompiler.ts
|
|
10947
|
-
import
|
|
11471
|
+
import path27 from "path";
|
|
10948
11472
|
import { Logger as Logger8 } from "akanjs/common";
|
|
10949
11473
|
import { compile } from "tailwindcss";
|
|
10950
11474
|
|
|
10951
11475
|
// pkgs/@akanjs/devkit/frontendBuild/cssImportResolver.ts
|
|
10952
|
-
import
|
|
11476
|
+
import path26 from "path";
|
|
10953
11477
|
var CSS_IMPORT_EXTS = ["", ".css", "/styles.css", "/index.css"];
|
|
10954
11478
|
|
|
10955
11479
|
class CssImportResolver {
|
|
@@ -11002,7 +11526,7 @@ class CssImportResolver {
|
|
|
11002
11526
|
const exact = this.#paths[id];
|
|
11003
11527
|
if (exact) {
|
|
11004
11528
|
for (const repl of exact) {
|
|
11005
|
-
const resolved = await this.#firstExisting(
|
|
11529
|
+
const resolved = await this.#firstExisting(path26.resolve(this.#workspaceRoot, repl));
|
|
11006
11530
|
if (resolved)
|
|
11007
11531
|
return resolved;
|
|
11008
11532
|
}
|
|
@@ -11013,7 +11537,7 @@ class CssImportResolver {
|
|
|
11013
11537
|
const suffix = id.slice(prefix.length);
|
|
11014
11538
|
for (const repl of replacements) {
|
|
11015
11539
|
const replPath = repl.endsWith("/*") ? repl.slice(0, -1) : repl;
|
|
11016
|
-
const resolved = await this.#firstExisting(
|
|
11540
|
+
const resolved = await this.#firstExisting(path26.resolve(this.#workspaceRoot, replPath + suffix));
|
|
11017
11541
|
if (resolved)
|
|
11018
11542
|
return resolved;
|
|
11019
11543
|
}
|
|
@@ -11043,25 +11567,25 @@ class CssImportResolver {
|
|
|
11043
11567
|
try {
|
|
11044
11568
|
if (!await Bun.file(pkgPath).exists())
|
|
11045
11569
|
return null;
|
|
11046
|
-
const pkgDir =
|
|
11570
|
+
const pkgDir = path26.dirname(pkgPath);
|
|
11047
11571
|
const pkg = await Bun.file(pkgPath).json();
|
|
11048
11572
|
const subpath = id === pkgName ? "." : `.${id.slice(pkgName.length)}`;
|
|
11049
11573
|
const exportValue = pkg.exports?.[subpath];
|
|
11050
11574
|
const styleEntry = (typeof exportValue === "string" ? exportValue : exportValue?.style || exportValue?.import || exportValue?.default) || pkg.exports?.["."]?.style || pkg.style || "index.css";
|
|
11051
|
-
return await this.#firstExisting(
|
|
11575
|
+
return await this.#firstExisting(path26.resolve(pkgDir, styleEntry));
|
|
11052
11576
|
} catch {
|
|
11053
11577
|
return null;
|
|
11054
11578
|
}
|
|
11055
11579
|
}
|
|
11056
11580
|
#resolutionBases(fromBase) {
|
|
11057
|
-
return [fromBase, this.#workspaceRoot,
|
|
11581
|
+
return [fromBase, this.#workspaceRoot, path26.dirname(Bun.main), path26.resolve(path26.dirname(Bun.main), "../..")];
|
|
11058
11582
|
}
|
|
11059
11583
|
#packageJsonCandidates(pkgName) {
|
|
11060
11584
|
return [
|
|
11061
|
-
|
|
11062
|
-
|
|
11063
|
-
|
|
11064
|
-
|
|
11585
|
+
path26.join(this.#workspaceRoot, "pkgs", pkgName, "package.json"),
|
|
11586
|
+
path26.join(this.#workspaceRoot, "node_modules", pkgName, "package.json"),
|
|
11587
|
+
path26.join(path26.dirname(Bun.main), "node_modules", pkgName, "package.json"),
|
|
11588
|
+
path26.join(path26.dirname(Bun.main), "../../", pkgName, "package.json")
|
|
11065
11589
|
];
|
|
11066
11590
|
}
|
|
11067
11591
|
async#firstExisting(basePath2) {
|
|
@@ -11079,7 +11603,7 @@ class CssImportResolver {
|
|
|
11079
11603
|
return parts[0] ?? null;
|
|
11080
11604
|
}
|
|
11081
11605
|
static isCssFile(filePath) {
|
|
11082
|
-
return
|
|
11606
|
+
return path26.extname(filePath) === ".css";
|
|
11083
11607
|
}
|
|
11084
11608
|
}
|
|
11085
11609
|
|
|
@@ -11146,7 +11670,7 @@ class CssCompiler {
|
|
|
11146
11670
|
pageKeys
|
|
11147
11671
|
} = {}) {
|
|
11148
11672
|
pageKeys ??= await this.#app.getPageKeys({ refresh });
|
|
11149
|
-
const seeds = pageKeys.map((key) =>
|
|
11673
|
+
const seeds = pageKeys.map((key) => path27.resolve(this.#app.cwdPath, "page", key));
|
|
11150
11674
|
const cssFiles = new Set;
|
|
11151
11675
|
const sourceFiles = new Set;
|
|
11152
11676
|
const queue = [...seeds];
|
|
@@ -11178,7 +11702,7 @@ class CssCompiler {
|
|
|
11178
11702
|
} catch {
|
|
11179
11703
|
continue;
|
|
11180
11704
|
}
|
|
11181
|
-
const importerDir =
|
|
11705
|
+
const importerDir = path27.dirname(filePath);
|
|
11182
11706
|
for (const imp of imports) {
|
|
11183
11707
|
const spec = imp.path;
|
|
11184
11708
|
if (!spec)
|
|
@@ -11204,7 +11728,7 @@ class CssCompiler {
|
|
|
11204
11728
|
const compileStarted = Date.now();
|
|
11205
11729
|
const compilers = await Promise.all(cssPaths.map(async (cssPath) => {
|
|
11206
11730
|
const css = await Bun.file(cssPath).text();
|
|
11207
|
-
const base =
|
|
11731
|
+
const base = path27.dirname(cssPath);
|
|
11208
11732
|
const compiler = await compile(css, {
|
|
11209
11733
|
base,
|
|
11210
11734
|
loadStylesheet: (id, fromBase) => this.#loadStylesheet(id, fromBase),
|
|
@@ -11235,11 +11759,11 @@ class CssCompiler {
|
|
|
11235
11759
|
async#loadStylesheet(id, fromBase) {
|
|
11236
11760
|
const p = await this.#resolveCssImport(id, fromBase);
|
|
11237
11761
|
const content = await Bun.file(p).text();
|
|
11238
|
-
return { path: p, base:
|
|
11762
|
+
return { path: p, base: path27.dirname(p), content };
|
|
11239
11763
|
}
|
|
11240
11764
|
async#resolveCssImport(id, fromBase) {
|
|
11241
11765
|
if (id.startsWith(".") || id.startsWith("/"))
|
|
11242
|
-
return
|
|
11766
|
+
return path27.resolve(fromBase, id);
|
|
11243
11767
|
const resolver = await this.#getCssImportResolver();
|
|
11244
11768
|
const resolved = await resolver.resolve(id, fromBase);
|
|
11245
11769
|
if (resolved)
|
|
@@ -11255,11 +11779,11 @@ class CssCompiler {
|
|
|
11255
11779
|
async#loadModule(id, fromBase) {
|
|
11256
11780
|
const p = __require.resolve(id, { paths: [fromBase] });
|
|
11257
11781
|
const mod = await import(p);
|
|
11258
|
-
return { path: p, base:
|
|
11782
|
+
return { path: p, base: path27.dirname(p), module: mod.default ?? mod };
|
|
11259
11783
|
}
|
|
11260
11784
|
async#resolveSourceImport(id, fromBase, resolvePackage) {
|
|
11261
11785
|
if (id.startsWith(".") || id.startsWith("/")) {
|
|
11262
|
-
const abs = id.startsWith("/") ? id :
|
|
11786
|
+
const abs = id.startsWith("/") ? id : path27.resolve(fromBase, id);
|
|
11263
11787
|
return resolveSourceFileCandidate(abs);
|
|
11264
11788
|
}
|
|
11265
11789
|
const pkg = await resolvePackage(id);
|
|
@@ -11301,7 +11825,7 @@ async function resolveSourceFileCandidate(absPathNoExt) {
|
|
|
11301
11825
|
return filePath;
|
|
11302
11826
|
}
|
|
11303
11827
|
for (const ext of SOURCE_EXTS3) {
|
|
11304
|
-
const filePath =
|
|
11828
|
+
const filePath = path27.join(absPathNoExt, `index${ext}`);
|
|
11305
11829
|
if (await Bun.file(filePath).exists())
|
|
11306
11830
|
return filePath;
|
|
11307
11831
|
}
|
|
@@ -11324,19 +11848,19 @@ function resolveSourceWithRequire(id, fromBase) {
|
|
|
11324
11848
|
}
|
|
11325
11849
|
}
|
|
11326
11850
|
function isSourceFile(filePath) {
|
|
11327
|
-
return SOURCE_EXTS3.includes(
|
|
11851
|
+
return SOURCE_EXTS3.includes(path27.extname(filePath));
|
|
11328
11852
|
}
|
|
11329
11853
|
function isIgnoredNodeModuleSource(filePath) {
|
|
11330
11854
|
return NODE_MODULES_RE3.test(filePath) && !AKANJS_NODE_MODULE_RE3.test(filePath);
|
|
11331
11855
|
}
|
|
11332
11856
|
function getPageKeyBasePath(pageKey, basePaths) {
|
|
11333
|
-
const normalized = pageKey.split(
|
|
11857
|
+
const normalized = pageKey.split(path27.sep).join("/").replace(/^\.\//, "");
|
|
11334
11858
|
const segments = normalized.split("/");
|
|
11335
11859
|
const firstPublicSegment = segments.find((segment) => segment !== "[lang]" && !/^\(.+\)$/.test(segment));
|
|
11336
11860
|
return firstPublicSegment && basePaths.includes(firstPublicSegment) ? firstPublicSegment : null;
|
|
11337
11861
|
}
|
|
11338
11862
|
// pkgs/@akanjs/devkit/frontendBuild/devChangePlanner.ts
|
|
11339
|
-
import
|
|
11863
|
+
import path28 from "path";
|
|
11340
11864
|
var SOURCE_EXTS4 = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
11341
11865
|
var CONFIG_BASENAMES = new Set(["akan.config.ts", "bunfig.toml", "tsconfig.json", "package.json"]);
|
|
11342
11866
|
var BARREL_FACETS = new Set(["common", "srvkit", "ui", "webkit", "plugin"]);
|
|
@@ -11348,11 +11872,11 @@ var RUNTIME_METADATA_BASENAMES2 = new Set(["dict.ts", "sig.ts", "useClient.ts",
|
|
|
11348
11872
|
class DevChangePlanner {
|
|
11349
11873
|
#workspaceRoot;
|
|
11350
11874
|
constructor({ workspaceRoot }) {
|
|
11351
|
-
this.#workspaceRoot =
|
|
11875
|
+
this.#workspaceRoot = path28.resolve(workspaceRoot);
|
|
11352
11876
|
}
|
|
11353
11877
|
plan({ generation, files, kinds, generatedFiles: generatedFiles2 = [] }) {
|
|
11354
11878
|
const fileList = uniqueResolved([...files, ...generatedFiles2]);
|
|
11355
|
-
const generatedSet = new Set(generatedFiles2.map((file) =>
|
|
11879
|
+
const generatedSet = new Set(generatedFiles2.map((file) => path28.resolve(file)));
|
|
11356
11880
|
const kindSet = new Set(kinds);
|
|
11357
11881
|
const roles = new Set;
|
|
11358
11882
|
const actions = new Set;
|
|
@@ -11369,13 +11893,13 @@ class DevChangePlanner {
|
|
|
11369
11893
|
}
|
|
11370
11894
|
for (const file of fileList) {
|
|
11371
11895
|
const reasons = new Set;
|
|
11372
|
-
const fileRoles = this.#rolesForFile(file, { isGenerated: generatedSet.has(
|
|
11896
|
+
const fileRoles = this.#rolesForFile(file, { isGenerated: generatedSet.has(path28.resolve(file)), reasons });
|
|
11373
11897
|
for (const role of fileRoles)
|
|
11374
11898
|
roles.add(role);
|
|
11375
11899
|
if (reasons.has("runtime-metadata"))
|
|
11376
11900
|
actions.add("restart-builder");
|
|
11377
11901
|
if (reasons.size > 0)
|
|
11378
|
-
reasonByFile[
|
|
11902
|
+
reasonByFile[path28.resolve(file)] = [...reasons].sort();
|
|
11379
11903
|
}
|
|
11380
11904
|
if (roles.has("barrel"))
|
|
11381
11905
|
actions.add("sync-generated");
|
|
@@ -11396,12 +11920,12 @@ class DevChangePlanner {
|
|
|
11396
11920
|
}
|
|
11397
11921
|
#rolesForFile(file, { isGenerated, reasons }) {
|
|
11398
11922
|
const roles = new Set;
|
|
11399
|
-
const abs =
|
|
11400
|
-
const base =
|
|
11401
|
-
const ext =
|
|
11923
|
+
const abs = path28.resolve(file);
|
|
11924
|
+
const base = path28.basename(abs);
|
|
11925
|
+
const ext = path28.extname(abs).toLowerCase();
|
|
11402
11926
|
const isSource = SOURCE_EXTS4.has(ext);
|
|
11403
|
-
const rel =
|
|
11404
|
-
const parts = rel.split(
|
|
11927
|
+
const rel = path28.relative(this.#workspaceRoot, abs);
|
|
11928
|
+
const parts = rel.split(path28.sep).filter(Boolean);
|
|
11405
11929
|
if (CONFIG_BASENAMES.has(base)) {
|
|
11406
11930
|
roles.add("config");
|
|
11407
11931
|
reasons.add("config-file");
|
|
@@ -11442,15 +11966,15 @@ class DevChangePlanner {
|
|
|
11442
11966
|
return roles;
|
|
11443
11967
|
}
|
|
11444
11968
|
#isServerBiased(abs, parts) {
|
|
11445
|
-
const base =
|
|
11969
|
+
const base = path28.basename(abs);
|
|
11446
11970
|
return parts.includes("srvkit") || SERVER_SUFFIXES2.some((suffix) => base.endsWith(suffix)) || base === "main.ts" || base === "server.ts";
|
|
11447
11971
|
}
|
|
11448
11972
|
#isClientBiased(abs, parts) {
|
|
11449
|
-
const base =
|
|
11973
|
+
const base = path28.basename(abs);
|
|
11450
11974
|
return parts.includes("ui") || parts.includes("webkit") || parts.includes("page") || CLIENT_SUFFIXES.some((suffix) => base.endsWith(suffix));
|
|
11451
11975
|
}
|
|
11452
11976
|
#isSharedBiased(abs, parts) {
|
|
11453
|
-
const base =
|
|
11977
|
+
const base = path28.basename(abs);
|
|
11454
11978
|
return parts.includes("common") || SHARED_SUFFIXES2.some((suffix) => base.endsWith(suffix)) || RUNTIME_METADATA_BASENAMES2.has(base);
|
|
11455
11979
|
}
|
|
11456
11980
|
#isRuntimeMetadataFile(parts, base) {
|
|
@@ -11475,16 +11999,16 @@ class DevChangePlanner {
|
|
|
11475
11999
|
return true;
|
|
11476
12000
|
}
|
|
11477
12001
|
#isWorkspaceSource(rel) {
|
|
11478
|
-
if (!rel || rel.startsWith("..") ||
|
|
12002
|
+
if (!rel || rel.startsWith("..") || path28.isAbsolute(rel))
|
|
11479
12003
|
return false;
|
|
11480
|
-
const [scope] = rel.split(
|
|
12004
|
+
const [scope] = rel.split(path28.sep);
|
|
11481
12005
|
return scope === "apps" || scope === "libs" || scope === "pkgs";
|
|
11482
12006
|
}
|
|
11483
12007
|
}
|
|
11484
|
-
var uniqueResolved = (files) => [...new Set(files.map((file) =>
|
|
12008
|
+
var uniqueResolved = (files) => [...new Set(files.map((file) => path28.resolve(file)))].sort();
|
|
11485
12009
|
// pkgs/@akanjs/devkit/frontendBuild/devGeneratedIndexSync.ts
|
|
11486
|
-
import { mkdir as mkdir6, readdir as
|
|
11487
|
-
import
|
|
12010
|
+
import { mkdir as mkdir6, readdir as readdir3, readFile as readFile2, rm as rm3, stat as stat4, writeFile as writeFile2 } from "fs/promises";
|
|
12011
|
+
import path29 from "path";
|
|
11488
12012
|
var BARREL_FACETS2 = new Set(["common", "srvkit", "ui", "webkit", "plugin"]);
|
|
11489
12013
|
var FACET_SOURCE_FILE_RE = /\.(ts|tsx)$/;
|
|
11490
12014
|
var FACET_EXCLUDED_FILE_RE = /(^index\.tsx?$|\.d\.ts$|\.(test|spec)\.(ts|tsx)$|\.css$|\.scss$|\.sass$)/;
|
|
@@ -11497,7 +12021,7 @@ var SCALAR_UI_TYPES = ["Template", "Unit"];
|
|
|
11497
12021
|
class DevGeneratedIndexSync {
|
|
11498
12022
|
#workspaceRoot;
|
|
11499
12023
|
constructor({ workspaceRoot }) {
|
|
11500
|
-
this.#workspaceRoot =
|
|
12024
|
+
this.#workspaceRoot = path29.resolve(workspaceRoot);
|
|
11501
12025
|
}
|
|
11502
12026
|
async syncForBatch(files) {
|
|
11503
12027
|
const indexPaths = new Set;
|
|
@@ -11507,7 +12031,7 @@ class DevGeneratedIndexSync {
|
|
|
11507
12031
|
if (facetIndex)
|
|
11508
12032
|
indexPaths.add(facetIndex);
|
|
11509
12033
|
const moduleIndex2 = await this.#moduleIndexForDirectoryEvent(file).catch((err) => {
|
|
11510
|
-
errors.push(`[generated-index] module detection failed for ${file}: ${
|
|
12034
|
+
errors.push(`[generated-index] module detection failed for ${file}: ${formatError2(err)}`);
|
|
11511
12035
|
return null;
|
|
11512
12036
|
});
|
|
11513
12037
|
if (moduleIndex2)
|
|
@@ -11520,17 +12044,17 @@ class DevGeneratedIndexSync {
|
|
|
11520
12044
|
if (changed)
|
|
11521
12045
|
changedFiles.push(indexPath);
|
|
11522
12046
|
} catch (err) {
|
|
11523
|
-
errors.push(`[generated-index] sync failed for ${indexPath}: ${
|
|
12047
|
+
errors.push(`[generated-index] sync failed for ${indexPath}: ${formatError2(err)}`);
|
|
11524
12048
|
}
|
|
11525
12049
|
}
|
|
11526
12050
|
return { changedFiles, errors };
|
|
11527
12051
|
}
|
|
11528
12052
|
#facetIndexFor(file) {
|
|
11529
|
-
const abs =
|
|
11530
|
-
const rel =
|
|
11531
|
-
if (rel.startsWith("..") ||
|
|
12053
|
+
const abs = path29.resolve(file);
|
|
12054
|
+
const rel = path29.relative(this.#workspaceRoot, abs);
|
|
12055
|
+
if (rel.startsWith("..") || path29.isAbsolute(rel))
|
|
11532
12056
|
return null;
|
|
11533
|
-
const parts = rel.split(
|
|
12057
|
+
const parts = rel.split(path29.sep).filter(Boolean);
|
|
11534
12058
|
if (parts.length < 4)
|
|
11535
12059
|
return null;
|
|
11536
12060
|
const [scope, project, facet, child] = parts;
|
|
@@ -11538,32 +12062,32 @@ class DevGeneratedIndexSync {
|
|
|
11538
12062
|
return null;
|
|
11539
12063
|
if (!child || child.startsWith(".") || child === "index.ts" || child === "index.tsx")
|
|
11540
12064
|
return null;
|
|
11541
|
-
return
|
|
12065
|
+
return path29.join(this.#workspaceRoot, scope, project, facet, "index.ts");
|
|
11542
12066
|
}
|
|
11543
12067
|
async#moduleIndexForDirectoryEvent(file) {
|
|
11544
|
-
const abs =
|
|
11545
|
-
const rel =
|
|
11546
|
-
if (rel.startsWith("..") ||
|
|
12068
|
+
const abs = path29.resolve(file);
|
|
12069
|
+
const rel = path29.relative(this.#workspaceRoot, abs);
|
|
12070
|
+
if (rel.startsWith("..") || path29.isAbsolute(rel))
|
|
11547
12071
|
return null;
|
|
11548
|
-
const parts = rel.split(
|
|
12072
|
+
const parts = rel.split(path29.sep).filter(Boolean);
|
|
11549
12073
|
if (parts.length !== 4 && parts.length !== 5)
|
|
11550
12074
|
return null;
|
|
11551
12075
|
const [scope, project, libSegment, moduleSegment, scalarSegment] = parts;
|
|
11552
12076
|
if (scope !== "apps" && scope !== "libs" || !project || libSegment !== "lib")
|
|
11553
12077
|
return null;
|
|
11554
|
-
const isExistingDirectory = await
|
|
11555
|
-
const looksLikeDeletedDirectory = !
|
|
12078
|
+
const isExistingDirectory = await stat4(abs).then((s) => s.isDirectory()).catch(() => false);
|
|
12079
|
+
const looksLikeDeletedDirectory = !path29.extname(abs);
|
|
11556
12080
|
if (!isExistingDirectory && !looksLikeDeletedDirectory)
|
|
11557
12081
|
return null;
|
|
11558
12082
|
if (moduleSegment === "__scalar" && scalarSegment) {
|
|
11559
|
-
return
|
|
12083
|
+
return path29.join(this.#workspaceRoot, scope, project, "lib", "__scalar", scalarSegment, "index.ts");
|
|
11560
12084
|
}
|
|
11561
12085
|
if (!moduleSegment || moduleSegment === "__scalar")
|
|
11562
12086
|
return null;
|
|
11563
|
-
return
|
|
12087
|
+
return path29.join(this.#workspaceRoot, scope, project, "lib", moduleSegment, "index.ts");
|
|
11564
12088
|
}
|
|
11565
12089
|
async#syncIndex(indexPath) {
|
|
11566
|
-
const dir =
|
|
12090
|
+
const dir = path29.dirname(indexPath);
|
|
11567
12091
|
const content = await this.#contentForIndex(indexPath);
|
|
11568
12092
|
if (content === null) {
|
|
11569
12093
|
if (!await exists(indexPath))
|
|
@@ -11571,23 +12095,23 @@ class DevGeneratedIndexSync {
|
|
|
11571
12095
|
await rm3(indexPath, { force: true });
|
|
11572
12096
|
return true;
|
|
11573
12097
|
}
|
|
11574
|
-
const current = await
|
|
12098
|
+
const current = await readFile2(indexPath, "utf8").catch(() => null);
|
|
11575
12099
|
if (current === content)
|
|
11576
12100
|
return false;
|
|
11577
12101
|
await mkdir6(dir, { recursive: true });
|
|
11578
|
-
await
|
|
12102
|
+
await writeFile2(indexPath, content);
|
|
11579
12103
|
return true;
|
|
11580
12104
|
}
|
|
11581
12105
|
async#contentForIndex(indexPath) {
|
|
11582
|
-
const parts =
|
|
12106
|
+
const parts = path29.relative(this.#workspaceRoot, indexPath).split(path29.sep).filter(Boolean);
|
|
11583
12107
|
const facet = parts.at(-2);
|
|
11584
12108
|
if (facet && BARREL_FACETS2.has(facet))
|
|
11585
|
-
return this.#facetContent(
|
|
11586
|
-
return this.#moduleContent(
|
|
12109
|
+
return this.#facetContent(path29.dirname(indexPath));
|
|
12110
|
+
return this.#moduleContent(path29.dirname(indexPath));
|
|
11587
12111
|
}
|
|
11588
12112
|
async#facetContent(dir) {
|
|
11589
|
-
const nameCasePattern =
|
|
11590
|
-
const entries = await
|
|
12113
|
+
const nameCasePattern = path29.basename(dir) === "ui" ? FACET_PASCAL_CASE_RE : FACET_CAMEL_CASE_RE;
|
|
12114
|
+
const entries = await readdir3(dir, { withFileTypes: true }).catch(() => []);
|
|
11591
12115
|
const exportNames = entries.flatMap((entry) => {
|
|
11592
12116
|
const name = entry.name;
|
|
11593
12117
|
if (name.startsWith("."))
|
|
@@ -11608,8 +12132,8 @@ class DevGeneratedIndexSync {
|
|
|
11608
12132
|
`;
|
|
11609
12133
|
}
|
|
11610
12134
|
async#moduleContent(dir) {
|
|
11611
|
-
const rel =
|
|
11612
|
-
const parts = rel.split(
|
|
12135
|
+
const rel = path29.relative(this.#workspaceRoot, dir);
|
|
12136
|
+
const parts = rel.split(path29.sep).filter(Boolean);
|
|
11613
12137
|
const moduleSegment = parts.at(-1);
|
|
11614
12138
|
if (!moduleSegment)
|
|
11615
12139
|
return null;
|
|
@@ -11621,7 +12145,7 @@ class DevGeneratedIndexSync {
|
|
|
11621
12145
|
const allowedTypes = isScalar ? SCALAR_UI_TYPES : moduleSegment.startsWith("_") ? SERVICE_UI_TYPES : MODULE_UI_TYPES;
|
|
11622
12146
|
const fileTypes = [];
|
|
11623
12147
|
for (const type of allowedTypes) {
|
|
11624
|
-
if (await exists(
|
|
12148
|
+
if (await exists(path29.join(dir, `${modelName}.${type}.tsx`)))
|
|
11625
12149
|
fileTypes.push(type);
|
|
11626
12150
|
}
|
|
11627
12151
|
if (fileTypes.length === 0)
|
|
@@ -11633,12 +12157,12 @@ ${fileTypes.map((type) => `import * as ${type} from "./${modelName}.${type}";`).
|
|
|
11633
12157
|
export const ${modelName} = { ${fileTypes.join(", ")} };`;
|
|
11634
12158
|
}
|
|
11635
12159
|
}
|
|
11636
|
-
var exists = async (file) =>
|
|
12160
|
+
var exists = async (file) => stat4(file).then(() => true).catch(() => false);
|
|
11637
12161
|
var capitalize4 = (value) => `${value.charAt(0).toUpperCase()}${value.slice(1)}`;
|
|
11638
|
-
var
|
|
12162
|
+
var formatError2 = (err) => err instanceof Error ? err.message : String(err);
|
|
11639
12163
|
// pkgs/@akanjs/devkit/frontendBuild/fontOptimizer.ts
|
|
11640
12164
|
import { mkdir as mkdir7 } from "fs/promises";
|
|
11641
|
-
import
|
|
12165
|
+
import path30 from "path";
|
|
11642
12166
|
import {
|
|
11643
12167
|
generateFontFace,
|
|
11644
12168
|
getMetricsForFamily,
|
|
@@ -11647,7 +12171,7 @@ import {
|
|
|
11647
12171
|
} from "fontaine";
|
|
11648
12172
|
import { createFont, woff2 } from "fonteditor-core";
|
|
11649
12173
|
import subsetFont from "subset-font";
|
|
11650
|
-
import
|
|
12174
|
+
import ts10 from "typescript";
|
|
11651
12175
|
var FONT_URL_PREFIX = "/_akan/fonts";
|
|
11652
12176
|
var DEFAULT_FONT_SUBSETS = ["latin"];
|
|
11653
12177
|
|
|
@@ -11662,7 +12186,7 @@ class FontOptimizer {
|
|
|
11662
12186
|
constructor(app, command = "start") {
|
|
11663
12187
|
this.#app = app;
|
|
11664
12188
|
this.#command = command;
|
|
11665
|
-
this.#artifactRoot =
|
|
12189
|
+
this.#artifactRoot = path30.join(command === "build" ? app.dist.cwdPath : app.cwdPath, ".akan/artifact");
|
|
11666
12190
|
}
|
|
11667
12191
|
async optimize() {
|
|
11668
12192
|
const fonts = await this.discoverFonts();
|
|
@@ -11681,7 +12205,7 @@ class FontOptimizer {
|
|
|
11681
12205
|
const pageKeys = await this.#app.getPageKeys();
|
|
11682
12206
|
const fonts = [];
|
|
11683
12207
|
await Promise.all(pageKeys.map(async (key) => {
|
|
11684
|
-
const filePath =
|
|
12208
|
+
const filePath = path30.resolve(this.#app.cwdPath, "page", key);
|
|
11685
12209
|
const file = Bun.file(filePath);
|
|
11686
12210
|
if (!await file.exists())
|
|
11687
12211
|
return;
|
|
@@ -11697,8 +12221,8 @@ class FontOptimizer {
|
|
|
11697
12221
|
this.#app.logger.warn(`[font] source not found: ${face.src}`);
|
|
11698
12222
|
continue;
|
|
11699
12223
|
}
|
|
11700
|
-
const outputPath =
|
|
11701
|
-
await mkdir7(
|
|
12224
|
+
const outputPath = path30.join(this.#artifactRoot, face.optimizedSrc.replace(/^\/_akan\//, ""));
|
|
12225
|
+
await mkdir7(path30.dirname(outputPath), { recursive: true });
|
|
11702
12226
|
const sourceBuffer = Buffer.from(await Bun.file(sourcePath).arrayBuffer());
|
|
11703
12227
|
const outputBuffer = font.subset === false ? await this.#convertToWoff2(sourceBuffer, sourcePath) : await subsetFont(sourceBuffer, await this.#getSubsetText(font), { targetFormat: "woff2" });
|
|
11704
12228
|
await Bun.write(outputPath, outputBuffer);
|
|
@@ -11712,17 +12236,17 @@ class FontOptimizer {
|
|
|
11712
12236
|
this.#cssParts.push(...faceCss, this.#buildRootVariableRule(font));
|
|
11713
12237
|
}
|
|
11714
12238
|
#extractFontsExport(source2, filePath) {
|
|
11715
|
-
const sourceFile2 =
|
|
12239
|
+
const sourceFile2 = ts10.createSourceFile(filePath, source2, ts10.ScriptTarget.Latest, true, ts10.ScriptKind.TSX);
|
|
11716
12240
|
const fonts = [];
|
|
11717
12241
|
for (const statement of sourceFile2.statements) {
|
|
11718
|
-
if (!
|
|
12242
|
+
if (!ts10.isVariableStatement(statement))
|
|
11719
12243
|
continue;
|
|
11720
|
-
const modifiers =
|
|
11721
|
-
const isExported = modifiers?.some((modifier) => modifier.kind ===
|
|
12244
|
+
const modifiers = ts10.canHaveModifiers(statement) ? ts10.getModifiers(statement) : undefined;
|
|
12245
|
+
const isExported = modifiers?.some((modifier) => modifier.kind === ts10.SyntaxKind.ExportKeyword) ?? false;
|
|
11722
12246
|
if (!isExported)
|
|
11723
12247
|
continue;
|
|
11724
12248
|
for (const declaration of statement.declarationList.declarations) {
|
|
11725
|
-
if (!
|
|
12249
|
+
if (!ts10.isIdentifier(declaration.name) || declaration.name.text !== "fonts")
|
|
11726
12250
|
continue;
|
|
11727
12251
|
const value = declaration.initializer ? this.#literalToValue(declaration.initializer) : null;
|
|
11728
12252
|
if (Array.isArray(value)) {
|
|
@@ -11733,20 +12257,20 @@ class FontOptimizer {
|
|
|
11733
12257
|
return fonts;
|
|
11734
12258
|
}
|
|
11735
12259
|
#literalToValue(node) {
|
|
11736
|
-
if (
|
|
12260
|
+
if (ts10.isStringLiteralLike(node))
|
|
11737
12261
|
return node.text;
|
|
11738
|
-
if (
|
|
12262
|
+
if (ts10.isNumericLiteral(node))
|
|
11739
12263
|
return Number(node.text);
|
|
11740
|
-
if (node.kind ===
|
|
12264
|
+
if (node.kind === ts10.SyntaxKind.TrueKeyword)
|
|
11741
12265
|
return true;
|
|
11742
|
-
if (node.kind ===
|
|
12266
|
+
if (node.kind === ts10.SyntaxKind.FalseKeyword)
|
|
11743
12267
|
return false;
|
|
11744
|
-
if (
|
|
12268
|
+
if (ts10.isArrayLiteralExpression(node))
|
|
11745
12269
|
return node.elements.map((element) => this.#literalToValue(element));
|
|
11746
|
-
if (
|
|
12270
|
+
if (ts10.isObjectLiteralExpression(node)) {
|
|
11747
12271
|
const obj = {};
|
|
11748
12272
|
for (const prop of node.properties) {
|
|
11749
|
-
if (!
|
|
12273
|
+
if (!ts10.isPropertyAssignment(prop))
|
|
11750
12274
|
continue;
|
|
11751
12275
|
const name = this.#getPropertyName(prop.name);
|
|
11752
12276
|
if (!name)
|
|
@@ -11755,13 +12279,13 @@ class FontOptimizer {
|
|
|
11755
12279
|
}
|
|
11756
12280
|
return obj;
|
|
11757
12281
|
}
|
|
11758
|
-
if (
|
|
12282
|
+
if (ts10.isAsExpression(node) || ts10.isSatisfiesExpression(node) || ts10.isParenthesizedExpression(node)) {
|
|
11759
12283
|
return this.#literalToValue(node.expression);
|
|
11760
12284
|
}
|
|
11761
12285
|
return;
|
|
11762
12286
|
}
|
|
11763
12287
|
#getPropertyName(name) {
|
|
11764
|
-
if (
|
|
12288
|
+
if (ts10.isIdentifier(name) || ts10.isStringLiteral(name) || ts10.isNumericLiteral(name))
|
|
11765
12289
|
return name.text;
|
|
11766
12290
|
return null;
|
|
11767
12291
|
}
|
|
@@ -11845,8 +12369,8 @@ class FontOptimizer {
|
|
|
11845
12369
|
return null;
|
|
11846
12370
|
const rel = src.replace(/^\//, "");
|
|
11847
12371
|
const candidates = [
|
|
11848
|
-
this.#command === "build" ?
|
|
11849
|
-
|
|
12372
|
+
this.#command === "build" ? path30.join(this.#app.dist.cwdPath, "public", rel) : null,
|
|
12373
|
+
path30.join(this.#app.cwdPath, "public", rel),
|
|
11850
12374
|
this.#resolveWorkspacePublicPath(rel)
|
|
11851
12375
|
].filter(Boolean);
|
|
11852
12376
|
for (const candidate of candidates) {
|
|
@@ -11874,7 +12398,7 @@ class FontOptimizer {
|
|
|
11874
12398
|
return "woff2";
|
|
11875
12399
|
if (signature === "OTTO")
|
|
11876
12400
|
return "otf";
|
|
11877
|
-
const ext =
|
|
12401
|
+
const ext = path30.extname(sourcePath).slice(1).toLowerCase();
|
|
11878
12402
|
if (ext === "otf" || ext === "woff" || ext === "woff2")
|
|
11879
12403
|
return ext;
|
|
11880
12404
|
return "ttf";
|
|
@@ -11883,7 +12407,7 @@ class FontOptimizer {
|
|
|
11883
12407
|
const [root, dep, ...rest] = rel.split("/");
|
|
11884
12408
|
if (root !== "libs" || !dep || rest.length === 0)
|
|
11885
12409
|
return null;
|
|
11886
|
-
return
|
|
12410
|
+
return path30.join(this.#app.workspace.workspaceRoot, "libs", dep, "public", ...rest);
|
|
11887
12411
|
}
|
|
11888
12412
|
async#getSubsetText(font) {
|
|
11889
12413
|
const parts = new Set;
|
|
@@ -11893,7 +12417,7 @@ class FontOptimizer {
|
|
|
11893
12417
|
if (font.subsetText)
|
|
11894
12418
|
parts.add(font.subsetText);
|
|
11895
12419
|
for (const filePath of font.subsetFiles ?? []) {
|
|
11896
|
-
const abs =
|
|
12420
|
+
const abs = path30.isAbsolute(filePath) ? filePath : path30.join(this.#app.cwdPath, filePath);
|
|
11897
12421
|
const file = Bun.file(abs);
|
|
11898
12422
|
if (await file.exists())
|
|
11899
12423
|
parts.add(await file.text());
|
|
@@ -11912,7 +12436,7 @@ class FontOptimizer {
|
|
|
11912
12436
|
return "";
|
|
11913
12437
|
}
|
|
11914
12438
|
async#collectAutoSubsetText() {
|
|
11915
|
-
const roots = ["page", "ui"].map((dir) =>
|
|
12439
|
+
const roots = ["page", "ui"].map((dir) => path30.join(this.#app.cwdPath, dir));
|
|
11916
12440
|
const glob = new Bun.Glob("**/*.{ts,tsx,js,jsx,html,md}");
|
|
11917
12441
|
const parts = [];
|
|
11918
12442
|
await Promise.all(roots.map(async (root) => {
|
|
@@ -12026,7 +12550,7 @@ ${declarations.map(([prop, value]) => ` ${prop}: ${value};`).join(`
|
|
|
12026
12550
|
}
|
|
12027
12551
|
}
|
|
12028
12552
|
// pkgs/@akanjs/devkit/frontendBuild/hmrChangeClassifier.ts
|
|
12029
|
-
import
|
|
12553
|
+
import path31 from "path";
|
|
12030
12554
|
var SOURCE_EXTS5 = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
12031
12555
|
var CSS_EXTS = new Set([".css"]);
|
|
12032
12556
|
var CONFIG_BASENAMES2 = new Set(["akan.config.ts", "bunfig.toml", "tsconfig.json", "package.json"]);
|
|
@@ -12035,10 +12559,10 @@ class HmrChangeClassifier {
|
|
|
12035
12559
|
classify(abs) {
|
|
12036
12560
|
if (this.#isUninteresting(abs))
|
|
12037
12561
|
return "ignore";
|
|
12038
|
-
const base =
|
|
12562
|
+
const base = path31.basename(abs);
|
|
12039
12563
|
if (CONFIG_BASENAMES2.has(base))
|
|
12040
12564
|
return "config";
|
|
12041
|
-
const ext =
|
|
12565
|
+
const ext = path31.extname(abs).toLowerCase();
|
|
12042
12566
|
if (CSS_EXTS.has(ext))
|
|
12043
12567
|
return "css";
|
|
12044
12568
|
if (SOURCE_EXTS5.has(ext))
|
|
@@ -12046,23 +12570,23 @@ class HmrChangeClassifier {
|
|
|
12046
12570
|
return "ignore";
|
|
12047
12571
|
}
|
|
12048
12572
|
#isUninteresting(abs) {
|
|
12049
|
-
const base =
|
|
12573
|
+
const base = path31.basename(abs);
|
|
12050
12574
|
if (!base)
|
|
12051
12575
|
return true;
|
|
12052
12576
|
if (base.startsWith("."))
|
|
12053
12577
|
return true;
|
|
12054
12578
|
if (base.endsWith("~") || base.endsWith(".swp") || base.endsWith(".swx") || base.endsWith(".tmp"))
|
|
12055
12579
|
return true;
|
|
12056
|
-
if (abs.includes(`${
|
|
12580
|
+
if (abs.includes(`${path31.sep}node_modules${path31.sep}`))
|
|
12057
12581
|
return true;
|
|
12058
|
-
if (abs.includes(`${
|
|
12582
|
+
if (abs.includes(`${path31.sep}.akan${path31.sep}`))
|
|
12059
12583
|
return true;
|
|
12060
12584
|
return false;
|
|
12061
12585
|
}
|
|
12062
12586
|
}
|
|
12063
12587
|
// pkgs/@akanjs/devkit/frontendBuild/hmrWatcher.ts
|
|
12064
12588
|
import fs4 from "fs";
|
|
12065
|
-
import
|
|
12589
|
+
import path32 from "path";
|
|
12066
12590
|
class HmrWatcher {
|
|
12067
12591
|
#roots;
|
|
12068
12592
|
#debounceMs;
|
|
@@ -12075,7 +12599,7 @@ class HmrWatcher {
|
|
|
12075
12599
|
#stopped = false;
|
|
12076
12600
|
#flushing = false;
|
|
12077
12601
|
constructor(opts) {
|
|
12078
|
-
this.#roots = [...new Set(opts.roots.map((r) =>
|
|
12602
|
+
this.#roots = [...new Set(opts.roots.map((r) => path32.resolve(r)))];
|
|
12079
12603
|
this.#debounceMs = opts.debounceMs ?? 80;
|
|
12080
12604
|
this.#onBatch = opts.onBatch;
|
|
12081
12605
|
this.#logger = opts.logger;
|
|
@@ -12086,7 +12610,7 @@ class HmrWatcher {
|
|
|
12086
12610
|
const w = fs4.watch(root, { recursive: true, persistent: false }, (_event, filename) => {
|
|
12087
12611
|
if (!filename)
|
|
12088
12612
|
return;
|
|
12089
|
-
const abs =
|
|
12613
|
+
const abs = path32.resolve(root, filename.toString());
|
|
12090
12614
|
this.#queue(abs);
|
|
12091
12615
|
});
|
|
12092
12616
|
this.#watchers.push(w);
|
|
@@ -12144,10 +12668,10 @@ class HmrWatcher {
|
|
|
12144
12668
|
}
|
|
12145
12669
|
}
|
|
12146
12670
|
// pkgs/@akanjs/devkit/frontendBuild/pagesBundleBuilder.ts
|
|
12147
|
-
import
|
|
12671
|
+
import path34 from "path";
|
|
12148
12672
|
|
|
12149
12673
|
// pkgs/@akanjs/devkit/transforms/externalizeFrameworkPlugin.ts
|
|
12150
|
-
import
|
|
12674
|
+
import path33 from "path";
|
|
12151
12675
|
var DEFAULT_INCLUDE = ["akanjs/", "@apps/", "@libs/"];
|
|
12152
12676
|
var DEFAULT_EXCLUDE_EXACT = new Set(["akanjs/webkit", "@akanjs/cli", "@akanjs/devkit"]);
|
|
12153
12677
|
var DEFAULT_EXCLUDE_PREFIX = ["@akanjs/cli/", "@akanjs/devkit/"];
|
|
@@ -12190,7 +12714,7 @@ async function createExternalizeFrameworkPlugin(options) {
|
|
|
12190
12714
|
const replPath = repl?.endsWith("/*") ? repl.slice(0, -1) : repl ?? "";
|
|
12191
12715
|
if (!replPath)
|
|
12192
12716
|
continue;
|
|
12193
|
-
const candidate =
|
|
12717
|
+
const candidate = path33.resolve(workspaceRoot, replPath + suffix);
|
|
12194
12718
|
const hit = await firstExisting(candidate);
|
|
12195
12719
|
if (hit)
|
|
12196
12720
|
return hit;
|
|
@@ -12202,8 +12726,8 @@ async function createExternalizeFrameworkPlugin(options) {
|
|
|
12202
12726
|
if (spec === pkg)
|
|
12203
12727
|
continue;
|
|
12204
12728
|
const suffix = spec.slice(pkg.length + 1);
|
|
12205
|
-
const pkgDir =
|
|
12206
|
-
const candidate =
|
|
12729
|
+
const pkgDir = path33.dirname(path33.resolve(workspaceRoot, entryFile));
|
|
12730
|
+
const candidate = path33.join(pkgDir, suffix);
|
|
12207
12731
|
const hit = await firstExisting(candidate);
|
|
12208
12732
|
if (hit)
|
|
12209
12733
|
return hit;
|
|
@@ -12253,7 +12777,7 @@ async function firstExisting(basePath2) {
|
|
|
12253
12777
|
return candidate;
|
|
12254
12778
|
}
|
|
12255
12779
|
for (const ext of CANDIDATE_EXTS3) {
|
|
12256
|
-
const candidate =
|
|
12780
|
+
const candidate = path33.join(basePath2, `index${ext}`);
|
|
12257
12781
|
if (await Bun.file(candidate).exists())
|
|
12258
12782
|
return candidate;
|
|
12259
12783
|
}
|
|
@@ -12344,11 +12868,11 @@ class PagesBundleBuilder {
|
|
|
12344
12868
|
const entryArtifact = result.outputs.find((a) => a.kind === "entry-point");
|
|
12345
12869
|
if (!entryArtifact)
|
|
12346
12870
|
throw new Error("[PagesBundleBuilder] Bun.build emitted no entry-point artifact");
|
|
12347
|
-
const bundlePath =
|
|
12871
|
+
const bundlePath = path34.resolve(entryArtifact.path);
|
|
12348
12872
|
const buildId = Date.now();
|
|
12349
12873
|
const outputBytes = result.outputs.reduce((sum, output) => sum + output.size, 0);
|
|
12350
12874
|
const chunkCount = result.outputs.filter((output) => output.kind === "chunk").length;
|
|
12351
|
-
this.#app.verbose(`[PagesBundleBuilder] ${
|
|
12875
|
+
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`);
|
|
12352
12876
|
return {
|
|
12353
12877
|
bundlePath,
|
|
12354
12878
|
buildId,
|
|
@@ -12430,11 +12954,11 @@ function loaderFor4(absPath) {
|
|
|
12430
12954
|
}
|
|
12431
12955
|
// pkgs/@akanjs/devkit/frontendBuild/precompressArtifacts.ts
|
|
12432
12956
|
import fs5 from "fs";
|
|
12433
|
-
import
|
|
12957
|
+
import path35 from "path";
|
|
12434
12958
|
var COMPRESSIBLE_EXTS = new Set([".css", ".html", ".js", ".json", ".svg"]);
|
|
12435
12959
|
var MIN_COMPRESS_BYTES = 1024;
|
|
12436
12960
|
async function precompressArtifacts(app) {
|
|
12437
|
-
const roots = [
|
|
12961
|
+
const roots = [path35.join(app.dist.cwdPath, ".akan/artifact/client")];
|
|
12438
12962
|
const result = { files: 0, inputBytes: 0, outputBytes: 0 };
|
|
12439
12963
|
await Promise.all(roots.map((root) => precompressRoot(root, result)));
|
|
12440
12964
|
if (result.files > 0) {
|
|
@@ -12460,7 +12984,7 @@ async function precompressRoot(root, result) {
|
|
|
12460
12984
|
async function shouldPrecompress(filePath) {
|
|
12461
12985
|
if (filePath.endsWith(".gz"))
|
|
12462
12986
|
return false;
|
|
12463
|
-
if (!COMPRESSIBLE_EXTS.has(
|
|
12987
|
+
if (!COMPRESSIBLE_EXTS.has(path35.extname(filePath).toLowerCase()))
|
|
12464
12988
|
return false;
|
|
12465
12989
|
const file = Bun.file(filePath);
|
|
12466
12990
|
if (!await file.exists())
|
|
@@ -12478,7 +13002,7 @@ function formatBytes(bytes) {
|
|
|
12478
13002
|
return `${(bytes / 1024 / 1024).toFixed(1)}MB`;
|
|
12479
13003
|
}
|
|
12480
13004
|
// pkgs/@akanjs/devkit/frontendBuild/ssrBaseArtifactBuilder.ts
|
|
12481
|
-
import
|
|
13005
|
+
import path36 from "path";
|
|
12482
13006
|
import { optimize } from "@tailwindcss/node";
|
|
12483
13007
|
function prepareCssAsset(command, basePath2, cssText) {
|
|
12484
13008
|
return optimize(cssText, { file: `${basePath2 || "root"}.css`, minify: command === "build" }).code;
|
|
@@ -12494,7 +13018,7 @@ class SsrBaseArtifactBuilder {
|
|
|
12494
13018
|
this.#app = app;
|
|
12495
13019
|
this.#command = command;
|
|
12496
13020
|
this.#artifactDir = `${command === "build" ? app.dist.cwdPath : app.cwdPath}/.akan/artifact`;
|
|
12497
|
-
this.#absArtifactDir =
|
|
13021
|
+
this.#absArtifactDir = path36.resolve(this.#artifactDir);
|
|
12498
13022
|
}
|
|
12499
13023
|
async build() {
|
|
12500
13024
|
const akanConfig2 = await this.#app.getConfig();
|
|
@@ -12516,7 +13040,7 @@ class SsrBaseArtifactBuilder {
|
|
|
12516
13040
|
rscRuntimeSsrManifest,
|
|
12517
13041
|
vendorMap,
|
|
12518
13042
|
cssAssets,
|
|
12519
|
-
pagesBundlePath: this.#command === "build" ?
|
|
13043
|
+
pagesBundlePath: this.#command === "build" ? path36.relative(this.#absArtifactDir, pagesBundle.bundlePath) : pagesBundle.bundlePath,
|
|
12520
13044
|
pagesBundleBuildId: pagesBundle.buildId,
|
|
12521
13045
|
domains: [...akanConfig2.domains],
|
|
12522
13046
|
subRoutes: Object.fromEntries(Array.from(akanConfig2.subRoutes.entries()).map(([basePath2, domains]) => [basePath2, [...domains]])),
|
|
@@ -12532,18 +13056,18 @@ class SsrBaseArtifactBuilder {
|
|
|
12532
13056
|
androidSha256CertFingerprints: target.deepLinks?.android?.sha256CertFingerprints
|
|
12533
13057
|
}))
|
|
12534
13058
|
};
|
|
12535
|
-
await Bun.write(
|
|
13059
|
+
await Bun.write(path36.join(this.#absArtifactDir, "base-artifact.json"), `${JSON.stringify(artifact, null, 2)}
|
|
12536
13060
|
`);
|
|
12537
13061
|
this.#app.verbose(`[base-artifact] complete in ${Date.now() - this.#started}ms`);
|
|
12538
13062
|
return { artifact, seedIndex, cssCompiler, optimizedFonts };
|
|
12539
13063
|
}
|
|
12540
13064
|
async#buildRuntimeClientEntries() {
|
|
12541
13065
|
const akanServerPath = await this.#resolveAkanServerPath();
|
|
12542
|
-
const rscClientEntry =
|
|
12543
|
-
const rscSegmentOutletEntry =
|
|
13066
|
+
const rscClientEntry = path36.resolve(akanServerPath, "rscClient.tsx");
|
|
13067
|
+
const rscSegmentOutletEntry = path36.resolve(akanServerPath, "rscSegmentOutlet.tsx");
|
|
12544
13068
|
const vendorEntries = VENDOR_SPECIFIERS.map((specifier) => ({
|
|
12545
13069
|
specifier,
|
|
12546
|
-
absPath:
|
|
13070
|
+
absPath: path36.resolve(akanServerPath, "vendor", `${specifier.replaceAll("/", "-").replaceAll(".", "-")}.ts`)
|
|
12547
13071
|
}));
|
|
12548
13072
|
const entries = [rscClientEntry, rscSegmentOutletEntry, ...vendorEntries.map((v) => v.absPath)];
|
|
12549
13073
|
const clientBundle = await new ClientEntriesBundler({ app: this.#app, entries, command: this.#command }).bundle();
|
|
@@ -12580,15 +13104,15 @@ class SsrBaseArtifactBuilder {
|
|
|
12580
13104
|
async#resolveAkanServerPath() {
|
|
12581
13105
|
const candidates = [];
|
|
12582
13106
|
try {
|
|
12583
|
-
candidates.push(
|
|
13107
|
+
candidates.push(path36.dirname(Bun.resolveSync("akanjs/server", this.#app.workspace.workspaceRoot)));
|
|
12584
13108
|
} catch {}
|
|
12585
|
-
candidates.push(
|
|
13109
|
+
candidates.push(path36.join(this.#app.workspace.workspaceRoot, "pkgs/akanjs/server"), path36.join(this.#app.workspace.workspaceRoot, "node_modules/akanjs/server"));
|
|
12586
13110
|
try {
|
|
12587
|
-
candidates.push(
|
|
13111
|
+
candidates.push(path36.dirname(Bun.resolveSync("akanjs/server", path36.dirname(Bun.main))));
|
|
12588
13112
|
} catch {}
|
|
12589
|
-
candidates.push(
|
|
13113
|
+
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"));
|
|
12590
13114
|
for (const candidate of candidates) {
|
|
12591
|
-
if (await Bun.file(
|
|
13115
|
+
if (await Bun.file(path36.join(candidate, "rscClient.tsx")).exists())
|
|
12592
13116
|
return candidate;
|
|
12593
13117
|
}
|
|
12594
13118
|
throw new Error(`[base-artifact] failed to locate akanjs/server; looked in: ${candidates.join(", ")}`);
|
|
@@ -12617,14 +13141,14 @@ ${preparedCssText}`).toString(36);
|
|
|
12617
13141
|
`styles/${cssAssetName}-${cssHash}.css`,
|
|
12618
13142
|
`/_akan/styles/${cssAssetName}-${cssHash}.css`
|
|
12619
13143
|
];
|
|
12620
|
-
await Bun.write(
|
|
13144
|
+
await Bun.write(path36.join(this.#absArtifactDir, cssRelPath), preparedCssText);
|
|
12621
13145
|
this.#app.verbose(`[base-artifact] wrote ${preparedCssText.length} bytes of CSS for ${basePath2} -> ${cssRelPath}`);
|
|
12622
13146
|
return [basePath2, { cssUrl, cssRelPath }];
|
|
12623
13147
|
}
|
|
12624
13148
|
}
|
|
12625
13149
|
// pkgs/@akanjs/devkit/frontendBuild/watchRootResolver.ts
|
|
12626
13150
|
import fs6 from "fs";
|
|
12627
|
-
import
|
|
13151
|
+
import path37 from "path";
|
|
12628
13152
|
|
|
12629
13153
|
class WatchRootResolver {
|
|
12630
13154
|
#app;
|
|
@@ -12634,15 +13158,15 @@ class WatchRootResolver {
|
|
|
12634
13158
|
async resolve() {
|
|
12635
13159
|
const tsconfig = await this.#app.getTsConfig();
|
|
12636
13160
|
const set = new Set;
|
|
12637
|
-
set.add(
|
|
13161
|
+
set.add(path37.resolve(`${this.#app.cwdPath}/page`));
|
|
12638
13162
|
for (const targets of Object.values(tsconfig.compilerOptions.paths ?? {})) {
|
|
12639
13163
|
for (const target of targets) {
|
|
12640
13164
|
if (!target)
|
|
12641
13165
|
continue;
|
|
12642
|
-
if (
|
|
13166
|
+
if (path37.isAbsolute(target))
|
|
12643
13167
|
continue;
|
|
12644
13168
|
const cleaned = target.replace(/\/?\*+.*$/, "").replace(/\/[^/]+\.[^/]+$/, "");
|
|
12645
|
-
const resolved =
|
|
13169
|
+
const resolved = path37.resolve(this.#app.workspace.workspaceRoot, cleaned);
|
|
12646
13170
|
if (fs6.existsSync(resolved))
|
|
12647
13171
|
set.add(resolved);
|
|
12648
13172
|
}
|
|
@@ -12709,7 +13233,7 @@ class ApplicationBuildRunner {
|
|
|
12709
13233
|
phases: this.#phases,
|
|
12710
13234
|
durationMs: Date.now() - this.#startedAt,
|
|
12711
13235
|
outputDir: this.#app.dist.cwdPath,
|
|
12712
|
-
artifactDir:
|
|
13236
|
+
artifactDir: path38.join(this.#app.dist.cwdPath, ".akan/artifact")
|
|
12713
13237
|
};
|
|
12714
13238
|
}
|
|
12715
13239
|
async typecheck(options = {}) {
|
|
@@ -12717,7 +13241,7 @@ class ApplicationBuildRunner {
|
|
|
12717
13241
|
await this.#app.getPageKeys({ refresh: true });
|
|
12718
13242
|
const { typecheckDir, tsconfigPath } = await this.#writeTypecheckTsconfig({ incremental });
|
|
12719
13243
|
if (clean)
|
|
12720
|
-
await rm4(
|
|
13244
|
+
await rm4(path38.join(typecheckDir, "tsconfig.tsbuildinfo"), { force: true });
|
|
12721
13245
|
await this.#checkProjectInChildProcess(tsconfigPath);
|
|
12722
13246
|
}
|
|
12723
13247
|
async#runPhase(id, label, task, summarize, options = {}) {
|
|
@@ -12789,7 +13313,7 @@ class ApplicationBuildRunner {
|
|
|
12789
13313
|
};
|
|
12790
13314
|
}
|
|
12791
13315
|
async#writeConsoleShim() {
|
|
12792
|
-
await Bun.write(
|
|
13316
|
+
await Bun.write(path38.join(this.#app.dist.cwdPath, "console.js"), `import { cnst, db, dict, option, server, sig, srv } from "./server.js";
|
|
12793
13317
|
import { assertAkanConsoleAllowed, startAkanConsole } from "./console-runtime.js";
|
|
12794
13318
|
|
|
12795
13319
|
const run = async () => {
|
|
@@ -12812,14 +13336,14 @@ void run().catch((error) => {
|
|
|
12812
13336
|
try {
|
|
12813
13337
|
return Bun.resolveSync("akanjs/server/rsc-worker", import.meta.dir);
|
|
12814
13338
|
} catch {
|
|
12815
|
-
return
|
|
13339
|
+
return path38.join(this.#app.workspace.workspaceRoot, "pkgs/akanjs/server/rscWorker.tsx");
|
|
12816
13340
|
}
|
|
12817
13341
|
}
|
|
12818
13342
|
#resolveConsoleRuntimeBuildEntry() {
|
|
12819
13343
|
try {
|
|
12820
|
-
return
|
|
13344
|
+
return path38.join(path38.dirname(Bun.resolveSync("akanjs/server", import.meta.dir)), "console.ts");
|
|
12821
13345
|
} catch {
|
|
12822
|
-
return
|
|
13346
|
+
return path38.join(this.#app.workspace.workspaceRoot, "pkgs/akanjs/server/console.ts");
|
|
12823
13347
|
}
|
|
12824
13348
|
}
|
|
12825
13349
|
async#buildCsr() {
|
|
@@ -12836,7 +13360,7 @@ void run().catch((error) => {
|
|
|
12836
13360
|
return { base, allRoutes };
|
|
12837
13361
|
}
|
|
12838
13362
|
async#writeTypecheckTsconfig({ incremental = true } = {}) {
|
|
12839
|
-
const typecheckDir =
|
|
13363
|
+
const typecheckDir = path38.join(this.#app.cwdPath, ".akan", "typecheck");
|
|
12840
13364
|
await mkdir8(typecheckDir, { recursive: true });
|
|
12841
13365
|
const tsconfig = {
|
|
12842
13366
|
extends: "../../tsconfig.json",
|
|
@@ -12855,7 +13379,7 @@ void run().catch((error) => {
|
|
|
12855
13379
|
],
|
|
12856
13380
|
references: []
|
|
12857
13381
|
};
|
|
12858
|
-
const tsconfigPath =
|
|
13382
|
+
const tsconfigPath = path38.join(typecheckDir, "tsconfig.json");
|
|
12859
13383
|
await Bun.write(tsconfigPath, `${JSON.stringify(tsconfig, null, 2)}
|
|
12860
13384
|
`);
|
|
12861
13385
|
return { typecheckDir, tsconfigPath };
|
|
@@ -12881,10 +13405,10 @@ void run().catch((error) => {
|
|
|
12881
13405
|
}
|
|
12882
13406
|
async#resolveTypecheckWorkerEntry() {
|
|
12883
13407
|
const candidates = [
|
|
12884
|
-
|
|
12885
|
-
|
|
12886
|
-
|
|
12887
|
-
|
|
13408
|
+
path38.join(this.#app.workspace.workspaceRoot, "pkgs/@akanjs/devkit/typecheck/typecheck.proc.ts"),
|
|
13409
|
+
path38.join(this.#app.workspace.workspaceRoot, "node_modules/@akanjs/devkit/typecheck/typecheck.proc.ts"),
|
|
13410
|
+
path38.join(import.meta.dir, "typecheck.proc.js"),
|
|
13411
|
+
path38.join(import.meta.dir, "typecheck.proc.ts")
|
|
12888
13412
|
];
|
|
12889
13413
|
for (const candidate of candidates)
|
|
12890
13414
|
if (await Bun.file(candidate).exists())
|
|
@@ -12918,7 +13442,7 @@ void run().catch((error) => {
|
|
|
12918
13442
|
}
|
|
12919
13443
|
// pkgs/@akanjs/devkit/applicationReleasePackager.ts
|
|
12920
13444
|
import { cp, mkdir as mkdir9, rm as rm5 } from "fs/promises";
|
|
12921
|
-
import
|
|
13445
|
+
import path39 from "path";
|
|
12922
13446
|
|
|
12923
13447
|
// pkgs/@akanjs/devkit/uploadRelease.ts
|
|
12924
13448
|
import { HttpClient as HttpClient2, Logger as Logger9 } from "akanjs/common";
|
|
@@ -13035,7 +13559,7 @@ class ApplicationReleasePackager {
|
|
|
13035
13559
|
await cp(this.#app.dist.cwdPath, buildRoot, { recursive: true });
|
|
13036
13560
|
await rm5(`${buildRoot}/frontend/.next`, { recursive: true, force: true });
|
|
13037
13561
|
const releaseRoot = this.#app.workspace.workspaceRoot;
|
|
13038
|
-
const releaseArchivePath =
|
|
13562
|
+
const releaseArchivePath = path39.relative(releaseRoot, `${releaseRoot}/releases/builds/${this.#app.name}-release.tar.gz`).split(path39.sep).join("/");
|
|
13039
13563
|
await this.#app.workspace.spawn("tar", ["-zcf", releaseArchivePath, "-C", buildRoot, "./"], { cwd: releaseRoot });
|
|
13040
13564
|
await this.#writeCsrZipIfPresent();
|
|
13041
13565
|
return { platformVersion };
|
|
@@ -13057,17 +13581,17 @@ class ApplicationReleasePackager {
|
|
|
13057
13581
|
await cp(this.#app.dist.cwdPath, `${sourceRoot}/apps/${this.#app.name}`, { recursive: true });
|
|
13058
13582
|
const libDeps = ["social", "shared", "platform", "util"];
|
|
13059
13583
|
await Promise.all(libDeps.map((lib) => cp(`${this.#app.workspace.cwdPath}/libs/${lib}`, `${sourceRoot}/libs/${lib}`, { recursive: true })));
|
|
13060
|
-
await Promise.all([".next", "ios", "android", "public/libs"].map(async (
|
|
13061
|
-
const targetPath = `${sourceRoot}/apps/${this.#app.name}/${
|
|
13584
|
+
await Promise.all([".next", "ios", "android", "public/libs"].map(async (path40) => {
|
|
13585
|
+
const targetPath = `${sourceRoot}/apps/${this.#app.name}/${path40}`;
|
|
13062
13586
|
if (await FileSys.dirExists(targetPath))
|
|
13063
13587
|
await rm5(targetPath, { recursive: true, force: true });
|
|
13064
13588
|
}));
|
|
13065
13589
|
const syncPaths = [".husky", ".gitignore", "package.json"];
|
|
13066
|
-
await Promise.all(syncPaths.map((
|
|
13590
|
+
await Promise.all(syncPaths.map((path40) => cp(`${this.#app.workspace.cwdPath}/${path40}`, `${sourceRoot}/${path40}`, { recursive: true })));
|
|
13067
13591
|
await this.#writeSourceTsconfig(sourceRoot, libDeps);
|
|
13068
13592
|
await Bun.write(`${sourceRoot}/README.md`, readme);
|
|
13069
13593
|
const sourceCwd = this.#app.workspace.cwdPath;
|
|
13070
|
-
const sourceArchivePath =
|
|
13594
|
+
const sourceArchivePath = path39.relative(sourceCwd, `${sourceCwd}/releases/sources/${this.#app.name}-source.tar.gz`).split(path39.sep).join("/");
|
|
13071
13595
|
await this.#app.workspace.spawn("tar", ["-zcf", sourceArchivePath, "-C", sourceRoot, "./"], { cwd: sourceCwd });
|
|
13072
13596
|
}
|
|
13073
13597
|
async#resetSourceRoot(sourceRoot) {
|
|
@@ -13150,20 +13674,20 @@ class ApplicationReleasePackager {
|
|
|
13150
13674
|
}
|
|
13151
13675
|
}
|
|
13152
13676
|
// pkgs/@akanjs/devkit/applicationTestPreload.ts
|
|
13153
|
-
import
|
|
13677
|
+
import path40 from "path";
|
|
13154
13678
|
var SIGNAL_TEST_PRELOAD_PATH = "test/signalTest.preload.ts";
|
|
13155
13679
|
async function resolveSignalTestPreloadPath(target) {
|
|
13156
13680
|
const candidates = [];
|
|
13157
13681
|
const addResolvedPackageCandidate = (basePath2) => {
|
|
13158
13682
|
try {
|
|
13159
|
-
candidates.push(
|
|
13683
|
+
candidates.push(path40.join(path40.dirname(Bun.resolveSync("akanjs/package.json", basePath2)), SIGNAL_TEST_PRELOAD_PATH));
|
|
13160
13684
|
} catch {}
|
|
13161
13685
|
};
|
|
13162
13686
|
addResolvedPackageCandidate(target.cwdPath);
|
|
13163
13687
|
addResolvedPackageCandidate(process.cwd());
|
|
13164
|
-
addResolvedPackageCandidate(
|
|
13688
|
+
addResolvedPackageCandidate(path40.dirname(Bun.main));
|
|
13165
13689
|
addResolvedPackageCandidate(import.meta.dir);
|
|
13166
|
-
candidates.push(
|
|
13690
|
+
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));
|
|
13167
13691
|
const uniqueCandidates = [...new Set(candidates)];
|
|
13168
13692
|
for (const candidate of uniqueCandidates) {
|
|
13169
13693
|
if (await Bun.file(candidate).exists())
|
|
@@ -13177,7 +13701,7 @@ ${uniqueCandidates.map((candidate) => ` - ${candidate}`).join(`
|
|
|
13177
13701
|
// pkgs/@akanjs/devkit/builder.ts
|
|
13178
13702
|
import { existsSync as existsSync2 } from "fs";
|
|
13179
13703
|
import { mkdir as mkdir10 } from "fs/promises";
|
|
13180
|
-
import
|
|
13704
|
+
import path41 from "path";
|
|
13181
13705
|
var SKIP_ENTRY_DIR_SET = new Set(["node_modules", "dist", "build", ".git", ".next"]);
|
|
13182
13706
|
var assetExtensions = [".css", ".md", ".js", ".png", ".ico", ".svg", ".json", ".template"];
|
|
13183
13707
|
var assetLoader = Object.fromEntries(assetExtensions.map((ext) => [ext, "file"]));
|
|
@@ -13194,14 +13718,14 @@ class Builder {
|
|
|
13194
13718
|
#globEntrypoints(cwd, pattern) {
|
|
13195
13719
|
const glob = new Bun.Glob(pattern);
|
|
13196
13720
|
return Array.from(glob.scanSync({ cwd, onlyFiles: true })).filter((relativePath) => {
|
|
13197
|
-
const segments = relativePath.split(
|
|
13721
|
+
const segments = relativePath.split(path41.sep);
|
|
13198
13722
|
return !segments.some((segment) => SKIP_ENTRY_DIR_SET.has(segment));
|
|
13199
|
-
}).map((rel) =>
|
|
13723
|
+
}).map((rel) => path41.join(cwd, rel));
|
|
13200
13724
|
}
|
|
13201
13725
|
#globFiles(cwd, pattern = "**/*.*") {
|
|
13202
13726
|
const glob = new Bun.Glob(pattern);
|
|
13203
13727
|
return Array.from(glob.scanSync({ cwd, onlyFiles: true })).filter((relativePath) => {
|
|
13204
|
-
const segments = relativePath.split(
|
|
13728
|
+
const segments = relativePath.split(path41.sep);
|
|
13205
13729
|
return !segments.some((segment) => SKIP_ENTRY_DIR_SET.has(segment));
|
|
13206
13730
|
});
|
|
13207
13731
|
}
|
|
@@ -13209,17 +13733,17 @@ class Builder {
|
|
|
13209
13733
|
const out = [];
|
|
13210
13734
|
for (const p of additionalEntryPoints) {
|
|
13211
13735
|
if (p.includes("*")) {
|
|
13212
|
-
const rel = p.startsWith(`${cwd}/`) || p.startsWith(`${cwd}${
|
|
13736
|
+
const rel = p.startsWith(`${cwd}/`) || p.startsWith(`${cwd}${path41.sep}`) ? p.slice(cwd.length + 1) : p;
|
|
13213
13737
|
out.push(...this.#globEntrypoints(cwd, rel));
|
|
13214
13738
|
} else
|
|
13215
|
-
out.push(
|
|
13739
|
+
out.push(path41.isAbsolute(p) ? p : path41.join(cwd, p));
|
|
13216
13740
|
}
|
|
13217
13741
|
return out;
|
|
13218
13742
|
}
|
|
13219
13743
|
#getBuildOptions({ bundle = false, additionalEntryPoints = [] } = {}) {
|
|
13220
13744
|
const cwd = this.#executor.cwdPath;
|
|
13221
13745
|
const entrypoints = [
|
|
13222
|
-
...bundle ? [
|
|
13746
|
+
...bundle ? [path41.join(cwd, "index.ts")] : this.#globEntrypoints(cwd, "**/*.{ts,tsx}"),
|
|
13223
13747
|
...this.#resolveAdditionalEntrypoints(cwd, additionalEntryPoints)
|
|
13224
13748
|
];
|
|
13225
13749
|
return {
|
|
@@ -13240,9 +13764,9 @@ class Builder {
|
|
|
13240
13764
|
for (const relativePath of this.#globFiles(cwd)) {
|
|
13241
13765
|
if (relativePath === "package.json")
|
|
13242
13766
|
continue;
|
|
13243
|
-
const sourcePath =
|
|
13244
|
-
const targetPath =
|
|
13245
|
-
await mkdir10(
|
|
13767
|
+
const sourcePath = path41.join(cwd, relativePath);
|
|
13768
|
+
const targetPath = path41.join(this.#distExecutor.cwdPath, relativePath);
|
|
13769
|
+
await mkdir10(path41.dirname(targetPath), { recursive: true });
|
|
13246
13770
|
await Bun.write(targetPath, Bun.file(sourcePath));
|
|
13247
13771
|
}
|
|
13248
13772
|
}
|
|
@@ -13253,13 +13777,13 @@ class Builder {
|
|
|
13253
13777
|
return withoutFormatDir;
|
|
13254
13778
|
if (!hasDotSlash && withoutFormatDir === publishedPath)
|
|
13255
13779
|
return publishedPath;
|
|
13256
|
-
const parsed =
|
|
13780
|
+
const parsed = path41.posix.parse(withoutFormatDir);
|
|
13257
13781
|
if (![".js", ".mjs", ".cjs"].includes(parsed.ext))
|
|
13258
13782
|
return withoutFormatDir;
|
|
13259
|
-
const withoutExt =
|
|
13783
|
+
const withoutExt = path41.posix.join(parsed.dir, parsed.name);
|
|
13260
13784
|
const sourcePath = withoutExt.startsWith("./") ? withoutExt.slice(2) : withoutExt;
|
|
13261
13785
|
const sourceCandidates = [`${sourcePath}.ts`, `${sourcePath}.tsx`];
|
|
13262
|
-
const matchedSource = sourceCandidates.find((candidate) => existsSync2(
|
|
13786
|
+
const matchedSource = sourceCandidates.find((candidate) => existsSync2(path41.join(this.#executor.cwdPath, candidate)));
|
|
13263
13787
|
if (!matchedSource)
|
|
13264
13788
|
return withoutFormatDir;
|
|
13265
13789
|
return hasDotSlash ? `./${matchedSource}` : matchedSource;
|
|
@@ -13308,9 +13832,9 @@ class Builder {
|
|
|
13308
13832
|
}
|
|
13309
13833
|
}
|
|
13310
13834
|
// pkgs/@akanjs/devkit/capacitorApp.ts
|
|
13311
|
-
import { cp as cp2, mkdir as mkdir11, readFile as
|
|
13835
|
+
import { cp as cp2, mkdir as mkdir11, readFile as readFile3, rm as rm6, writeFile as writeFile3 } from "fs/promises";
|
|
13312
13836
|
import os from "os";
|
|
13313
|
-
import
|
|
13837
|
+
import path42 from "path";
|
|
13314
13838
|
import { select as select2 } from "@inquirer/prompts";
|
|
13315
13839
|
import { MobileProject } from "@trapezedev/project";
|
|
13316
13840
|
import { capitalize as capitalize5 } from "akanjs/common";
|
|
@@ -13517,13 +14041,13 @@ var rootCapacitorConfigFilenames = [
|
|
|
13517
14041
|
"capacitor.config.js",
|
|
13518
14042
|
"capacitor.config.json"
|
|
13519
14043
|
];
|
|
13520
|
-
var rootCapacitorConfigPaths = (appRoot) => rootCapacitorConfigFilenames.map((file) =>
|
|
14044
|
+
var rootCapacitorConfigPaths = (appRoot) => rootCapacitorConfigFilenames.map((file) => path42.join(appRoot, file));
|
|
13521
14045
|
async function clearRootCapacitorConfigs(appRoot) {
|
|
13522
14046
|
await Promise.all(rootCapacitorConfigPaths(appRoot).map((file) => rm6(file, { force: true })));
|
|
13523
14047
|
}
|
|
13524
14048
|
async function writeRootCapacitorConfig(appRoot, content) {
|
|
13525
14049
|
await clearRootCapacitorConfigs(appRoot);
|
|
13526
|
-
await Bun.write(
|
|
14050
|
+
await Bun.write(path42.join(appRoot, "capacitor.config.json"), content);
|
|
13527
14051
|
}
|
|
13528
14052
|
var getLocalIP = () => {
|
|
13529
14053
|
const interfaces = os.networkInterfaces();
|
|
@@ -13632,13 +14156,13 @@ function buildIosNativeRunCommand({
|
|
|
13632
14156
|
scheme = "App",
|
|
13633
14157
|
configuration = "Debug"
|
|
13634
14158
|
}) {
|
|
13635
|
-
const derivedDataPath =
|
|
14159
|
+
const derivedDataPath = path42.join(appRoot, "ios/DerivedData", device.id);
|
|
13636
14160
|
const productPlatform = device.kind === "device" ? "iphoneos" : "iphonesimulator";
|
|
13637
14161
|
const destination = device.kind === "device" ? `id=${device.xcodebuildId ?? device.id}` : `platform=iOS Simulator,id=${device.id}`;
|
|
13638
14162
|
return {
|
|
13639
14163
|
configuration,
|
|
13640
14164
|
derivedDataPath,
|
|
13641
|
-
appPath:
|
|
14165
|
+
appPath: path42.join(derivedDataPath, "Build/Products", `${configuration}-${productPlatform}`, "App.app"),
|
|
13642
14166
|
xcodebuildArgs: [
|
|
13643
14167
|
"-project",
|
|
13644
14168
|
"App.xcodeproj",
|
|
@@ -13851,7 +14375,7 @@ function materializeCapacitorConfig(target, { operation, localServerUrl, localIp
|
|
|
13851
14375
|
...capacitorConfig,
|
|
13852
14376
|
appId,
|
|
13853
14377
|
appName,
|
|
13854
|
-
webDir:
|
|
14378
|
+
webDir: path42.posix.join(".akan", "mobile", name, "www"),
|
|
13855
14379
|
plugins: {
|
|
13856
14380
|
CapacitorCookies: { enabled: true },
|
|
13857
14381
|
...pluginsConfig,
|
|
@@ -13915,10 +14439,10 @@ class CapacitorApp {
|
|
|
13915
14439
|
constructor(app, target) {
|
|
13916
14440
|
this.app = app;
|
|
13917
14441
|
this.target = target;
|
|
13918
|
-
this.targetRootPath =
|
|
13919
|
-
this.targetRoot =
|
|
13920
|
-
this.targetWebRoot =
|
|
13921
|
-
this.targetAssetRoot =
|
|
14442
|
+
this.targetRootPath = path42.posix.join(".akan", "mobile", this.target.name);
|
|
14443
|
+
this.targetRoot = path42.join(this.app.cwdPath, this.targetRootPath);
|
|
14444
|
+
this.targetWebRoot = path42.join(this.targetRoot, "www");
|
|
14445
|
+
this.targetAssetRoot = path42.join(this.targetRoot, "assets");
|
|
13922
14446
|
this.project = new MobileProject(this.app.cwdPath, {
|
|
13923
14447
|
android: { path: this.androidRootPath },
|
|
13924
14448
|
ios: { path: this.iosProjectPath }
|
|
@@ -13933,9 +14457,9 @@ class CapacitorApp {
|
|
|
13933
14457
|
await mkdir11(this.targetRoot, { recursive: true });
|
|
13934
14458
|
if (regenerate) {
|
|
13935
14459
|
if (!platform || platform === "ios")
|
|
13936
|
-
await rm6(
|
|
14460
|
+
await rm6(path42.join(this.app.cwdPath, this.iosRootPath), { recursive: true, force: true });
|
|
13937
14461
|
if (!platform || platform === "android")
|
|
13938
|
-
await rm6(
|
|
14462
|
+
await rm6(path42.join(this.app.cwdPath, this.androidRootPath), { recursive: true, force: true });
|
|
13939
14463
|
}
|
|
13940
14464
|
const project = this.project;
|
|
13941
14465
|
await this.project.load();
|
|
@@ -14059,7 +14583,7 @@ ${textError instanceof Error ? textError.message : ""}`);
|
|
|
14059
14583
|
const xcodebuildArgs = noAllowProvisioningUpdates ? command.xcodebuildArgs : [...command.xcodebuildArgs.slice(0, -1), "-allowProvisioningUpdates", ...command.xcodebuildArgs.slice(-1)];
|
|
14060
14584
|
try {
|
|
14061
14585
|
await this.#spawn("xcodebuild", xcodebuildArgs, {
|
|
14062
|
-
cwd:
|
|
14586
|
+
cwd: path42.join(this.app.cwdPath, this.iosProjectPath),
|
|
14063
14587
|
env: mobileEnv
|
|
14064
14588
|
});
|
|
14065
14589
|
const devicectlId = runTarget.devicectlId ?? runTarget.id;
|
|
@@ -14084,7 +14608,7 @@ ${textError instanceof Error ? textError.message : ""}`);
|
|
|
14084
14608
|
return isRecord2(this.target.ios) && typeof this.target.ios.scheme === "string" ? this.target.ios.scheme : "App";
|
|
14085
14609
|
}
|
|
14086
14610
|
async#getIosDevelopmentTeam() {
|
|
14087
|
-
const pbxprojPath =
|
|
14611
|
+
const pbxprojPath = path42.join(this.app.cwdPath, this.iosProjectPath, "App.xcodeproj/project.pbxproj");
|
|
14088
14612
|
if (!await Bun.file(pbxprojPath).exists())
|
|
14089
14613
|
return;
|
|
14090
14614
|
return (await Bun.file(pbxprojPath).text()).match(/DEVELOPMENT_TEAM = ([^;]+);/)?.[1]?.trim();
|
|
@@ -14111,7 +14635,7 @@ ${error.message}`;
|
|
|
14111
14635
|
await this.#setDeepLinksInAndroid(this.target.deepLinks?.schemes ?? [], this.target.deepLinks?.domains ?? []);
|
|
14112
14636
|
}
|
|
14113
14637
|
async#updateAndroidBuildTypes() {
|
|
14114
|
-
const appGradle = await FileEditor.create(
|
|
14638
|
+
const appGradle = await FileEditor.create(path42.join(this.app.cwdPath, this.androidRootPath, "app/build.gradle"));
|
|
14115
14639
|
const buildTypesBlock = `
|
|
14116
14640
|
debug {
|
|
14117
14641
|
applicationIdSuffix ".debug"
|
|
@@ -14155,7 +14679,7 @@ ${error.message}`;
|
|
|
14155
14679
|
const gradleCommand = isWindows ? "gradlew.bat" : "./gradlew";
|
|
14156
14680
|
await this.app.spawn(gradleCommand, [assembleType === "apk" ? "assembleRelease" : "bundleRelease"], {
|
|
14157
14681
|
stdio: "inherit",
|
|
14158
|
-
cwd:
|
|
14682
|
+
cwd: path42.join(this.app.cwdPath, this.androidRootPath),
|
|
14159
14683
|
env: await this.#commandEnv("release", env)
|
|
14160
14684
|
});
|
|
14161
14685
|
}
|
|
@@ -14163,10 +14687,10 @@ ${error.message}`;
|
|
|
14163
14687
|
await this.#spawnMobile("npx", ["cap", "open", "android"], { operation: "local", env: "local" });
|
|
14164
14688
|
}
|
|
14165
14689
|
async#ensureAndroidAssetsDir() {
|
|
14166
|
-
await mkdir11(
|
|
14690
|
+
await mkdir11(path42.join(this.app.cwdPath, this.androidAssetsPath), { recursive: true });
|
|
14167
14691
|
}
|
|
14168
14692
|
async#ensureAndroidDebugKeystore() {
|
|
14169
|
-
const keystorePath =
|
|
14693
|
+
const keystorePath = path42.join(this.app.cwdPath, this.androidRootPath, "app/debug.keystore");
|
|
14170
14694
|
if (await Bun.file(keystorePath).exists())
|
|
14171
14695
|
return;
|
|
14172
14696
|
await this.#spawn("keytool", [
|
|
@@ -14205,7 +14729,7 @@ ${error.message}`;
|
|
|
14205
14729
|
await this.#spawnMobile("npx", args, { operation, env }, { stdio: "inherit" });
|
|
14206
14730
|
}
|
|
14207
14731
|
async#assertAndroidReleaseSigningConfig() {
|
|
14208
|
-
const gradlePropertiesPath =
|
|
14732
|
+
const gradlePropertiesPath = path42.join(this.app.cwdPath, this.androidRootPath, "gradle.properties");
|
|
14209
14733
|
const gradleProperties = await Bun.file(gradlePropertiesPath).exists() ? await Bun.file(gradlePropertiesPath).text() : "";
|
|
14210
14734
|
const missingKeys = getMissingAndroidReleaseSigningKeys({ gradleProperties });
|
|
14211
14735
|
if (missingKeys.length > 0)
|
|
@@ -14232,12 +14756,12 @@ ${error.message}`;
|
|
|
14232
14756
|
await this.#prepareAndroid({ operation: "release", env: "main" });
|
|
14233
14757
|
}
|
|
14234
14758
|
async prepareWww() {
|
|
14235
|
-
const htmlSource =
|
|
14759
|
+
const htmlSource = path42.join(this.app.dist.cwdPath, "csr", targetHtmlFilename(this.target));
|
|
14236
14760
|
if (!await Bun.file(htmlSource).exists())
|
|
14237
14761
|
throw new Error(`CSR html for mobile target '${this.target.name}' not found: ${htmlSource}`);
|
|
14238
14762
|
await rm6(this.targetWebRoot, { recursive: true, force: true });
|
|
14239
14763
|
await mkdir11(this.targetWebRoot, { recursive: true });
|
|
14240
|
-
await Bun.write(
|
|
14764
|
+
await Bun.write(path42.join(this.targetWebRoot, "index.html"), this.#injectMobileTargetMeta(await Bun.file(htmlSource).text()));
|
|
14241
14765
|
}
|
|
14242
14766
|
#injectMobileTargetMeta(html) {
|
|
14243
14767
|
const basePath2 = this.target.basePath?.replace(/^\/+|\/+$/g, "") ?? "";
|
|
@@ -14261,7 +14785,7 @@ ${error.message}`;
|
|
|
14261
14785
|
});
|
|
14262
14786
|
const content = `${JSON.stringify(config, null, 2)}
|
|
14263
14787
|
`;
|
|
14264
|
-
await Bun.write(
|
|
14788
|
+
await Bun.write(path42.join(this.targetRoot, "capacitor.config.json"), content);
|
|
14265
14789
|
return content;
|
|
14266
14790
|
}
|
|
14267
14791
|
async#prepareTargetAssets() {
|
|
@@ -14269,11 +14793,11 @@ ${error.message}`;
|
|
|
14269
14793
|
return;
|
|
14270
14794
|
await mkdir11(this.targetAssetRoot, { recursive: true });
|
|
14271
14795
|
if (this.target.assets.icon)
|
|
14272
|
-
await cp2(
|
|
14796
|
+
await cp2(path42.join(this.app.cwdPath, this.target.assets.icon), path42.join(this.targetAssetRoot, "icon.png"), {
|
|
14273
14797
|
force: true
|
|
14274
14798
|
});
|
|
14275
14799
|
if (this.target.assets.splash)
|
|
14276
|
-
await cp2(
|
|
14800
|
+
await cp2(path42.join(this.app.cwdPath, this.target.assets.splash), path42.join(this.targetAssetRoot, "splash.png"), {
|
|
14277
14801
|
force: true
|
|
14278
14802
|
});
|
|
14279
14803
|
}
|
|
@@ -14281,11 +14805,11 @@ ${error.message}`;
|
|
|
14281
14805
|
const files = this.target.files?.[platform];
|
|
14282
14806
|
if (!files)
|
|
14283
14807
|
return;
|
|
14284
|
-
const platformRoot =
|
|
14808
|
+
const platformRoot = path42.join(this.app.cwdPath, platform === "ios" ? this.iosRootPath : this.androidRootPath);
|
|
14285
14809
|
await Promise.all(Object.entries(files).map(async ([to, from]) => {
|
|
14286
|
-
const targetPath =
|
|
14287
|
-
await mkdir11(
|
|
14288
|
-
await cp2(
|
|
14810
|
+
const targetPath = path42.join(platformRoot, to);
|
|
14811
|
+
await mkdir11(path42.dirname(targetPath), { recursive: true });
|
|
14812
|
+
await cp2(path42.join(this.app.cwdPath, from), targetPath, { force: true });
|
|
14289
14813
|
}));
|
|
14290
14814
|
}
|
|
14291
14815
|
async#generateAssets({ operation, env }) {
|
|
@@ -14295,7 +14819,7 @@ ${error.message}`;
|
|
|
14295
14819
|
"@capacitor/assets",
|
|
14296
14820
|
"generate",
|
|
14297
14821
|
"--assetPath",
|
|
14298
|
-
|
|
14822
|
+
path42.posix.join(this.targetRootPath, "assets"),
|
|
14299
14823
|
"--iosProject",
|
|
14300
14824
|
this.iosProjectPath,
|
|
14301
14825
|
"--androidProject",
|
|
@@ -14329,13 +14853,18 @@ ${error.message}`;
|
|
|
14329
14853
|
}
|
|
14330
14854
|
for (const permission of this.target.permissions ?? []) {
|
|
14331
14855
|
const claimants = nativePlugins.get(permission);
|
|
14332
|
-
if (
|
|
14333
|
-
|
|
14856
|
+
if (claimants?.length) {
|
|
14857
|
+
const ctx = this.#makeNativeContext({ operation, env });
|
|
14858
|
+
for (const plugin of claimants)
|
|
14859
|
+
await plugin.capacitor?.configureNative?.(ctx);
|
|
14334
14860
|
continue;
|
|
14335
14861
|
}
|
|
14336
|
-
|
|
14337
|
-
|
|
14338
|
-
|
|
14862
|
+
if (permission === "camera")
|
|
14863
|
+
await this.addCamera();
|
|
14864
|
+
else if (permission === "contacts")
|
|
14865
|
+
await this.addContact();
|
|
14866
|
+
else if (permission === "location")
|
|
14867
|
+
await this.addLocation();
|
|
14339
14868
|
}
|
|
14340
14869
|
}
|
|
14341
14870
|
#makeNativeContext({ operation, env }) {
|
|
@@ -14452,11 +14981,33 @@ ${error.message}`;
|
|
|
14452
14981
|
await this.#clearRootCapacitorConfigs();
|
|
14453
14982
|
}
|
|
14454
14983
|
}
|
|
14984
|
+
async addCamera() {
|
|
14985
|
+
await this.#setPermissionInIos({
|
|
14986
|
+
cameraUsageDescription: "$(PRODUCT_NAME) requires access to the camera to take photos.",
|
|
14987
|
+
photoAddUsageDescription: "$(PRODUCT_NAME) requires access to the photo library to take photos.",
|
|
14988
|
+
photoUsageDescription: "$(PRODUCT_NAME) requires access to the photo library to take photos."
|
|
14989
|
+
});
|
|
14990
|
+
this.#setPermissionsInAndroid(["READ_MEDIA_IMAGES", "READ_EXTERNAL_STORAGE", "WRITE_EXTERNAL_STORAGE"]);
|
|
14991
|
+
}
|
|
14992
|
+
async addContact() {
|
|
14993
|
+
await this.#setPermissionInIos({
|
|
14994
|
+
contactsUsageDescription: "$(PRODUCT_NAME) requires access to the contacts to add new contacts."
|
|
14995
|
+
});
|
|
14996
|
+
this.#setPermissionsInAndroid(["READ_CONTACTS", "WRITE_CONTACTS"]);
|
|
14997
|
+
}
|
|
14998
|
+
async addLocation() {
|
|
14999
|
+
await this.#setPermissionInIos({
|
|
15000
|
+
locationAlwaysUsageDescription: "$(PRODUCT_NAME) requires access to the location to get the user's location.",
|
|
15001
|
+
locationWhenInUseUsageDescription: "$(PRODUCT_NAME) requires access to the location to get the user's location."
|
|
15002
|
+
});
|
|
15003
|
+
this.#setPermissionsInAndroid(["ACCESS_COARSE_LOCATION", "ACCESS_FINE_LOCATION"]);
|
|
15004
|
+
this.#setFeaturesInAndroid(["android.hardware.location.gps"]);
|
|
15005
|
+
}
|
|
14455
15006
|
#addIosEntitlements(entitlements) {
|
|
14456
15007
|
Object.assign(this.#iosEntitlements, entitlements);
|
|
14457
15008
|
}
|
|
14458
15009
|
async#editIosAppDelegate(transform) {
|
|
14459
|
-
const appDelegatePath =
|
|
15010
|
+
const appDelegatePath = path42.join(this.app.cwdPath, this.iosProjectPath, "App/AppDelegate.swift");
|
|
14460
15011
|
if (!await Bun.file(appDelegatePath).exists())
|
|
14461
15012
|
return;
|
|
14462
15013
|
const editor = await FileEditor.create(appDelegatePath);
|
|
@@ -14498,7 +15049,7 @@ ${error.message}`;
|
|
|
14498
15049
|
if (Object.keys(this.#iosEntitlements).length === 0)
|
|
14499
15050
|
return;
|
|
14500
15051
|
const entitlementsRelPath = "App/App.entitlements";
|
|
14501
|
-
const entitlementsPath =
|
|
15052
|
+
const entitlementsPath = path42.join(this.app.cwdPath, this.iosProjectPath, entitlementsRelPath);
|
|
14502
15053
|
const body = [
|
|
14503
15054
|
'<?xml version="1.0" encoding="UTF-8"?>',
|
|
14504
15055
|
'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">',
|
|
@@ -14512,12 +15063,12 @@ ${error.message}`;
|
|
|
14512
15063
|
`);
|
|
14513
15064
|
const currentBody = await Bun.file(entitlementsPath).exists() ? await Bun.file(entitlementsPath).text() : undefined;
|
|
14514
15065
|
if (currentBody !== body)
|
|
14515
|
-
await
|
|
15066
|
+
await writeFile3(entitlementsPath, body);
|
|
14516
15067
|
await this.#setCodeSignEntitlementsInIos(entitlementsRelPath);
|
|
14517
15068
|
}
|
|
14518
15069
|
async#setCodeSignEntitlementsInIos(entitlementsRelPath) {
|
|
14519
|
-
const pbxprojPath =
|
|
14520
|
-
const lines = (await
|
|
15070
|
+
const pbxprojPath = path42.join(this.app.cwdPath, this.iosProjectPath, "App.xcodeproj/project.pbxproj");
|
|
15071
|
+
const lines = (await readFile3(pbxprojPath, "utf8")).split(`
|
|
14521
15072
|
`);
|
|
14522
15073
|
let changed = false;
|
|
14523
15074
|
for (let index = 0;index < lines.length; index++) {
|
|
@@ -14539,12 +15090,12 @@ ${error.message}`;
|
|
|
14539
15090
|
changed = true;
|
|
14540
15091
|
}
|
|
14541
15092
|
if (changed)
|
|
14542
|
-
await
|
|
15093
|
+
await writeFile3(pbxprojPath, lines.join(`
|
|
14543
15094
|
`));
|
|
14544
15095
|
}
|
|
14545
15096
|
async#setUrlSchemesInAndroid(schemes) {
|
|
14546
|
-
const manifestPath =
|
|
14547
|
-
let manifest = await
|
|
15097
|
+
const manifestPath = path42.join(this.app.cwdPath, this.androidRootPath, "app/src/main/AndroidManifest.xml");
|
|
15098
|
+
let manifest = await readFile3(manifestPath, "utf8");
|
|
14548
15099
|
let changed = false;
|
|
14549
15100
|
for (const scheme of schemes) {
|
|
14550
15101
|
if (manifest.includes(`android:scheme="${scheme}"`))
|
|
@@ -14563,12 +15114,12 @@ ${filter}$1`);
|
|
|
14563
15114
|
changed = true;
|
|
14564
15115
|
}
|
|
14565
15116
|
if (changed)
|
|
14566
|
-
await
|
|
15117
|
+
await writeFile3(manifestPath, manifest);
|
|
14567
15118
|
}
|
|
14568
15119
|
async#setDeepLinksInAndroid(schemes, domains) {
|
|
14569
15120
|
await this.#setUrlSchemesInAndroid(schemes);
|
|
14570
|
-
const manifestPath =
|
|
14571
|
-
let manifest = await
|
|
15121
|
+
const manifestPath = path42.join(this.app.cwdPath, this.androidRootPath, "app/src/main/AndroidManifest.xml");
|
|
15122
|
+
let manifest = await readFile3(manifestPath, "utf8");
|
|
14572
15123
|
let changed = false;
|
|
14573
15124
|
const pathPrefix = resolveMobilePath(this.target, "/");
|
|
14574
15125
|
for (const domain of domains) {
|
|
@@ -14588,7 +15139,7 @@ ${filter}$1`);
|
|
|
14588
15139
|
changed = true;
|
|
14589
15140
|
}
|
|
14590
15141
|
if (changed)
|
|
14591
|
-
await
|
|
15142
|
+
await writeFile3(manifestPath, manifest);
|
|
14592
15143
|
}
|
|
14593
15144
|
#setFeaturesInAndroid(features) {
|
|
14594
15145
|
for (const feature of features) {
|
|
@@ -14669,7 +15220,7 @@ var Pkg = createInternalArgToken("Pkg");
|
|
|
14669
15220
|
var Module = createInternalArgToken("Module");
|
|
14670
15221
|
var Workspace = createInternalArgToken("Workspace");
|
|
14671
15222
|
// pkgs/@akanjs/devkit/commandDecorators/command.ts
|
|
14672
|
-
import
|
|
15223
|
+
import path43 from "path";
|
|
14673
15224
|
import { confirm, input as input2, select as select3 } from "@inquirer/prompts";
|
|
14674
15225
|
import { Logger as Logger10 } from "akanjs/common";
|
|
14675
15226
|
import chalk6 from "chalk";
|
|
@@ -15173,7 +15724,7 @@ var runCommands = async (...commands) => {
|
|
|
15173
15724
|
process.exit(1);
|
|
15174
15725
|
});
|
|
15175
15726
|
const __dirname2 = getDirname(import.meta.url);
|
|
15176
|
-
const packageJsonCandidates = [`${
|
|
15727
|
+
const packageJsonCandidates = [`${path43.dirname(Bun.main)}/package.json`, `${__dirname2}/../package.json`];
|
|
15177
15728
|
let cliPackageJson = null;
|
|
15178
15729
|
for (const packageJsonPath of packageJsonCandidates) {
|
|
15179
15730
|
if (!await FileSys.fileExists(packageJsonPath))
|
|
@@ -15420,7 +15971,7 @@ import { capitalize as capitalize7 } from "akanjs/common";
|
|
|
15420
15971
|
// pkgs/@akanjs/devkit/getRelatedCnsts.ts
|
|
15421
15972
|
import { readFileSync as readFileSync4, realpathSync } from "fs";
|
|
15422
15973
|
import ora2 from "ora";
|
|
15423
|
-
import * as
|
|
15974
|
+
import * as ts11 from "typescript";
|
|
15424
15975
|
var tsTranspiler = new Bun.Transpiler({ loader: "ts" });
|
|
15425
15976
|
var tsxTranspiler = new Bun.Transpiler({ loader: "tsx" });
|
|
15426
15977
|
var getTranspiler = (filePath) => filePath.endsWith(".tsx") ? tsxTranspiler : tsTranspiler;
|
|
@@ -15453,10 +16004,10 @@ var scanModuleSpecifiers = (source2, filePath, includeExports) => {
|
|
|
15453
16004
|
return importSpecifiers;
|
|
15454
16005
|
};
|
|
15455
16006
|
var parseTsConfig = (tsConfigPath = "./tsconfig.json") => {
|
|
15456
|
-
const configFile =
|
|
15457
|
-
return
|
|
16007
|
+
const configFile = ts11.readConfigFile(tsConfigPath, (path44) => {
|
|
16008
|
+
return ts11.sys.readFile(path44);
|
|
15458
16009
|
});
|
|
15459
|
-
return
|
|
16010
|
+
return ts11.parseJsonConfigFileContent(configFile.config, ts11.sys, realpathSync(tsConfigPath).replace(/[^/\\]+$/, ""));
|
|
15460
16011
|
};
|
|
15461
16012
|
var collectImportedFiles = (constantFilePath, parsedConfig) => {
|
|
15462
16013
|
const allFilesToAnalyze = new Set([constantFilePath]);
|
|
@@ -15471,7 +16022,7 @@ var collectImportedFiles = (constantFilePath, parsedConfig) => {
|
|
|
15471
16022
|
for (const importPath of scanModuleSpecifiers(source2, filePath, false)) {
|
|
15472
16023
|
if (!importPath.startsWith("."))
|
|
15473
16024
|
continue;
|
|
15474
|
-
const resolved =
|
|
16025
|
+
const resolved = ts11.resolveModuleName(importPath, filePath, parsedConfig.options, ts11.sys).resolvedModule?.resolvedFileName;
|
|
15475
16026
|
if (resolved && !allFilesToAnalyze.has(resolved)) {
|
|
15476
16027
|
allFilesToAnalyze.add(resolved);
|
|
15477
16028
|
collectImported(resolved);
|
|
@@ -15488,7 +16039,7 @@ var collectImportedFiles = (constantFilePath, parsedConfig) => {
|
|
|
15488
16039
|
var createTsProgram = (filePaths, options) => {
|
|
15489
16040
|
const spinner = ora2("Creating TypeScript program for all files...");
|
|
15490
16041
|
spinner.start();
|
|
15491
|
-
const program2 =
|
|
16042
|
+
const program2 = ts11.createProgram(Array.from(filePaths), options);
|
|
15492
16043
|
const checker = program2.getTypeChecker();
|
|
15493
16044
|
spinner.succeed("TypeScript program created.");
|
|
15494
16045
|
return {
|
|
@@ -15528,17 +16079,17 @@ var analyzeProperties = (filesToAnalyze, program2, checker) => {
|
|
|
15528
16079
|
function visit(node) {
|
|
15529
16080
|
if (!source2)
|
|
15530
16081
|
return;
|
|
15531
|
-
if (
|
|
16082
|
+
if (ts11.isPropertyAccessExpression(node)) {
|
|
15532
16083
|
const left = node.expression;
|
|
15533
16084
|
const right = node.name;
|
|
15534
|
-
const { line } =
|
|
15535
|
-
if (
|
|
16085
|
+
const { line } = ts11.getLineAndCharacterOfPosition(source2, node.getStart());
|
|
16086
|
+
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},`))) {
|
|
15536
16087
|
const symbol = getCachedSymbol(right);
|
|
15537
16088
|
if (symbol?.declarations && symbol.declarations.length > 0) {
|
|
15538
16089
|
const key = symbol.declarations[0]?.getSourceFile().fileName.split("/").pop()?.split(".")[0] ?? "";
|
|
15539
16090
|
const property = propertyMap.get(key);
|
|
15540
16091
|
const isScalar = symbol.declarations[0]?.getSourceFile().fileName.includes("_") ?? false;
|
|
15541
|
-
const symbolFilePath = symbol.declarations[0]?.getSourceFile().fileName.replace(`${
|
|
16092
|
+
const symbolFilePath = symbol.declarations[0]?.getSourceFile().fileName.replace(`${ts11.sys.getCurrentDirectory()}/`, "");
|
|
15542
16093
|
if (!symbolFilePath)
|
|
15543
16094
|
throw new Error(`No symbol file path found for ${left.text}.${right.text}`);
|
|
15544
16095
|
if (property) {
|
|
@@ -15562,10 +16113,10 @@ var analyzeProperties = (filesToAnalyze, program2, checker) => {
|
|
|
15562
16113
|
}
|
|
15563
16114
|
}
|
|
15564
16115
|
}
|
|
15565
|
-
} else if (
|
|
16116
|
+
} else if (ts11.isImportDeclaration(node) && ts11.isStringLiteral(node.moduleSpecifier)) {
|
|
15566
16117
|
const importPath = node.moduleSpecifier.text;
|
|
15567
16118
|
if (importPath.startsWith(".")) {
|
|
15568
|
-
const resolved =
|
|
16119
|
+
const resolved = ts11.resolveModuleName(importPath, filePath, program2.getCompilerOptions(), ts11.sys).resolvedModule?.resolvedFileName;
|
|
15569
16120
|
const moduleName = importPath.split("/").pop()?.split(".")[0] ?? "";
|
|
15570
16121
|
const property = propertyMap.get(moduleName);
|
|
15571
16122
|
const isScalar = importPath.includes("_");
|
|
@@ -15580,7 +16131,7 @@ var analyzeProperties = (filesToAnalyze, program2, checker) => {
|
|
|
15580
16131
|
}
|
|
15581
16132
|
}
|
|
15582
16133
|
}
|
|
15583
|
-
|
|
16134
|
+
ts11.forEachChild(node, visit);
|
|
15584
16135
|
}
|
|
15585
16136
|
visit(source2);
|
|
15586
16137
|
}
|
|
@@ -15672,10 +16223,10 @@ ${document}
|
|
|
15672
16223
|
}
|
|
15673
16224
|
// pkgs/@akanjs/devkit/qualityScanner.ts
|
|
15674
16225
|
import { createHash } from "crypto";
|
|
15675
|
-
import { readdir as
|
|
15676
|
-
import
|
|
16226
|
+
import { readdir as readdir4, readFile as readFile4, stat as stat5 } from "fs/promises";
|
|
16227
|
+
import path44 from "path";
|
|
15677
16228
|
import ignore2 from "ignore";
|
|
15678
|
-
import
|
|
16229
|
+
import ts12 from "typescript";
|
|
15679
16230
|
var MAX_FILE_LINES = 2000;
|
|
15680
16231
|
var PLACEHOLDER_EXPORT_NAMES = new Set([
|
|
15681
16232
|
"aa",
|
|
@@ -15787,7 +16338,7 @@ class AkanQualityScanner {
|
|
|
15787
16338
|
const ignoreFilter = ignore2().add(await this.#readGitIgnore(workspaceRoot));
|
|
15788
16339
|
const files = [];
|
|
15789
16340
|
for (const targetRoot of ["apps", "libs"]) {
|
|
15790
|
-
const absoluteTargetRoot =
|
|
16341
|
+
const absoluteTargetRoot = path44.join(workspaceRoot, targetRoot);
|
|
15791
16342
|
if (!await isDirectory(absoluteTargetRoot))
|
|
15792
16343
|
continue;
|
|
15793
16344
|
await this.#walkTargetFiles(workspaceRoot, absoluteTargetRoot, ignoreFilter, files);
|
|
@@ -15795,16 +16346,16 @@ class AkanQualityScanner {
|
|
|
15795
16346
|
return files.sort();
|
|
15796
16347
|
}
|
|
15797
16348
|
async#readGitIgnore(workspaceRoot) {
|
|
15798
|
-
const gitIgnorePath =
|
|
16349
|
+
const gitIgnorePath = path44.join(workspaceRoot, ".gitignore");
|
|
15799
16350
|
if (!await Bun.file(gitIgnorePath).exists())
|
|
15800
16351
|
return [];
|
|
15801
|
-
return (await
|
|
16352
|
+
return (await readFile4(gitIgnorePath, "utf8")).split(/\r?\n/);
|
|
15802
16353
|
}
|
|
15803
16354
|
async#walkTargetFiles(workspaceRoot, currentPath, ignoreFilter, files) {
|
|
15804
|
-
const entries = await
|
|
16355
|
+
const entries = await readdir4(currentPath, { withFileTypes: true });
|
|
15805
16356
|
for (const entry of entries) {
|
|
15806
|
-
const absolutePath =
|
|
15807
|
-
const relativePath = toPosix(
|
|
16357
|
+
const absolutePath = path44.join(currentPath, entry.name);
|
|
16358
|
+
const relativePath = toPosix(path44.relative(workspaceRoot, absolutePath));
|
|
15808
16359
|
if (shouldSkipPath(relativePath, entry.isDirectory(), ignoreFilter))
|
|
15809
16360
|
continue;
|
|
15810
16361
|
if (entry.isDirectory()) {
|
|
@@ -15817,13 +16368,13 @@ class AkanQualityScanner {
|
|
|
15817
16368
|
}
|
|
15818
16369
|
}
|
|
15819
16370
|
async#readSourceFile(workspaceRoot, file) {
|
|
15820
|
-
const absolutePath =
|
|
15821
|
-
const content = await
|
|
16371
|
+
const absolutePath = path44.join(workspaceRoot, file);
|
|
16372
|
+
const content = await readFile4(absolutePath, "utf8");
|
|
15822
16373
|
return {
|
|
15823
16374
|
file,
|
|
15824
16375
|
absolutePath,
|
|
15825
16376
|
content,
|
|
15826
|
-
sourceFile:
|
|
16377
|
+
sourceFile: ts12.createSourceFile(file, content, ts12.ScriptTarget.Latest, true, getScriptKind(file))
|
|
15827
16378
|
};
|
|
15828
16379
|
}
|
|
15829
16380
|
#scanGlobalQuality(sourceFiles) {
|
|
@@ -15948,7 +16499,7 @@ class AkanQualityScanner {
|
|
|
15948
16499
|
const suffix = CONVENTION_SUFFIXES.find((candidate) => sourceFile2.file.endsWith(candidate));
|
|
15949
16500
|
if (!suffix)
|
|
15950
16501
|
return [];
|
|
15951
|
-
const modelName = toPascalCase(
|
|
16502
|
+
const modelName = toPascalCase(path44.basename(sourceFile2.file, suffix));
|
|
15952
16503
|
const warnings = [];
|
|
15953
16504
|
for (const declaration of getTopLevelDeclarations(sourceFile2)) {
|
|
15954
16505
|
if (isAllowedConventionDeclaration(suffix, modelName, declaration))
|
|
@@ -15959,7 +16510,7 @@ class AkanQualityScanner {
|
|
|
15959
16510
|
severity: "warning",
|
|
15960
16511
|
file: sourceFile2.file,
|
|
15961
16512
|
line: declaration.line,
|
|
15962
|
-
message: `${
|
|
16513
|
+
message: `${path44.basename(sourceFile2.file)} should not declare top-level ${declaration.kind} "${declaration.name}". Allowed declarations: ${getConventionDescription(suffix, modelName)}.`
|
|
15963
16514
|
});
|
|
15964
16515
|
}
|
|
15965
16516
|
return warnings;
|
|
@@ -16031,7 +16582,7 @@ function getExportedFunctionLikes(sourceFile2) {
|
|
|
16031
16582
|
const declarations = [];
|
|
16032
16583
|
const nameExempt = isPageRouteFile(sourceFile2.file) || isUiComponentFile(sourceFile2.file);
|
|
16033
16584
|
for (const statement of sourceFile2.sourceFile.statements) {
|
|
16034
|
-
if (
|
|
16585
|
+
if (ts12.isFunctionDeclaration(statement) && statement.name && isExported(statement)) {
|
|
16035
16586
|
declarations.push({
|
|
16036
16587
|
name: statement.name.text,
|
|
16037
16588
|
kind: "function",
|
|
@@ -16041,7 +16592,7 @@ function getExportedFunctionLikes(sourceFile2) {
|
|
|
16041
16592
|
duplicateNameExempt: nameExempt || isConventionDuplicateNameExempt(sourceFile2.file, false)
|
|
16042
16593
|
});
|
|
16043
16594
|
}
|
|
16044
|
-
if (
|
|
16595
|
+
if (ts12.isClassDeclaration(statement) && statement.name && isExported(statement)) {
|
|
16045
16596
|
declarations.push({
|
|
16046
16597
|
name: statement.name.text,
|
|
16047
16598
|
kind: "class",
|
|
@@ -16051,9 +16602,9 @@ function getExportedFunctionLikes(sourceFile2) {
|
|
|
16051
16602
|
duplicateNameExempt: nameExempt || isConventionDuplicateNameExempt(sourceFile2.file, isEnumClassStatement(sourceFile2.sourceFile, statement))
|
|
16052
16603
|
});
|
|
16053
16604
|
}
|
|
16054
|
-
if (
|
|
16605
|
+
if (ts12.isVariableStatement(statement) && isExported(statement)) {
|
|
16055
16606
|
for (const declaration of statement.declarationList.declarations) {
|
|
16056
|
-
if (!
|
|
16607
|
+
if (!ts12.isIdentifier(declaration.name) || !isFunctionLikeInitializer(declaration.initializer))
|
|
16057
16608
|
continue;
|
|
16058
16609
|
declarations.push({
|
|
16059
16610
|
name: declaration.name.text,
|
|
@@ -16092,14 +16643,14 @@ function isInLibModule(file) {
|
|
|
16092
16643
|
return (segments[0] === "apps" || segments[0] === "libs") && segments.includes("lib");
|
|
16093
16644
|
}
|
|
16094
16645
|
function isEnumClassStatement(sourceFile2, statement) {
|
|
16095
|
-
if (!
|
|
16646
|
+
if (!ts12.isClassDeclaration(statement))
|
|
16096
16647
|
return false;
|
|
16097
|
-
const heritageClause = statement.heritageClauses?.find((clause) => clause.token ===
|
|
16648
|
+
const heritageClause = statement.heritageClauses?.find((clause) => clause.token === ts12.SyntaxKind.ExtendsKeyword);
|
|
16098
16649
|
const expression = heritageClause?.types[0]?.expression;
|
|
16099
16650
|
return !!expression && expression.getText(sourceFile2).startsWith("enumOf(");
|
|
16100
16651
|
}
|
|
16101
16652
|
function getExportedClassNames(sourceFile2) {
|
|
16102
|
-
return sourceFile2.statements.filter((statement) =>
|
|
16653
|
+
return sourceFile2.statements.filter((statement) => ts12.isClassDeclaration(statement) && !!statement.name).filter((statement) => isExported(statement)).map((statement) => statement.name.text);
|
|
16103
16654
|
}
|
|
16104
16655
|
function isComponentDeclarationFile(file) {
|
|
16105
16656
|
if (!file.endsWith(".tsx"))
|
|
@@ -16115,7 +16666,7 @@ function isComponentDeclarationFile(file) {
|
|
|
16115
16666
|
function getComponentFileDeclarations(sourceFile2) {
|
|
16116
16667
|
const reExportedNames = new Set;
|
|
16117
16668
|
for (const statement of sourceFile2.statements) {
|
|
16118
|
-
if (
|
|
16669
|
+
if (ts12.isExportDeclaration(statement) && statement.exportClause && ts12.isNamedExports(statement.exportClause)) {
|
|
16119
16670
|
for (const element of statement.exportClause.elements)
|
|
16120
16671
|
reExportedNames.add((element.propertyName ?? element.name).text);
|
|
16121
16672
|
}
|
|
@@ -16125,19 +16676,19 @@ function getComponentFileDeclarations(sourceFile2) {
|
|
|
16125
16676
|
const isDefaultExport = isDefaultExportStatement(statement);
|
|
16126
16677
|
const inlineExported = isExported(statement);
|
|
16127
16678
|
const add = (name, kind, line) => declarations.push({ name, kind, line, exported: inlineExported || reExportedNames.has(name), isDefaultExport });
|
|
16128
|
-
if (
|
|
16679
|
+
if (ts12.isInterfaceDeclaration(statement))
|
|
16129
16680
|
add(statement.name.text, "interface", getLine(sourceFile2, statement));
|
|
16130
|
-
else if (
|
|
16681
|
+
else if (ts12.isTypeAliasDeclaration(statement))
|
|
16131
16682
|
add(statement.name.text, "type", getLine(sourceFile2, statement));
|
|
16132
|
-
else if (
|
|
16683
|
+
else if (ts12.isEnumDeclaration(statement))
|
|
16133
16684
|
add(statement.name.text, "enum", getLine(sourceFile2, statement));
|
|
16134
|
-
else if (
|
|
16685
|
+
else if (ts12.isFunctionDeclaration(statement) && statement.name)
|
|
16135
16686
|
add(statement.name.text, "function", getLine(sourceFile2, statement));
|
|
16136
|
-
else if (
|
|
16687
|
+
else if (ts12.isClassDeclaration(statement) && statement.name)
|
|
16137
16688
|
add(statement.name.text, "class", getLine(sourceFile2, statement));
|
|
16138
|
-
else if (
|
|
16689
|
+
else if (ts12.isVariableStatement(statement)) {
|
|
16139
16690
|
for (const declaration of statement.declarationList.declarations) {
|
|
16140
|
-
if (!
|
|
16691
|
+
if (!ts12.isIdentifier(declaration.name))
|
|
16141
16692
|
continue;
|
|
16142
16693
|
const kind = isFunctionLikeInitializer(declaration.initializer) ? "function" : "variable";
|
|
16143
16694
|
add(declaration.name.text, kind, getLine(sourceFile2, declaration));
|
|
@@ -16149,15 +16700,15 @@ function getComponentFileDeclarations(sourceFile2) {
|
|
|
16149
16700
|
function getCompoundComponentNames(sourceFile2) {
|
|
16150
16701
|
const names = new Set;
|
|
16151
16702
|
for (const statement of sourceFile2.statements) {
|
|
16152
|
-
if (!
|
|
16703
|
+
if (!ts12.isExpressionStatement(statement))
|
|
16153
16704
|
continue;
|
|
16154
16705
|
const { expression } = statement;
|
|
16155
|
-
if (!
|
|
16706
|
+
if (!ts12.isBinaryExpression(expression) || expression.operatorToken.kind !== ts12.SyntaxKind.EqualsToken)
|
|
16156
16707
|
continue;
|
|
16157
|
-
if (!
|
|
16708
|
+
if (!ts12.isPropertyAccessExpression(expression.left) || !isPascalCaseName(expression.left.name.text))
|
|
16158
16709
|
continue;
|
|
16159
16710
|
names.add(expression.left.name.text);
|
|
16160
|
-
if (
|
|
16711
|
+
if (ts12.isIdentifier(expression.right) && isPascalCaseName(expression.right.text))
|
|
16161
16712
|
names.add(expression.right.text);
|
|
16162
16713
|
}
|
|
16163
16714
|
return names;
|
|
@@ -16177,9 +16728,9 @@ function isPascalCaseName(name) {
|
|
|
16177
16728
|
return /^[A-Z]/.test(name) && !/^[A-Z0-9_]+$/.test(name);
|
|
16178
16729
|
}
|
|
16179
16730
|
function isDefaultExportStatement(statement) {
|
|
16180
|
-
if (
|
|
16731
|
+
if (ts12.isExportAssignment(statement))
|
|
16181
16732
|
return !statement.isExportEquals;
|
|
16182
|
-
return !!(
|
|
16733
|
+
return !!(ts12.getCombinedModifierFlags(statement) & ts12.ModifierFlags.Default);
|
|
16183
16734
|
}
|
|
16184
16735
|
function getPlaceholderExportWarnings(sourceFile2) {
|
|
16185
16736
|
if (!sourceFile2.file.endsWith("/index.ts") && !sourceFile2.file.endsWith("/index.tsx"))
|
|
@@ -16209,7 +16760,7 @@ function getDictionaryTextWarnings(sourceFile2) {
|
|
|
16209
16760
|
function getGlobalMutationWarnings(sourceFile2) {
|
|
16210
16761
|
const warnings = [];
|
|
16211
16762
|
for (const statement of sourceFile2.sourceFile.statements) {
|
|
16212
|
-
if (
|
|
16763
|
+
if (ts12.isModuleDeclaration(statement) && statement.name.getText(sourceFile2.sourceFile) === "global") {
|
|
16213
16764
|
warnings.push({
|
|
16214
16765
|
rule: "akan.file.global-declaration",
|
|
16215
16766
|
scope: "file",
|
|
@@ -16219,7 +16770,7 @@ function getGlobalMutationWarnings(sourceFile2) {
|
|
|
16219
16770
|
message: "Global declarations require an explicit low-level integration allowlist."
|
|
16220
16771
|
});
|
|
16221
16772
|
}
|
|
16222
|
-
if (
|
|
16773
|
+
if (ts12.isInterfaceDeclaration(statement) && statement.name.text === "Window") {
|
|
16223
16774
|
warnings.push({
|
|
16224
16775
|
rule: "akan.file.window-augmentation",
|
|
16225
16776
|
scope: "file",
|
|
@@ -16229,7 +16780,7 @@ function getGlobalMutationWarnings(sourceFile2) {
|
|
|
16229
16780
|
message: "Window augmentation should be isolated to approved browser integration files."
|
|
16230
16781
|
});
|
|
16231
16782
|
}
|
|
16232
|
-
if (
|
|
16783
|
+
if (ts12.isExpressionStatement(statement) && statement.expression.getText(sourceFile2.sourceFile).includes(".prototype.")) {
|
|
16233
16784
|
warnings.push({
|
|
16234
16785
|
rule: "akan.file.prototype-mutation",
|
|
16235
16786
|
scope: "file",
|
|
@@ -16247,23 +16798,23 @@ function getTopLevelDeclarations(sourceFile2) {
|
|
|
16247
16798
|
}
|
|
16248
16799
|
function getTopLevelDeclaration(sourceFile2, statement) {
|
|
16249
16800
|
const line = getLine(sourceFile2, statement);
|
|
16250
|
-
if (
|
|
16801
|
+
if (ts12.isClassDeclaration(statement) && statement.name) {
|
|
16251
16802
|
return [{ name: statement.name.text, kind: "class", line, exported: isExported(statement), node: statement }];
|
|
16252
16803
|
}
|
|
16253
|
-
if (
|
|
16804
|
+
if (ts12.isFunctionDeclaration(statement) && statement.name) {
|
|
16254
16805
|
return [{ name: statement.name.text, kind: "function", line, exported: isExported(statement), node: statement }];
|
|
16255
16806
|
}
|
|
16256
|
-
if (
|
|
16807
|
+
if (ts12.isInterfaceDeclaration(statement)) {
|
|
16257
16808
|
return [{ name: statement.name.text, kind: "interface", line, exported: isExported(statement), node: statement }];
|
|
16258
16809
|
}
|
|
16259
|
-
if (
|
|
16810
|
+
if (ts12.isTypeAliasDeclaration(statement)) {
|
|
16260
16811
|
return [{ name: statement.name.text, kind: "type", line, exported: isExported(statement), node: statement }];
|
|
16261
16812
|
}
|
|
16262
|
-
if (
|
|
16813
|
+
if (ts12.isEnumDeclaration(statement)) {
|
|
16263
16814
|
return [{ name: statement.name.text, kind: "enum", line, exported: isExported(statement), node: statement }];
|
|
16264
16815
|
}
|
|
16265
|
-
if (
|
|
16266
|
-
return statement.declarationList.declarations.filter((declaration) =>
|
|
16816
|
+
if (ts12.isVariableStatement(statement)) {
|
|
16817
|
+
return statement.declarationList.declarations.filter((declaration) => ts12.isIdentifier(declaration.name)).map((declaration) => ({
|
|
16267
16818
|
name: declaration.name.text,
|
|
16268
16819
|
kind: "variable",
|
|
16269
16820
|
line: getLine(sourceFile2, declaration),
|
|
@@ -16271,7 +16822,7 @@ function getTopLevelDeclaration(sourceFile2, statement) {
|
|
|
16271
16822
|
node: statement
|
|
16272
16823
|
}));
|
|
16273
16824
|
}
|
|
16274
|
-
if (
|
|
16825
|
+
if (ts12.isExportDeclaration(statement)) {
|
|
16275
16826
|
return [{ name: "export declaration", kind: "export", line, exported: true, node: statement }];
|
|
16276
16827
|
}
|
|
16277
16828
|
return [];
|
|
@@ -16296,9 +16847,9 @@ function isAllowedConstantDeclaration(modelName, declaration) {
|
|
|
16296
16847
|
return false;
|
|
16297
16848
|
if ([`${modelName}Input`, `${modelName}Object`, modelName, `Light${modelName}`, `${modelName}Insight`].includes(declaration.name))
|
|
16298
16849
|
return true;
|
|
16299
|
-
if (!
|
|
16850
|
+
if (!ts12.isClassDeclaration(declaration.node))
|
|
16300
16851
|
return false;
|
|
16301
|
-
const heritageClause = declaration.node.heritageClauses?.find((clause) => clause.token ===
|
|
16852
|
+
const heritageClause = declaration.node.heritageClauses?.find((clause) => clause.token === ts12.SyntaxKind.ExtendsKeyword);
|
|
16302
16853
|
const expression = heritageClause?.types[0]?.expression;
|
|
16303
16854
|
return !!expression && expression.getText().startsWith("enumOf(");
|
|
16304
16855
|
}
|
|
@@ -16364,13 +16915,13 @@ function getModuleInfo(file) {
|
|
|
16364
16915
|
return { moduleName, fileName, kind: "database" };
|
|
16365
16916
|
}
|
|
16366
16917
|
function isExportedConst(declaration) {
|
|
16367
|
-
return declaration.exported &&
|
|
16918
|
+
return declaration.exported && ts12.isVariableStatement(declaration.node) && (declaration.node.declarationList.flags & ts12.NodeFlags.Const) !== 0;
|
|
16368
16919
|
}
|
|
16369
16920
|
function isExported(node) {
|
|
16370
|
-
return !!
|
|
16921
|
+
return !!ts12.getCombinedModifierFlags(node) && !!(ts12.getCombinedModifierFlags(node) & ts12.ModifierFlags.Export);
|
|
16371
16922
|
}
|
|
16372
16923
|
function isFunctionLikeInitializer(node) {
|
|
16373
|
-
return !!node && (
|
|
16924
|
+
return !!node && (ts12.isArrowFunction(node) || ts12.isFunctionExpression(node));
|
|
16374
16925
|
}
|
|
16375
16926
|
function getBodyFingerprint(sourceFile2, node) {
|
|
16376
16927
|
if (!node)
|
|
@@ -16386,13 +16937,13 @@ function shouldSkipPath(relativePath, isDirectory, ignoreFilter) {
|
|
|
16386
16937
|
}
|
|
16387
16938
|
async function isDirectory(absolutePath) {
|
|
16388
16939
|
try {
|
|
16389
|
-
return (await
|
|
16940
|
+
return (await stat5(absolutePath)).isDirectory();
|
|
16390
16941
|
} catch {
|
|
16391
16942
|
return false;
|
|
16392
16943
|
}
|
|
16393
16944
|
}
|
|
16394
16945
|
function getScriptKind(file) {
|
|
16395
|
-
return file.endsWith(".tsx") ?
|
|
16946
|
+
return file.endsWith(".tsx") ? ts12.ScriptKind.TSX : ts12.ScriptKind.TS;
|
|
16396
16947
|
}
|
|
16397
16948
|
function getLine(sourceFile2, node) {
|
|
16398
16949
|
return sourceFile2.getLineAndCharacterOfPosition(node.getStart(sourceFile2)).line + 1;
|
|
@@ -16413,7 +16964,7 @@ function toPascalCase(value) {
|
|
|
16413
16964
|
return value.replace(/(^|[-_./])([a-zA-Z0-9])/g, (_, __, char) => char.toUpperCase()).replace(/[-_./]/g, "");
|
|
16414
16965
|
}
|
|
16415
16966
|
function toPosix(value) {
|
|
16416
|
-
return value.split(
|
|
16967
|
+
return value.split(path44.sep).join("/");
|
|
16417
16968
|
}
|
|
16418
16969
|
function groupBy(items, getKey) {
|
|
16419
16970
|
const grouped = new Map;
|
|
@@ -17505,7 +18056,7 @@ class ApplicationCommand extends command("application", [ApplicationScript], ({
|
|
|
17505
18056
|
import { Logger as Logger16 } from "akanjs/common";
|
|
17506
18057
|
|
|
17507
18058
|
// pkgs/@akanjs/cli/package/package.runner.ts
|
|
17508
|
-
import
|
|
18059
|
+
import path45 from "path";
|
|
17509
18060
|
import { Logger as Logger14 } from "akanjs/common";
|
|
17510
18061
|
var {$: $2 } = globalThis.Bun;
|
|
17511
18062
|
|
|
@@ -17525,11 +18076,11 @@ class PackageRunner extends runner("package") {
|
|
|
17525
18076
|
}
|
|
17526
18077
|
async#getInstalledPackageJson() {
|
|
17527
18078
|
const packageJsonCandidates = [
|
|
17528
|
-
`${
|
|
18079
|
+
`${path45.dirname(Bun.main)}/package.json`,
|
|
17529
18080
|
`${process.cwd()}/node_modules/akanjs/package.json`
|
|
17530
18081
|
];
|
|
17531
18082
|
try {
|
|
17532
|
-
packageJsonCandidates.unshift(Bun.resolveSync("akanjs/package.json",
|
|
18083
|
+
packageJsonCandidates.unshift(Bun.resolveSync("akanjs/package.json", path45.dirname(Bun.main)));
|
|
17533
18084
|
} catch {}
|
|
17534
18085
|
for (const packageJsonPath of packageJsonCandidates) {
|
|
17535
18086
|
if (!await Bun.file(packageJsonPath).exists())
|
|
@@ -17538,7 +18089,7 @@ class PackageRunner extends runner("package") {
|
|
|
17538
18089
|
if (packageJson.name === "akanjs" || packageJson.name === "@akanjs/cli")
|
|
17539
18090
|
return packageJson;
|
|
17540
18091
|
}
|
|
17541
|
-
throw new Error(`[package] failed to locate akanjs package.json from ${
|
|
18092
|
+
throw new Error(`[package] failed to locate akanjs package.json from ${path45.dirname(Bun.main)}`);
|
|
17542
18093
|
}
|
|
17543
18094
|
async createPackage(workspace, pkgName) {
|
|
17544
18095
|
await workspace.applyTemplate({ basePath: `pkgs/${pkgName}`, template: "pkgRoot", dict: { pkgName } });
|
|
@@ -17713,7 +18264,7 @@ class PackageScript extends script("package", [PackageRunner]) {
|
|
|
17713
18264
|
}
|
|
17714
18265
|
|
|
17715
18266
|
// pkgs/@akanjs/cli/cloud/cloud.runner.ts
|
|
17716
|
-
import
|
|
18267
|
+
import path46 from "path";
|
|
17717
18268
|
import { confirm as confirm4, input as input5, select as select8 } from "@inquirer/prompts";
|
|
17718
18269
|
import { Logger as Logger15, sleep } from "akanjs/common";
|
|
17719
18270
|
import chalk7 from "chalk";
|
|
@@ -17984,7 +18535,7 @@ ${chalk7.green("\u27A4")} Authentication Required`));
|
|
|
17984
18535
|
await Promise.all(akanPkgs.map(async (library) => {
|
|
17985
18536
|
Logger15.info(`Publishing ${library}@${nextVersion} to ${registry ?? "npm"}...`);
|
|
17986
18537
|
await workspace.spawn("npm", ["publish", "--tag", tag, ...this.#getRegistryArgs(registry), ...this.#getLocalRegistryAuthArgs(registry)], {
|
|
17987
|
-
cwd:
|
|
18538
|
+
cwd: path46.join(workspace.workspaceRoot, "dist/pkgs", library),
|
|
17988
18539
|
env: this.#getRegistryEnv(registry),
|
|
17989
18540
|
stdio: "inherit"
|
|
17990
18541
|
});
|
|
@@ -18038,12 +18589,12 @@ ${chalk7.green("\u27A4")} Authentication Required`));
|
|
|
18038
18589
|
async downloadEnv(cloudApi2, workspace, workspaceId) {
|
|
18039
18590
|
await workspace.mkdir("local");
|
|
18040
18591
|
const localPath = await cloudApi2.downloadEnv(workspaceId);
|
|
18041
|
-
const relativePath =
|
|
18592
|
+
const relativePath = path46.relative(workspace.workspaceRoot, localPath).split(path46.sep).join("/");
|
|
18042
18593
|
await workspace.spawn("tar", ["-xf", relativePath], { cwd: workspace.workspaceRoot });
|
|
18043
18594
|
await workspace.remove(localPath);
|
|
18044
18595
|
}
|
|
18045
18596
|
async uploadEnv(cloudApi2, workspaceId, filePath) {
|
|
18046
|
-
const file = new File([Bun.file(filePath)],
|
|
18597
|
+
const file = new File([Bun.file(filePath)], path46.basename(filePath));
|
|
18047
18598
|
await cloudApi2.uploadEnv(workspaceId, file);
|
|
18048
18599
|
}
|
|
18049
18600
|
async downloadEnvByScp(workspace) {
|
|
@@ -18113,8 +18664,8 @@ ${chalk7.green("\u27A4")} Authentication Required`));
|
|
|
18113
18664
|
const secretGlobs = config.secrets ?? [];
|
|
18114
18665
|
if (secretGlobs.length === 0)
|
|
18115
18666
|
return [];
|
|
18116
|
-
const appDir =
|
|
18117
|
-
return secretGlobs.flatMap((pattern) => Array.from(new Bun.Glob(pattern).scanSync({ cwd: appDir, onlyFiles: true })).map((match) => `apps/${appName}/${match.split(
|
|
18667
|
+
const appDir = path46.join(workspace.workspaceRoot, "apps", appName);
|
|
18668
|
+
return secretGlobs.flatMap((pattern) => Array.from(new Bun.Glob(pattern).scanSync({ cwd: appDir, onlyFiles: true })).map((match) => `apps/${appName}/${match.split(path46.sep).join("/")}`));
|
|
18118
18669
|
}));
|
|
18119
18670
|
return secretPaths.flat();
|
|
18120
18671
|
}
|
|
@@ -18184,14 +18735,14 @@ class CloudScript extends script("cloud", [CloudRunner, ApplicationScript, Packa
|
|
|
18184
18735
|
}
|
|
18185
18736
|
async uploadEnv(workspace, { host = GlobalConfig.akanCloudHost } = {}) {
|
|
18186
18737
|
const workspaceId = workspace.getWorkspaceId({ allowEmpty: true });
|
|
18187
|
-
const { path:
|
|
18738
|
+
const { path: path47 } = await this.cloudRunner.gatherEnvFiles(workspace);
|
|
18188
18739
|
if (workspaceId) {
|
|
18189
18740
|
await this.login(workspace, host);
|
|
18190
18741
|
const cloudApi2 = await CloudApi.fromHost(workspace, host);
|
|
18191
|
-
await this.cloudRunner.uploadEnv(cloudApi2, workspaceId,
|
|
18742
|
+
await this.cloudRunner.uploadEnv(cloudApi2, workspaceId, path47);
|
|
18192
18743
|
return;
|
|
18193
18744
|
}
|
|
18194
|
-
await this.cloudRunner.uploadEnvByScp(workspace,
|
|
18745
|
+
await this.cloudRunner.uploadEnvByScp(workspace, path47);
|
|
18195
18746
|
}
|
|
18196
18747
|
async deployAkan(workspace, { test = true, registryUrl } = {}) {
|
|
18197
18748
|
const akanPkgs = await this.cloudRunner.getAkanPkgs(workspace);
|
|
@@ -18432,8 +18983,8 @@ class RepairRunner extends runner("repair") {
|
|
|
18432
18983
|
}
|
|
18433
18984
|
|
|
18434
18985
|
// pkgs/@akanjs/cli/workflow/workflow.runner.ts
|
|
18435
|
-
import { mkdir as mkdir12, readFile as
|
|
18436
|
-
import
|
|
18986
|
+
import { mkdir as mkdir12, readFile as readFile5, writeFile as writeFile4 } from "fs/promises";
|
|
18987
|
+
import path47 from "path";
|
|
18437
18988
|
import { capitalize as capitalize8 } from "akanjs/common";
|
|
18438
18989
|
|
|
18439
18990
|
// pkgs/@akanjs/cli/workflows/shared.ts
|
|
@@ -18999,7 +19550,7 @@ var workflowSpecs = [
|
|
|
18999
19550
|
];
|
|
19000
19551
|
|
|
19001
19552
|
// pkgs/@akanjs/cli/workflow/workflow.runner.ts
|
|
19002
|
-
var resolvePath = (filePath) =>
|
|
19553
|
+
var resolvePath = (filePath) => path47.isAbsolute(filePath) ? filePath : path47.join(process.cwd(), filePath);
|
|
19003
19554
|
var isRecord3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19004
19555
|
var isWorkflowPlan2 = (value) => {
|
|
19005
19556
|
if (!isRecord3(value))
|
|
@@ -19097,7 +19648,7 @@ var defaultValidationExecutor = (workspace) => async (command3) => {
|
|
|
19097
19648
|
};
|
|
19098
19649
|
}
|
|
19099
19650
|
};
|
|
19100
|
-
var readJsonFile = async (filePath) => JSON.parse(await
|
|
19651
|
+
var readJsonFile = async (filePath) => JSON.parse(await readFile5(resolvePath(filePath), "utf8"));
|
|
19101
19652
|
var planInputString2 = (plan2, key) => {
|
|
19102
19653
|
const value = plan2.inputs[key];
|
|
19103
19654
|
return typeof value === "string" ? value : "";
|
|
@@ -19193,8 +19744,8 @@ class WorkflowRunner extends runner("workflow") {
|
|
|
19193
19744
|
const plan2 = createWorkflowPlan(spec, compactWorkflowInputs(inputs));
|
|
19194
19745
|
if (out) {
|
|
19195
19746
|
const outPath = resolvePath(out);
|
|
19196
|
-
await mkdir12(
|
|
19197
|
-
await
|
|
19747
|
+
await mkdir12(path47.dirname(outPath), { recursive: true });
|
|
19748
|
+
await writeFile4(outPath, jsonText(plan2));
|
|
19198
19749
|
}
|
|
19199
19750
|
return format === "json" ? jsonText(plan2) : renderWorkflowPlan(plan2);
|
|
19200
19751
|
}
|
|
@@ -19212,7 +19763,7 @@ class WorkflowRunner extends runner("workflow") {
|
|
|
19212
19763
|
};
|
|
19213
19764
|
let plan2;
|
|
19214
19765
|
try {
|
|
19215
|
-
const parsed = JSON.parse(await
|
|
19766
|
+
const parsed = JSON.parse(await readFile5(resolvePath(planPath), "utf8"));
|
|
19216
19767
|
if (!isWorkflowPlan2(parsed)) {
|
|
19217
19768
|
const report = failedApplyReport("unknown", [
|
|
19218
19769
|
{
|
|
@@ -21252,14 +21803,14 @@ class GuidelinePrompt extends Prompter {
|
|
|
21252
21803
|
async#getScanFilePaths(matchPattern, { avoidDirs = ["node_modules", ".next"], filterText } = {}) {
|
|
21253
21804
|
const glob = new Bun.Glob(matchPattern);
|
|
21254
21805
|
const paths = [];
|
|
21255
|
-
for await (const
|
|
21256
|
-
if (avoidDirs.some((dir) =>
|
|
21806
|
+
for await (const path48 of glob.scan({ cwd: this.workspace.workspaceRoot, absolute: true })) {
|
|
21807
|
+
if (avoidDirs.some((dir) => path48.includes(dir)))
|
|
21257
21808
|
continue;
|
|
21258
|
-
const fileContent = await FileSys.readText(
|
|
21809
|
+
const fileContent = await FileSys.readText(path48);
|
|
21259
21810
|
const textFilter = filterText ? new RegExp(filterText) : null;
|
|
21260
21811
|
if (filterText && !textFilter?.test(fileContent))
|
|
21261
21812
|
continue;
|
|
21262
|
-
paths.push(
|
|
21813
|
+
paths.push(path48);
|
|
21263
21814
|
}
|
|
21264
21815
|
return paths;
|
|
21265
21816
|
}
|
|
@@ -21579,7 +22130,7 @@ class LibraryCommand extends command("library", [LibraryScript], ({ public: targ
|
|
|
21579
22130
|
|
|
21580
22131
|
// pkgs/@akanjs/cli/localRegistry/localRegistry.runner.ts
|
|
21581
22132
|
import { mkdir as mkdir13, rm as rm7 } from "fs/promises";
|
|
21582
|
-
import
|
|
22133
|
+
import path48 from "path";
|
|
21583
22134
|
import { Logger as Logger19 } from "akanjs/common";
|
|
21584
22135
|
var defaultLocalRegistryUrl = "http://127.0.0.1:4873";
|
|
21585
22136
|
var containerName = "akan-verdaccio";
|
|
@@ -21597,8 +22148,8 @@ class LocalRegistryRunner extends runner("localRegistry") {
|
|
|
21597
22148
|
Logger19.info(`Local registry is already running at ${registry}`);
|
|
21598
22149
|
return registry;
|
|
21599
22150
|
} catch {}
|
|
21600
|
-
const configPath2 =
|
|
21601
|
-
const storagePath =
|
|
22151
|
+
const configPath2 = path48.join(workspace.workspaceRoot, "pkgs/@akanjs/cli/localRegistry/verdaccio.yaml");
|
|
22152
|
+
const storagePath = path48.join(workspace.workspaceRoot, ".akan/verdaccio/storage");
|
|
21602
22153
|
await mkdir13(storagePath, { recursive: true });
|
|
21603
22154
|
await workspace.spawn("docker", [
|
|
21604
22155
|
"run",
|
|
@@ -21621,13 +22172,13 @@ class LocalRegistryRunner extends runner("localRegistry") {
|
|
|
21621
22172
|
try {
|
|
21622
22173
|
await workspace.spawn("docker", ["rm", "-f", containerName], { stdio: "inherit" });
|
|
21623
22174
|
} catch {}
|
|
21624
|
-
await rm7(
|
|
22175
|
+
await rm7(path48.join(workspace.workspaceRoot, ".akan/verdaccio"), { recursive: true, force: true });
|
|
21625
22176
|
Logger19.info("Local registry storage has been reset");
|
|
21626
22177
|
}
|
|
21627
22178
|
async smoke(workspace, { registryUrl } = {}) {
|
|
21628
22179
|
const registry = this.getRegistryUrl(registryUrl);
|
|
21629
|
-
const smokeRoot =
|
|
21630
|
-
await rm7(
|
|
22180
|
+
const smokeRoot = path48.join(workspace.workspaceRoot, ".akan/e2e");
|
|
22181
|
+
await rm7(path48.join(smokeRoot, smokeRepoName), { recursive: true, force: true });
|
|
21631
22182
|
await workspace.spawn(process.execPath, [
|
|
21632
22183
|
"dist/pkgs/create-akan-workspace/index.js",
|
|
21633
22184
|
smokeRepoName,
|
|
@@ -21644,12 +22195,12 @@ class LocalRegistryRunner extends runner("localRegistry") {
|
|
|
21644
22195
|
stdio: "inherit"
|
|
21645
22196
|
});
|
|
21646
22197
|
await workspace.spawn("akan", ["typecheck", smokeAppName], {
|
|
21647
|
-
cwd:
|
|
22198
|
+
cwd: path48.join(smokeRoot, smokeRepoName),
|
|
21648
22199
|
env: { ...process.env, AKAN_NPM_REGISTRY: registry, NPM_CONFIG_REGISTRY: registry },
|
|
21649
22200
|
stdio: "inherit"
|
|
21650
22201
|
});
|
|
21651
22202
|
await workspace.spawn("akan", ["build", smokeAppName], {
|
|
21652
|
-
cwd:
|
|
22203
|
+
cwd: path48.join(smokeRoot, smokeRepoName),
|
|
21653
22204
|
env: { ...process.env, AKAN_NPM_REGISTRY: registry, NPM_CONFIG_REGISTRY: registry },
|
|
21654
22205
|
stdio: "inherit"
|
|
21655
22206
|
});
|
|
@@ -22005,11 +22556,11 @@ class WorkflowCommand extends command("workflow", [WorkflowScript], ({ public: t
|
|
|
22005
22556
|
}
|
|
22006
22557
|
|
|
22007
22558
|
// pkgs/@akanjs/cli/workspace/workspace.script.ts
|
|
22008
|
-
import
|
|
22559
|
+
import path50 from "path";
|
|
22009
22560
|
import { Logger as Logger26 } from "akanjs/common";
|
|
22010
22561
|
|
|
22011
22562
|
// pkgs/@akanjs/cli/workspace/workspace.runner.ts
|
|
22012
|
-
import
|
|
22563
|
+
import path49 from "path";
|
|
22013
22564
|
var defaultWorkspacePeerDependencies = new Set([
|
|
22014
22565
|
"@react-spring/web",
|
|
22015
22566
|
"@use-gesture/react",
|
|
@@ -22067,7 +22618,7 @@ class WorkspaceRunner extends runner("workspace") {
|
|
|
22067
22618
|
owner = ""
|
|
22068
22619
|
}) {
|
|
22069
22620
|
const cwdPath = process.cwd();
|
|
22070
|
-
const workspaceRoot =
|
|
22621
|
+
const workspaceRoot = path49.join(cwdPath, dirname2, repoName);
|
|
22071
22622
|
const normalizedRegistryUrl = registryUrl ? getNpmRegistryUrl(registryUrl) : undefined;
|
|
22072
22623
|
const workspace = WorkspaceExecutor.fromRoot({ workspaceRoot, repoName });
|
|
22073
22624
|
const templateSpinner = workspace.spinning(`Creating workspace template files in ${dirname2}/${repoName}...`);
|
|
@@ -22123,9 +22674,9 @@ class WorkspaceRunner extends runner("workspace") {
|
|
|
22123
22674
|
}
|
|
22124
22675
|
async#getCliPackageJson() {
|
|
22125
22676
|
const packageJsonCandidates = [
|
|
22126
|
-
|
|
22127
|
-
|
|
22128
|
-
|
|
22677
|
+
path49.join(import.meta.dir, "../package.json"),
|
|
22678
|
+
path49.join(import.meta.dir, "package.json"),
|
|
22679
|
+
path49.join(path49.dirname(Bun.main), "package.json")
|
|
22129
22680
|
];
|
|
22130
22681
|
try {
|
|
22131
22682
|
packageJsonCandidates.unshift(Bun.resolveSync("@akanjs/cli/package.json", import.meta.dir));
|
|
@@ -22141,9 +22692,9 @@ class WorkspaceRunner extends runner("workspace") {
|
|
|
22141
22692
|
}
|
|
22142
22693
|
async#getAkanPackageJson() {
|
|
22143
22694
|
const packageJsonCandidates = [
|
|
22144
|
-
|
|
22145
|
-
|
|
22146
|
-
|
|
22695
|
+
path49.join(import.meta.dir, "../../../akanjs/package.json"),
|
|
22696
|
+
path49.join(process.cwd(), "pkgs/akanjs/package.json"),
|
|
22697
|
+
path49.join(path49.dirname(Bun.main), "node_modules/akanjs/package.json")
|
|
22147
22698
|
];
|
|
22148
22699
|
try {
|
|
22149
22700
|
packageJsonCandidates.unshift(Bun.resolveSync("akanjs/package.json", import.meta.dir));
|
|
@@ -22157,13 +22708,13 @@ class WorkspaceRunner extends runner("workspace") {
|
|
|
22157
22708
|
}
|
|
22158
22709
|
let current = import.meta.dir;
|
|
22159
22710
|
for (let depth = 0;depth < 6; depth++) {
|
|
22160
|
-
const packageJsonPath =
|
|
22711
|
+
const packageJsonPath = path49.join(current, "package.json");
|
|
22161
22712
|
if (await Bun.file(packageJsonPath).exists()) {
|
|
22162
22713
|
const packageJson = await FileSys.readJson(packageJsonPath);
|
|
22163
22714
|
if (packageJson.name === "akanjs")
|
|
22164
22715
|
return packageJson;
|
|
22165
22716
|
}
|
|
22166
|
-
const parent =
|
|
22717
|
+
const parent = path49.dirname(current);
|
|
22167
22718
|
if (parent === current)
|
|
22168
22719
|
break;
|
|
22169
22720
|
current = parent;
|
|
@@ -22240,7 +22791,7 @@ class WorkspaceScript extends script("workspace", [
|
|
|
22240
22791
|
} catch (_) {
|
|
22241
22792
|
gitSpinner.fail("Git repository initialization failed. It's not fatal, you can commit manually");
|
|
22242
22793
|
}
|
|
22243
|
-
const workspacePath2 =
|
|
22794
|
+
const workspacePath2 = path50.join(dirname2, repoName);
|
|
22244
22795
|
Logger26.rawLog(`
|
|
22245
22796
|
\uD83C\uDF89 Welcome aboard! Workspace created in ${dirname2}/${repoName}`);
|
|
22246
22797
|
Logger26.rawLog(`\uD83D\uDE80 Run \`cd ${workspacePath2} && akan start ${appName}\` to start the development server.`);
|