@akanjs/cli 3.0.0-beta.9 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.build-stamp +1 -1
- package/CodeAgent-zfab7pkn.js +9 -0
- package/CodeAgentRpcHost-p7h6n2hp.js +7 -0
- package/CodeAgentRpcListener-7p7z5dd7.js +97 -0
- package/CodeTui-0zhnr0pw.js +1457 -0
- package/README.ko.md +83 -28
- package/README.md +70 -27
- package/TunnelShare-cwh9ezsm.js +9 -0
- package/{agent.command-0q17pnrs.js → agent.command-aja6z9mn.js} +8 -9
- package/akanCode.js +102 -0
- package/application.command-049ehgx3.js +246 -0
- package/{applicationBuildRunner-kxwbssgn.js → applicationBuildRunner-75n5rpwp.js} +121 -77
- package/buildBatch.proc.js +120 -32
- package/cloud.command-gw4kqxt8.js +95 -0
- package/cloud.script-c723cpcb.js +20 -0
- package/code.command-x9t6z5nw.js +154 -0
- package/commandManifest.json +1 -1
- package/consoleToStderr-h5bryj94.js +7 -0
- package/context.command-yfbe1rtd.js +48 -0
- package/context.runner-erfe68j5.js +21 -0
- package/{dependencyScanner-shs82ynp.js → dependencyScanner-06z2dmrr.js} +2 -2
- package/{devTui-m1atgkc9.js → devTui-q7k7bakd.js} +122 -40
- package/fileSys-wzzrntkw.js +9 -0
- package/guideline.command-kq9gp690.js +42 -0
- package/guidelines/agentRule/agentRule.instruction.md +154 -26
- package/guidelines/conventions/conventions.instruction.md +138 -48
- package/guidelines/mcpRule/mcpRule.instruction.md +7 -5
- package/guidelines/queryRule/queryRule.instruction.md +21 -7
- package/guidelines/runtimeRule/runtimeRule.instruction.md +291 -6
- package/guidelines/ssrRule/ssrRule.instruction.md +4 -2
- package/guidelines/transportRule/transportRule.instruction.md +10 -8
- package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +20 -0
- package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +66 -3
- package/incrementalBuilder.proc.js +564 -109
- package/{index-2tv3fdx4.js → index-150s07n8.js} +1230 -1459
- package/{index-vyvre9en.js → index-25fvrxmy.js} +6 -2
- package/{index-kcxmv48c.js → index-2ahj896a.js} +45 -79
- package/index-2wc41k5w.js +49 -0
- package/index-3hx1z96c.js +87 -0
- package/{index-q0y2jq9j.js → index-52w0fvh8.js} +21 -4
- package/{index-04bk599g.js → index-5g4rkrvt.js} +10 -17
- package/index-5pvxf7z0.js +53 -0
- package/index-5q14pwzd.js +69 -0
- package/{index-vxtad5bd.js → index-66yspb67.js} +5 -8
- package/index-7md2g9vw.js +6 -0
- package/index-7p4c0yer.js +1058 -0
- package/{index-d43r08tf.js → index-8b639zes.js} +77 -150
- package/{index-ktb5njgy.js → index-8kvy8qb4.js} +49 -99
- package/index-94s080qm.js +266 -0
- package/index-9dp031by.js +12 -0
- package/{index-0g7r8xz3.js → index-a37by9hn.js} +114 -232
- package/{index-k2j1hc4r.js → index-b95yhqjr.js} +12 -12
- package/{index-3d9y066c.js → index-bjwxs904.js} +9 -8
- package/{index-2xp0kfkt.js → index-br8pkrk1.js} +37 -25
- package/index-c14nsvnv.js +700 -0
- package/index-c6eggbee.js +123 -0
- package/index-d2242ksy.js +99 -0
- package/{index-92zztqy1.js → index-dy0jx9ay.js} +2 -17
- package/{index-a64esmtb.js → index-fkvb79qe.js} +523 -1022
- package/index-h54yj9wr.js +1119 -0
- package/{index-by5gpp8x.js → index-hj6w4ka1.js} +2 -1
- package/{index-y6n8nmny.js → index-kn5d4jmg.js} +75 -203
- package/index-m3xsb1ms.js +4300 -0
- package/{index-gyd220p2.js → index-mb59b8x0.js} +554 -577
- package/{index-j9yhg404.js → index-mzjb6zp4.js} +4 -7
- package/index-p6pbz9n5.js +25 -0
- package/{index-sj5vxr8f.js → index-qe71g4ze.js} +983 -898
- package/index-rfcz04w9.js +187 -0
- package/{index-hwkygn9s.js → index-senscydg.js} +331 -36
- package/{index-ffvk10zz.js → index-vs8mefhy.js} +107 -241
- package/index-wa5jbxj1.js +760 -0
- package/index-y5ga5w9t.js +2729 -0
- package/{index-9077wzd2.js → index-y7hx1ygz.js} +43 -26
- package/{index-h7yw2z9n.js → index-zzvvc845.js} +8 -14
- package/index.js +23 -22
- package/{library.command-qzzbj6d8.js → library.command-keqjevpp.js} +4 -5
- package/{localRegistry.command-vyrgg4xw.js → localRegistry.command-pydeq5zf.js} +23 -43
- package/{module.command-rq5hq3ax.js → module.command-dkrnqx3v.js} +8 -12
- package/{package.command-d9hd6v9n.js → package.command-wmc0ys5y.js} +6 -7
- package/package.json +15 -7
- package/{page.command-126d56te.js → page.command-tf3erhrv.js} +4 -5
- package/{primitive.command-taxd1538.js → primitive.command-7hqpegj4.js} +9 -23
- package/prompter-76k56b37.js +8 -0
- package/{quality.command-6gsna0a3.js → quality.command-8122axq3.js} +205 -377
- package/{recipeScanner-fpagtgc1.js → recipeScanner-4b69ybe0.js} +1 -1
- package/{repair.command-tq2dgy72.js → repair.command-mcy12h0n.js} +11 -35
- package/{routeSourceValidator-apyqw7wk.js → routeSourceValidator-7ycnfz0e.js} +0 -6
- package/{scalar.command-3bcmrrkv.js → scalar.command-vvvbzttc.js} +7 -11
- package/skills/akan-code/SKILL.md +130 -0
- package/skills/akan-debug/SKILL.md +42 -0
- package/skills/akan-deps/SKILL.md +50 -0
- package/skills/akan-err/SKILL.md +39 -0
- package/skills/akan-module/SKILL.md +45 -0
- package/skills/akan-scaffold/SKILL.md +76 -0
- package/skills/akan-scalar/SKILL.md +52 -0
- package/skills/akan-service/SKILL.md +34 -0
- package/skills/akan-store/SKILL.md +67 -0
- package/skills/akan-ui/SKILL.md +63 -0
- package/skills/akan-validate/SKILL.md +44 -0
- package/{subspace.command-eddzqpx3.js → subspace.command-pzvqfy5h.js} +53 -62
- package/templates/__scalar/__model__/__model__.abstract.md.template +8 -0
- package/templates/app/page/_index.tsx +257 -258
- package/templates/app/page/_layout.tsx +5 -1
- package/templates/app/page/_overrides.tsx +12 -0
- package/templates/app/page/styles.css.template +316 -14
- package/templates/app/public/apple-touch-icon.png +0 -0
- package/templates/app/public/favicon.ico +0 -0
- package/templates/app/public/jelly/cloud.webp +0 -0
- package/templates/app/public/jelly/comet.webp +0 -0
- package/templates/app/public/jelly/moon.webp +0 -0
- package/templates/app/public/jelly/planet.webp +0 -0
- package/templates/app/public/jelly/rocket.webp +0 -0
- package/templates/app/public/jelly/star.webp +0 -0
- package/templates/app/public/jelly/sugar.webp +0 -0
- package/templates/app/public/logo.png +0 -0
- package/templates/app/ui/Recipe/index.ts +9 -0
- package/templates/app/ui/Recipe/jellyButton.ts +63 -0
- package/templates/appSample/lib/__scalar/workHistory/workHistory.abstract.ts +8 -39
- package/templates/appSample/lib/_noti/noti.abstract.ts +6 -29
- package/templates/appSample/lib/task/Task.Unit.tsx +1 -1
- package/templates/appSample/lib/task/Task.Util.tsx +10 -13
- package/templates/appSample/lib/task/Task.View.tsx +2 -2
- package/templates/appSample/lib/task/Task.Zone.tsx +5 -2
- package/templates/appSample/lib/task/task.abstract.ts +12 -32
- package/templates/appSample/lib/task/task.signal.spec.ts +1 -15
- package/templates/appSample/lib/task/task.signal.test.ts +15 -1
- package/templates/appSample/lib/task/task.signal.ts +10 -8
- package/templates/appSample/page/task/[taskId]/_index.tsx +6 -6
- package/templates/appSample/page/task/[taskId]/edit.tsx +5 -4
- package/templates/appSample/page/task/_index.tsx +4 -3
- package/templates/appSample/page/task/_layout.tsx +1 -1
- package/templates/appSample/page/task/new.tsx +5 -4
- package/templates/appSample/srvkit/{AuthGuard.ts → guards.ts} +7 -4
- package/templates/appSample/srvkit/{SessionInternalArg.ts → internalArgs.ts} +6 -4
- package/templates/appSample/ui/GlobalLoading.tsx +2 -1
- package/templates/appSample/ui/QuantityControl.tsx +3 -3
- package/templates/client.ts +7 -30
- package/templates/crudPages/[__model__Id]/edit/page.tsx +2 -1
- package/templates/crudPages/[__model__Id]/page.tsx +2 -1
- package/templates/crudPages/new/page.tsx +2 -1
- package/templates/crudPages/page.tsx +2 -1
- package/templates/crudSinglePage/page.tsx +2 -1
- package/templates/lib/__lib/lib.dictionary.ts +0 -2
- package/templates/lib/__lib/lib.document.ts +0 -2
- package/templates/lib/sig.ts +8 -30
- package/templates/localDev/docker-compose.yaml.template +3 -14
- package/templates/module/__model__.signal.ts +12 -4
- package/templates/pkgRoot/tsconfig.json.template +2 -7
- package/templates/server.ts +1 -3
- package/templates/service/__model__.abstract.md.template +8 -0
- package/templates/workspaceRoot/.gitignore.template +0 -1
- package/templates/workspaceRoot/AGENTS.md.template +6 -0
- package/templates/workspaceRoot/package.json.template +1 -3
- package/tunnel.command-82zz5xnq.js +129 -0
- package/{typeChecker-3xgrzc2v.js → typeChecker-px49mezc.js} +1 -1
- package/typecheck.proc.js +1 -1
- package/workflow.command-y8x3kgjv.js +79 -0
- package/{workspace.command-06wvstgr.js → workspace.command-jvsb7brc.js} +79 -109
- package/abstractCompactor-gmkc0z8j.js +0 -102
- package/application.command-18y0s485.js +0 -204
- package/applicationReleasePackager-4yasxwv9.js +0 -244
- package/capacitorApp-36rbr858.js +0 -12
- package/cloud.command-av97ndh6.js +0 -94
- package/cloud.script-cm11xjdz.js +0 -20
- package/context.command-5v37ef3n.js +0 -81
- package/devTuiView-0hc2emhe.js +0 -9
- package/getDirname-dr3jz1xg.js +0 -7
- package/guideline.command-4pz9g1rt.js +0 -360
- package/guidelines/agentRule/agentRule.generate.json +0 -31
- package/guidelines/componentRule/componentRule.generate.json +0 -31
- package/guidelines/conventions/conventions.generate.json +0 -25
- package/guidelines/cssRule/cssRule.generate.json +0 -31
- package/guidelines/docPageRule/docPageRule.generate.json +0 -31
- package/guidelines/docPageRule/docPageRule.instruction.md +0 -25
- package/guidelines/docSyncRule/docSyncRule.generate.json +0 -31
- package/guidelines/docSyncRule/docSyncRule.instruction.md +0 -25
- package/guidelines/enumConstant/enumConstant.generate.json +0 -31
- package/guidelines/enumConstant/enumConstant.instruction.md +0 -28
- package/guidelines/fieldRule/fieldRule.generate.json +0 -31
- package/guidelines/framework/framework.generate.json +0 -32
- package/guidelines/mcpRule/mcpRule.generate.json +0 -35
- package/guidelines/modelConstant/modelConstant.generate.json +0 -32
- package/guidelines/modelDictionary/modelDictionary.generate.json +0 -32
- package/guidelines/modelDocument/modelDocument.generate.json +0 -31
- package/guidelines/modelService/modelService.generate.json +0 -31
- package/guidelines/modelSignal/modelSignal.generate.json +0 -31
- package/guidelines/modelStore/modelStore.generate.json +0 -31
- package/guidelines/modelTemplate/modelTemplate.generate.json +0 -31
- package/guidelines/modelUnit/modelUnit.generate.json +0 -31
- package/guidelines/modelUtil/modelUtil.generate.json +0 -31
- package/guidelines/modelView/modelView.generate.json +0 -31
- package/guidelines/modelZone/modelZone.generate.json +0 -31
- package/guidelines/moduleCodegen/moduleCodegen.generate.json +0 -31
- package/guidelines/moduleCodegen/moduleCodegen.instruction.md +0 -28
- package/guidelines/moduleOverview/moduleOverview.generate.json +0 -31
- package/guidelines/queryRule/queryRule.generate.json +0 -31
- package/guidelines/recipeRule/recipeRule.generate.json +0 -31
- package/guidelines/runtimeRule/runtimeRule.generate.json +0 -25
- package/guidelines/scalarConstant/scalarConstant.generate.json +0 -32
- package/guidelines/scalarDictionary/scalarDictionary.generate.json +0 -32
- package/guidelines/scalarModule/scalarModule.generate.json +0 -31
- package/guidelines/sharedUiUsage/sharedUiUsage.generate.json +0 -31
- package/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +0 -25
- package/guidelines/ssrRule/ssrRule.generate.json +0 -31
- package/guidelines/transportRule/transportRule.generate.json +0 -31
- package/guidelines/utilUiUsage/utilUiUsage.generate.json +0 -31
- package/guidelines/utilUiUsage/utilUiUsage.instruction.md +0 -25
- package/guidelines/workspaceOnboarding/workspaceOnboarding.generate.json +0 -24
- package/guidelines/workspaceRecipes/workspaceRecipes.generate.json +0 -33
- package/index-47pj3aee.js +0 -76
- package/index-5ystnsd5.js +0 -841
- package/index-6wwzs1bc.js +0 -7
- package/index-a17x49vg.js +0 -229
- package/index-m0xccmmm.js +0 -228
- package/index-meh558jy.js +0 -65
- package/index-rtxxan88.js +0 -471
- package/index-te54x9zm.js +0 -338
- package/index-w8kmx1b6.js +0 -2176
- package/index-wt7qrtd4.js +0 -1516
- package/templates/__scalar/__model__/__model__.abstract.md +0 -28
- package/templates/module/__model__.abstract.md +0 -28
- package/templates/service/__model__.abstract.md +0 -28
- package/templates/workspaceRoot/patches/react-dom@19.2.7.patch.template +0 -62
- package/workflow.command-gtdnzvbz.js +0 -108
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
App,
|
|
4
|
+
Apps,
|
|
5
|
+
Sys,
|
|
6
|
+
Exec,
|
|
7
|
+
Workspace,
|
|
8
|
+
command
|
|
9
|
+
} from "./index-a37by9hn.js";
|
|
10
|
+
import"./index-52w0fvh8.js";
|
|
11
|
+
import"./index-150s07n8.js";
|
|
12
|
+
import {
|
|
13
|
+
getMobileTargetChoices
|
|
14
|
+
} from "./index-7p4c0yer.js";
|
|
15
|
+
import"./index-senscydg.js";
|
|
16
|
+
import"./index-66yspb67.js";
|
|
17
|
+
import {
|
|
18
|
+
ApplicationScript
|
|
19
|
+
} from "./index-qe71g4ze.js";
|
|
20
|
+
import"./index-7md2g9vw.js";
|
|
21
|
+
import"./index-mzjb6zp4.js";
|
|
22
|
+
|
|
23
|
+
// pkgs/@akanjs/cli/application/application.command.ts
|
|
24
|
+
var mobileTargetOption = {
|
|
25
|
+
desc: "native target name (a key of native.targets) or all",
|
|
26
|
+
ask: "Select native target",
|
|
27
|
+
enum: async ({ app }) => await getMobileTargetChoices(app)
|
|
28
|
+
};
|
|
29
|
+
var deviceOption = {
|
|
30
|
+
desc: "simulator, emulator or device to run on: its id or name (e.g. 'iPhone 17' or 'Pixel_10')",
|
|
31
|
+
default: ""
|
|
32
|
+
};
|
|
33
|
+
var teamOption = { flag: "T", desc: "Apple team id the signing is narrowed to", default: "" };
|
|
34
|
+
var devEnvs = ["local", "debug", "develop", "main"];
|
|
35
|
+
var buildEnvOption = { enum: devEnvs, desc: "backend environment", default: "debug" };
|
|
36
|
+
var startEnvOption = {
|
|
37
|
+
enum: devEnvs,
|
|
38
|
+
desc: "backend environment of a --release build; a dev build follows `akan start`, which keeps its own",
|
|
39
|
+
default: "local"
|
|
40
|
+
};
|
|
41
|
+
var releaseEnvOption = {
|
|
42
|
+
enum: ["debug", "develop", "main", "local"],
|
|
43
|
+
desc: "backend environment",
|
|
44
|
+
default: "main"
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
class ApplicationCommand extends command("application", [ApplicationScript], ({ public: target }) => ({
|
|
48
|
+
createApplication: target({ desc: "Create a new application in the workspace" }).arg("appName", String, { desc: "name of application" }).option("start", Boolean, { desc: "start application", default: false }).with(Workspace).exec(async function(appName, start, workspace) {
|
|
49
|
+
await this.applicationScript.createApplication(appName.toLowerCase().replace(/ /g, "-"), workspace, { start });
|
|
50
|
+
}),
|
|
51
|
+
removeApplication: target({ desc: "Remove an application from the workspace" }).with(App).exec(async function(app) {
|
|
52
|
+
await this.applicationScript.removeApplication(app);
|
|
53
|
+
}),
|
|
54
|
+
planSlice: target({ desc: "List the exact files an app needs to live in a workspace of its own" }).with(App).option("format", String, { desc: "output format", default: "text", enum: ["text", "json"] }).exec(async function(app, format) {
|
|
55
|
+
await this.applicationScript.planSlice(app, format);
|
|
56
|
+
}),
|
|
57
|
+
sync: target({ desc: "Sync dependencies and configuration for an app or library" }).with(Sys).exec(async function(sys) {
|
|
58
|
+
await this.applicationScript.sync(sys);
|
|
59
|
+
}),
|
|
60
|
+
script: target({ desc: "Run a custom script in the application" }).with(App).arg("filename", String, { desc: "name of script", nullable: true }).exec(async function(app, filename) {
|
|
61
|
+
await this.applicationScript.script(app, filename);
|
|
62
|
+
}),
|
|
63
|
+
console: target({ desc: "Open an interactive server console for the application" }).with(App).exec(async function(app) {
|
|
64
|
+
await this.applicationScript.console(app);
|
|
65
|
+
}),
|
|
66
|
+
logs: target({ desc: "Tail the running application's logs, filtered (attaches to akan-control.sock)" }).with(App).option("level", String, { desc: "minimum level: trace, verbose, debug, info, warn, error", nullable: true }).option("grep", String, { desc: "substring the message must contain", nullable: true }).option("endpoint", String, {
|
|
67
|
+
desc: "endpoint glob(s), comma-separated: mutation:*, query:userList",
|
|
68
|
+
nullable: true
|
|
69
|
+
}).option("trace", String, { desc: "one request's traceId", nullable: true }).option("child", String, { desc: "replica index(es), comma-separated", nullable: true }).option("role", String, {
|
|
70
|
+
flag: "R",
|
|
71
|
+
desc: "process role(s): gateway, federation, batch, all, rsc-worker",
|
|
72
|
+
nullable: true
|
|
73
|
+
}).option("origin", String, { desc: "call origin(s): http, websocket, mcp, internal, page", nullable: true }).option("since", String, {
|
|
74
|
+
desc: "only records newer than this: a duration ago in ms, s, m, h or d (30s, 5m, 2h), or an epoch-ms timestamp",
|
|
75
|
+
nullable: true
|
|
76
|
+
}).option("replay", Number, { flag: "n", desc: "records to replay from the buffer before following", default: 0 }).option("json", Boolean, { desc: "print NDJSON records instead of rendered lines", default: false }).option("follow", Boolean, { desc: "keep streaming; pass --follow false for history only", default: true }).option("runtimeDir", String, {
|
|
77
|
+
flag: "d",
|
|
78
|
+
desc: "runtime dir holding akan-control.sock (default: local/apps/<app>/runtime)",
|
|
79
|
+
nullable: true
|
|
80
|
+
}).exec(async function(app, level, grep, endpoint, trace, child, role, origin, since, replay, json, follow, runtimeDir) {
|
|
81
|
+
await this.applicationScript.logs(app, {
|
|
82
|
+
level,
|
|
83
|
+
grep,
|
|
84
|
+
endpoint,
|
|
85
|
+
trace,
|
|
86
|
+
child,
|
|
87
|
+
role,
|
|
88
|
+
origin,
|
|
89
|
+
since,
|
|
90
|
+
replay,
|
|
91
|
+
json,
|
|
92
|
+
follow,
|
|
93
|
+
runtimeDir
|
|
94
|
+
});
|
|
95
|
+
}),
|
|
96
|
+
build: target({ short: true, desc: "Build the application for production (frontend + backend)" }).with(App).option("write", Boolean, { desc: "write code generation", default: true }).option("fast", Boolean, { desc: "fast build", default: false }).option("quiet", Boolean, { desc: "hide build progress output", default: false }).exec(async function(app, write, fast, quiet) {
|
|
97
|
+
await this.applicationScript.build(app, { write, fast, quiet });
|
|
98
|
+
}),
|
|
99
|
+
typecheck: target({ short: true, desc: "Typecheck the application" }).with(App).option("write", Boolean, { desc: "write code generation", default: true }).option("clean", Boolean, { desc: "clear typecheck cache before running", default: false }).option("incremental", Boolean, { desc: "reuse TypeScript incremental cache", default: true }).exec(async function(app, write, clean, incremental) {
|
|
100
|
+
await this.applicationScript.typecheck(app, { write, clean, incremental });
|
|
101
|
+
}),
|
|
102
|
+
test: target({ desc: "Prepare and test an app, library, or package" }).with(Exec).option("write", Boolean, { desc: "write code generation", default: true }).exec(async function(exec, write) {
|
|
103
|
+
await this.applicationScript.test(exec, { write });
|
|
104
|
+
}),
|
|
105
|
+
buildIos: target({ short: true, desc: "Build the iOS app on the native runtime" }).with(App).option("target", String, mobileTargetOption).option("env", String, buildEnvOption).option("debug", Boolean, { desc: "debug build instead of release", default: false }).option("write", Boolean, { desc: "write code generation", default: true }).exec(async function(app, target, env, debug, write) {
|
|
106
|
+
await this.applicationScript.buildIos(app, { target, env, profile: debug ? "debug" : "release", write });
|
|
107
|
+
}),
|
|
108
|
+
buildAndroid: target({ short: true, desc: "Build the Android app (apk) on the native runtime" }).with(App).option("target", String, mobileTargetOption).option("env", String, buildEnvOption).option("debug", Boolean, { desc: "debug build instead of release", default: false }).option("write", Boolean, { desc: "write code generation", default: true }).exec(async function(app, target, env, debug, write) {
|
|
109
|
+
await this.applicationScript.buildAndroid(app, { target, env, profile: debug ? "debug" : "release", write });
|
|
110
|
+
}),
|
|
111
|
+
buildDesktop: target({ short: true, desc: "Build the desktop app for this computer (macOS, Windows or Linux)" }).with(App).option("target", String, mobileTargetOption).option("env", String, buildEnvOption).option("debug", Boolean, { desc: "debug build instead of release", default: false }).option("installer", Boolean, {
|
|
112
|
+
desc: "also what a person downloads: a Windows setup program (NSIS, /S for silent), a macOS dmg, a Linux AppImage",
|
|
113
|
+
default: false
|
|
114
|
+
}).option("arch", String, {
|
|
115
|
+
desc: "the CPU the app runs on, arm64 or x64 of this OS (default this computer's); a macOS app is arm64 only",
|
|
116
|
+
enum: ["arm64", "x64"],
|
|
117
|
+
nullable: true
|
|
118
|
+
}).option("write", Boolean, { desc: "write code generation", default: true }).exec(async function(app, target, env, debug, installer, arch, write) {
|
|
119
|
+
await this.applicationScript.buildDesktop(app, {
|
|
120
|
+
target,
|
|
121
|
+
env,
|
|
122
|
+
profile: debug ? "debug" : "release",
|
|
123
|
+
installer,
|
|
124
|
+
write,
|
|
125
|
+
...arch ? { arch } : {}
|
|
126
|
+
});
|
|
127
|
+
}),
|
|
128
|
+
start: target({ short: true, desc: "Start development server(s) (frontend SSR + backend)" }).with(Apps).option("plain", Boolean, { desc: "print prefixed lines instead of the full-screen view", default: false }).option("kill", Boolean, { flag: "k", desc: "free the dev ports first, whoever is holding them", default: false }).option("concurrency", Number, {
|
|
129
|
+
desc: "apps to boot at a time (default: what this machine's memory and cores allow)",
|
|
130
|
+
nullable: true
|
|
131
|
+
}).option("dbup", Boolean, { desc: "start the local database first", default: true }).option("open", Boolean, { desc: "open web browser?", default: false }).option("share", Boolean, { desc: "also share each app on a public URL through an akan tunnel", default: false }).option("write", Boolean, { desc: "write code generation", default: true }).exec(async function(apps, plain, kill, concurrency, dbup, open, share, write) {
|
|
132
|
+
await this.applicationScript.start(apps, { plain, kill, concurrency, dbup, open, share, write });
|
|
133
|
+
}),
|
|
134
|
+
startIos: target({ short: true, desc: "Run the iOS app in a simulator or on an iPhone, following `akan start`" }).with(App).option("target", String, mobileTargetOption).option("env", String, startEnvOption).option("release", Boolean, { desc: "run a release build of its own bundle instead", default: false }).option("device", String, deviceOption).option("team", String, teamOption).option("write", Boolean, { desc: "write code generation", default: true }).exec(async function(app, target, env, release, device, team, write) {
|
|
135
|
+
await this.applicationScript.startIos(app, {
|
|
136
|
+
target,
|
|
137
|
+
env,
|
|
138
|
+
operation: release ? "release" : "local",
|
|
139
|
+
device: device || undefined,
|
|
140
|
+
teamId: team || undefined,
|
|
141
|
+
write
|
|
142
|
+
});
|
|
143
|
+
}),
|
|
144
|
+
startAndroid: target({
|
|
145
|
+
short: true,
|
|
146
|
+
desc: "Run the Android app in an emulator or on a device, following `akan start`"
|
|
147
|
+
}).with(App).option("target", String, mobileTargetOption).option("env", String, startEnvOption).option("release", Boolean, { desc: "run a release build of its own bundle instead", default: false }).option("device", String, deviceOption).option("write", Boolean, { desc: "write code generation", default: true }).exec(async function(app, target, env, release, device, write) {
|
|
148
|
+
await this.applicationScript.startAndroid(app, {
|
|
149
|
+
target,
|
|
150
|
+
env,
|
|
151
|
+
operation: release ? "release" : "local",
|
|
152
|
+
device: device || undefined,
|
|
153
|
+
write
|
|
154
|
+
});
|
|
155
|
+
}),
|
|
156
|
+
startDesktop: target({
|
|
157
|
+
short: true,
|
|
158
|
+
desc: "Run the desktop app on this computer (macOS, Windows or Linux), following `akan start`"
|
|
159
|
+
}).with(App).option("target", String, mobileTargetOption).option("env", String, startEnvOption).option("release", Boolean, { desc: "run a release build of its own bundle instead", default: false }).option("write", Boolean, { desc: "write code generation", default: true }).exec(async function(app, target, env, release, write) {
|
|
160
|
+
await this.applicationScript.startDesktop(app, {
|
|
161
|
+
target,
|
|
162
|
+
env,
|
|
163
|
+
operation: release ? "release" : "local",
|
|
164
|
+
write
|
|
165
|
+
});
|
|
166
|
+
}),
|
|
167
|
+
releaseIos: target({ desc: "Build and sign the iOS app for the App Store (.ipa)" }).with(App).option("target", String, mobileTargetOption).option("env", String, releaseEnvOption).option("team", String, teamOption).option("adHoc", Boolean, { desc: "sign with an ad-hoc profile instead of app-store", default: false }).option("write", Boolean, { desc: "write code generation", default: true }).option("allowLocalRelease", Boolean, { flag: "l", desc: "allow release with --env local", default: false }).exec(async function(app, target, env, team, adHoc, write, allowLocalRelease) {
|
|
168
|
+
await this.applicationScript.releaseIos(app, {
|
|
169
|
+
target,
|
|
170
|
+
env,
|
|
171
|
+
teamId: team || undefined,
|
|
172
|
+
adHoc,
|
|
173
|
+
write,
|
|
174
|
+
allowLocalRelease
|
|
175
|
+
});
|
|
176
|
+
}),
|
|
177
|
+
releaseAndroid: target({ desc: "Build and sign the Android app for the Play Store (aab, or apk)" }).with(App).option("assembleType", String, { enum: ["aab", "apk"], default: "aab" }).option("target", String, mobileTargetOption).option("env", String, releaseEnvOption).option("write", Boolean, { desc: "write code generation", default: true }).option("allowLocalRelease", Boolean, { flag: "l", desc: "allow release with --env local", default: false }).exec(async function(app, assembleType, target, env, write, allowLocalRelease) {
|
|
178
|
+
await this.applicationScript.releaseAndroid(app, assembleType, {
|
|
179
|
+
target,
|
|
180
|
+
env,
|
|
181
|
+
write,
|
|
182
|
+
allowLocalRelease
|
|
183
|
+
});
|
|
184
|
+
}),
|
|
185
|
+
packUpdate: target({
|
|
186
|
+
desc: "Pack an unsigned over-the-air update of the mobile web bundle, for the signer to publish"
|
|
187
|
+
}).with(App).option("platform", String, { enum: ["ios", "android"], desc: "the app it updates" }).option("target", String, mobileTargetOption).option("env", String, releaseEnvOption).option("out", String, {
|
|
188
|
+
desc: "output folder (default: .akan/native/<target>/updates/<platform>)",
|
|
189
|
+
nullable: true
|
|
190
|
+
}).option("against", String, {
|
|
191
|
+
desc: "bundle.json of the store build it must run in; fails when it needs a new one",
|
|
192
|
+
nullable: true
|
|
193
|
+
}).option("write", Boolean, { desc: "write code generation", default: true }).option("allowLocalRelease", Boolean, { flag: "l", desc: "allow packing with --env local", default: false }).exec(async function(app, platform, target, env, out, against, write, allowLocalRelease) {
|
|
194
|
+
await this.applicationScript.packUpdate(app, platform, {
|
|
195
|
+
target,
|
|
196
|
+
env,
|
|
197
|
+
out: out ?? undefined,
|
|
198
|
+
against: against ?? undefined,
|
|
199
|
+
write,
|
|
200
|
+
allowLocalRelease
|
|
201
|
+
});
|
|
202
|
+
}),
|
|
203
|
+
updateKeygen: target({ desc: "Make (once) the key an app's update releases are signed with; print its public key" }).with(App).option("platform", String, {
|
|
204
|
+
enum: ["desktop", "android", "ios"],
|
|
205
|
+
default: "desktop",
|
|
206
|
+
desc: "the platform whose app id the key signs for (an appId may differ per platform)"
|
|
207
|
+
}).option("target", String, mobileTargetOption).exec(async function(app, platform, target) {
|
|
208
|
+
await this.applicationScript.updateKeygen(app, platform, { target });
|
|
209
|
+
}),
|
|
210
|
+
publishUpdate: target({ desc: "Build and sign an update release installed apps take (desktop, android or ios)" }).with(App).option("platform", String, {
|
|
211
|
+
enum: ["desktop", "android", "ios"],
|
|
212
|
+
default: "desktop",
|
|
213
|
+
desc: "desktop is this computer's OS and CPU; android and ios publish the web bundle"
|
|
214
|
+
}).option("target", String, mobileTargetOption).option("env", String, releaseEnvOption).option("channel", String, {
|
|
215
|
+
desc: "the manifest to publish to (default: the target's updates.channel, else --env)",
|
|
216
|
+
nullable: true
|
|
217
|
+
}).option("write", Boolean, { desc: "write code generation", default: true }).option("allowLocalRelease", Boolean, { flag: "l", desc: "allow release with --env local", default: false }).exec(async function(app, platform, target, env, channel, write, allowLocalRelease) {
|
|
218
|
+
await this.applicationScript.publishUpdate(app, platform, {
|
|
219
|
+
target,
|
|
220
|
+
env,
|
|
221
|
+
...channel ? { channel } : {},
|
|
222
|
+
write,
|
|
223
|
+
allowLocalRelease
|
|
224
|
+
});
|
|
225
|
+
}),
|
|
226
|
+
dbup: target({ desc: "Start local database services for a database mode" }).with(Workspace).option("mode", String, {
|
|
227
|
+
desc: "database mode; left out, every mode the workspace's apps declare",
|
|
228
|
+
enum: ["single", "multiple", "cluster"],
|
|
229
|
+
nullable: true
|
|
230
|
+
}).exec(async function(workspace, mode) {
|
|
231
|
+
await this.applicationScript.dbupDeclared(workspace, mode);
|
|
232
|
+
}),
|
|
233
|
+
dbExport: target({ desc: "Write every model table of an app to one NDJSON file each" }).with(App).option("dir", String, { desc: "directory under the workspace to write", default: "local/transfer" }).exec(async function(app, dir) {
|
|
234
|
+
await this.applicationScript.transferDatabase(app, "export", dir);
|
|
235
|
+
}),
|
|
236
|
+
dbImport: target({ desc: "Read files db-export wrote into an app's database, in the mode the shell names" }).with(App).option("dir", String, { desc: "directory under the workspace to read", default: "local/transfer" }).exec(async function(app, dir) {
|
|
237
|
+
await this.applicationScript.transferDatabase(app, "import", dir);
|
|
238
|
+
}),
|
|
239
|
+
dbdown: target({ desc: "Stop local database services" }).with(Workspace).exec(async function(workspace) {
|
|
240
|
+
await this.applicationScript.dbdown(workspace);
|
|
241
|
+
})
|
|
242
|
+
})) {
|
|
243
|
+
}
|
|
244
|
+
export {
|
|
245
|
+
ApplicationCommand
|
|
246
|
+
};
|
|
@@ -1,22 +1,55 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
Spinner
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-150s07n8.js";
|
|
5
|
+
import"./index-m3xsb1ms.js";
|
|
5
6
|
import {
|
|
6
7
|
AllRoutesBuilder,
|
|
7
8
|
CsrArtifactBuilder,
|
|
8
9
|
FontPruner,
|
|
9
10
|
precompressArtifacts,
|
|
10
11
|
SsrBaseArtifactBuilder
|
|
11
|
-
} from "./index-
|
|
12
|
-
import"./index-
|
|
13
|
-
import"./index-q0y2jq9j.js";
|
|
14
|
-
import"./index-hwkygn9s.js";
|
|
12
|
+
} from "./index-fkvb79qe.js";
|
|
13
|
+
import"./index-52w0fvh8.js";
|
|
15
14
|
import"./index-n68jx79w.js";
|
|
16
15
|
|
|
17
16
|
// pkgs/@akanjs/devkit/applicationBuildRunner.ts
|
|
18
17
|
import { mkdir, rm } from "fs/promises";
|
|
18
|
+
import path2 from "path";
|
|
19
|
+
|
|
20
|
+
// pkgs/@akanjs/devkit/transforms/serverEnvPlugin.ts
|
|
21
|
+
import { existsSync, realpathSync } from "fs";
|
|
19
22
|
import path from "path";
|
|
23
|
+
var escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
24
|
+
var createServerEnvPlugin = ({ envDir, environment, environments }) => {
|
|
25
|
+
const others = [...new Set(environments)].filter((name) => name !== environment);
|
|
26
|
+
const dirs = new Set([path.resolve(envDir), existsSync(envDir) ? realpathSync.native(envDir) : envDir]);
|
|
27
|
+
const names = others.map(escapeRegExp).join("|");
|
|
28
|
+
const filter = new RegExp(`^(?:${[...dirs].map(escapeRegExp).join("|")})[\\\\/]env\\.server\\.(?:${names})\\.ts$`);
|
|
29
|
+
return {
|
|
30
|
+
name: "akan-server-env",
|
|
31
|
+
setup(build) {
|
|
32
|
+
if (!others.length)
|
|
33
|
+
return;
|
|
34
|
+
build.onLoad({ filter }, async (args) => {
|
|
35
|
+
const name = path.basename(args.path, ".ts").slice("env.server.".length);
|
|
36
|
+
const { exports } = new Bun.Transpiler({ loader: "ts" }).scan(await Bun.file(args.path).text());
|
|
37
|
+
const message = `env/env.server.${name}.ts is not in this build: \`akan build\` bundles the server env of AKAN_PUBLIC_ENV=${environment} alone, the environment its image runs. To run ${name}, build for it: AKAN_PUBLIC_ENV=${name} in the workspace's .env, which outranks the shell, or --env ${name} on a desktop or mobile build.`;
|
|
38
|
+
return {
|
|
39
|
+
loader: "js",
|
|
40
|
+
contents: [
|
|
41
|
+
`const refuse = () => { throw new Error(${JSON.stringify(message)}); };`,
|
|
42
|
+
"const unbuilt = new Proxy({}, { get: refuse, has: refuse, ownKeys: refuse, getOwnPropertyDescriptor: refuse });",
|
|
43
|
+
`export { ${exports.map((exported) => `unbuilt as ${JSON.stringify(exported)}`).join(", ")} };`
|
|
44
|
+
].join(`
|
|
45
|
+
`)
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// pkgs/@akanjs/devkit/applicationBuildRunner.ts
|
|
20
53
|
var BUILD_PHASE_EMOJIS = {
|
|
21
54
|
prepare: "\uD83E\uDDF9",
|
|
22
55
|
typecheck: "\uD83D\uDD0E",
|
|
@@ -51,54 +84,52 @@ class ApplicationBuildRunner {
|
|
|
51
84
|
#app;
|
|
52
85
|
#fast;
|
|
53
86
|
#reporter;
|
|
87
|
+
#environment;
|
|
88
|
+
#spinner;
|
|
54
89
|
#startedAt = Date.now();
|
|
55
90
|
#phases = [];
|
|
56
|
-
constructor(app, { fast = false, reporter } = {}) {
|
|
91
|
+
constructor(app, { fast = false, reporter, environment } = {}) {
|
|
57
92
|
this.#app = app;
|
|
58
93
|
this.#fast = fast;
|
|
59
94
|
this.#reporter = reporter;
|
|
95
|
+
this.#environment = environment;
|
|
60
96
|
}
|
|
61
97
|
async build({ spinner = false } = {}) {
|
|
62
|
-
|
|
98
|
+
this.#spinner = spinner;
|
|
63
99
|
const { web, assets } = await this.#app.getConfig();
|
|
64
|
-
await this.#runPhase("prepare", "Preparing output directory", () => this.#app.prepareCommand("build")
|
|
65
|
-
spinner
|
|
66
|
-
});
|
|
100
|
+
await this.#runPhase("prepare", "Preparing output directory", () => this.#app.prepareCommand("build"));
|
|
67
101
|
if (!this.#fast)
|
|
68
|
-
await this.#runPhase("typecheck", "Typechecking", () => this.typecheck()
|
|
69
|
-
await this.#runPhase("backend", "Compiling backend", () => this.#buildBackend(), (result) => `${result.entrypoints} entrypoints, ${result.outputs} outputs
|
|
70
|
-
await this.#runPhase("ssr", "Building SSR route artifacts", async () => web.ssr ? await this.#buildSsr() : null, (result) => result ? `${result.allRoutes.manifest.routeIds.length} routes, ${result.allRoutes.manifest.knownEntries.length} entries` : web.ssr ? "skipped" : "disabled by akan.config.ts web.ssr"
|
|
71
|
-
await this.#runPhase("csr", "Building CSR assets", async () => web.csr ? await this.#
|
|
72
|
-
await this.#runPhase("assets", "Trimming unread static assets", async () => assets.pruneFonts ? await new FontPruner(this.#app, assets).prune() : null, (result) => result ? `${result.removed.length} font file(s) dropped, ${ApplicationBuildRunner.formatBytes(result.freedBytes)} freed; ${result.kept.length} kept` : "disabled by akan.config.ts assets.pruneFonts"
|
|
73
|
-
await this.#runPhase("compress", "Compressing static assets", () => precompressArtifacts(this.#app), (result) => result.files > 0 ? `${result.files} files, ${ApplicationBuildRunner.formatBytes(result.inputBytes)} -> gzip ${ApplicationBuildRunner.formatBytes(result.outputBytes)} / br ${ApplicationBuildRunner.formatBytes(result.brotliBytes)}` : "no files"
|
|
74
|
-
await this.#runPhase("metadata", "Writing production metadata", () => this
|
|
75
|
-
spinner
|
|
76
|
-
});
|
|
102
|
+
await this.#runPhase("typecheck", "Typechecking", () => this.typecheck());
|
|
103
|
+
await this.#runPhase("backend", "Compiling backend", () => this.#buildBackend(), (result) => `${result.entrypoints} entrypoints, ${result.outputs} outputs`);
|
|
104
|
+
await this.#runPhase("ssr", "Building SSR route artifacts", async () => web.ssr ? await this.#buildSsr() : null, (result) => result ? `${result.allRoutes.manifest.routeIds.length} routes, ${result.allRoutes.manifest.knownEntries.length} entries` : web.ssr ? "skipped" : "disabled by akan.config.ts web.ssr");
|
|
105
|
+
await this.#runPhase("csr", "Building CSR assets", async () => web.csr ? await new CsrArtifactBuilder(this.#app, "build").build() : null, (result) => result?.outputDir ?? (web.csr ? "skipped" : "disabled by akan.config.ts web.csr"));
|
|
106
|
+
await this.#runPhase("assets", "Trimming unread static assets", async () => assets.pruneFonts ? await new FontPruner(this.#app, assets).prune() : null, (result) => result ? `${result.removed.length} font file(s) dropped, ${ApplicationBuildRunner.formatBytes(result.freedBytes)} freed; ${result.kept.length} kept` : "disabled by akan.config.ts assets.pruneFonts");
|
|
107
|
+
await this.#runPhase("compress", "Compressing static assets", () => precompressArtifacts(this.#app), (result) => result.files > 0 ? `${result.files} files, ${ApplicationBuildRunner.formatBytes(result.inputBytes)} -> gzip ${ApplicationBuildRunner.formatBytes(result.outputBytes)} / br ${ApplicationBuildRunner.formatBytes(result.brotliBytes)}` : "no files");
|
|
108
|
+
await this.#runPhase("metadata", "Writing production metadata", () => this.buildAppMeta());
|
|
77
109
|
return {
|
|
78
110
|
phases: this.#phases,
|
|
79
111
|
durationMs: Date.now() - this.#startedAt,
|
|
80
112
|
outputDir: this.#app.dist.cwdPath,
|
|
81
|
-
artifactDir:
|
|
113
|
+
artifactDir: path2.join(this.#app.dist.cwdPath, ".akan/artifact")
|
|
82
114
|
};
|
|
83
115
|
}
|
|
84
116
|
async typecheck(options = {}) {
|
|
85
117
|
const { clean = false, incremental = true } = options;
|
|
86
118
|
await this.#app.getPageKeys({ refresh: true });
|
|
87
|
-
const { typecheckDir, tsconfigPath } = await this.#writeTypecheckTsconfig(
|
|
119
|
+
const { typecheckDir, tsconfigPath } = await this.#writeTypecheckTsconfig(incremental);
|
|
88
120
|
if (clean)
|
|
89
|
-
await rm(
|
|
121
|
+
await rm(path2.join(typecheckDir, "tsconfig.tsbuildinfo"), { force: true });
|
|
90
122
|
await this.#checkProjectInChildProcess(tsconfigPath);
|
|
91
123
|
}
|
|
92
|
-
async#runPhase(id, label, task, summarize
|
|
124
|
+
async#runPhase(id, label, task, summarize) {
|
|
93
125
|
this.#reporter?.phaseStart?.({ id, label });
|
|
94
126
|
const phaseStartedAt = Date.now();
|
|
95
|
-
const spinner =
|
|
127
|
+
const spinner = this.#spinner ? new Spinner(label, { prefix: `${BUILD_PHASE_EMOJIS[id]} ${id}` }).start() : undefined;
|
|
96
128
|
try {
|
|
97
129
|
const result = await task();
|
|
98
130
|
const phase = { id, label, durationMs: Date.now() - phaseStartedAt, summary: summarize?.(result) };
|
|
99
131
|
this.#phases.push(phase);
|
|
100
|
-
|
|
101
|
-
spinner?.succeed(`${label}${summary}`);
|
|
132
|
+
spinner?.succeed(`${label}${phase.summary ? `: ${phase.summary}` : ""}`);
|
|
102
133
|
this.#reporter?.phaseDone?.(phase);
|
|
103
134
|
return result;
|
|
104
135
|
} catch (error) {
|
|
@@ -107,63 +138,85 @@ class ApplicationBuildRunner {
|
|
|
107
138
|
throw error;
|
|
108
139
|
}
|
|
109
140
|
}
|
|
110
|
-
async
|
|
141
|
+
async buildAppMeta() {
|
|
111
142
|
const akanConfig = await this.#app.getConfig();
|
|
143
|
+
const dockerfile = akanConfig.dockerfileFor(this.#environment ?? akanConfig.baseDevEnv.env);
|
|
112
144
|
await Promise.all([
|
|
113
145
|
this.#app.dist.writeJson("package.json", akanConfig.getProductionPackageJson()),
|
|
114
|
-
this.#app.dist.writeFile(`${this.#app.dist.cwdPath}/Dockerfile`,
|
|
146
|
+
this.#app.dist.writeFile(`${this.#app.dist.cwdPath}/Dockerfile`, dockerfile),
|
|
147
|
+
this.#app.dist.writeJson("akan.build.json", {
|
|
148
|
+
buildId: await this.#resolveBuildId(),
|
|
149
|
+
akanVersion: akanConfig.akanVersion,
|
|
150
|
+
builtAt: new Date().toISOString()
|
|
151
|
+
})
|
|
115
152
|
]);
|
|
116
153
|
}
|
|
154
|
+
async#resolveBuildId() {
|
|
155
|
+
const fromEnv = process.env.AKAN_BUILD_ID?.trim();
|
|
156
|
+
if (fromEnv)
|
|
157
|
+
return fromEnv;
|
|
158
|
+
const root = this.#app.workspace.workspaceRoot;
|
|
159
|
+
const sha = Bun.spawnSync(["git", "rev-parse", "--short=12", "HEAD"], { cwd: root, stderr: "ignore" });
|
|
160
|
+
if (sha.exitCode !== 0)
|
|
161
|
+
return null;
|
|
162
|
+
const dirty = Bun.spawnSync(["git", "status", "--porcelain", "--untracked-files=no"], {
|
|
163
|
+
cwd: root,
|
|
164
|
+
stderr: "ignore"
|
|
165
|
+
});
|
|
166
|
+
const suffix = dirty.exitCode === 0 && dirty.stdout.toString().trim() ? "-dirty" : "";
|
|
167
|
+
return `${sha.stdout.toString().trim()}${suffix}`;
|
|
168
|
+
}
|
|
117
169
|
async#buildBackend() {
|
|
118
|
-
const
|
|
119
|
-
const backendExternals = [
|
|
120
|
-
...new Set([...akanConfig.externalLibs, ...SSR_RENDER_EXTERNALS, ...AKAN_OPTIONAL_BACKEND_EXTERNALS])
|
|
121
|
-
];
|
|
122
|
-
const { web } = akanConfig;
|
|
170
|
+
const { externalLibs, web, baseDevEnv, branches } = await this.#app.getConfig();
|
|
123
171
|
const backendEntryPoints = [`${this.#app.cwdPath}/main.ts`, `${this.#app.cwdPath}/server.ts`];
|
|
124
172
|
for (const entrypoint of backendEntryPoints) {
|
|
125
173
|
if (!await Bun.file(entrypoint).exists())
|
|
126
174
|
throw new Error(`Backend entrypoint not found: ${entrypoint}`);
|
|
127
175
|
}
|
|
128
|
-
const
|
|
129
|
-
entrypoints: backendEntryPoints,
|
|
176
|
+
const sharedConfig = {
|
|
130
177
|
outdir: this.#app.dist.cwdPath,
|
|
131
178
|
target: "bun",
|
|
132
179
|
minify: AKAN_BACKEND_MINIFY,
|
|
133
180
|
naming: { entry: "[name].[ext]", chunk: "chunk-[hash].[ext]" },
|
|
134
|
-
define: { "process.env.NODE_ENV": JSON.stringify("production") }
|
|
135
|
-
|
|
181
|
+
define: { "process.env.NODE_ENV": JSON.stringify("production") }
|
|
182
|
+
};
|
|
183
|
+
const serverEnvPlugin = createServerEnvPlugin({
|
|
184
|
+
envDir: path2.join(this.#app.cwdPath, "env"),
|
|
185
|
+
environment: this.#environment ?? baseDevEnv.env,
|
|
186
|
+
environments: ["local", "testing", ...branches]
|
|
136
187
|
});
|
|
188
|
+
const backendConfig = {
|
|
189
|
+
...sharedConfig,
|
|
190
|
+
plugins: [this.#createExternalSpecifiersPlugin(externalLibs), serverEnvPlugin]
|
|
191
|
+
};
|
|
192
|
+
const [mainResult, serverResult] = [
|
|
193
|
+
await this.#buildOrThrow("backend", { ...backendConfig, entrypoints: [backendEntryPoints[0]] }),
|
|
194
|
+
await this.#buildOrThrow("backend", { ...backendConfig, entrypoints: [backendEntryPoints[1]], splitting: true })
|
|
195
|
+
];
|
|
137
196
|
const rscWorkerResult = web.ssr ? await this.#buildOrThrow("rsc-worker", {
|
|
197
|
+
...backendConfig,
|
|
138
198
|
entrypoints: [this.#resolveRscWorkerBuildEntry()],
|
|
139
|
-
|
|
140
|
-
target: "bun",
|
|
141
|
-
minify: AKAN_BACKEND_MINIFY,
|
|
142
|
-
naming: { entry: "[name].[ext]", chunk: "chunk-[hash].[ext]" },
|
|
143
|
-
conditions: ["react-server"],
|
|
144
|
-
define: { "process.env.NODE_ENV": JSON.stringify("production") },
|
|
145
|
-
plugins: backendExternals.length > 0 ? [this.#createExternalSpecifiersPlugin(backendExternals)] : []
|
|
199
|
+
conditions: ["react-server"]
|
|
146
200
|
}) : null;
|
|
147
201
|
const consoleRuntimeResult = await this.#buildOrThrow("console-runtime", {
|
|
202
|
+
...sharedConfig,
|
|
148
203
|
entrypoints: [this.#resolveConsoleRuntimeBuildEntry()],
|
|
149
|
-
|
|
150
|
-
target: "bun",
|
|
151
|
-
minify: AKAN_BACKEND_MINIFY,
|
|
152
|
-
naming: { entry: "console-runtime.[ext]", chunk: "chunk-[hash].[ext]" },
|
|
153
|
-
define: { "process.env.NODE_ENV": JSON.stringify("production") }
|
|
204
|
+
naming: { entry: "console-runtime.[ext]", chunk: "chunk-[hash].[ext]" }
|
|
154
205
|
});
|
|
155
206
|
await this.#writeConsoleShim();
|
|
207
|
+
const results = [mainResult, serverResult, rscWorkerResult, consoleRuntimeResult];
|
|
156
208
|
return {
|
|
157
209
|
entrypoints: backendEntryPoints.length + (rscWorkerResult ? 2 : 1),
|
|
158
|
-
outputs:
|
|
210
|
+
outputs: results.reduce((sum, result) => sum + (result?.outputs.length ?? 0), 1)
|
|
159
211
|
};
|
|
160
212
|
}
|
|
161
213
|
async#writeConsoleShim() {
|
|
162
|
-
await Bun.write(
|
|
163
|
-
|
|
214
|
+
await Bun.write(path2.join(this.#app.dist.cwdPath, "console.js"), `process.env.AKAN_COMMAND_TYPE = "console";
|
|
215
|
+
const { cnst, db, dict, option, server, sig, srv } = await import("./server.js");
|
|
216
|
+
const { assertAkanConsoleAllowed, startAkanConsole } = await import("./console-runtime.js");
|
|
164
217
|
|
|
165
218
|
const run = async () => {
|
|
166
|
-
assertAkanConsoleAllowed(
|
|
219
|
+
assertAkanConsoleAllowed();
|
|
167
220
|
await server.start({ listen: false, web: false });
|
|
168
221
|
try {
|
|
169
222
|
await startAkanConsole(server, { globals: { cnst, db, dict, option, sig, srv } });
|
|
@@ -182,19 +235,16 @@ void run().catch((error) => {
|
|
|
182
235
|
try {
|
|
183
236
|
return Bun.resolveSync("akanjs/server/rsc-worker", import.meta.dir);
|
|
184
237
|
} catch {
|
|
185
|
-
return
|
|
238
|
+
return path2.join(this.#app.workspace.workspaceRoot, "pkgs/akanjs/server/rscWorker.tsx");
|
|
186
239
|
}
|
|
187
240
|
}
|
|
188
241
|
#resolveConsoleRuntimeBuildEntry() {
|
|
189
242
|
try {
|
|
190
|
-
return
|
|
243
|
+
return path2.join(path2.dirname(Bun.resolveSync("akanjs/server", import.meta.dir)), "console.ts");
|
|
191
244
|
} catch {
|
|
192
|
-
return
|
|
245
|
+
return path2.join(this.#app.workspace.workspaceRoot, "pkgs/akanjs/server/console.ts");
|
|
193
246
|
}
|
|
194
247
|
}
|
|
195
|
-
async#buildCsr() {
|
|
196
|
-
return await new CsrArtifactBuilder(this.#app, "build").build();
|
|
197
|
-
}
|
|
198
248
|
async#buildSsr() {
|
|
199
249
|
const pageKeys = await this.#app.getPageKeys();
|
|
200
250
|
if (pageKeys.length === 0) {
|
|
@@ -205,11 +255,11 @@ void run().catch((error) => {
|
|
|
205
255
|
const allRoutes = await new AllRoutesBuilder(this.#app, base.artifact, "build").build();
|
|
206
256
|
return { base, allRoutes };
|
|
207
257
|
}
|
|
208
|
-
async#writeTypecheckTsconfig(
|
|
209
|
-
const typecheckDir =
|
|
258
|
+
async#writeTypecheckTsconfig(incremental) {
|
|
259
|
+
const typecheckDir = path2.join(this.#app.cwdPath, ".akan", "typecheck");
|
|
210
260
|
await mkdir(typecheckDir, { recursive: true });
|
|
211
261
|
const libPageIncludes = (await this.#app.getPageRoots()).filter((root) => root.keyPrefix).flatMap((root) => {
|
|
212
|
-
const rel =
|
|
262
|
+
const rel = path2.relative(typecheckDir, root.realDir).split(path2.sep).join("/");
|
|
213
263
|
return [`${rel}/**/*.ts`, `${rel}/**/*.tsx`];
|
|
214
264
|
});
|
|
215
265
|
const tsconfig = {
|
|
@@ -230,7 +280,7 @@ void run().catch((error) => {
|
|
|
230
280
|
],
|
|
231
281
|
references: []
|
|
232
282
|
};
|
|
233
|
-
const tsconfigPath =
|
|
283
|
+
const tsconfigPath = path2.join(typecheckDir, "tsconfig.json");
|
|
234
284
|
await Bun.write(tsconfigPath, `${JSON.stringify(tsconfig, null, 2)}
|
|
235
285
|
`);
|
|
236
286
|
return { typecheckDir, tsconfigPath };
|
|
@@ -256,10 +306,10 @@ void run().catch((error) => {
|
|
|
256
306
|
}
|
|
257
307
|
async#resolveTypecheckWorkerEntry() {
|
|
258
308
|
const candidates = [
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
309
|
+
path2.join(this.#app.workspace.workspaceRoot, "pkgs/@akanjs/devkit/typecheck/typecheck.proc.ts"),
|
|
310
|
+
path2.join(this.#app.workspace.workspaceRoot, "node_modules/@akanjs/devkit/typecheck/typecheck.proc.ts"),
|
|
311
|
+
path2.join(import.meta.dir, "typecheck.proc.js"),
|
|
312
|
+
path2.join(import.meta.dir, "typecheck.proc.ts")
|
|
263
313
|
];
|
|
264
314
|
for (const candidate of candidates)
|
|
265
315
|
if (await Bun.file(candidate).exists())
|
|
@@ -272,9 +322,9 @@ void run().catch((error) => {
|
|
|
272
322
|
throw new AggregateError(result.logs, `[${label}] Bun.build failed`);
|
|
273
323
|
return result;
|
|
274
324
|
}
|
|
275
|
-
#createExternalSpecifiersPlugin(
|
|
276
|
-
const
|
|
277
|
-
const escaped =
|
|
325
|
+
#createExternalSpecifiersPlugin(externalLibs) {
|
|
326
|
+
const specifiers = new Set([...externalLibs, ...SSR_RENDER_EXTERNALS, ...AKAN_OPTIONAL_BACKEND_EXTERNALS]);
|
|
327
|
+
const escaped = [...specifiers].map((specifier) => specifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
|
|
278
328
|
const filter = new RegExp(`^(${escaped.join("|")})(?:/.*)?$`);
|
|
279
329
|
return {
|
|
280
330
|
name: "akan-backend-externalize-specifiers",
|
|
@@ -283,13 +333,7 @@ void run().catch((error) => {
|
|
|
283
333
|
}
|
|
284
334
|
};
|
|
285
335
|
}
|
|
286
|
-
static formatBytes
|
|
287
|
-
if (bytes < 1024)
|
|
288
|
-
return `${bytes}B`;
|
|
289
|
-
if (bytes < 1024 * 1024)
|
|
290
|
-
return `${(bytes / 1024).toFixed(1)}KB`;
|
|
291
|
-
return `${(bytes / 1024 / 1024).toFixed(1)}MB`;
|
|
292
|
-
}
|
|
336
|
+
static formatBytes = FontPruner.formatBytes;
|
|
293
337
|
}
|
|
294
338
|
export {
|
|
295
339
|
ApplicationBuildRunner
|