@akanjs/cli 3.0.0-beta.2 → 3.0.0-beta.20
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-awv258wb.js +9 -0
- package/CodeAgentRpcHost-p7h6n2hp.js +7 -0
- package/CodeAgentRpcListener-7p7z5dd7.js +97 -0
- package/CodeTui-1nqh35ez.js +1457 -0
- package/README.md +3 -0
- package/TunnelShare-scf4e4pd.js +9 -0
- package/{agent.command-d2gfxfck.js → agent.command-1s9ag7sb.js} +8 -9
- package/akanCode.js +102 -0
- package/{application.command-pj2m7584.js → application.command-49hwy6va.js} +51 -78
- package/{applicationBuildRunner-kxwbssgn.js → applicationBuildRunner-ybyp97pv.js} +63 -64
- package/{applicationReleasePackager-4yasxwv9.js → applicationReleasePackager-esnrphw8.js} +40 -60
- package/buildBatch.proc.js +19 -24
- package/{capacitorApp-36rbr858.js → capacitorApp-1synz4en.js} +3 -4
- package/cloud.command-d7rqtzt9.js +94 -0
- package/cloud.script-bkbpcr96.js +19 -0
- package/code.command-nn48xzej.js +154 -0
- package/commandManifest.json +1 -1
- package/consoleToStderr-h5bryj94.js +7 -0
- package/context.command-s3mcmvpa.js +48 -0
- package/context.runner-k99nb5pk.js +21 -0
- package/{dependencyScanner-shs82ynp.js → dependencyScanner-ye2e6pdz.js} +2 -2
- package/{devTui-40ggmd99.js → devTui-q7k7bakd.js} +122 -40
- package/fileSys-5ngz93ga.js +9 -0
- package/guideline.command-sct4qnt5.js +42 -0
- package/guidelines/agentRule/agentRule.instruction.md +206 -25
- package/guidelines/conventions/conventions.instruction.md +79 -24
- package/guidelines/fieldRule/fieldRule.instruction.md +1 -0
- package/guidelines/mcpRule/mcpRule.instruction.md +7 -5
- package/guidelines/queryRule/queryRule.instruction.md +17 -7
- package/guidelines/runtimeRule/runtimeRule.instruction.md +74 -0
- package/guidelines/ssrRule/ssrRule.instruction.md +4 -2
- package/guidelines/transportRule/transportRule.instruction.md +51 -0
- package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +66 -3
- package/incrementalBuilder.proc.js +31 -48
- package/{index-h7yw2z9n.js → index-0bq14vr1.js} +8 -14
- package/index-13ffe9wp.js +69 -0
- package/index-22d57v4c.js +266 -0
- package/{index-fz5q3gd7.js → index-31yr441d.js} +10 -17
- package/index-3hx1z96c.js +87 -0
- package/index-3sq321ak.js +53 -0
- package/{index-kcxmv48c.js → index-3t7g9e4r.js} +45 -79
- package/{index-q0y2jq9j.js → index-5b6tavv3.js} +6 -3
- package/{index-47pj3aee.js → index-5e0n4hqx.js} +11 -12
- package/{index-259dsnz3.js → index-5pc1qrbv.js} +5 -8
- package/index-7md2g9vw.js +6 -0
- package/index-8mna0947.js +187 -0
- package/{index-zry5nz81.js → index-8sf7wmdr.js} +51 -30
- package/{index-2tv3fdx4.js → index-9d9bgcx4.js} +342 -765
- package/index-9dp031by.js +12 -0
- package/{index-ne2qy0nk.js → index-ahemdr5n.js} +12 -12
- package/{index-ws5e0j51.js → index-as7xmyz8.js} +40 -24
- package/index-axzjaqve.js +1118 -0
- package/{index-3d9y066c.js → index-bjwxs904.js} +9 -8
- package/index-c6eggbee.js +123 -0
- package/index-d2242ksy.js +99 -0
- package/{index-a64esmtb.js → index-ddxvdd1p.js} +169 -305
- package/{index-92zztqy1.js → index-dy0jx9ay.js} +2 -17
- package/{index-pnqbkf5p.js → index-dzf3r49a.js} +6 -2
- package/{index-w8kmx1b6.js → index-fgq75haa.js} +198 -290
- package/{index-by5gpp8x.js → index-hj6w4ka1.js} +2 -1
- package/{index-hwkygn9s.js → index-khpfpcsd.js} +302 -33
- package/{index-wt7qrtd4.js → index-mxav6j3c.js} +93 -232
- package/{index-gyd220p2.js → index-myhc3c1j.js} +554 -577
- package/{index-600zhnve.js → index-nv5976x3.js} +56 -197
- package/index-p6pbz9n5.js +25 -0
- package/{index-4edzf1gr.js → index-przybvy5.js} +77 -150
- package/index-smme4r47.js +49 -0
- package/{index-mak3cd28.js → index-w2zdcw3k.js} +137 -255
- package/index-wa5jbxj1.js +760 -0
- package/{index-v0qh106m.js → index-ww4z397j.js} +527 -723
- package/{index-j9yhg404.js → index-xqjwd384.js} +4 -7
- package/{index-7737gxcp.js → index-xqpzbab5.js} +107 -241
- package/index-xsjh6nzh.js +2729 -0
- package/{index-ktb5njgy.js → index-ygn77a5w.js} +47 -99
- package/index-ztp3e73t.js +700 -0
- package/index.js +23 -22
- package/{library.command-nbsky672.js → library.command-1gx04jgn.js} +4 -5
- package/{localRegistry.command-yeq57wjr.js → localRegistry.command-zndxj1q6.js} +22 -42
- package/{module.command-29vqzrh8.js → module.command-3waddk95.js} +8 -11
- package/{package.command-axv0abmn.js → package.command-zrc7br1y.js} +6 -7
- package/package.json +14 -5
- package/{page.command-vs9s3zrh.js → page.command-vpjgardh.js} +4 -5
- package/{primitive.command-cbxmqbtc.js → primitive.command-sz84tk4t.js} +9 -22
- package/prompter-ptaa3nk0.js +8 -0
- package/{quality.command-gmbs7nws.js → quality.command-g869hafs.js} +203 -376
- package/{recipeScanner-fpagtgc1.js → recipeScanner-4b69ybe0.js} +1 -1
- package/{repair.command-bqsjptsj.js → repair.command-chsnjvvv.js} +11 -35
- package/{routeSourceValidator-apyqw7wk.js → routeSourceValidator-7ycnfz0e.js} +0 -6
- package/{scalar.command-6k1vhe9s.js → scalar.command-2v21newx.js} +7 -10
- 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-fwjfcts7.js → subspace.command-ckcbwfp1.js} +138 -67
- package/templates/__scalar/__model__/__model__.abstract.md.template +8 -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.abstract.ts +12 -32
- package/templates/appSample/lib/task/task.signal.spec.ts +15 -18
- package/templates/appSample/lib/task/task.signal.test.ts +15 -1
- package/templates/appSample/lib/task/task.signal.ts +1 -1
- package/templates/appSample/srvkit/{AuthGuard.ts → guards.ts} +7 -4
- package/templates/appSample/srvkit/{SessionInternalArg.ts → internalArgs.ts} +6 -4
- 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 +0 -2
- package/templates/service/__model__.abstract.md.template +8 -0
- package/tunnel.command-kd2yr4fx.js +129 -0
- package/{typeChecker-3xgrzc2v.js → typeChecker-px49mezc.js} +1 -1
- package/typecheck.proc.js +1 -1
- package/workflow.command-44252cqv.js +79 -0
- package/{workspace.command-8s050m0h.js → workspace.command-fqcztt5p.js} +77 -109
- package/abstractCompactor-mjh5ppsq.js +0 -101
- package/cloud.command-jshwdq22.js +0 -93
- package/context.command-ez8a0zyz.js +0 -80
- package/devTuiView-c08ccbat.js +0 -9
- package/getDirname-dr3jz1xg.js +0 -7
- package/guideline.command-xmqwx8zm.js +0 -359
- 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-2hq52jq3.js +0 -465
- package/index-6wwzs1bc.js +0 -7
- package/index-8pm30m73.js +0 -841
- package/index-kn1h7p1x.js +0 -560
- package/index-meh558jy.js +0 -65
- package/index-rwg2aa4f.js +0 -229
- 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/workflow.command-nwpcdc8p.js +0 -107
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
FileSys2
|
|
4
|
+
} from "./index-5b6tavv3.js";
|
|
5
|
+
import {
|
|
6
|
+
ConfigLock
|
|
7
|
+
} from "./index-3hx1z96c.js";
|
|
8
|
+
|
|
9
|
+
// pkgs/@akanjs/devkit/cloud/globalConfig.ts
|
|
10
|
+
import { mkdir, rename, 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 rename(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 };
|
|
@@ -5,33 +5,26 @@ import {
|
|
|
5
5
|
writeGeneratedSyncState,
|
|
6
6
|
createRepairReport,
|
|
7
7
|
renderRepairReport
|
|
8
|
-
} from "./index-
|
|
8
|
+
} from "./index-myhc3c1j.js";
|
|
9
9
|
import {
|
|
10
10
|
AkanContextAnalyzer
|
|
11
|
-
} from "./index-
|
|
11
|
+
} from "./index-ygn77a5w.js";
|
|
12
12
|
import {
|
|
13
13
|
runner
|
|
14
|
-
} from "./index-
|
|
14
|
+
} from "./index-w2zdcw3k.js";
|
|
15
15
|
|
|
16
16
|
// pkgs/@akanjs/cli/repair/repair.runner.ts
|
|
17
|
-
var
|
|
17
|
+
var spawnShell = async (workspace, command) => await workspace.spawn("bash", ["-lc", command.startsWith("akan ") ? `bun run ${command}` : command], {
|
|
18
|
+
cwd: workspace.workspaceRoot
|
|
19
|
+
});
|
|
18
20
|
var defaultExecutor = (workspace) => async (command) => {
|
|
21
|
+
const base = { command: command.command, reason: command.reason };
|
|
19
22
|
try {
|
|
20
|
-
|
|
21
|
-
cwd: workspace.workspaceRoot
|
|
22
|
-
});
|
|
23
|
-
return {
|
|
24
|
-
command: command.command,
|
|
25
|
-
reason: command.reason,
|
|
26
|
-
status: "passed",
|
|
27
|
-
exitCode: 0,
|
|
28
|
-
stdout
|
|
29
|
-
};
|
|
23
|
+
return { ...base, status: "passed", exitCode: 0, stdout: await spawnShell(workspace, command.command) };
|
|
30
24
|
} catch (error) {
|
|
31
25
|
const commandError = error;
|
|
32
26
|
return {
|
|
33
|
-
|
|
34
|
-
reason: command.reason,
|
|
27
|
+
...base,
|
|
35
28
|
status: "failed",
|
|
36
29
|
exitCode: commandError.code ?? 1,
|
|
37
30
|
stdout: commandError.stdout,
|
|
@@ -158,4 +151,4 @@ class RepairRunner extends runner("repair") {
|
|
|
158
151
|
}
|
|
159
152
|
}
|
|
160
153
|
|
|
161
|
-
export { RepairRunner };
|
|
154
|
+
export { spawnShell, RepairRunner };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// pkgs/@akanjs/devkit/cloud/configLock.ts
|
|
3
|
+
import { mkdir, open, readFile, rm, stat } from "fs/promises";
|
|
4
|
+
import path from "path";
|
|
5
|
+
|
|
6
|
+
class ConfigLock {
|
|
7
|
+
static waitTimeoutMs = 30000;
|
|
8
|
+
static #unknownHolderStaleMs = 1e4;
|
|
9
|
+
static #pollMs = 50;
|
|
10
|
+
static async run(lockPath, fn) {
|
|
11
|
+
await mkdir(path.dirname(lockPath), { recursive: true, mode: 448 });
|
|
12
|
+
const deadline = Date.now() + ConfigLock.waitTimeoutMs;
|
|
13
|
+
while (!await ConfigLock.#take(lockPath)) {
|
|
14
|
+
if (Date.now() >= deadline) {
|
|
15
|
+
const holder = (await ConfigLock.#holder(lockPath))?.pid ?? "unknown";
|
|
16
|
+
throw new Error(`${lockPath} is held by process ${holder}; if no akan command is running, delete it and retry.`);
|
|
17
|
+
}
|
|
18
|
+
await ConfigLock.#reclaimIfAbandoned(lockPath);
|
|
19
|
+
await Bun.sleep(ConfigLock.#pollMs);
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
return await fn();
|
|
23
|
+
} finally {
|
|
24
|
+
await rm(lockPath, { force: true });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
static async#take(lockPath) {
|
|
28
|
+
const handle = await open(lockPath, "wx", 384).catch((error) => {
|
|
29
|
+
if (error.code === "EEXIST")
|
|
30
|
+
return null;
|
|
31
|
+
throw error;
|
|
32
|
+
});
|
|
33
|
+
if (!handle)
|
|
34
|
+
return false;
|
|
35
|
+
try {
|
|
36
|
+
await handle.writeFile(JSON.stringify({ pid: process.pid, at: Date.now() }));
|
|
37
|
+
} finally {
|
|
38
|
+
await handle.close();
|
|
39
|
+
}
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
static async#reclaimIfAbandoned(lockPath) {
|
|
43
|
+
if (!await ConfigLock.#abandoned(lockPath))
|
|
44
|
+
return;
|
|
45
|
+
const guard = `${lockPath}.reclaim`;
|
|
46
|
+
if (!await ConfigLock.#take(guard)) {
|
|
47
|
+
if (await ConfigLock.#abandoned(guard))
|
|
48
|
+
await rm(guard, { force: true });
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
if (await ConfigLock.#abandoned(lockPath))
|
|
53
|
+
await rm(lockPath, { force: true });
|
|
54
|
+
} finally {
|
|
55
|
+
await rm(guard, { force: true });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
static async#abandoned(lockPath) {
|
|
59
|
+
const info = await stat(lockPath).catch(() => null);
|
|
60
|
+
if (!info)
|
|
61
|
+
return false;
|
|
62
|
+
const holder = await ConfigLock.#holder(lockPath);
|
|
63
|
+
if (!holder)
|
|
64
|
+
return Date.now() - info.mtimeMs > ConfigLock.#unknownHolderStaleMs;
|
|
65
|
+
return !ConfigLock.#isAlive(holder.pid);
|
|
66
|
+
}
|
|
67
|
+
static async#holder(lockPath) {
|
|
68
|
+
try {
|
|
69
|
+
const parsed = JSON.parse(await readFile(lockPath, "utf8"));
|
|
70
|
+
return typeof parsed.pid === "number" && typeof parsed.at === "number" ? { pid: parsed.pid, at: parsed.at } : null;
|
|
71
|
+
} catch {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
static #isAlive(pid) {
|
|
76
|
+
if (!Number.isInteger(pid) || pid <= 0)
|
|
77
|
+
return false;
|
|
78
|
+
try {
|
|
79
|
+
process.kill(pid, 0);
|
|
80
|
+
return true;
|
|
81
|
+
} catch (error) {
|
|
82
|
+
return error.code === "EPERM";
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export { ConfigLock };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
runner,
|
|
4
|
+
script
|
|
5
|
+
} from "./index-w2zdcw3k.js";
|
|
6
|
+
import {
|
|
7
|
+
generatedFilesForSync,
|
|
8
|
+
createPassedPrimitiveReport,
|
|
9
|
+
scalarChangedFiles
|
|
10
|
+
} from "./index-myhc3c1j.js";
|
|
11
|
+
import {
|
|
12
|
+
pluralizeName
|
|
13
|
+
} from "./index-nz8prx9g.js";
|
|
14
|
+
|
|
15
|
+
// pkgs/@akanjs/cli/scalar/scalar.runner.ts
|
|
16
|
+
class ScalarRunner extends runner("scalar") {
|
|
17
|
+
async applyScalarTemplate(sys, scalarName) {
|
|
18
|
+
await sys.applyTemplate({
|
|
19
|
+
basePath: "./lib/__scalar",
|
|
20
|
+
template: "__scalar",
|
|
21
|
+
dict: { model: scalarName, models: pluralizeName(scalarName), sysName: sys.name },
|
|
22
|
+
overwrite: false
|
|
23
|
+
});
|
|
24
|
+
const read = async (suffix) => {
|
|
25
|
+
const filename = `${scalarName}.${suffix}`;
|
|
26
|
+
return { filename, content: await sys.readFile(`lib/__scalar/${scalarName}/${filename}`) };
|
|
27
|
+
};
|
|
28
|
+
return {
|
|
29
|
+
abstract: await read("abstract.md"),
|
|
30
|
+
constant: await read("constant.ts"),
|
|
31
|
+
dictionary: await read("dictionary.ts"),
|
|
32
|
+
document: await read("document.ts")
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// pkgs/@akanjs/cli/scalar/scalar.script.ts
|
|
38
|
+
class ScalarScript extends script("scalar", [ScalarRunner]) {
|
|
39
|
+
async createScalar(sys, scalarName) {
|
|
40
|
+
const files = await this.scalarRunner.applyScalarTemplate(sys, scalarName);
|
|
41
|
+
return createPassedPrimitiveReport({
|
|
42
|
+
command: "create-scalar",
|
|
43
|
+
changedFiles: scalarChangedFiles(sys, scalarName, files),
|
|
44
|
+
generatedFiles: generatedFilesForSync(sys),
|
|
45
|
+
target: sys.name
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
async removeScalar(sys, scalarName) {
|
|
49
|
+
await sys.removeDir(`lib/__scalar/${scalarName}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export { ScalarScript };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
} from "./index-
|
|
3
|
+
FileSys2
|
|
4
|
+
} from "./index-5b6tavv3.js";
|
|
5
5
|
|
|
6
6
|
// pkgs/@akanjs/devkit/dependencyScanner.ts
|
|
7
7
|
import { builtinModules } from "module";
|
|
@@ -10,7 +10,10 @@ import ignore from "ignore";
|
|
|
10
10
|
import ts from "typescript";
|
|
11
11
|
var testFileRegex = /\.(?:test|spec)\.[cm]?[tj]sx?$/;
|
|
12
12
|
var skipDirs = ["node_modules", "dist", "build", ".git", ".next", "public", "ios", "android", "__fixtures__"];
|
|
13
|
-
var isSkippedPath = (filePath) =>
|
|
13
|
+
var isSkippedPath = (filePath) => {
|
|
14
|
+
const posixPath = filePath.split(path.sep).join("/");
|
|
15
|
+
return skipDirs.some((dir) => posixPath.includes(`/${dir}/`) || posixPath.startsWith(`${dir}/`));
|
|
16
|
+
};
|
|
14
17
|
var builtinModuleSet = new Set([...builtinModules, ...builtinModules.map((mod) => `node:${mod}`)]);
|
|
15
18
|
var stripShebang = (source) => source.replace(/^#!.*(?:\r?\n|$)/, "");
|
|
16
19
|
|
|
@@ -54,24 +57,21 @@ class TypeScriptDependencyScanner2 {
|
|
|
54
57
|
async getPackageBuildDependencies(projectName) {
|
|
55
58
|
const runtimeDeps = new Set;
|
|
56
59
|
const devDeps = new Set;
|
|
57
|
-
const sourceFiles = await this.#
|
|
58
|
-
|
|
59
|
-
excludeTestFiles: true
|
|
60
|
-
});
|
|
61
|
-
const cssFiles = await this.#findCssFiles(this.#directory);
|
|
60
|
+
const sourceFiles = await this.#findFiles("**/*.{ts,tsx}", { excludeBuildFiles: true, excludeTestFiles: true });
|
|
61
|
+
const cssFiles = await this.#findFiles("**/*.css");
|
|
62
62
|
for (const filePath of sourceFiles) {
|
|
63
|
-
const fileContent = await
|
|
63
|
+
const fileContent = await FileSys2.readText(filePath);
|
|
64
64
|
const { imports, typeImports } = this.#extractImports(fileContent, filePath);
|
|
65
65
|
this.#addNormalizedImports(runtimeDeps, imports, projectName);
|
|
66
66
|
this.#addNormalizedImports(devDeps, typeImports, projectName);
|
|
67
67
|
}
|
|
68
68
|
for (const filePath of cssFiles) {
|
|
69
|
-
const fileContent = await
|
|
69
|
+
const fileContent = await FileSys2.readText(filePath);
|
|
70
70
|
this.#addNormalizedImports(runtimeDeps, this.#extractCssPluginImports(fileContent), projectName);
|
|
71
71
|
}
|
|
72
72
|
const buildFilePath = path.join(this.#directory, "build.ts");
|
|
73
|
-
if (await
|
|
74
|
-
const fileContent = await
|
|
73
|
+
if (await FileSys2.fileExists(buildFilePath)) {
|
|
74
|
+
const fileContent = await FileSys2.readText(buildFilePath);
|
|
75
75
|
const { imports, typeImports } = this.#extractImports(fileContent, buildFilePath);
|
|
76
76
|
this.#addNormalizedImports(devDeps, [...imports, ...typeImports], projectName);
|
|
77
77
|
}
|
|
@@ -95,7 +95,7 @@ class TypeScriptDependencyScanner2 {
|
|
|
95
95
|
if (!await Bun.file(packageJsonPath).exists())
|
|
96
96
|
return false;
|
|
97
97
|
try {
|
|
98
|
-
const packageJson = await
|
|
98
|
+
const packageJson = await FileSys2.readJson(packageJsonPath);
|
|
99
99
|
return packageJson.name === dep && !!packageJson.version;
|
|
100
100
|
} catch {
|
|
101
101
|
return false;
|
|
@@ -106,27 +106,21 @@ class TypeScriptDependencyScanner2 {
|
|
|
106
106
|
return this.#getImportSetsFromDependencies(depSets, fileDependencies);
|
|
107
107
|
}
|
|
108
108
|
#getImportSetsFromDependencies(depSets, fileDependencies) {
|
|
109
|
-
const importedDepSets =
|
|
110
|
-
for (
|
|
111
|
-
|
|
112
|
-
fileDependencies.forEach((imps) => {
|
|
113
|
-
imps.forEach((imp) => {
|
|
109
|
+
const importedDepSets = depSets.map(() => new Set);
|
|
110
|
+
for (const imps of fileDependencies.values())
|
|
111
|
+
for (const imp of imps) {
|
|
114
112
|
if (imp.startsWith("."))
|
|
115
|
-
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
113
|
+
continue;
|
|
114
|
+
const parts = imp.split("/");
|
|
115
|
+
for (let length = 1;length <= parts.length; length++) {
|
|
116
|
+
const importName = parts.slice(0, length).join("/");
|
|
117
|
+
const setIndex = depSets.findIndex((depSet) => depSet.has(importName));
|
|
118
|
+
if (setIndex === -1)
|
|
119
|
+
continue;
|
|
120
|
+
importedDepSets[setIndex]?.add(importName);
|
|
121
|
+
break;
|
|
127
122
|
}
|
|
128
|
-
}
|
|
129
|
-
});
|
|
123
|
+
}
|
|
130
124
|
return importedDepSets;
|
|
131
125
|
}
|
|
132
126
|
async getDependencies() {
|
|
@@ -134,43 +128,25 @@ class TypeScriptDependencyScanner2 {
|
|
|
134
128
|
this.#fileRuntimeDependencies.clear();
|
|
135
129
|
this.#fileTypeDependencies.clear();
|
|
136
130
|
this.#visitedFiles.clear();
|
|
137
|
-
const
|
|
138
|
-
for (const file of files)
|
|
131
|
+
for (const file of await this.#findFiles("**/*.{ts,tsx}"))
|
|
139
132
|
await this.#analyzeFile(file, this.#directory);
|
|
140
133
|
return this.#fileDependencies;
|
|
141
134
|
}
|
|
142
|
-
async#
|
|
135
|
+
async#findFiles(pattern, {
|
|
143
136
|
excludeBuildFiles = false,
|
|
144
137
|
excludeTestFiles = false
|
|
145
138
|
} = {}) {
|
|
146
139
|
const files = [];
|
|
147
|
-
const
|
|
148
|
-
for await (const filePath of glob.scan({ cwd: directory, onlyFiles: true })) {
|
|
140
|
+
for await (const filePath of new Bun.Glob(pattern).scan({ cwd: this.#directory, onlyFiles: true })) {
|
|
149
141
|
if (isSkippedPath(filePath))
|
|
150
142
|
continue;
|
|
151
143
|
if (excludeBuildFiles && filePath === "build.ts")
|
|
152
144
|
continue;
|
|
153
145
|
if (excludeTestFiles && testFileRegex.test(filePath))
|
|
154
146
|
continue;
|
|
155
|
-
const fullPath = path.join(directory, filePath);
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
continue;
|
|
159
|
-
files.push(fullPath);
|
|
160
|
-
}
|
|
161
|
-
return files;
|
|
162
|
-
}
|
|
163
|
-
async#findCssFiles(directory) {
|
|
164
|
-
const files = [];
|
|
165
|
-
const glob = new Bun.Glob("**/*.css");
|
|
166
|
-
for await (const filePath of glob.scan({ cwd: directory, onlyFiles: true })) {
|
|
167
|
-
if (isSkippedPath(filePath))
|
|
168
|
-
continue;
|
|
169
|
-
const fullPath = path.join(directory, filePath);
|
|
170
|
-
const relativePath = path.relative(this.#workspaceRoot, fullPath);
|
|
171
|
-
if (this.#ig.ignores(relativePath))
|
|
172
|
-
continue;
|
|
173
|
-
files.push(fullPath);
|
|
147
|
+
const fullPath = path.join(this.#directory, filePath);
|
|
148
|
+
if (!this.#ig.ignores(path.relative(this.#workspaceRoot, fullPath)))
|
|
149
|
+
files.push(fullPath);
|
|
174
150
|
}
|
|
175
151
|
return files;
|
|
176
152
|
}
|
|
@@ -179,7 +155,7 @@ class TypeScriptDependencyScanner2 {
|
|
|
179
155
|
return;
|
|
180
156
|
this.#visitedFiles.add(filePath);
|
|
181
157
|
try {
|
|
182
|
-
const fileContent = await
|
|
158
|
+
const fileContent = await FileSys2.readText(filePath);
|
|
183
159
|
const { imports, typeImports } = this.#extractImports(fileContent, filePath);
|
|
184
160
|
const resolvedImports = await this.#resolveImports(imports, filePath, baseDir);
|
|
185
161
|
const resolvedTypeImports = await this.#resolveImports(typeImports, filePath, baseDir);
|
|
@@ -191,19 +167,17 @@ class TypeScriptDependencyScanner2 {
|
|
|
191
167
|
}
|
|
192
168
|
async#resolveImports(imports, filePath, baseDir) {
|
|
193
169
|
return await Promise.all(imports.map(async (importPath) => {
|
|
194
|
-
if (importPath.startsWith("."))
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
}
|
|
198
|
-
return importPath;
|
|
170
|
+
if (!importPath.startsWith("."))
|
|
171
|
+
return importPath;
|
|
172
|
+
return await this.#ensureExtension(`./${path.join(path.relative(baseDir, filePath), importPath)}`);
|
|
199
173
|
}));
|
|
200
174
|
}
|
|
201
175
|
async#ensureExtension(filePath) {
|
|
202
|
-
if (await
|
|
176
|
+
if (await FileSys2.fileExists(`${filePath}.ts`))
|
|
203
177
|
return `${filePath}.ts`;
|
|
204
|
-
else if (await
|
|
178
|
+
else if (await FileSys2.fileExists(`${filePath}.tsx`))
|
|
205
179
|
return `${filePath}.tsx`;
|
|
206
|
-
else if (await
|
|
180
|
+
else if (await FileSys2.fileExists(filePath))
|
|
207
181
|
return filePath;
|
|
208
182
|
return `${filePath}.ts`;
|
|
209
183
|
}
|
|
@@ -262,22 +236,14 @@ class TypeScriptDependencyScanner2 {
|
|
|
262
236
|
`;
|
|
263
237
|
const projectImports = imports.filter((i) => !i.startsWith("react") && !i.startsWith("@"));
|
|
264
238
|
const externalImports = imports.filter((i) => i.startsWith("react") || i.startsWith("@"));
|
|
265
|
-
if (projectImports.length > 0)
|
|
239
|
+
if (projectImports.length > 0)
|
|
266
240
|
graph += ` Project dependencies:
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
`;
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
if (externalImports.length > 0) {
|
|
241
|
+
${projectImports.map((imp) => ` \u2192 ${imp}
|
|
242
|
+
`).join("")}`;
|
|
243
|
+
if (externalImports.length > 0)
|
|
274
244
|
graph += ` External dependencies:
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
graph += ` \u2192 ${imp}
|
|
278
|
-
`;
|
|
279
|
-
});
|
|
280
|
-
}
|
|
245
|
+
${externalImports.map((imp) => ` \u2192 ${imp}
|
|
246
|
+
`).join("")}`;
|
|
281
247
|
graph += `
|
|
282
248
|
`;
|
|
283
249
|
}
|