@akanjs/devkit 1.0.20 → 2.1.0-rc.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/README.ko.md +65 -0
- package/README.md +62 -6
- package/aiEditor.ts +304 -0
- package/akanApp/akanApp.host.ts +393 -0
- package/akanApp/index.ts +1 -0
- package/akanConfig/akanConfig.test.ts +236 -0
- package/akanConfig/akanConfig.ts +384 -0
- package/akanConfig/index.ts +2 -0
- package/akanConfig/types.ts +23 -0
- package/applicationBuildReporter.ts +69 -0
- package/applicationBuildRunner.ts +302 -0
- package/applicationReleasePackager.ts +206 -0
- package/artifact/implicitRootLayout.ts +155 -0
- package/artifact/index.ts +1 -0
- package/artifact/routeSeedIndex.test.ts +98 -0
- package/artifact/routeSeedIndex.ts +130 -0
- package/auth.ts +41 -0
- package/builder.ts +164 -0
- package/capacitor.base.config.ts +88 -0
- package/capacitorApp.ts +440 -0
- package/commandDecorators/argMeta.ts +102 -0
- package/commandDecorators/command.ts +351 -0
- package/commandDecorators/commandBuilder.ts +224 -0
- package/commandDecorators/commandDecorators.test.ts +212 -0
- package/commandDecorators/commandMeta.ts +7 -0
- package/commandDecorators/dependencyBuilder.ts +100 -0
- package/{esm/src/commandDecorators/helpFormatter.js → commandDecorators/helpFormatter.ts} +100 -47
- package/{esm/src/commandDecorators/index.js → commandDecorators/index.ts} +4 -2
- package/commandDecorators/targetMeta.ts +31 -0
- package/commandDecorators/types.ts +10 -0
- package/constants.ts +25 -0
- package/createTunnel.ts +36 -0
- package/dependencyScanner.ts +357 -0
- package/devkitUtils.test.ts +259 -0
- package/executors.test.ts +315 -0
- package/executors.ts +1390 -0
- package/{esm/src/extractDeps.js → extractDeps.ts} +26 -20
- package/{esm/src/fileEditor.js → fileEditor.ts} +51 -32
- package/fileSys.ts +39 -0
- package/frontendBuild/allRoutesBuilder.ts +103 -0
- package/frontendBuild/buildRouteClient.test.ts +190 -0
- package/frontendBuild/clientBuildTypes.ts +114 -0
- package/frontendBuild/clientEntriesBundler.ts +303 -0
- package/frontendBuild/clientEntryDiscovery.ts +199 -0
- package/frontendBuild/csrArtifactBuilder.ts +237 -0
- package/frontendBuild/cssCompiler.ts +286 -0
- package/frontendBuild/cssImportResolver.ts +116 -0
- package/frontendBuild/fontOptimizer.ts +427 -0
- package/frontendBuild/frontendBuild.test.ts +204 -0
- package/frontendBuild/hmrChangeClassifier.ts +28 -0
- package/frontendBuild/hmrWatcher.ts +102 -0
- package/frontendBuild/index.ts +18 -0
- package/frontendBuild/pagesBundleBuilder.ts +137 -0
- package/frontendBuild/pagesEntrySourceGenerator.ts +37 -0
- package/frontendBuild/precompressArtifacts.ts +59 -0
- package/frontendBuild/routeClientBuilder.ts +290 -0
- package/frontendBuild/routesManifestArtifactSerializer.ts +62 -0
- package/frontendBuild/ssrBaseArtifactBuilder.ts +139 -0
- package/frontendBuild/vendorSpecifiers.ts +16 -0
- package/frontendBuild/watchRootResolver.ts +28 -0
- package/getCredentials.ts +19 -0
- package/getDirname.ts +3 -0
- package/getModelFileData.ts +59 -0
- package/getRelatedCnsts.ts +313 -0
- package/guideline.ts +19 -0
- package/incrementalBuilder/incrementalBuilder.host.test.ts +51 -0
- package/incrementalBuilder/incrementalBuilder.host.ts +152 -0
- package/incrementalBuilder/incrementalBuilder.proc.ts +331 -0
- package/incrementalBuilder/index.ts +1 -0
- package/{esm/src/index.js → index.ts} +28 -15
- package/lint/no-deep-internal-import.grit +25 -0
- package/lint/no-import-client-functions.grit +32 -0
- package/lint/no-import-external-library.grit +21 -0
- package/lint/no-js-private-class-method.grit +42 -0
- package/lint/no-use-client-in-server.grit +7 -0
- package/lint/non-scalar-props-restricted.grit +13 -0
- package/linter.ts +271 -0
- package/mobile/index.ts +1 -0
- package/mobile/mobileTarget.test.ts +53 -0
- package/mobile/mobileTarget.ts +88 -0
- package/package.json +48 -31
- package/prompter.ts +72 -0
- package/scanInfo.ts +606 -0
- package/selectModel.ts +11 -0
- package/{esm/src/spinner.js → spinner.ts} +22 -28
- package/{esm/src/capacitorApp.js → src/capacitorApp.ts} +82 -81
- package/sshTunnel.ts +152 -0
- package/{esm/src/streamAi.js → streamAi.ts} +18 -12
- package/transforms/barrelAnalyzer.ts +278 -0
- package/transforms/barrelImportsPlugin.ts +504 -0
- package/transforms/externalizeFrameworkPlugin.ts +185 -0
- package/transforms/index.ts +5 -0
- package/transforms/rscUseClientTransform.ts +59 -0
- package/transforms/transforms.test.ts +208 -0
- package/transforms/useClientBundlePlugin.ts +47 -0
- package/tsconfig.json +37 -0
- package/typeChecker.ts +264 -0
- package/types.ts +44 -0
- package/ui/MultiScrollList.tsx +242 -0
- package/ui/ScrollList.tsx +107 -0
- package/ui/index.ts +2 -0
- package/{esm/src/uploadRelease.js → uploadRelease.ts} +50 -34
- package/{esm/src/useStdoutDimensions.js → useStdoutDimensions.ts} +5 -5
- package/cjs/index.js +0 -21
- package/cjs/src/aiEditor.js +0 -311
- package/cjs/src/auth.js +0 -72
- package/cjs/src/builder.js +0 -114
- package/cjs/src/capacitorApp.js +0 -313
- package/cjs/src/commandDecorators/argMeta.js +0 -88
- package/cjs/src/commandDecorators/command.js +0 -324
- package/cjs/src/commandDecorators/commandMeta.js +0 -30
- package/cjs/src/commandDecorators/helpFormatter.js +0 -211
- package/cjs/src/commandDecorators/index.js +0 -31
- package/cjs/src/commandDecorators/targetMeta.js +0 -57
- package/cjs/src/commandDecorators/types.js +0 -15
- package/cjs/src/constants.js +0 -46
- package/cjs/src/createTunnel.js +0 -49
- package/cjs/src/dependencyScanner.js +0 -220
- package/cjs/src/executors.js +0 -964
- package/cjs/src/extractDeps.js +0 -103
- package/cjs/src/fileEditor.js +0 -120
- package/cjs/src/getCredentials.js +0 -44
- package/cjs/src/getDirname.js +0 -38
- package/cjs/src/getModelFileData.js +0 -66
- package/cjs/src/getRelatedCnsts.js +0 -260
- package/cjs/src/guideline.js +0 -15
- package/cjs/src/index.js +0 -65
- package/cjs/src/linter.js +0 -238
- package/cjs/src/prompter.js +0 -85
- package/cjs/src/scanInfo.js +0 -491
- package/cjs/src/selectModel.js +0 -46
- package/cjs/src/spinner.js +0 -93
- package/cjs/src/streamAi.js +0 -62
- package/cjs/src/typeChecker.js +0 -207
- package/cjs/src/types.js +0 -15
- package/cjs/src/uploadRelease.js +0 -112
- package/cjs/src/useStdoutDimensions.js +0 -43
- package/esm/index.js +0 -1
- package/esm/src/aiEditor.js +0 -282
- package/esm/src/auth.js +0 -42
- package/esm/src/builder.js +0 -81
- package/esm/src/commandDecorators/argMeta.js +0 -54
- package/esm/src/commandDecorators/command.js +0 -290
- package/esm/src/commandDecorators/commandMeta.js +0 -7
- package/esm/src/commandDecorators/targetMeta.js +0 -33
- package/esm/src/commandDecorators/types.js +0 -0
- package/esm/src/constants.js +0 -17
- package/esm/src/createTunnel.js +0 -26
- package/esm/src/dependencyScanner.js +0 -187
- package/esm/src/executors.js +0 -928
- package/esm/src/getCredentials.js +0 -11
- package/esm/src/getDirname.js +0 -5
- package/esm/src/getModelFileData.js +0 -33
- package/esm/src/getRelatedCnsts.js +0 -221
- package/esm/src/guideline.js +0 -0
- package/esm/src/linter.js +0 -205
- package/esm/src/prompter.js +0 -51
- package/esm/src/scanInfo.js +0 -455
- package/esm/src/selectModel.js +0 -13
- package/esm/src/typeChecker.js +0 -174
- package/esm/src/types.js +0 -0
- package/index.d.ts +0 -1
- package/src/aiEditor.d.ts +0 -50
- package/src/auth.d.ts +0 -9
- package/src/builder.d.ts +0 -18
- package/src/capacitorApp.d.ts +0 -39
- package/src/commandDecorators/argMeta.d.ts +0 -67
- package/src/commandDecorators/command.d.ts +0 -2
- package/src/commandDecorators/commandMeta.d.ts +0 -2
- package/src/commandDecorators/helpFormatter.d.ts +0 -3
- package/src/commandDecorators/index.d.ts +0 -6
- package/src/commandDecorators/targetMeta.d.ts +0 -19
- package/src/commandDecorators/types.d.ts +0 -1
- package/src/constants.d.ts +0 -26
- package/src/createTunnel.d.ts +0 -8
- package/src/dependencyScanner.d.ts +0 -23
- package/src/executors.d.ts +0 -296
- package/src/extractDeps.d.ts +0 -7
- package/src/fileEditor.d.ts +0 -16
- package/src/getCredentials.d.ts +0 -12
- package/src/getDirname.d.ts +0 -1
- package/src/getModelFileData.d.ts +0 -16
- package/src/getRelatedCnsts.d.ts +0 -53
- package/src/guideline.d.ts +0 -19
- package/src/index.d.ts +0 -23
- package/src/linter.d.ts +0 -109
- package/src/prompter.d.ts +0 -14
- package/src/scanInfo.d.ts +0 -82
- package/src/selectModel.d.ts +0 -1
- package/src/spinner.d.ts +0 -20
- package/src/streamAi.d.ts +0 -6
- package/src/typeChecker.d.ts +0 -52
- package/src/types.d.ts +0 -31
- package/src/uploadRelease.d.ts +0 -10
- package/src/useStdoutDimensions.d.ts +0 -1
package/cjs/src/typeChecker.js
DELETED
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __export = (target, all) => {
|
|
8
|
-
for (var name in all)
|
|
9
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
-
};
|
|
11
|
-
var __copyProps = (to, from, except, desc) => {
|
|
12
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
-
for (let key of __getOwnPropNames(from))
|
|
14
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
-
}
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
-
mod
|
|
26
|
-
));
|
|
27
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
-
var typeChecker_exports = {};
|
|
29
|
-
__export(typeChecker_exports, {
|
|
30
|
-
TypeChecker: () => TypeChecker
|
|
31
|
-
});
|
|
32
|
-
module.exports = __toCommonJS(typeChecker_exports);
|
|
33
|
-
var import_chalk = __toESM(require("chalk"));
|
|
34
|
-
var fs = __toESM(require("fs"));
|
|
35
|
-
var path = __toESM(require("path"));
|
|
36
|
-
var ts = __toESM(require("typescript"));
|
|
37
|
-
class TypeChecker {
|
|
38
|
-
configPath;
|
|
39
|
-
configFile;
|
|
40
|
-
config;
|
|
41
|
-
constructor(executor) {
|
|
42
|
-
const configPath = this.#findConfigFile(executor.cwdPath);
|
|
43
|
-
if (!configPath)
|
|
44
|
-
throw new Error("No tsconfig.json found in the project");
|
|
45
|
-
this.configPath = configPath;
|
|
46
|
-
this.configFile = ts.readConfigFile(this.configPath, (fileName) => ts.sys.readFile(fileName));
|
|
47
|
-
const parsedConfig = ts.parseJsonConfigFileContent(
|
|
48
|
-
this.configFile.config,
|
|
49
|
-
ts.sys,
|
|
50
|
-
path.dirname(this.configPath),
|
|
51
|
-
void 0,
|
|
52
|
-
this.configPath
|
|
53
|
-
);
|
|
54
|
-
if (parsedConfig.errors.length > 0) {
|
|
55
|
-
const errorMessages = parsedConfig.errors.map((error) => ts.flattenDiagnosticMessageText(error.messageText, "\n")).join("\n");
|
|
56
|
-
throw new Error(`Error parsing tsconfig.json:
|
|
57
|
-
${errorMessages}`);
|
|
58
|
-
}
|
|
59
|
-
this.config = parsedConfig;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Find tsconfig.json by walking up the directory tree
|
|
63
|
-
*/
|
|
64
|
-
#findConfigFile(searchPath) {
|
|
65
|
-
return ts.findConfigFile(searchPath, (fileName) => ts.sys.fileExists(fileName), "tsconfig.json");
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Type-check a single TypeScript file
|
|
69
|
-
* @param filePath - Path to the TypeScript file to check
|
|
70
|
-
* @returns Array of diagnostic messages
|
|
71
|
-
*/
|
|
72
|
-
check(filePath) {
|
|
73
|
-
const program = ts.createProgram([filePath], this.config.options);
|
|
74
|
-
const diagnostics = [
|
|
75
|
-
...program.getSemanticDiagnostics(),
|
|
76
|
-
...program.getSyntacticDiagnostics(),
|
|
77
|
-
// Only check declaration diagnostics when declaration emit is enabled
|
|
78
|
-
...this.config.options.declaration ? program.getDeclarationDiagnostics() : []
|
|
79
|
-
];
|
|
80
|
-
const errors = diagnostics.filter((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error);
|
|
81
|
-
const warnings = diagnostics.filter((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Warning);
|
|
82
|
-
const fileDiagnostics = diagnostics.filter((diagnostic) => diagnostic.file?.fileName === filePath);
|
|
83
|
-
const fileErrors = fileDiagnostics.filter((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error);
|
|
84
|
-
const fileWarnings = fileDiagnostics.filter((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Warning);
|
|
85
|
-
return { diagnostics, errors, warnings, fileDiagnostics, fileErrors, fileWarnings };
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Format diagnostics for console output
|
|
89
|
-
* @param diagnostics - Array of TypeScript diagnostics
|
|
90
|
-
* @returns Formatted string
|
|
91
|
-
*/
|
|
92
|
-
formatDiagnostics(diagnostics) {
|
|
93
|
-
if (diagnostics.length === 0)
|
|
94
|
-
return import_chalk.default.bold("\u2705 No type errors found");
|
|
95
|
-
const output = [];
|
|
96
|
-
let errorCount = 0;
|
|
97
|
-
let warningCount = 0;
|
|
98
|
-
let suggestionCount = 0;
|
|
99
|
-
const diagnosticsByFile = /* @__PURE__ */ new Map();
|
|
100
|
-
diagnostics.forEach((diagnostic) => {
|
|
101
|
-
if (diagnostic.category === ts.DiagnosticCategory.Error)
|
|
102
|
-
errorCount++;
|
|
103
|
-
else if (diagnostic.category === ts.DiagnosticCategory.Warning)
|
|
104
|
-
warningCount++;
|
|
105
|
-
else if (diagnostic.category === ts.DiagnosticCategory.Suggestion)
|
|
106
|
-
suggestionCount++;
|
|
107
|
-
if (diagnostic.file) {
|
|
108
|
-
const fileName = diagnostic.file.fileName;
|
|
109
|
-
if (!diagnosticsByFile.has(fileName))
|
|
110
|
-
diagnosticsByFile.set(fileName, []);
|
|
111
|
-
const fileDiagnostics = diagnosticsByFile.get(fileName);
|
|
112
|
-
if (fileDiagnostics)
|
|
113
|
-
fileDiagnostics.push(diagnostic);
|
|
114
|
-
} else {
|
|
115
|
-
if (!diagnosticsByFile.has(""))
|
|
116
|
-
diagnosticsByFile.set("", []);
|
|
117
|
-
const fileDiagnostics = diagnosticsByFile.get("");
|
|
118
|
-
if (fileDiagnostics)
|
|
119
|
-
fileDiagnostics.push(diagnostic);
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
diagnosticsByFile.forEach((fileDiagnostics, fileName) => {
|
|
123
|
-
if (fileName)
|
|
124
|
-
output.push(`
|
|
125
|
-
${import_chalk.default.cyan(fileName)}`);
|
|
126
|
-
fileDiagnostics.forEach((diagnostic) => {
|
|
127
|
-
const categoryText = diagnostic.category === ts.DiagnosticCategory.Error ? "error" : diagnostic.category === ts.DiagnosticCategory.Warning ? "warning" : "suggestion";
|
|
128
|
-
const categoryColor = diagnostic.category === ts.DiagnosticCategory.Error ? import_chalk.default.red : diagnostic.category === ts.DiagnosticCategory.Warning ? import_chalk.default.yellow : import_chalk.default.blue;
|
|
129
|
-
const icon = diagnostic.category === ts.DiagnosticCategory.Error ? "\u274C" : diagnostic.category === ts.DiagnosticCategory.Warning ? "\u26A0\uFE0F" : "\u{1F4A1}";
|
|
130
|
-
const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
|
|
131
|
-
const tsCode = import_chalk.default.dim(`(TS${diagnostic.code})`);
|
|
132
|
-
if (diagnostic.file && diagnostic.start !== void 0) {
|
|
133
|
-
const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
|
134
|
-
output.push(`
|
|
135
|
-
${icon} ${categoryColor(categoryText)}: ${message} ${tsCode}`);
|
|
136
|
-
output.push(` ${import_chalk.default.gray("at")} ${fileName}:${import_chalk.default.bold(`${line + 1}:${character + 1}`)}`);
|
|
137
|
-
const sourceLines = diagnostic.file.text.split("\n");
|
|
138
|
-
if (line < sourceLines.length) {
|
|
139
|
-
const sourceLine = sourceLines[line];
|
|
140
|
-
const lineNumber = (line + 1).toString().padStart(5, " ");
|
|
141
|
-
output.push(`
|
|
142
|
-
${import_chalk.default.dim(lineNumber + " |")} ${sourceLine}`);
|
|
143
|
-
const underlinePrefix = " ".repeat(character);
|
|
144
|
-
const length = diagnostic.length ?? 1;
|
|
145
|
-
const underline = "~".repeat(Math.max(1, length));
|
|
146
|
-
output.push(
|
|
147
|
-
`${import_chalk.default.dim(" ".repeat(lineNumber.length) + " |")} ${underlinePrefix}${categoryColor(underline)}`
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
} else
|
|
151
|
-
output.push(`
|
|
152
|
-
${icon} ${categoryColor(categoryText)}: ${message} ${tsCode}`);
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
const summary = [];
|
|
156
|
-
if (errorCount > 0)
|
|
157
|
-
summary.push(import_chalk.default.red(`${errorCount} error(s)`));
|
|
158
|
-
if (warningCount > 0)
|
|
159
|
-
summary.push(import_chalk.default.yellow(`${warningCount} warning(s)`));
|
|
160
|
-
if (suggestionCount > 0)
|
|
161
|
-
summary.push(import_chalk.default.blue(`${suggestionCount} suggestion(s)`));
|
|
162
|
-
return `
|
|
163
|
-
${summary.join(", ")} found` + output.join("\n");
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Get detailed diagnostic information with code snippet
|
|
167
|
-
* @param filePath - Path to the TypeScript file to check
|
|
168
|
-
* @returns Object containing diagnostics and detailed information
|
|
169
|
-
*/
|
|
170
|
-
getDetailedDiagnostics(filePath) {
|
|
171
|
-
const { diagnostics } = this.check(filePath);
|
|
172
|
-
const sourceFile = ts.createSourceFile(filePath, fs.readFileSync(filePath, "utf8"), ts.ScriptTarget.Latest, true);
|
|
173
|
-
const details = diagnostics.map((diagnostic) => {
|
|
174
|
-
if (diagnostic.file && diagnostic.start !== void 0) {
|
|
175
|
-
const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
|
176
|
-
const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
|
|
177
|
-
const lines = sourceFile.text.split("\n");
|
|
178
|
-
const codeSnippet = line < lines.length ? lines[line] : void 0;
|
|
179
|
-
return { line: line + 1, column: character + 1, message, code: diagnostic.code, codeSnippet };
|
|
180
|
-
}
|
|
181
|
-
return {
|
|
182
|
-
line: 0,
|
|
183
|
-
column: 0,
|
|
184
|
-
message: ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"),
|
|
185
|
-
code: diagnostic.code
|
|
186
|
-
};
|
|
187
|
-
});
|
|
188
|
-
return { diagnostics, details };
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* Check if a file has type errors
|
|
192
|
-
* @param filePath - Path to the TypeScript file to check
|
|
193
|
-
* @returns true if there are no type errors, false otherwise
|
|
194
|
-
*/
|
|
195
|
-
hasNoTypeErrors(filePath) {
|
|
196
|
-
try {
|
|
197
|
-
const { diagnostics } = this.check(filePath);
|
|
198
|
-
return diagnostics.length === 0;
|
|
199
|
-
} catch (error) {
|
|
200
|
-
return false;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
205
|
-
0 && (module.exports = {
|
|
206
|
-
TypeChecker
|
|
207
|
-
});
|
package/cjs/src/types.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
-
var __copyProps = (to, from, except, desc) => {
|
|
6
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
7
|
-
for (let key of __getOwnPropNames(from))
|
|
8
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
9
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
10
|
-
}
|
|
11
|
-
return to;
|
|
12
|
-
};
|
|
13
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
14
|
-
var types_exports = {};
|
|
15
|
-
module.exports = __toCommonJS(types_exports);
|
package/cjs/src/uploadRelease.js
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __export = (target, all) => {
|
|
8
|
-
for (var name in all)
|
|
9
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
-
};
|
|
11
|
-
var __copyProps = (to, from, except, desc) => {
|
|
12
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
-
for (let key of __getOwnPropNames(from))
|
|
14
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
-
}
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
-
mod
|
|
26
|
-
));
|
|
27
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
-
var uploadRelease_exports = {};
|
|
29
|
-
__export(uploadRelease_exports, {
|
|
30
|
-
uploadRelease: () => uploadRelease
|
|
31
|
-
});
|
|
32
|
-
module.exports = __toCommonJS(uploadRelease_exports);
|
|
33
|
-
var import_common = require("@akanjs/common");
|
|
34
|
-
var import_axios = __toESM(require("axios"));
|
|
35
|
-
var import_form_data = __toESM(require("form-data"));
|
|
36
|
-
var import_fs = __toESM(require("fs"));
|
|
37
|
-
var import_spinner = require("./spinner");
|
|
38
|
-
const spinning = (message) => {
|
|
39
|
-
const spinner = new import_spinner.Spinner(message, { prefix: message, enableSpin: true }).start();
|
|
40
|
-
return spinner;
|
|
41
|
-
};
|
|
42
|
-
const uploadRelease = async (appName, {
|
|
43
|
-
workspaceRoot,
|
|
44
|
-
environment,
|
|
45
|
-
buildNum,
|
|
46
|
-
platformVersion,
|
|
47
|
-
os,
|
|
48
|
-
local
|
|
49
|
-
}) => {
|
|
50
|
-
const logger = new import_common.Logger("uploadRelease");
|
|
51
|
-
const basePath = local ? "http://localhost:8080/backend" : "https://cloud.akanjs.com/backend";
|
|
52
|
-
const buildPath = `${workspaceRoot}/releases/builds/${appName}-release.tar.gz`;
|
|
53
|
-
const appBuildPath = `${workspaceRoot}/releases/builds/${appName}-appBuild.zip`;
|
|
54
|
-
const sourcePath = `${workspaceRoot}/releases/sources/${appName}-source.tar.gz`;
|
|
55
|
-
const readingFilesSpinner = spinning("Reading files...");
|
|
56
|
-
try {
|
|
57
|
-
const build = import_fs.default.readFileSync(buildPath);
|
|
58
|
-
const source = import_fs.default.readFileSync(sourcePath);
|
|
59
|
-
const appBuild = import_fs.default.readFileSync(appBuildPath);
|
|
60
|
-
const buildStat = import_fs.default.statSync(buildPath);
|
|
61
|
-
const sourceStat = import_fs.default.statSync(sourcePath);
|
|
62
|
-
const appBuildStat = import_fs.default.statSync(appBuildPath);
|
|
63
|
-
readingFilesSpinner.succeed("Reading files... done");
|
|
64
|
-
const preparingFormSpinner = spinning("Preparing form data...");
|
|
65
|
-
const formData = new import_form_data.default();
|
|
66
|
-
formData.append("files", build, `${appName}-release.tar.gz`);
|
|
67
|
-
formData.append("files", source, `${appName}-source.tar.gz`);
|
|
68
|
-
formData.append("files", appBuild, `${appName}-appBuild.zip`);
|
|
69
|
-
formData.append(
|
|
70
|
-
"metas",
|
|
71
|
-
JSON.stringify([
|
|
72
|
-
{ lastModifiedAt: buildStat.mtime, size: buildStat.size },
|
|
73
|
-
{ lastModifiedAt: sourceStat.mtime, size: sourceStat.size },
|
|
74
|
-
{ lastModifiedAt: appBuildStat.mtime, size: appBuildStat.size }
|
|
75
|
-
])
|
|
76
|
-
);
|
|
77
|
-
formData.append("type", "release");
|
|
78
|
-
preparingFormSpinner.succeed("Preparing form data... done");
|
|
79
|
-
try {
|
|
80
|
-
const uploadingFilesSpinner = spinning("Uploading files to server...");
|
|
81
|
-
const [buildFile, sourceFile, appBuildFile] = (await import_axios.default.post(`${basePath}/file/addFilesRestApi`, formData)).data;
|
|
82
|
-
uploadingFilesSpinner.succeed("Uploading files to server... done");
|
|
83
|
-
const fetchingAppSpinner = spinning(`Fetching dev app information for ${appName}...`);
|
|
84
|
-
const major = platformVersion ? parseInt(platformVersion.split(".")[0]) : 1;
|
|
85
|
-
const minor = platformVersion ? parseInt(platformVersion.split(".")[1]) : 0;
|
|
86
|
-
const patch = platformVersion ? parseInt(platformVersion.split(".")[2]) : 0;
|
|
87
|
-
const devApp = (await import_axios.default.get(`${basePath}/devApp/devAppInName/${appName}`)).data;
|
|
88
|
-
fetchingAppSpinner.succeed(`Fetching dev app information for ${appName}... done`);
|
|
89
|
-
const pushingReleaseSpinner = spinning(`Pushing release to ${environment} environment...`);
|
|
90
|
-
const release = (await import_axios.default.post(
|
|
91
|
-
`${basePath}/release/pushRelease/${devApp.id}/${environment}/${major}/${minor}/${patch}/${sourceFile.id}/${buildFile.id}/${appBuildFile.id}${os ? `/${os}` : ""}`
|
|
92
|
-
)).data;
|
|
93
|
-
pushingReleaseSpinner.succeed(`Pushing release to ${environment} environment... done`);
|
|
94
|
-
new import_spinner.Spinner(`Successfully pushed release to ${appName}-${environment} server. `, {
|
|
95
|
-
prefix: `Successfully pushed release to ${appName}-${environment} server. `,
|
|
96
|
-
enableSpin: false
|
|
97
|
-
}).succeed(`Successfully pushed release to ${appName}-${environment} server. `);
|
|
98
|
-
return release;
|
|
99
|
-
} catch (e) {
|
|
100
|
-
const errorMessage = e instanceof Error ? e.message : "Unknown error";
|
|
101
|
-
return null;
|
|
102
|
-
}
|
|
103
|
-
} catch (e) {
|
|
104
|
-
const errorMessage = e instanceof Error ? e.message : "Unknown error";
|
|
105
|
-
readingFilesSpinner.fail(`Reading files failed: ${errorMessage}`);
|
|
106
|
-
return null;
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
110
|
-
0 && (module.exports = {
|
|
111
|
-
uploadRelease
|
|
112
|
-
});
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
var useStdoutDimensions_exports = {};
|
|
20
|
-
__export(useStdoutDimensions_exports, {
|
|
21
|
-
useStdoutDimensions: () => useStdoutDimensions
|
|
22
|
-
});
|
|
23
|
-
module.exports = __toCommonJS(useStdoutDimensions_exports);
|
|
24
|
-
var import_ink = require("ink");
|
|
25
|
-
var import_react = require("react");
|
|
26
|
-
const useStdoutDimensions = () => {
|
|
27
|
-
const { stdout } = (0, import_ink.useStdout)();
|
|
28
|
-
const [dimensions, setDimensions] = (0, import_react.useState)([stdout.columns, stdout.rows]);
|
|
29
|
-
(0, import_react.useEffect)(() => {
|
|
30
|
-
const handler = () => {
|
|
31
|
-
setDimensions([stdout.columns, stdout.rows]);
|
|
32
|
-
};
|
|
33
|
-
stdout.on("resize", handler);
|
|
34
|
-
return () => {
|
|
35
|
-
stdout.off("resize", handler);
|
|
36
|
-
};
|
|
37
|
-
}, [stdout]);
|
|
38
|
-
return dimensions;
|
|
39
|
-
};
|
|
40
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
41
|
-
0 && (module.exports = {
|
|
42
|
-
useStdoutDimensions
|
|
43
|
-
});
|
package/esm/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./src";
|
package/esm/src/aiEditor.js
DELETED
|
@@ -1,282 +0,0 @@
|
|
|
1
|
-
import { Logger } from "@akanjs/common";
|
|
2
|
-
import { input, select } from "@inquirer/prompts";
|
|
3
|
-
import {
|
|
4
|
-
AIMessage,
|
|
5
|
-
HumanMessage,
|
|
6
|
-
mapChatMessagesToStoredMessages,
|
|
7
|
-
mapStoredMessagesToChatMessages
|
|
8
|
-
} from "@langchain/core/messages";
|
|
9
|
-
import { ChatDeepSeek } from "@langchain/deepseek";
|
|
10
|
-
import { ChatOpenAI } from "@langchain/openai";
|
|
11
|
-
import chalk from "chalk";
|
|
12
|
-
import fs from "fs";
|
|
13
|
-
import { getAkanGlobalConfig, setAkanGlobalConfig } from "./auth";
|
|
14
|
-
import { Spinner } from "./spinner";
|
|
15
|
-
const MAX_ASK_TRY = 300;
|
|
16
|
-
const supportedLlmModels = ["deepseek-chat", "deepseek-reasoner"];
|
|
17
|
-
class AiSession {
|
|
18
|
-
static #cacheDir = "node_modules/.cache/akan/aiSession";
|
|
19
|
-
static #chat = null;
|
|
20
|
-
static async init({ temperature = 0, useExisting = true } = {}) {
|
|
21
|
-
if (useExisting) {
|
|
22
|
-
const llmConfig2 = this.getLlmConfig();
|
|
23
|
-
if (llmConfig2) {
|
|
24
|
-
this.#setChatModel(llmConfig2.model, llmConfig2.apiKey);
|
|
25
|
-
Logger.rawLog(chalk.dim(`\u{1F916}akan editor uses existing LLM config (${llmConfig2.model})`));
|
|
26
|
-
return this;
|
|
27
|
-
}
|
|
28
|
-
} else
|
|
29
|
-
Logger.rawLog(chalk.yellow("\u{1F916}akan-editor is not initialized. LLM configuration should be set first."));
|
|
30
|
-
const llmConfig = await this.#requestLlmConfig();
|
|
31
|
-
const { model, apiKey } = llmConfig;
|
|
32
|
-
await this.#validateApiKey(model, apiKey);
|
|
33
|
-
return this.#setChatModel(model, apiKey, { temperature }).setLlmConfig({ model, apiKey });
|
|
34
|
-
}
|
|
35
|
-
static #setChatModel(model, apiKey, { temperature = 0 } = {}) {
|
|
36
|
-
this.#chat = new ChatDeepSeek({
|
|
37
|
-
modelName: model,
|
|
38
|
-
temperature,
|
|
39
|
-
streaming: true,
|
|
40
|
-
apiKey
|
|
41
|
-
// configuration: { baseURL: "https://api.deepseek.com/v1", apiKey },
|
|
42
|
-
});
|
|
43
|
-
return this;
|
|
44
|
-
}
|
|
45
|
-
static getLlmConfig() {
|
|
46
|
-
const akanConfig = getAkanGlobalConfig();
|
|
47
|
-
return akanConfig.llm ?? null;
|
|
48
|
-
}
|
|
49
|
-
static setLlmConfig(llmConfig) {
|
|
50
|
-
const akanConfig = getAkanGlobalConfig();
|
|
51
|
-
akanConfig.llm = llmConfig;
|
|
52
|
-
setAkanGlobalConfig(akanConfig);
|
|
53
|
-
return this;
|
|
54
|
-
}
|
|
55
|
-
static async #requestLlmConfig() {
|
|
56
|
-
const model = await select({ message: "Select a LLM model", choices: supportedLlmModels });
|
|
57
|
-
const apiKey = await input({ message: "Enter your API key" });
|
|
58
|
-
return { model, apiKey };
|
|
59
|
-
}
|
|
60
|
-
static async #validateApiKey(modelName, apiKey) {
|
|
61
|
-
const spinner = new Spinner("Validating LLM API key...", { prefix: `\u{1F916}akan-editor` }).start();
|
|
62
|
-
const chat = new ChatOpenAI({
|
|
63
|
-
modelName,
|
|
64
|
-
temperature: 0,
|
|
65
|
-
configuration: { baseURL: "https://api.deepseek.com/v1", apiKey }
|
|
66
|
-
});
|
|
67
|
-
try {
|
|
68
|
-
await chat.invoke("Hi, and just say 'ok'");
|
|
69
|
-
spinner.succeed("LLM API key is valid");
|
|
70
|
-
return true;
|
|
71
|
-
} catch (error) {
|
|
72
|
-
spinner.fail(
|
|
73
|
-
chalk.red(
|
|
74
|
-
`LLM API key is invalid. Please check your API key and try again. You can set it again by running "akan set-llm" or reset by running "akan reset-llm"`
|
|
75
|
-
)
|
|
76
|
-
);
|
|
77
|
-
throw error;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
static clearCache(workspaceRoot) {
|
|
81
|
-
const cacheDir = `${workspaceRoot}/${this.#cacheDir}`;
|
|
82
|
-
fs.rmSync(cacheDir, { recursive: true, force: true });
|
|
83
|
-
}
|
|
84
|
-
messageHistory = [];
|
|
85
|
-
sessionKey;
|
|
86
|
-
isCacheLoaded = false;
|
|
87
|
-
workspace;
|
|
88
|
-
constructor(type, { workspace, cacheKey, isContinued }) {
|
|
89
|
-
this.workspace = workspace;
|
|
90
|
-
this.sessionKey = `${type}${cacheKey ? `-${cacheKey}` : ""}`;
|
|
91
|
-
if (isContinued)
|
|
92
|
-
this.#loadCache();
|
|
93
|
-
}
|
|
94
|
-
#loadCache() {
|
|
95
|
-
const cacheFile = `${AiSession.#cacheDir}/${this.sessionKey}.json`;
|
|
96
|
-
const isCacheExists = this.workspace.exists(cacheFile);
|
|
97
|
-
if (isCacheExists)
|
|
98
|
-
this.messageHistory = mapStoredMessagesToChatMessages(this.workspace.readJson(cacheFile));
|
|
99
|
-
else
|
|
100
|
-
this.messageHistory = [];
|
|
101
|
-
this.isCacheLoaded = isCacheExists;
|
|
102
|
-
return isCacheExists;
|
|
103
|
-
}
|
|
104
|
-
#saveCache() {
|
|
105
|
-
const cacheFilePath = `${AiSession.#cacheDir}/${this.sessionKey}.json`;
|
|
106
|
-
this.workspace.writeJson(cacheFilePath, mapChatMessagesToStoredMessages(this.messageHistory));
|
|
107
|
-
}
|
|
108
|
-
async ask(question, {
|
|
109
|
-
onReasoning = (reasoning) => {
|
|
110
|
-
Logger.raw(chalk.dim(reasoning));
|
|
111
|
-
},
|
|
112
|
-
onChunk = (chunk) => {
|
|
113
|
-
Logger.raw(chunk);
|
|
114
|
-
}
|
|
115
|
-
} = {}) {
|
|
116
|
-
if (!AiSession.#chat)
|
|
117
|
-
await AiSession.init();
|
|
118
|
-
if (!AiSession.#chat)
|
|
119
|
-
throw new Error("Failed to initialize the AI session");
|
|
120
|
-
const loader = new Spinner(`${AiSession.#chat.model} is thinking...`, {
|
|
121
|
-
prefix: `\u{1F916}akan-editor`
|
|
122
|
-
}).start();
|
|
123
|
-
try {
|
|
124
|
-
const humanMessage = new HumanMessage(question);
|
|
125
|
-
this.messageHistory.push(humanMessage);
|
|
126
|
-
const stream = await AiSession.#chat.stream(this.messageHistory);
|
|
127
|
-
let reasoningResponse = "", fullResponse = "", tokenIdx = 0;
|
|
128
|
-
for await (const chunk of stream) {
|
|
129
|
-
if (loader.isSpinning())
|
|
130
|
-
loader.succeed(`${AiSession.#chat.model} responded`);
|
|
131
|
-
if (!fullResponse.length) {
|
|
132
|
-
const reasoningContent = chunk.additional_kwargs.reasoning_content ?? "";
|
|
133
|
-
if (reasoningContent.length) {
|
|
134
|
-
reasoningResponse += reasoningContent;
|
|
135
|
-
onReasoning(reasoningContent);
|
|
136
|
-
continue;
|
|
137
|
-
} else if (chunk.content.length) {
|
|
138
|
-
reasoningResponse += "\n";
|
|
139
|
-
onReasoning(reasoningResponse);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
const content = chunk.content;
|
|
143
|
-
if (typeof content === "string") {
|
|
144
|
-
fullResponse += content;
|
|
145
|
-
onChunk(content);
|
|
146
|
-
}
|
|
147
|
-
tokenIdx++;
|
|
148
|
-
}
|
|
149
|
-
fullResponse += "\n";
|
|
150
|
-
onChunk("\n");
|
|
151
|
-
this.messageHistory.push(new AIMessage(fullResponse));
|
|
152
|
-
return { content: fullResponse, messageHistory: this.messageHistory };
|
|
153
|
-
} catch (error) {
|
|
154
|
-
loader.fail(`${AiSession.#chat.model} failed to respond`);
|
|
155
|
-
throw new Error("Failed to stream response");
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
async edit(question, { onChunk, onReasoning, maxTry = MAX_ASK_TRY, validate, approve } = {}) {
|
|
159
|
-
for (let tryCount = 0; tryCount < maxTry; tryCount++) {
|
|
160
|
-
let response = await this.ask(question, { onChunk, onReasoning });
|
|
161
|
-
if (validate?.length && tryCount === 0) {
|
|
162
|
-
const validateQuestion = `Double check if the response meets the requirements and conditions, and follow the instructions. If not, rewrite it.
|
|
163
|
-
${validate.map((v) => `- ${v}`).join("\n")}`;
|
|
164
|
-
response = await this.ask(validateQuestion, { onChunk, onReasoning });
|
|
165
|
-
}
|
|
166
|
-
const isConfirmed = approve ? true : await select({
|
|
167
|
-
message: "Do you want to edit the response?",
|
|
168
|
-
choices: [
|
|
169
|
-
{ name: "\u2705 Yes, confirm and apply this result", value: true },
|
|
170
|
-
{ name: "\u{1F504} No, I want to edit it more", value: false }
|
|
171
|
-
]
|
|
172
|
-
});
|
|
173
|
-
if (isConfirmed) {
|
|
174
|
-
this.#saveCache();
|
|
175
|
-
return response.content;
|
|
176
|
-
}
|
|
177
|
-
question = await input({ message: "What do you want to change?" });
|
|
178
|
-
tryCount++;
|
|
179
|
-
}
|
|
180
|
-
throw new Error("Failed to edit");
|
|
181
|
-
}
|
|
182
|
-
async editTypescript(question, options = {}) {
|
|
183
|
-
const content = await this.edit(question, options);
|
|
184
|
-
return this.#getTypescriptCode(content);
|
|
185
|
-
}
|
|
186
|
-
#getTypescriptCode(content) {
|
|
187
|
-
//! will be deprecated
|
|
188
|
-
const code = /```(typescript|tsx)([\s\S]*?)```/.exec(content);
|
|
189
|
-
return code ? code[2] : content;
|
|
190
|
-
}
|
|
191
|
-
addToolMessgaes(messages) {
|
|
192
|
-
const toolMessages = messages.map((message) => new HumanMessage(message.content));
|
|
193
|
-
this.messageHistory.push(...toolMessages);
|
|
194
|
-
return this;
|
|
195
|
-
}
|
|
196
|
-
async writeTypescripts(question, executor, options = {}) {
|
|
197
|
-
const content = await this.edit(question, options);
|
|
198
|
-
const writes = this.#getTypescriptCodes(content);
|
|
199
|
-
for (const write of writes)
|
|
200
|
-
executor.writeFile(write.filePath, write.content);
|
|
201
|
-
return await this.#tryFixTypescripts(writes, executor, options);
|
|
202
|
-
}
|
|
203
|
-
async #editTypescripts(question, options = {}) {
|
|
204
|
-
const content = await this.edit(question, options);
|
|
205
|
-
return this.#getTypescriptCodes(content);
|
|
206
|
-
}
|
|
207
|
-
async #tryFixTypescripts(writes, executor, options = {}) {
|
|
208
|
-
const MAX_EDIT_TRY = 5;
|
|
209
|
-
for (let tryCount = 0; tryCount < MAX_EDIT_TRY; tryCount++) {
|
|
210
|
-
const loader = new Spinner(`Type checking and linting...`, { prefix: `\u{1F916}akan-editor` }).start();
|
|
211
|
-
const fileChecks = await Promise.all(
|
|
212
|
-
writes.map(async ({ filePath }) => {
|
|
213
|
-
const typeCheckResult = executor.typeCheck(filePath);
|
|
214
|
-
const lintResult = await executor.lint(filePath);
|
|
215
|
-
const needFix2 = !!typeCheckResult.fileErrors.length || !!lintResult.errors.length;
|
|
216
|
-
return { filePath, typeCheckResult, lintResult, needFix: needFix2 };
|
|
217
|
-
})
|
|
218
|
-
);
|
|
219
|
-
const needFix = fileChecks.some((fileCheck) => fileCheck.needFix);
|
|
220
|
-
if (needFix) {
|
|
221
|
-
loader.fail("Type checking and linting has some errors, try to fix them");
|
|
222
|
-
fileChecks.forEach((fileCheck) => {
|
|
223
|
-
Logger.rawLog(
|
|
224
|
-
`TypeCheck Result
|
|
225
|
-
${fileCheck.typeCheckResult.message}
|
|
226
|
-
Lint Result
|
|
227
|
-
${fileCheck.lintResult.message}`
|
|
228
|
-
);
|
|
229
|
-
this.addToolMessgaes([
|
|
230
|
-
{ type: "typescript", content: fileCheck.typeCheckResult.message },
|
|
231
|
-
{ type: "eslint", content: fileCheck.lintResult.message }
|
|
232
|
-
]);
|
|
233
|
-
});
|
|
234
|
-
writes = await this.#editTypescripts("Fix the typescript and eslint errors", {
|
|
235
|
-
...options,
|
|
236
|
-
validate: void 0,
|
|
237
|
-
approve: true
|
|
238
|
-
});
|
|
239
|
-
for (const write of writes)
|
|
240
|
-
executor.writeFile(write.filePath, write.content);
|
|
241
|
-
} else {
|
|
242
|
-
loader.succeed("Type checking and linting has no errors");
|
|
243
|
-
return writes;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
throw new Error("Failed to create scalar");
|
|
247
|
-
}
|
|
248
|
-
#getTypescriptCodes(text) {
|
|
249
|
-
const codes = text.match(/```(typescript|tsx)([\s\S]*?)```/g);
|
|
250
|
-
if (!codes)
|
|
251
|
-
return [];
|
|
252
|
-
const result = codes.map((code) => {
|
|
253
|
-
const content = /```(typescript|tsx)([\s\S]*?)```/.exec(code)?.[2];
|
|
254
|
-
if (!content)
|
|
255
|
-
return null;
|
|
256
|
-
const filePath = /\/\/ File: (.*?)(?:\n|$)/.exec(content)?.[1]?.trim();
|
|
257
|
-
if (!filePath)
|
|
258
|
-
return null;
|
|
259
|
-
const contentWithoutFilepath = content.replace(`// File: ${filePath}
|
|
260
|
-
`, "").trim();
|
|
261
|
-
return { filePath, content: contentWithoutFilepath };
|
|
262
|
-
});
|
|
263
|
-
return result.filter((code) => code !== null);
|
|
264
|
-
}
|
|
265
|
-
async editMarkdown(request, options = {}) {
|
|
266
|
-
const content = await this.edit(request, options);
|
|
267
|
-
return this.#getMarkdownContent(content);
|
|
268
|
-
}
|
|
269
|
-
#getMarkdownContent(text) {
|
|
270
|
-
const searchText = "```markdown";
|
|
271
|
-
const firstIndex = text.indexOf("```markdown");
|
|
272
|
-
const lastIndex = text.lastIndexOf("```");
|
|
273
|
-
if (firstIndex === -1)
|
|
274
|
-
return text;
|
|
275
|
-
else
|
|
276
|
-
return text.slice(firstIndex + searchText.length, lastIndex).trim();
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
export {
|
|
280
|
-
AiSession,
|
|
281
|
-
supportedLlmModels
|
|
282
|
-
};
|