@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.
Files changed (224) hide show
  1. package/.build-stamp +1 -1
  2. package/CodeAgent-zfab7pkn.js +9 -0
  3. package/CodeAgentRpcHost-p7h6n2hp.js +7 -0
  4. package/CodeAgentRpcListener-7p7z5dd7.js +97 -0
  5. package/CodeTui-0zhnr0pw.js +1457 -0
  6. package/README.ko.md +83 -28
  7. package/README.md +70 -27
  8. package/TunnelShare-cwh9ezsm.js +9 -0
  9. package/{agent.command-0q17pnrs.js → agent.command-aja6z9mn.js} +8 -9
  10. package/akanCode.js +102 -0
  11. package/application.command-049ehgx3.js +246 -0
  12. package/{applicationBuildRunner-kxwbssgn.js → applicationBuildRunner-75n5rpwp.js} +121 -77
  13. package/buildBatch.proc.js +120 -32
  14. package/cloud.command-gw4kqxt8.js +95 -0
  15. package/cloud.script-c723cpcb.js +20 -0
  16. package/code.command-x9t6z5nw.js +154 -0
  17. package/commandManifest.json +1 -1
  18. package/consoleToStderr-h5bryj94.js +7 -0
  19. package/context.command-yfbe1rtd.js +48 -0
  20. package/context.runner-erfe68j5.js +21 -0
  21. package/{dependencyScanner-shs82ynp.js → dependencyScanner-06z2dmrr.js} +2 -2
  22. package/{devTui-m1atgkc9.js → devTui-q7k7bakd.js} +122 -40
  23. package/fileSys-wzzrntkw.js +9 -0
  24. package/guideline.command-kq9gp690.js +42 -0
  25. package/guidelines/agentRule/agentRule.instruction.md +154 -26
  26. package/guidelines/conventions/conventions.instruction.md +138 -48
  27. package/guidelines/mcpRule/mcpRule.instruction.md +7 -5
  28. package/guidelines/queryRule/queryRule.instruction.md +21 -7
  29. package/guidelines/runtimeRule/runtimeRule.instruction.md +291 -6
  30. package/guidelines/ssrRule/ssrRule.instruction.md +4 -2
  31. package/guidelines/transportRule/transportRule.instruction.md +10 -8
  32. package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +20 -0
  33. package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +66 -3
  34. package/incrementalBuilder.proc.js +564 -109
  35. package/{index-2tv3fdx4.js → index-150s07n8.js} +1230 -1459
  36. package/{index-vyvre9en.js → index-25fvrxmy.js} +6 -2
  37. package/{index-kcxmv48c.js → index-2ahj896a.js} +45 -79
  38. package/index-2wc41k5w.js +49 -0
  39. package/index-3hx1z96c.js +87 -0
  40. package/{index-q0y2jq9j.js → index-52w0fvh8.js} +21 -4
  41. package/{index-04bk599g.js → index-5g4rkrvt.js} +10 -17
  42. package/index-5pvxf7z0.js +53 -0
  43. package/index-5q14pwzd.js +69 -0
  44. package/{index-vxtad5bd.js → index-66yspb67.js} +5 -8
  45. package/index-7md2g9vw.js +6 -0
  46. package/index-7p4c0yer.js +1058 -0
  47. package/{index-d43r08tf.js → index-8b639zes.js} +77 -150
  48. package/{index-ktb5njgy.js → index-8kvy8qb4.js} +49 -99
  49. package/index-94s080qm.js +266 -0
  50. package/index-9dp031by.js +12 -0
  51. package/{index-0g7r8xz3.js → index-a37by9hn.js} +114 -232
  52. package/{index-k2j1hc4r.js → index-b95yhqjr.js} +12 -12
  53. package/{index-3d9y066c.js → index-bjwxs904.js} +9 -8
  54. package/{index-2xp0kfkt.js → index-br8pkrk1.js} +37 -25
  55. package/index-c14nsvnv.js +700 -0
  56. package/index-c6eggbee.js +123 -0
  57. package/index-d2242ksy.js +99 -0
  58. package/{index-92zztqy1.js → index-dy0jx9ay.js} +2 -17
  59. package/{index-a64esmtb.js → index-fkvb79qe.js} +523 -1022
  60. package/index-h54yj9wr.js +1119 -0
  61. package/{index-by5gpp8x.js → index-hj6w4ka1.js} +2 -1
  62. package/{index-y6n8nmny.js → index-kn5d4jmg.js} +75 -203
  63. package/index-m3xsb1ms.js +4300 -0
  64. package/{index-gyd220p2.js → index-mb59b8x0.js} +554 -577
  65. package/{index-j9yhg404.js → index-mzjb6zp4.js} +4 -7
  66. package/index-p6pbz9n5.js +25 -0
  67. package/{index-sj5vxr8f.js → index-qe71g4ze.js} +983 -898
  68. package/index-rfcz04w9.js +187 -0
  69. package/{index-hwkygn9s.js → index-senscydg.js} +331 -36
  70. package/{index-ffvk10zz.js → index-vs8mefhy.js} +107 -241
  71. package/index-wa5jbxj1.js +760 -0
  72. package/index-y5ga5w9t.js +2729 -0
  73. package/{index-9077wzd2.js → index-y7hx1ygz.js} +43 -26
  74. package/{index-h7yw2z9n.js → index-zzvvc845.js} +8 -14
  75. package/index.js +23 -22
  76. package/{library.command-qzzbj6d8.js → library.command-keqjevpp.js} +4 -5
  77. package/{localRegistry.command-vyrgg4xw.js → localRegistry.command-pydeq5zf.js} +23 -43
  78. package/{module.command-rq5hq3ax.js → module.command-dkrnqx3v.js} +8 -12
  79. package/{package.command-d9hd6v9n.js → package.command-wmc0ys5y.js} +6 -7
  80. package/package.json +15 -7
  81. package/{page.command-126d56te.js → page.command-tf3erhrv.js} +4 -5
  82. package/{primitive.command-taxd1538.js → primitive.command-7hqpegj4.js} +9 -23
  83. package/prompter-76k56b37.js +8 -0
  84. package/{quality.command-6gsna0a3.js → quality.command-8122axq3.js} +205 -377
  85. package/{recipeScanner-fpagtgc1.js → recipeScanner-4b69ybe0.js} +1 -1
  86. package/{repair.command-tq2dgy72.js → repair.command-mcy12h0n.js} +11 -35
  87. package/{routeSourceValidator-apyqw7wk.js → routeSourceValidator-7ycnfz0e.js} +0 -6
  88. package/{scalar.command-3bcmrrkv.js → scalar.command-vvvbzttc.js} +7 -11
  89. package/skills/akan-code/SKILL.md +130 -0
  90. package/skills/akan-debug/SKILL.md +42 -0
  91. package/skills/akan-deps/SKILL.md +50 -0
  92. package/skills/akan-err/SKILL.md +39 -0
  93. package/skills/akan-module/SKILL.md +45 -0
  94. package/skills/akan-scaffold/SKILL.md +76 -0
  95. package/skills/akan-scalar/SKILL.md +52 -0
  96. package/skills/akan-service/SKILL.md +34 -0
  97. package/skills/akan-store/SKILL.md +67 -0
  98. package/skills/akan-ui/SKILL.md +63 -0
  99. package/skills/akan-validate/SKILL.md +44 -0
  100. package/{subspace.command-eddzqpx3.js → subspace.command-pzvqfy5h.js} +53 -62
  101. package/templates/__scalar/__model__/__model__.abstract.md.template +8 -0
  102. package/templates/app/page/_index.tsx +257 -258
  103. package/templates/app/page/_layout.tsx +5 -1
  104. package/templates/app/page/_overrides.tsx +12 -0
  105. package/templates/app/page/styles.css.template +316 -14
  106. package/templates/app/public/apple-touch-icon.png +0 -0
  107. package/templates/app/public/favicon.ico +0 -0
  108. package/templates/app/public/jelly/cloud.webp +0 -0
  109. package/templates/app/public/jelly/comet.webp +0 -0
  110. package/templates/app/public/jelly/moon.webp +0 -0
  111. package/templates/app/public/jelly/planet.webp +0 -0
  112. package/templates/app/public/jelly/rocket.webp +0 -0
  113. package/templates/app/public/jelly/star.webp +0 -0
  114. package/templates/app/public/jelly/sugar.webp +0 -0
  115. package/templates/app/public/logo.png +0 -0
  116. package/templates/app/ui/Recipe/index.ts +9 -0
  117. package/templates/app/ui/Recipe/jellyButton.ts +63 -0
  118. package/templates/appSample/lib/__scalar/workHistory/workHistory.abstract.ts +8 -39
  119. package/templates/appSample/lib/_noti/noti.abstract.ts +6 -29
  120. package/templates/appSample/lib/task/Task.Unit.tsx +1 -1
  121. package/templates/appSample/lib/task/Task.Util.tsx +10 -13
  122. package/templates/appSample/lib/task/Task.View.tsx +2 -2
  123. package/templates/appSample/lib/task/Task.Zone.tsx +5 -2
  124. package/templates/appSample/lib/task/task.abstract.ts +12 -32
  125. package/templates/appSample/lib/task/task.signal.spec.ts +1 -15
  126. package/templates/appSample/lib/task/task.signal.test.ts +15 -1
  127. package/templates/appSample/lib/task/task.signal.ts +10 -8
  128. package/templates/appSample/page/task/[taskId]/_index.tsx +6 -6
  129. package/templates/appSample/page/task/[taskId]/edit.tsx +5 -4
  130. package/templates/appSample/page/task/_index.tsx +4 -3
  131. package/templates/appSample/page/task/_layout.tsx +1 -1
  132. package/templates/appSample/page/task/new.tsx +5 -4
  133. package/templates/appSample/srvkit/{AuthGuard.ts → guards.ts} +7 -4
  134. package/templates/appSample/srvkit/{SessionInternalArg.ts → internalArgs.ts} +6 -4
  135. package/templates/appSample/ui/GlobalLoading.tsx +2 -1
  136. package/templates/appSample/ui/QuantityControl.tsx +3 -3
  137. package/templates/client.ts +7 -30
  138. package/templates/crudPages/[__model__Id]/edit/page.tsx +2 -1
  139. package/templates/crudPages/[__model__Id]/page.tsx +2 -1
  140. package/templates/crudPages/new/page.tsx +2 -1
  141. package/templates/crudPages/page.tsx +2 -1
  142. package/templates/crudSinglePage/page.tsx +2 -1
  143. package/templates/lib/__lib/lib.dictionary.ts +0 -2
  144. package/templates/lib/__lib/lib.document.ts +0 -2
  145. package/templates/lib/sig.ts +8 -30
  146. package/templates/localDev/docker-compose.yaml.template +3 -14
  147. package/templates/module/__model__.signal.ts +12 -4
  148. package/templates/pkgRoot/tsconfig.json.template +2 -7
  149. package/templates/server.ts +1 -3
  150. package/templates/service/__model__.abstract.md.template +8 -0
  151. package/templates/workspaceRoot/.gitignore.template +0 -1
  152. package/templates/workspaceRoot/AGENTS.md.template +6 -0
  153. package/templates/workspaceRoot/package.json.template +1 -3
  154. package/tunnel.command-82zz5xnq.js +129 -0
  155. package/{typeChecker-3xgrzc2v.js → typeChecker-px49mezc.js} +1 -1
  156. package/typecheck.proc.js +1 -1
  157. package/workflow.command-y8x3kgjv.js +79 -0
  158. package/{workspace.command-06wvstgr.js → workspace.command-jvsb7brc.js} +79 -109
  159. package/abstractCompactor-gmkc0z8j.js +0 -102
  160. package/application.command-18y0s485.js +0 -204
  161. package/applicationReleasePackager-4yasxwv9.js +0 -244
  162. package/capacitorApp-36rbr858.js +0 -12
  163. package/cloud.command-av97ndh6.js +0 -94
  164. package/cloud.script-cm11xjdz.js +0 -20
  165. package/context.command-5v37ef3n.js +0 -81
  166. package/devTuiView-0hc2emhe.js +0 -9
  167. package/getDirname-dr3jz1xg.js +0 -7
  168. package/guideline.command-4pz9g1rt.js +0 -360
  169. package/guidelines/agentRule/agentRule.generate.json +0 -31
  170. package/guidelines/componentRule/componentRule.generate.json +0 -31
  171. package/guidelines/conventions/conventions.generate.json +0 -25
  172. package/guidelines/cssRule/cssRule.generate.json +0 -31
  173. package/guidelines/docPageRule/docPageRule.generate.json +0 -31
  174. package/guidelines/docPageRule/docPageRule.instruction.md +0 -25
  175. package/guidelines/docSyncRule/docSyncRule.generate.json +0 -31
  176. package/guidelines/docSyncRule/docSyncRule.instruction.md +0 -25
  177. package/guidelines/enumConstant/enumConstant.generate.json +0 -31
  178. package/guidelines/enumConstant/enumConstant.instruction.md +0 -28
  179. package/guidelines/fieldRule/fieldRule.generate.json +0 -31
  180. package/guidelines/framework/framework.generate.json +0 -32
  181. package/guidelines/mcpRule/mcpRule.generate.json +0 -35
  182. package/guidelines/modelConstant/modelConstant.generate.json +0 -32
  183. package/guidelines/modelDictionary/modelDictionary.generate.json +0 -32
  184. package/guidelines/modelDocument/modelDocument.generate.json +0 -31
  185. package/guidelines/modelService/modelService.generate.json +0 -31
  186. package/guidelines/modelSignal/modelSignal.generate.json +0 -31
  187. package/guidelines/modelStore/modelStore.generate.json +0 -31
  188. package/guidelines/modelTemplate/modelTemplate.generate.json +0 -31
  189. package/guidelines/modelUnit/modelUnit.generate.json +0 -31
  190. package/guidelines/modelUtil/modelUtil.generate.json +0 -31
  191. package/guidelines/modelView/modelView.generate.json +0 -31
  192. package/guidelines/modelZone/modelZone.generate.json +0 -31
  193. package/guidelines/moduleCodegen/moduleCodegen.generate.json +0 -31
  194. package/guidelines/moduleCodegen/moduleCodegen.instruction.md +0 -28
  195. package/guidelines/moduleOverview/moduleOverview.generate.json +0 -31
  196. package/guidelines/queryRule/queryRule.generate.json +0 -31
  197. package/guidelines/recipeRule/recipeRule.generate.json +0 -31
  198. package/guidelines/runtimeRule/runtimeRule.generate.json +0 -25
  199. package/guidelines/scalarConstant/scalarConstant.generate.json +0 -32
  200. package/guidelines/scalarDictionary/scalarDictionary.generate.json +0 -32
  201. package/guidelines/scalarModule/scalarModule.generate.json +0 -31
  202. package/guidelines/sharedUiUsage/sharedUiUsage.generate.json +0 -31
  203. package/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +0 -25
  204. package/guidelines/ssrRule/ssrRule.generate.json +0 -31
  205. package/guidelines/transportRule/transportRule.generate.json +0 -31
  206. package/guidelines/utilUiUsage/utilUiUsage.generate.json +0 -31
  207. package/guidelines/utilUiUsage/utilUiUsage.instruction.md +0 -25
  208. package/guidelines/workspaceOnboarding/workspaceOnboarding.generate.json +0 -24
  209. package/guidelines/workspaceRecipes/workspaceRecipes.generate.json +0 -33
  210. package/index-47pj3aee.js +0 -76
  211. package/index-5ystnsd5.js +0 -841
  212. package/index-6wwzs1bc.js +0 -7
  213. package/index-a17x49vg.js +0 -229
  214. package/index-m0xccmmm.js +0 -228
  215. package/index-meh558jy.js +0 -65
  216. package/index-rtxxan88.js +0 -471
  217. package/index-te54x9zm.js +0 -338
  218. package/index-w8kmx1b6.js +0 -2176
  219. package/index-wt7qrtd4.js +0 -1516
  220. package/templates/__scalar/__model__/__model__.abstract.md +0 -28
  221. package/templates/module/__model__.abstract.md +0 -28
  222. package/templates/service/__model__.abstract.md +0 -28
  223. package/templates/workspaceRoot/patches/react-dom@19.2.7.patch.template +0 -62
  224. package/workflow.command-gtdnzvbz.js +0 -108
