@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
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import fs from "fs";
|
|
2
|
-
import yaml from "js-yaml";
|
|
3
|
-
const getCredentials = (app, environment) => {
|
|
4
|
-
const secret = yaml.load(
|
|
5
|
-
fs.readFileSync(`${app.workspace.workspaceRoot}/infra/app/values/${app.name}-secret.yaml`, "utf-8")
|
|
6
|
-
);
|
|
7
|
-
return secret[environment];
|
|
8
|
-
};
|
|
9
|
-
export {
|
|
10
|
-
getCredentials
|
|
11
|
-
};
|
package/esm/src/getDirname.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import fs from "fs";
|
|
2
|
-
const getModelFileData = (modulePath, modelName) => {
|
|
3
|
-
const moduleType = modulePath.startsWith("apps") ? "app" : "lib";
|
|
4
|
-
const moduleName = modulePath.split("/")[1];
|
|
5
|
-
const constantFilePath = `${modulePath}/lib/${modelName}/${modelName}.constant.ts`;
|
|
6
|
-
const unitFilePath = `${modulePath}/lib/${modelName}/${modelName}.Unit.tsx`;
|
|
7
|
-
const viewFilePath = `${modulePath}/lib/${modelName}/${modelName}.View.tsx`;
|
|
8
|
-
const constantFileStr = fs.readFileSync(constantFilePath, "utf8");
|
|
9
|
-
const unitFileStr = fs.readFileSync(unitFilePath, "utf8");
|
|
10
|
-
const viewFileStr = fs.readFileSync(viewFilePath, "utf8");
|
|
11
|
-
const constantFileLines = constantFileStr.split("\n");
|
|
12
|
-
const importLibNames = constantFileLines.filter((line) => line.startsWith("import { cnst as ")).map((line) => line.split("cnst as ")[1].split(" ")[0]);
|
|
13
|
-
const importLocalPaths = constantFileLines.filter((line) => line.startsWith("import { ") && line.includes('from "../')).map((line) => line.split("from ")[1].split('"')[1]);
|
|
14
|
-
const importModelNames = importLocalPaths.map((path) => path.split("/")[1]).filter((name) => !name.startsWith("_"));
|
|
15
|
-
const hasImportScalar = !!importLocalPaths.map((path) => path.split("/")[1]).filter((name) => name.startsWith("_")).length;
|
|
16
|
-
return {
|
|
17
|
-
moduleType,
|
|
18
|
-
moduleName,
|
|
19
|
-
modelName,
|
|
20
|
-
constantFilePath,
|
|
21
|
-
unitFilePath,
|
|
22
|
-
viewFilePath,
|
|
23
|
-
importModelNames,
|
|
24
|
-
hasImportScalar,
|
|
25
|
-
importLibNames,
|
|
26
|
-
constantFileStr,
|
|
27
|
-
unitFileStr,
|
|
28
|
-
viewFileStr
|
|
29
|
-
};
|
|
30
|
-
};
|
|
31
|
-
export {
|
|
32
|
-
getModelFileData
|
|
33
|
-
};
|
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
import * as fs from "fs";
|
|
2
|
-
import ora from "ora";
|
|
3
|
-
import * as ts from "typescript";
|
|
4
|
-
const parseTsConfig = (tsConfigPath = "./tsconfig.json") => {
|
|
5
|
-
const configFile = ts.readConfigFile(tsConfigPath, (path) => {
|
|
6
|
-
return ts.sys.readFile(path);
|
|
7
|
-
});
|
|
8
|
-
return ts.parseJsonConfigFileContent(
|
|
9
|
-
configFile.config,
|
|
10
|
-
ts.sys,
|
|
11
|
-
fs.realpathSync(tsConfigPath).replace(/[^/\\]+$/, "")
|
|
12
|
-
);
|
|
13
|
-
};
|
|
14
|
-
const collectImportedFiles = (constantFilePath, parsedConfig) => {
|
|
15
|
-
const allFilesToAnalyze = /* @__PURE__ */ new Set([constantFilePath]);
|
|
16
|
-
const analyzedFiles = /* @__PURE__ */ new Set();
|
|
17
|
-
const spinner = ora("Collecting related files...");
|
|
18
|
-
spinner.start();
|
|
19
|
-
function collectImported(filePath) {
|
|
20
|
-
if (analyzedFiles.has(filePath))
|
|
21
|
-
return;
|
|
22
|
-
analyzedFiles.add(filePath);
|
|
23
|
-
const tempProgram = ts.createProgram([filePath], parsedConfig.options);
|
|
24
|
-
const source = tempProgram.getSourceFile(filePath);
|
|
25
|
-
if (!source)
|
|
26
|
-
return;
|
|
27
|
-
function collectImports(node) {
|
|
28
|
-
if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) {
|
|
29
|
-
const importPath = node.moduleSpecifier.text;
|
|
30
|
-
if (importPath.startsWith(".")) {
|
|
31
|
-
const resolved = ts.resolveModuleName(importPath, filePath, parsedConfig.options, ts.sys).resolvedModule?.resolvedFileName;
|
|
32
|
-
if (resolved && !allFilesToAnalyze.has(resolved)) {
|
|
33
|
-
allFilesToAnalyze.add(resolved);
|
|
34
|
-
collectImported(resolved);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
ts.forEachChild(node, collectImports);
|
|
39
|
-
}
|
|
40
|
-
collectImports(source);
|
|
41
|
-
}
|
|
42
|
-
collectImported(constantFilePath);
|
|
43
|
-
spinner.succeed(`Found ${allFilesToAnalyze.size} related files.`);
|
|
44
|
-
return {
|
|
45
|
-
allFilesToAnalyze,
|
|
46
|
-
analyzedFiles
|
|
47
|
-
};
|
|
48
|
-
};
|
|
49
|
-
const collectExportedFiles = (constantFilePath, parsedConfig) => {
|
|
50
|
-
const allFilesToAnalyze = /* @__PURE__ */ new Set([constantFilePath]);
|
|
51
|
-
const analyzedFiles = /* @__PURE__ */ new Set();
|
|
52
|
-
const spinner = ora("Collecting files from exports...");
|
|
53
|
-
spinner.start();
|
|
54
|
-
function collectExported(filePath) {
|
|
55
|
-
if (analyzedFiles.has(filePath))
|
|
56
|
-
return;
|
|
57
|
-
analyzedFiles.add(filePath);
|
|
58
|
-
const tempProgram = ts.createProgram([filePath], parsedConfig.options);
|
|
59
|
-
const source = tempProgram.getSourceFile(filePath);
|
|
60
|
-
if (!source)
|
|
61
|
-
return;
|
|
62
|
-
function collectExports(node) {
|
|
63
|
-
if (ts.isExportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier) && !node.exportClause) {
|
|
64
|
-
const exportPath = node.moduleSpecifier.text;
|
|
65
|
-
if (exportPath.startsWith(".")) {
|
|
66
|
-
const resolved = ts.resolveModuleName(exportPath, filePath, parsedConfig.options, ts.sys).resolvedModule?.resolvedFileName;
|
|
67
|
-
if (resolved && !allFilesToAnalyze.has(resolved)) {
|
|
68
|
-
allFilesToAnalyze.add(resolved);
|
|
69
|
-
collectExported(resolved);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
} else if (ts.isExportDeclaration(node) && node.exportClause && ts.isNamedExports(node.exportClause) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {
|
|
73
|
-
const exportPath = node.moduleSpecifier.text;
|
|
74
|
-
if (exportPath.startsWith(".")) {
|
|
75
|
-
const resolved = ts.resolveModuleName(exportPath, filePath, parsedConfig.options, ts.sys).resolvedModule?.resolvedFileName;
|
|
76
|
-
if (resolved && !allFilesToAnalyze.has(resolved)) {
|
|
77
|
-
allFilesToAnalyze.add(resolved);
|
|
78
|
-
collectExported(resolved);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
} else if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) {
|
|
82
|
-
const importPath = node.moduleSpecifier.text;
|
|
83
|
-
if (importPath.startsWith(".")) {
|
|
84
|
-
const resolved = ts.resolveModuleName(importPath, filePath, parsedConfig.options, ts.sys).resolvedModule?.resolvedFileName;
|
|
85
|
-
if (resolved && !allFilesToAnalyze.has(resolved)) {
|
|
86
|
-
allFilesToAnalyze.add(resolved);
|
|
87
|
-
collectExported(resolved);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
if ((ts.isVariableStatement(node) || ts.isFunctionDeclaration(node) || ts.isClassDeclaration(node)) && node.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword)) {
|
|
92
|
-
}
|
|
93
|
-
ts.forEachChild(node, collectExports);
|
|
94
|
-
}
|
|
95
|
-
collectExports(source);
|
|
96
|
-
}
|
|
97
|
-
collectExported(constantFilePath);
|
|
98
|
-
spinner.succeed(`Found ${allFilesToAnalyze.size} related files from exports.`);
|
|
99
|
-
return {
|
|
100
|
-
allFilesToAnalyze,
|
|
101
|
-
analyzedFiles
|
|
102
|
-
};
|
|
103
|
-
};
|
|
104
|
-
const createTsProgram = (filePaths, options) => {
|
|
105
|
-
const spinner = ora("Creating TypeScript program for all files...");
|
|
106
|
-
spinner.start();
|
|
107
|
-
const program = ts.createProgram(Array.from(filePaths), options);
|
|
108
|
-
const checker = program.getTypeChecker();
|
|
109
|
-
spinner.succeed("TypeScript program created.");
|
|
110
|
-
return {
|
|
111
|
-
program,
|
|
112
|
-
checker
|
|
113
|
-
};
|
|
114
|
-
};
|
|
115
|
-
const createSymbolCache = (checker) => {
|
|
116
|
-
const symbolCache = /* @__PURE__ */ new Map();
|
|
117
|
-
return (node) => {
|
|
118
|
-
const cacheKey = `${node.getSourceFile().fileName}:${node.pos}:${node.end}`;
|
|
119
|
-
if (!symbolCache.has(cacheKey)) {
|
|
120
|
-
symbolCache.set(cacheKey, checker.getSymbolAtLocation(node));
|
|
121
|
-
}
|
|
122
|
-
return symbolCache.get(cacheKey);
|
|
123
|
-
};
|
|
124
|
-
};
|
|
125
|
-
const analyzeProperties = (filesToAnalyze, program, checker) => {
|
|
126
|
-
const propertyMap = /* @__PURE__ */ new Map();
|
|
127
|
-
const analyzedFiles = /* @__PURE__ */ new Set();
|
|
128
|
-
const sourceLineCache = /* @__PURE__ */ new Map();
|
|
129
|
-
const getCachedSymbol = createSymbolCache(checker);
|
|
130
|
-
const spinner = ora("Analyzing property relationships...");
|
|
131
|
-
spinner.start();
|
|
132
|
-
function analyzeFileProperties(filePath) {
|
|
133
|
-
if (analyzedFiles.has(filePath))
|
|
134
|
-
return;
|
|
135
|
-
analyzedFiles.add(filePath);
|
|
136
|
-
const source = program.getSourceFile(filePath);
|
|
137
|
-
if (!source)
|
|
138
|
-
return;
|
|
139
|
-
if (!sourceLineCache.has(filePath)) {
|
|
140
|
-
sourceLineCache.set(filePath, source.getFullText().split("\n"));
|
|
141
|
-
}
|
|
142
|
-
const sourceLines = sourceLineCache.get(filePath);
|
|
143
|
-
function visit(node) {
|
|
144
|
-
if (!source)
|
|
145
|
-
return;
|
|
146
|
-
if (ts.isPropertyAccessExpression(node)) {
|
|
147
|
-
const left = node.expression;
|
|
148
|
-
const right = node.name;
|
|
149
|
-
const { line } = ts.getLineAndCharacterOfPosition(source, node.getStart());
|
|
150
|
-
if (ts.isIdentifier(left) && sourceLines && sourceLines.length > line && (sourceLines[line].includes(`@Field.Prop(() => ${left.text}.${right.text}`) || sourceLines[line].includes(`base.Filter(${left.text}.${right.text},`))) {
|
|
151
|
-
const symbol = getCachedSymbol(right);
|
|
152
|
-
if (symbol?.declarations && symbol.declarations.length > 0) {
|
|
153
|
-
const key = symbol.declarations[0].getSourceFile().fileName.split("/").pop()?.split(".")[0] ?? "";
|
|
154
|
-
const property = propertyMap.get(key);
|
|
155
|
-
const isScalar = symbol.declarations[0].getSourceFile().fileName.includes("_");
|
|
156
|
-
const symbolFilePath = symbol.declarations[0].getSourceFile().fileName.replace(`${ts.sys.getCurrentDirectory()}/`, "");
|
|
157
|
-
if (property) {
|
|
158
|
-
propertyMap.set(`${left.text}.${right.text}`, {
|
|
159
|
-
filePath: symbolFilePath,
|
|
160
|
-
isLibModule: true,
|
|
161
|
-
isImport: false,
|
|
162
|
-
libName: left.text,
|
|
163
|
-
source: fs.readFileSync(symbolFilePath, "utf-8"),
|
|
164
|
-
isScalar
|
|
165
|
-
});
|
|
166
|
-
} else {
|
|
167
|
-
propertyMap.set(key, {
|
|
168
|
-
filePath: symbolFilePath,
|
|
169
|
-
isLibModule: true,
|
|
170
|
-
isImport: false,
|
|
171
|
-
libName: left.text,
|
|
172
|
-
isScalar,
|
|
173
|
-
source: fs.readFileSync(symbolFilePath, "utf-8")
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
} else if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) {
|
|
179
|
-
const importPath = node.moduleSpecifier.text;
|
|
180
|
-
if (importPath.startsWith(".")) {
|
|
181
|
-
const resolved = ts.resolveModuleName(importPath, filePath, program.getCompilerOptions(), ts.sys).resolvedModule?.resolvedFileName;
|
|
182
|
-
const moduleName = importPath.split("/").pop()?.split(".")[0] ?? "";
|
|
183
|
-
const property = propertyMap.get(moduleName);
|
|
184
|
-
const isScalar = importPath.includes("_");
|
|
185
|
-
if (moduleName && resolved && (!property || property.filePath !== resolved)) {
|
|
186
|
-
propertyMap.set(moduleName, {
|
|
187
|
-
filePath: resolved,
|
|
188
|
-
isLibModule: false,
|
|
189
|
-
isImport: true,
|
|
190
|
-
isScalar,
|
|
191
|
-
source: fs.readFileSync(resolved, "utf-8")
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
ts.forEachChild(node, visit);
|
|
197
|
-
}
|
|
198
|
-
visit(source);
|
|
199
|
-
}
|
|
200
|
-
for (const filePath of filesToAnalyze) {
|
|
201
|
-
analyzeFileProperties(filePath);
|
|
202
|
-
}
|
|
203
|
-
spinner.succeed(`Analysis complete. Found ${propertyMap.size} properties.`);
|
|
204
|
-
return propertyMap;
|
|
205
|
-
};
|
|
206
|
-
const getRelatedCnsts = (constantFilePath) => {
|
|
207
|
-
const parsedConfig = parseTsConfig();
|
|
208
|
-
const { allFilesToAnalyze } = collectImportedFiles(constantFilePath, parsedConfig);
|
|
209
|
-
const { program, checker } = createTsProgram(allFilesToAnalyze, parsedConfig.options);
|
|
210
|
-
const propertyMap = analyzeProperties(allFilesToAnalyze, program, checker);
|
|
211
|
-
return Array.from(propertyMap.entries()).map(([key, value]) => ({ key, ...value }));
|
|
212
|
-
};
|
|
213
|
-
export {
|
|
214
|
-
analyzeProperties,
|
|
215
|
-
collectExportedFiles,
|
|
216
|
-
collectImportedFiles,
|
|
217
|
-
createSymbolCache,
|
|
218
|
-
createTsProgram,
|
|
219
|
-
getRelatedCnsts,
|
|
220
|
-
parseTsConfig
|
|
221
|
-
};
|
package/esm/src/guideline.js
DELETED
|
File without changes
|
package/esm/src/linter.js
DELETED
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
import { Logger } from "@akanjs/common";
|
|
2
|
-
import chalk from "chalk";
|
|
3
|
-
import { ESLint } from "eslint";
|
|
4
|
-
import * as fs from "fs";
|
|
5
|
-
import * as path from "path";
|
|
6
|
-
class Linter {
|
|
7
|
-
#logger = new Logger("Linter");
|
|
8
|
-
#eslint;
|
|
9
|
-
lintRoot;
|
|
10
|
-
constructor(cwdPath) {
|
|
11
|
-
this.lintRoot = this.#findEslintRootPath(cwdPath);
|
|
12
|
-
this.#eslint = new ESLint({ cwd: this.lintRoot, errorOnUnmatchedPattern: false });
|
|
13
|
-
}
|
|
14
|
-
#findEslintRootPath(dir) {
|
|
15
|
-
const configPath = path.join(dir, "eslint.config.ts");
|
|
16
|
-
if (fs.existsSync(configPath))
|
|
17
|
-
return dir;
|
|
18
|
-
const parentDir = path.dirname(dir);
|
|
19
|
-
return this.#findEslintRootPath(parentDir);
|
|
20
|
-
}
|
|
21
|
-
async lint(filePath, { fix = false, dryRun = false } = {}) {
|
|
22
|
-
if (fix)
|
|
23
|
-
return await this.fixFile(filePath, dryRun);
|
|
24
|
-
return await this.lintFile(filePath);
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Lint a single file using ESLint
|
|
28
|
-
* @param filePath - Path to the file to lint
|
|
29
|
-
* @returns Array of ESLint results
|
|
30
|
-
*/
|
|
31
|
-
async lintFile(filePath) {
|
|
32
|
-
if (!fs.existsSync(filePath))
|
|
33
|
-
throw new Error(`File not found: ${filePath}`);
|
|
34
|
-
const isIgnored = await this.#eslint.isPathIgnored(filePath);
|
|
35
|
-
if (isIgnored) {
|
|
36
|
-
this.#logger.warn(`File ${filePath} is ignored by ESLint configuration`);
|
|
37
|
-
return { fixed: false, results: [], errors: [], warnings: [] };
|
|
38
|
-
}
|
|
39
|
-
const results = await this.#eslint.lintFiles([filePath]);
|
|
40
|
-
const errors = results.flatMap((result) => result.messages.filter((message) => message.severity === 2));
|
|
41
|
-
const warnings = results.flatMap((result) => result.messages.filter((message) => message.severity === 1));
|
|
42
|
-
return { fixed: false, results, errors, warnings };
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Format lint results for console output
|
|
46
|
-
* @param results - Array of ESLint results
|
|
47
|
-
* @returns Formatted string
|
|
48
|
-
*/
|
|
49
|
-
formatLintResults(results) {
|
|
50
|
-
if (results.length === 0)
|
|
51
|
-
return "No files to lint";
|
|
52
|
-
const output = [];
|
|
53
|
-
let totalErrors = 0;
|
|
54
|
-
let totalWarnings = 0;
|
|
55
|
-
results.forEach((result) => {
|
|
56
|
-
totalErrors += result.errorCount;
|
|
57
|
-
totalWarnings += result.warningCount;
|
|
58
|
-
if (result.messages.length > 0) {
|
|
59
|
-
output.push(`
|
|
60
|
-
${chalk.cyan(result.filePath)}`);
|
|
61
|
-
let sourceLines = [];
|
|
62
|
-
if (fs.existsSync(result.filePath)) {
|
|
63
|
-
try {
|
|
64
|
-
const sourceContent = fs.readFileSync(result.filePath, "utf8");
|
|
65
|
-
sourceLines = sourceContent.split("\n");
|
|
66
|
-
} catch (error) {
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
result.messages.forEach((message) => {
|
|
70
|
-
const type = message.severity === 2 ? "error" : "warning";
|
|
71
|
-
const typeColor = message.severity === 2 ? chalk.red : chalk.yellow;
|
|
72
|
-
const icon = message.severity === 2 ? "\u274C" : "\u26A0\uFE0F";
|
|
73
|
-
const ruleInfo = message.ruleId ? chalk.dim(` (${message.ruleId})`) : "";
|
|
74
|
-
output.push(`
|
|
75
|
-
${icon} ${typeColor(type)}: ${message.message}${ruleInfo}`);
|
|
76
|
-
output.push(` ${chalk.gray("at")} ${result.filePath}:${chalk.bold(`${message.line}:${message.column}`)}`);
|
|
77
|
-
if (sourceLines.length > 0 && message.line <= sourceLines.length) {
|
|
78
|
-
const sourceLine = sourceLines[message.line - 1];
|
|
79
|
-
const lineNumber = message.line.toString().padStart(5, " ");
|
|
80
|
-
output.push(`
|
|
81
|
-
${chalk.dim(lineNumber + " |")} ${sourceLine}`);
|
|
82
|
-
const underlinePrefix = " ".repeat(message.column - 1);
|
|
83
|
-
const underlineLength = message.endColumn ? message.endColumn - message.column : 1;
|
|
84
|
-
const underline = "^".repeat(Math.max(1, underlineLength));
|
|
85
|
-
output.push(`${chalk.dim(" ".repeat(lineNumber.length) + " |")} ${underlinePrefix}${typeColor(underline)}`);
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
if (totalErrors === 0 && totalWarnings === 0)
|
|
91
|
-
return chalk.bold("\u2705 No ESLint errors or warnings found");
|
|
92
|
-
const errorText = totalErrors > 0 ? chalk.red(`${totalErrors} error(s)`) : "0 errors";
|
|
93
|
-
const warningText = totalWarnings > 0 ? chalk.yellow(`${totalWarnings} warning(s)`) : "0 warnings";
|
|
94
|
-
const summary = [`
|
|
95
|
-
${errorText}, ${warningText} found`];
|
|
96
|
-
return summary.concat(output).join("\n");
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Get detailed lint information
|
|
100
|
-
* @param filePath - Path to the file to lint
|
|
101
|
-
* @returns Object containing detailed lint information
|
|
102
|
-
*/
|
|
103
|
-
async getDetailedLintInfo(filePath) {
|
|
104
|
-
const { results } = await this.lintFile(filePath);
|
|
105
|
-
const details = results.flatMap(
|
|
106
|
-
(result) => result.messages.map((message) => ({
|
|
107
|
-
line: message.line,
|
|
108
|
-
column: message.column,
|
|
109
|
-
message: message.message,
|
|
110
|
-
ruleId: message.ruleId,
|
|
111
|
-
severity: message.severity === 2 ? "error" : "warning",
|
|
112
|
-
fix: message.fix,
|
|
113
|
-
suggestions: message.suggestions
|
|
114
|
-
}))
|
|
115
|
-
);
|
|
116
|
-
const stats = results.reduce(
|
|
117
|
-
(acc, result) => ({
|
|
118
|
-
errorCount: acc.errorCount + result.errorCount,
|
|
119
|
-
warningCount: acc.warningCount + result.warningCount,
|
|
120
|
-
fixableErrorCount: acc.fixableErrorCount + result.fixableErrorCount,
|
|
121
|
-
fixableWarningCount: acc.fixableWarningCount + result.fixableWarningCount
|
|
122
|
-
}),
|
|
123
|
-
{ errorCount: 0, warningCount: 0, fixableErrorCount: 0, fixableWarningCount: 0 }
|
|
124
|
-
);
|
|
125
|
-
return { results, details, stats };
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Check if a file has lint errors
|
|
129
|
-
* @param filePath - Path to the file to check
|
|
130
|
-
* @returns true if there are no errors, false otherwise
|
|
131
|
-
*/
|
|
132
|
-
async hasNoLintErrors(filePath) {
|
|
133
|
-
try {
|
|
134
|
-
const { results } = await this.lintFile(filePath);
|
|
135
|
-
return results.every((result) => result.errorCount === 0);
|
|
136
|
-
} catch (error) {
|
|
137
|
-
return false;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Get only error messages (excluding warnings)
|
|
142
|
-
* @param filePath - Path to the file to lint
|
|
143
|
-
* @returns Array of error messages
|
|
144
|
-
*/
|
|
145
|
-
async getErrors(filePath) {
|
|
146
|
-
const { results } = await this.lintFile(filePath);
|
|
147
|
-
return results.flatMap((result) => result.messages.filter((message) => message.severity === 2));
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Get only warning messages
|
|
151
|
-
* @param filePath - Path to the file to lint
|
|
152
|
-
* @returns Array of warning messages
|
|
153
|
-
*/
|
|
154
|
-
async getWarnings(filePath) {
|
|
155
|
-
const { results } = await this.lintFile(filePath);
|
|
156
|
-
return results.flatMap((result) => result.messages.filter((message) => message.severity === 1));
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Fix lint errors automatically
|
|
160
|
-
* @param filePath - Path to the file to fix
|
|
161
|
-
* @param dryRun - If true, returns the fixed content without writing to file
|
|
162
|
-
* @returns Fixed content and remaining issues
|
|
163
|
-
*/
|
|
164
|
-
async fixFile(filePath, dryRun = false) {
|
|
165
|
-
if (!fs.existsSync(filePath))
|
|
166
|
-
throw new Error(`File not found: ${filePath}`);
|
|
167
|
-
const eslint = new ESLint({ cwd: this.lintRoot, fix: true });
|
|
168
|
-
const results = await eslint.lintFiles([filePath]);
|
|
169
|
-
const errors = results.flatMap((result) => result.messages.filter((message) => message.severity === 2));
|
|
170
|
-
const warnings = results.flatMap((result) => result.messages.filter((message) => message.severity === 1));
|
|
171
|
-
if (!dryRun)
|
|
172
|
-
await ESLint.outputFixes(results);
|
|
173
|
-
const fixedResult = results[0];
|
|
174
|
-
return { fixed: fixedResult.output !== void 0, output: fixedResult.output, results, errors, warnings };
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Get ESLint configuration for a file
|
|
178
|
-
* @param filePath - Path to the file
|
|
179
|
-
* @returns ESLint configuration object
|
|
180
|
-
*/
|
|
181
|
-
async getConfigForFile(filePath) {
|
|
182
|
-
const eslint = new ESLint();
|
|
183
|
-
const config = await eslint.calculateConfigForFile(filePath);
|
|
184
|
-
return config;
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* Get rules that are causing errors in a file
|
|
188
|
-
* @param filePath - Path to the file to check
|
|
189
|
-
* @returns Object mapping rule IDs to their error counts
|
|
190
|
-
*/
|
|
191
|
-
async getProblematicRules(filePath) {
|
|
192
|
-
const { results } = await this.lintFile(filePath);
|
|
193
|
-
const ruleCounts = {};
|
|
194
|
-
results.forEach((result) => {
|
|
195
|
-
result.messages.forEach((message) => {
|
|
196
|
-
if (message.ruleId)
|
|
197
|
-
ruleCounts[message.ruleId] = (ruleCounts[message.ruleId] || 0) + 1;
|
|
198
|
-
});
|
|
199
|
-
});
|
|
200
|
-
return ruleCounts;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
export {
|
|
204
|
-
Linter
|
|
205
|
-
};
|
package/esm/src/prompter.js
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { input, select } from "@inquirer/prompts";
|
|
2
|
-
import fsPromise from "fs/promises";
|
|
3
|
-
import { getDirname } from "./getDirname";
|
|
4
|
-
class Prompter {
|
|
5
|
-
static async selectGuideline() {
|
|
6
|
-
const guideNames = (await fsPromise.readdir(`${getDirname(import.meta.url)}/src/guidelines`)).filter(
|
|
7
|
-
(name) => !name.startsWith("_")
|
|
8
|
-
);
|
|
9
|
-
return await select({ message: "Select a guideline", choices: guideNames.map((name) => ({ name, value: name })) });
|
|
10
|
-
}
|
|
11
|
-
static async getGuideJson(guideName) {
|
|
12
|
-
const filePath = `${getDirname(import.meta.url)}/src/guidelines/${guideName}/${guideName}.generate.json`;
|
|
13
|
-
const guideJson = await fsPromise.readFile(filePath, "utf-8");
|
|
14
|
-
return JSON.parse(guideJson);
|
|
15
|
-
}
|
|
16
|
-
static async getInstruction(guideName) {
|
|
17
|
-
const filePath = `${getDirname(import.meta.url)}/src/guidelines/${guideName}/${guideName}.instruction.md`;
|
|
18
|
-
const content = await fsPromise.readFile(filePath, "utf-8");
|
|
19
|
-
return content;
|
|
20
|
-
}
|
|
21
|
-
static async getUpdateRequest(guideName) {
|
|
22
|
-
return await input({ message: `What do you want to update in ${guideName}?` });
|
|
23
|
-
}
|
|
24
|
-
async makeTsFileUpdatePrompt({ context, request }) {
|
|
25
|
-
return `You are a senior developer writing TypeScript-based programs using Akan.js, an in-house framework. Here's an overview of the Akan.js framework:
|
|
26
|
-
${await this.getDocumentation("framework")}
|
|
27
|
-
Please understand the following background information, write code that meets the requirements, verify that it satisfies the validation conditions, and return the result.
|
|
28
|
-
|
|
29
|
-
# Background Information
|
|
30
|
-
\`\`\`markdown
|
|
31
|
-
${context}
|
|
32
|
-
\`\`\`
|
|
33
|
-
|
|
34
|
-
# Requirements
|
|
35
|
-
\`\`\`markdown
|
|
36
|
-
${request}
|
|
37
|
-
\`\`\`
|
|
38
|
-
`;
|
|
39
|
-
}
|
|
40
|
-
async getDocumentation(guideName) {
|
|
41
|
-
const filePath = `${getDirname(import.meta.url)}/src/guidelines/${guideName}/${guideName}.instruction.md`;
|
|
42
|
-
const document = await fsPromise.readFile(filePath, "utf-8");
|
|
43
|
-
return `\`\`\`markdown
|
|
44
|
-
${document}
|
|
45
|
-
\`\`\`
|
|
46
|
-
`;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
export {
|
|
50
|
-
Prompter
|
|
51
|
-
};
|