@@ -0,0 +1,266 @@
1
+ // @bun
2
+ import {
3
+ FileSys2
4
+ } from "./index-52w0fvh8.js";
5
+ import {
6
+ ConfigLock
7
+ } from "./index-3hx1z96c.js";
8
+
9
+ // pkgs/@akanjs/devkit/cloud/globalConfig.ts
10
+ import { mkdir, rm, writeFile } from "fs/promises";
11
+ import dayjs from "dayjs";
12
+
13
+ // pkgs/@akanjs/devkit/cloud/constants.ts
14
+ import path from "path";
15
+ var basePath = path.join(Bun.env.HOME ?? Bun.env.USERPROFILE ?? "", ".akan");
16
+ var configPath = path.join(basePath, "config.json");
17
+ var getDefaultHostConfig = (host = GlobalConfig.akanCloudHost) => ({ host });
18
+ var defaultAkanGlobalConfig = {
19
+ cloudHost: {},
20
+ remoteEnvServers: {},
21
+ testTargets: {}
22
+ };
23
+
24
+ // pkgs/@akanjs/devkit/cloud/globalConfig.ts
25
+ class GlobalConfig {
26
+ static akanCloudHost = process.env.USE_AKANJS_PKGS === "true" ? `http://localhost:${process.env.CLOUD_HOST_PORT ?? 8283}` : "https://cloud.akanjs.com";
27
+ static async#getAkanGlobalConfig() {
28
+ const exists = await FileSys2.fileExists(configPath);
29
+ const akanConfig = exists ? await FileSys2.readJson(configPath) : {};
30
+ return {
31
+ ...defaultAkanGlobalConfig,
32
+ ...akanConfig,
33
+ cloudHost: akanConfig.cloudHost ?? defaultAkanGlobalConfig.cloudHost,
34
+ remoteEnvServers: akanConfig.remoteEnvServers ?? defaultAkanGlobalConfig.remoteEnvServers,
35
+ testTargets: akanConfig.testTargets ?? defaultAkanGlobalConfig.testTargets
36
+ };
37
+ }
38
+ static async#setAkanGlobalConfig(akanConfig) {
39
+ await mkdir(basePath, { recursive: true, mode: 448 });
40
+ const temp = `${configPath}.${process.pid}.${crypto.randomUUID()}.tmp`;
41
+ try {
42
+ await writeFile(temp, JSON.stringify(akanConfig, null, 2), { mode: 384 });
43
+ await FileSys2.replace(temp, configPath);
44
+ } catch (error) {
45
+ await rm(temp, { force: true });
46
+ throw error;
47
+ }
48
+ }
49
+ static #lockPath = `${configPath}.lock`;
50
+ static async#update(mutate) {
51
+ await ConfigLock.run(GlobalConfig.#lockPath, async () => {
52
+ await GlobalConfig.#setAkanGlobalConfig(mutate(await GlobalConfig.#getAkanGlobalConfig()));
53
+ });
54
+ }
55
+ static async getHostConfig(host = GlobalConfig.akanCloudHost) {
56
+ const akanConfig = await GlobalConfig.#getAkanGlobalConfig();
57
+ return GlobalConfig.toHostConfig(akanConfig.cloudHost[host] ?? getDefaultHostConfig(host));
58
+ }
59
+ static async setHostConfig(config = getDefaultHostConfig()) {
60
+ await GlobalConfig.#update((akanConfig) => GlobalConfig.#withHost(akanConfig, config));
61
+ }
62
+ static #withHost(akanConfig, config) {
63
+ return {
64
+ ...akanConfig,
65
+ cloudHost: { ...akanConfig.cloudHost, [config.host]: GlobalConfig.toHostConfigDto(config) }
66
+ };
67
+ }
68
+ static async refreshHostAuth(host, refresh) {
69
+ try {
70
+ return await ConfigLock.run(GlobalConfig.#lockPath, async () => {
71
+ const akanConfig = await GlobalConfig.#getAkanGlobalConfig();
72
+ const current = GlobalConfig.toHostConfig(akanConfig.cloudHost[host] ?? getDefaultHostConfig(host));
73
+ const accessToken = current.auth?.accessToken;
74
+ const refreshToken = accessToken?.refreshToken;
75
+ if (!accessToken || !refreshToken || !GlobalConfig.needRefreshToken(accessToken))
76
+ return current;
77
+ const claimed = {
78
+ ...current,
79
+ auth: { ...current.auth, accessToken: { ...accessToken, refreshToken: null } }
80
+ };
81
+ await GlobalConfig.#setAkanGlobalConfig(GlobalConfig.#withHost(akanConfig, claimed));
82
+ const next = await refresh(refreshToken).catch(() => null);
83
+ if (!next?.jwt)
84
+ return claimed;
85
+ const refreshed = { ...current, auth: { ...current.auth, accessToken: next } };
86
+ await GlobalConfig.#setAkanGlobalConfig(GlobalConfig.#withHost(await GlobalConfig.#getAkanGlobalConfig(), refreshed));
87
+ return refreshed;
88
+ });
89
+ } catch {
90
+ return await GlobalConfig.getHostConfig(host);
91
+ }
92
+ }
93
+ static async getRemoteEnvServers() {
94
+ return (await GlobalConfig.#getAkanGlobalConfig()).remoteEnvServers;
95
+ }
96
+ static async setRemoteEnvServer(name, config) {
97
+ await GlobalConfig.#update((akanConfig) => ({
98
+ ...akanConfig,
99
+ remoteEnvServers: { ...akanConfig.remoteEnvServers, [name]: config }
100
+ }));
101
+ }
102
+ static async removeRemoteEnvServer(name) {
103
+ await GlobalConfig.#update((akanConfig) => {
104
+ const { [name]: _, ...remoteEnvServers } = akanConfig.remoteEnvServers;
105
+ return { ...akanConfig, remoteEnvServers };
106
+ });
107
+ }
108
+ static async getTestTargets() {
109
+ return (await GlobalConfig.#getAkanGlobalConfig()).testTargets;
110
+ }
111
+ static async setTestTargets(testTargets) {
112
+ await GlobalConfig.#update((akanConfig) => ({
113
+ ...akanConfig,
114
+ testTargets: { ...akanConfig.testTargets, ...testTargets }
115
+ }));
116
+ }
117
+ static needRefreshToken(accessToken) {
118
+ return !!accessToken?.expiresAt?.isBefore(dayjs().add(1, "hour"));
119
+ }
120
+ static toAccessToken(accessToken) {
121
+ return {
122
+ jwt: accessToken.jwt,
123
+ refreshToken: accessToken.refreshToken ?? null,
124
+ expiresAt: accessToken.expiresAt ? dayjs(accessToken.expiresAt) : null
125
+ };
126
+ }
127
+ static toAccessTokenDto(accessToken) {
128
+ return {
129
+ jwt: accessToken.jwt,
130
+ refreshToken: accessToken.refreshToken ?? null,
131
+ expiresAt: accessToken.expiresAt?.toString() ?? null
132
+ };
133
+ }
134
+ static toHostConfigDto(hostConfig) {
135
+ return {
136
+ host: hostConfig.host,
137
+ auth: {
138
+ accessToken: hostConfig.auth?.accessToken ? GlobalConfig.toAccessTokenDto(hostConfig.auth.accessToken) : undefined,
139
+ self: hostConfig.auth?.self
140
+ }
141
+ };
142
+ }
143
+ static toHostConfig(hostConfigDto) {
144
+ return {
145
+ host: hostConfigDto.host,
146
+ auth: {
147
+ accessToken: hostConfigDto.auth?.accessToken ? GlobalConfig.toAccessToken(hostConfigDto.auth.accessToken) : undefined,
148
+ self: hostConfigDto.auth?.self
149
+ }
150
+ };
151
+ }
152
+ }
153
+
154
+ // pkgs/@akanjs/devkit/cloud/cloudApi.ts
155
+ class HttpClient {
156
+ baseUrl;
157
+ headers = {};
158
+ constructor(baseUrl, headers = {}) {
159
+ this.baseUrl = baseUrl;
160
+ this.headers = headers;
161
+ }
162
+ async get(url, { headers, signal } = {}) {
163
+ const response = await fetch(`${this.baseUrl}${url}`, {
164
+ headers: { "Content-Type": "application/json", ...this.headers, ...headers },
165
+ ...signal ? { signal } : {}
166
+ });
167
+ return await HttpClient.#body(response, url);
168
+ }
169
+ async getFile(url, localPath, headers) {
170
+ const response = await fetch(`${this.baseUrl}${url}`, {
171
+ headers: { ...this.headers, ...headers }
172
+ });
173
+ if (!response.ok)
174
+ throw new Error(`Failed to download file: ${response.status} ${response.statusText}`);
175
+ await Bun.write(localPath, response);
176
+ }
177
+ async post(url, data, { headers, signal } = {}) {
178
+ const isFormData = data instanceof FormData;
179
+ const response = await fetch(`${this.baseUrl}${url}`, {
180
+ method: "POST",
181
+ body: isFormData ? data : JSON.stringify(data),
182
+ headers: isFormData ? { ...this.headers, ...headers } : { "Content-Type": "application/json", ...this.headers, ...headers },
183
+ ...signal ? { signal } : {}
184
+ });
185
+ return await HttpClient.#body(response, url);
186
+ }
187
+ static async#body(response, url) {
188
+ const text = await response.text();
189
+ if (!response.ok)
190
+ throw new Error(`${response.status} ${response.statusText} from ${url}: ${text.slice(0, 200)}`);
191
+ return JSON.parse(text);
192
+ }
193
+ setHeaders(headers) {
194
+ Object.assign(this.headers, headers);
195
+ return this;
196
+ }
197
+ }
198
+
199
+ class CloudApi {
200
+ #api;
201
+ #accessToken = null;
202
+ #workspace;
203
+ host;
204
+ url;
205
+ static async fromHost(workspace, host) {
206
+ const hostConfig = await GlobalConfig.getHostConfig(host);
207
+ const accessToken = hostConfig.auth?.accessToken;
208
+ if (!accessToken || !GlobalConfig.needRefreshToken(accessToken))
209
+ return new CloudApi(workspace, hostConfig);
210
+ const tokenless = new CloudApi(workspace, hostConfig);
211
+ const refreshed = await GlobalConfig.refreshHostAuth(hostConfig.host, (refreshToken) => tokenless.refreshAuthToken(refreshToken));
212
+ return new CloudApi(workspace, refreshed);
213
+ }
214
+ constructor(workspace, hostConfig) {
215
+ this.#workspace = workspace;
216
+ this.#accessToken = hostConfig.auth?.accessToken ?? null;
217
+ this.host = hostConfig.host;
218
+ this.url = `${this.host}/api`;
219
+ this.#api = new HttpClient(this.url);
220
+ if (this.#accessToken && !GlobalConfig.needRefreshToken(this.#accessToken))
221
+ this.#api.setHeaders({ Authorization: `Bearer ${this.#accessToken.jwt}` });
222
+ }
223
+ #authorize(accessTokenDto) {
224
+ this.#accessToken = GlobalConfig.toAccessToken(accessTokenDto);
225
+ this.#api.setHeaders({ Authorization: `Bearer ${this.#accessToken.jwt}` });
226
+ return this.#accessToken;
227
+ }
228
+ async uploadEnv(devProjectId, file) {
229
+ const formData = new FormData;
230
+ formData.append("devProjectId", devProjectId);
231
+ formData.append("file", file);
232
+ return await this.#api.post(`/uploadEnv/${devProjectId}`, formData);
233
+ }
234
+ async downloadEnv(devProjectId) {
235
+ const localPath = `${this.#workspace.workspaceRoot}/local/env.tar`;
236
+ await this.#api.getFile(`/downloadEnv/${devProjectId}`, localPath);
237
+ return localPath;
238
+ }
239
+ async getRemoteAuthToken(remoteId) {
240
+ try {
241
+ return this.#authorize(await this.#api.get(`/getRemoteAuthToken/${remoteId}`));
242
+ } catch (_) {
243
+ return null;
244
+ }
245
+ }
246
+ async refreshAuthToken(refreshToken) {
247
+ return this.#authorize(await this.#api.post(`/refreshAuthToken`, { refreshToken }, { signal: AbortSignal.timeout(20000) }));
248
+ }
249
+ async requestTunnel(input) {
250
+ return await this.#api.post(`/tunnel/requestTunnel`, input);
251
+ }
252
+ async tunnelListInSelf() {
253
+ return await this.#api.get(`/tunnel/tunnelListInSelf`);
254
+ }
255
+ async revokeTunnel(code) {
256
+ return await this.#api.post(`/tunnel/revokeTunnel`, { code }, { signal: AbortSignal.timeout(5000) });
257
+ }
258
+ async getRemoteSelf() {
259
+ try {
260
+ return await this.#api.get(`/getRemoteSelf`);
261
+ } catch {
262
+ return null;
263
+ }
264
+ }
265
+ }
266
+ export { getDefaultHostConfig, GlobalConfig, CloudApi };
@@ -0,0 +1,12 @@
1
+ // @bun
2
+ // pkgs/@akanjs/cli/openBrowser.ts
3
+ import { spawn } from "child_process";
4
+ function openBrowser(url) {
5
+ const command = process.platform === "darwin" ? ["open", url] : process.platform === "win32" ? ["cmd", "/c", "start", "", url] : ["xdg-open", url];
6
+ const child = spawn(command[0], command.slice(1), { detached: true, stdio: "ignore" });
7
+ child.on("error", () => {});
8
+ child.unref();
9
+ return Promise.resolve();
10
+ }
11
+
12
+ export { openBrowser };