truecourse 0.1.16 → 0.1.18
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.md +178 -0
- package/assets/demo.gif +0 -0
- package/assets/icon.svg +20 -0
- package/assets/logo.svg +29 -0
- package/assets/screenshot.png +0 -0
- package/assets/screenshot_analytics.png +0 -0
- package/assets/screenshot_code-review.png +0 -0
- package/assets/screenshot_diff.png +0 -0
- package/assets/screenshot_er.png +0 -0
- package/assets/screenshot_flows.png +0 -0
- package/cli.mjs +32 -16
- package/package.json +1 -1
- package/public/assets/{index-CIrs4v5l.js → index-BM6GwBRV.js} +157 -157
- package/public/index.html +1 -1
- package/server.mjs +156 -68
package/public/index.html
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
} catch (e) {}
|
|
21
21
|
})();
|
|
22
22
|
</script>
|
|
23
|
-
<script type="module" crossorigin src="/assets/index-
|
|
23
|
+
<script type="module" crossorigin src="/assets/index-BM6GwBRV.js"></script>
|
|
24
24
|
<link rel="stylesheet" crossorigin href="/assets/index-n9Z6c8B0.css">
|
|
25
25
|
</head>
|
|
26
26
|
<body class="font-sans">
|
package/server.mjs
CHANGED
|
@@ -18414,7 +18414,7 @@ var require_view = __commonJS({
|
|
|
18414
18414
|
var dirname4 = path10.dirname;
|
|
18415
18415
|
var basename3 = path10.basename;
|
|
18416
18416
|
var extname = path10.extname;
|
|
18417
|
-
var
|
|
18417
|
+
var join8 = path10.join;
|
|
18418
18418
|
var resolve6 = path10.resolve;
|
|
18419
18419
|
module2.exports = View2;
|
|
18420
18420
|
function View2(name21, options) {
|
|
@@ -18462,12 +18462,12 @@ var require_view = __commonJS({
|
|
|
18462
18462
|
};
|
|
18463
18463
|
View2.prototype.resolve = function resolve7(dir, file2) {
|
|
18464
18464
|
var ext2 = this.ext;
|
|
18465
|
-
var path11 =
|
|
18465
|
+
var path11 = join8(dir, file2);
|
|
18466
18466
|
var stat = tryStat(path11);
|
|
18467
18467
|
if (stat && stat.isFile()) {
|
|
18468
18468
|
return path11;
|
|
18469
18469
|
}
|
|
18470
|
-
path11 =
|
|
18470
|
+
path11 = join8(dir, basename3(file2, ext2), "index" + ext2);
|
|
18471
18471
|
stat = tryStat(path11);
|
|
18472
18472
|
if (stat && stat.isFile()) {
|
|
18473
18473
|
return path11;
|
|
@@ -19100,7 +19100,7 @@ var require_send = __commonJS({
|
|
|
19100
19100
|
var Stream = __require("stream");
|
|
19101
19101
|
var util2 = __require("util");
|
|
19102
19102
|
var extname = path10.extname;
|
|
19103
|
-
var
|
|
19103
|
+
var join8 = path10.join;
|
|
19104
19104
|
var normalize2 = path10.normalize;
|
|
19105
19105
|
var resolve6 = path10.resolve;
|
|
19106
19106
|
var sep2 = path10.sep;
|
|
@@ -19319,7 +19319,7 @@ var require_send = __commonJS({
|
|
|
19319
19319
|
return res;
|
|
19320
19320
|
}
|
|
19321
19321
|
parts = path11.split(sep2);
|
|
19322
|
-
path11 = normalize2(
|
|
19322
|
+
path11 = normalize2(join8(root, path11));
|
|
19323
19323
|
} else {
|
|
19324
19324
|
if (UP_PATH_REGEXP.test(path11)) {
|
|
19325
19325
|
debug2('malicious path "%s"', path11);
|
|
@@ -19454,7 +19454,7 @@ var require_send = __commonJS({
|
|
|
19454
19454
|
if (err) return self2.onStatError(err);
|
|
19455
19455
|
return self2.error(404);
|
|
19456
19456
|
}
|
|
19457
|
-
var p =
|
|
19457
|
+
var p = join8(path11, self2._index[i]);
|
|
19458
19458
|
debug2('stat "%s"', p);
|
|
19459
19459
|
fs9.stat(p, function(err2, stat) {
|
|
19460
19460
|
if (err2) return next(err2);
|
|
@@ -24061,7 +24061,7 @@ var init_sql = __esm({
|
|
|
24061
24061
|
return new SQL([new StringChunk(str)]);
|
|
24062
24062
|
}
|
|
24063
24063
|
sql2.raw = raw;
|
|
24064
|
-
function
|
|
24064
|
+
function join8(chunks, separator) {
|
|
24065
24065
|
const result = [];
|
|
24066
24066
|
for (const [i, chunk] of chunks.entries()) {
|
|
24067
24067
|
if (i > 0 && separator !== void 0) {
|
|
@@ -24071,7 +24071,7 @@ var init_sql = __esm({
|
|
|
24071
24071
|
}
|
|
24072
24072
|
return new SQL(result);
|
|
24073
24073
|
}
|
|
24074
|
-
sql2.join =
|
|
24074
|
+
sql2.join = join8;
|
|
24075
24075
|
function identifier(value) {
|
|
24076
24076
|
return new Name(value);
|
|
24077
24077
|
}
|
|
@@ -28098,7 +28098,7 @@ var init_select2 = __esm({
|
|
|
28098
28098
|
return (table, on) => {
|
|
28099
28099
|
const baseTableName = this.tableName;
|
|
28100
28100
|
const tableName = getTableLikeName(table);
|
|
28101
|
-
if (typeof tableName === "string" && this.config.joins?.some((
|
|
28101
|
+
if (typeof tableName === "string" && this.config.joins?.some((join8) => join8.alias === tableName)) {
|
|
28102
28102
|
throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
28103
28103
|
}
|
|
28104
28104
|
if (!this.isPartialSelect) {
|
|
@@ -29141,7 +29141,7 @@ var init_update = __esm({
|
|
|
29141
29141
|
createJoin(joinType) {
|
|
29142
29142
|
return (table, on) => {
|
|
29143
29143
|
const tableName = getTableLikeName(table);
|
|
29144
|
-
if (typeof tableName === "string" && this.config.joins.some((
|
|
29144
|
+
if (typeof tableName === "string" && this.config.joins.some((join8) => join8.alias === tableName)) {
|
|
29145
29145
|
throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
29146
29146
|
}
|
|
29147
29147
|
if (typeof on === "function") {
|
|
@@ -29237,10 +29237,10 @@ var init_update = __esm({
|
|
|
29237
29237
|
const fromFields = this.getTableLikeFields(this.config.from);
|
|
29238
29238
|
fields[tableName] = fromFields;
|
|
29239
29239
|
}
|
|
29240
|
-
for (const
|
|
29241
|
-
const tableName2 = getTableLikeName(
|
|
29242
|
-
if (typeof tableName2 === "string" && !is(
|
|
29243
|
-
const fromFields = this.getTableLikeFields(
|
|
29240
|
+
for (const join8 of this.config.joins) {
|
|
29241
|
+
const tableName2 = getTableLikeName(join8.table);
|
|
29242
|
+
if (typeof tableName2 === "string" && !is(join8.table, SQL)) {
|
|
29243
|
+
const fromFields = this.getTableLikeFields(join8.table);
|
|
29244
29244
|
fields[tableName2] = fromFields;
|
|
29245
29245
|
}
|
|
29246
29246
|
}
|
|
@@ -49382,7 +49382,7 @@ var require_util = __commonJS({
|
|
|
49382
49382
|
return path10;
|
|
49383
49383
|
}
|
|
49384
49384
|
exports2.normalize = normalize2;
|
|
49385
|
-
function
|
|
49385
|
+
function join8(aRoot, aPath) {
|
|
49386
49386
|
if (aRoot === "") {
|
|
49387
49387
|
aRoot = ".";
|
|
49388
49388
|
}
|
|
@@ -49414,7 +49414,7 @@ var require_util = __commonJS({
|
|
|
49414
49414
|
}
|
|
49415
49415
|
return joined;
|
|
49416
49416
|
}
|
|
49417
|
-
exports2.join =
|
|
49417
|
+
exports2.join = join8;
|
|
49418
49418
|
exports2.isAbsolute = function(aPath) {
|
|
49419
49419
|
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
49420
49420
|
};
|
|
@@ -49587,7 +49587,7 @@ var require_util = __commonJS({
|
|
|
49587
49587
|
parsed.path = parsed.path.substring(0, index + 1);
|
|
49588
49588
|
}
|
|
49589
49589
|
}
|
|
49590
|
-
sourceURL =
|
|
49590
|
+
sourceURL = join8(urlGenerate(parsed), sourceURL);
|
|
49591
49591
|
}
|
|
49592
49592
|
return normalize2(sourceURL);
|
|
49593
49593
|
}
|
|
@@ -60104,7 +60104,7 @@ ${lanes.join("\n")}
|
|
|
60104
60104
|
return process.memoryUsage().heapUsed;
|
|
60105
60105
|
},
|
|
60106
60106
|
getFileSize(path10) {
|
|
60107
|
-
const stat =
|
|
60107
|
+
const stat = statSync6(path10);
|
|
60108
60108
|
if (stat == null ? void 0 : stat.isFile()) {
|
|
60109
60109
|
return stat.size;
|
|
60110
60110
|
}
|
|
@@ -60148,7 +60148,7 @@ ${lanes.join("\n")}
|
|
|
60148
60148
|
}
|
|
60149
60149
|
};
|
|
60150
60150
|
return nodeSystem;
|
|
60151
|
-
function
|
|
60151
|
+
function statSync6(path10) {
|
|
60152
60152
|
try {
|
|
60153
60153
|
return _fs.statSync(path10, statSyncOptions);
|
|
60154
60154
|
} catch {
|
|
@@ -60207,7 +60207,7 @@ ${lanes.join("\n")}
|
|
|
60207
60207
|
activeSession.post("Profiler.stop", (err, { profile }) => {
|
|
60208
60208
|
var _a25;
|
|
60209
60209
|
if (!err) {
|
|
60210
|
-
if ((_a25 =
|
|
60210
|
+
if ((_a25 = statSync6(profilePath)) == null ? void 0 : _a25.isDirectory()) {
|
|
60211
60211
|
profilePath = _path.join(profilePath, `${(/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-")}+P${process.pid}.cpuprofile`);
|
|
60212
60212
|
}
|
|
60213
60213
|
try {
|
|
@@ -60327,7 +60327,7 @@ ${lanes.join("\n")}
|
|
|
60327
60327
|
let stat;
|
|
60328
60328
|
if (typeof dirent === "string" || dirent.isSymbolicLink()) {
|
|
60329
60329
|
const name21 = combinePaths(path10, entry);
|
|
60330
|
-
stat =
|
|
60330
|
+
stat = statSync6(name21);
|
|
60331
60331
|
if (!stat) {
|
|
60332
60332
|
continue;
|
|
60333
60333
|
}
|
|
@@ -60351,7 +60351,7 @@ ${lanes.join("\n")}
|
|
|
60351
60351
|
return matchFiles(path10, extensions, excludes, includes, useCaseSensitiveFileNames2, process.cwd(), depth, getAccessibleFileSystemEntries, realpath);
|
|
60352
60352
|
}
|
|
60353
60353
|
function fileSystemEntryExists(path10, entryKind) {
|
|
60354
|
-
const stat =
|
|
60354
|
+
const stat = statSync6(path10);
|
|
60355
60355
|
if (!stat) {
|
|
60356
60356
|
return false;
|
|
60357
60357
|
}
|
|
@@ -60393,7 +60393,7 @@ ${lanes.join("\n")}
|
|
|
60393
60393
|
}
|
|
60394
60394
|
function getModifiedTime3(path10) {
|
|
60395
60395
|
var _a25;
|
|
60396
|
-
return (_a25 =
|
|
60396
|
+
return (_a25 = statSync6(path10)) == null ? void 0 : _a25.mtime;
|
|
60397
60397
|
}
|
|
60398
60398
|
function setModifiedTime(path10, time4) {
|
|
60399
60399
|
try {
|
|
@@ -263905,8 +263905,8 @@ var init_file_analyzer = __esm({
|
|
|
263905
263905
|
});
|
|
263906
263906
|
|
|
263907
263907
|
// packages/analyzer/dist/dependency-graph.js
|
|
263908
|
-
import { resolve as resolve2, dirname as dirname2 } from "path";
|
|
263909
|
-
import { realpathSync } from "fs";
|
|
263908
|
+
import { resolve as resolve2, dirname as dirname2, join as join3 } from "path";
|
|
263909
|
+
import { existsSync as existsSync4, readFileSync as readFileSync2, readdirSync as readdirSync3, realpathSync, statSync as statSync4 } from "fs";
|
|
263910
263910
|
function resolveRelativeFallback(importSource, containingFile, analyzedFiles) {
|
|
263911
263911
|
const fromDir = dirname2(containingFile);
|
|
263912
263912
|
const basePath = resolve2(fromDir, importSource);
|
|
@@ -263927,9 +263927,77 @@ function resolveRelativeFallback(importSource, containingFile, analyzedFiles) {
|
|
|
263927
263927
|
}
|
|
263928
263928
|
return null;
|
|
263929
263929
|
}
|
|
263930
|
+
function buildWorkspacePackageMap(rootPath) {
|
|
263931
|
+
const packageMap = /* @__PURE__ */ new Map();
|
|
263932
|
+
for (const pattern of monorepoPatterns) {
|
|
263933
|
+
const dirPath = join3(rootPath, pattern);
|
|
263934
|
+
if (!existsSync4(dirPath) || !statSync4(dirPath).isDirectory())
|
|
263935
|
+
continue;
|
|
263936
|
+
try {
|
|
263937
|
+
for (const entry of readdirSync3(dirPath)) {
|
|
263938
|
+
const pkgDir = join3(dirPath, entry);
|
|
263939
|
+
const pkgJsonPath = join3(pkgDir, "package.json");
|
|
263940
|
+
if (!existsSync4(pkgJsonPath))
|
|
263941
|
+
continue;
|
|
263942
|
+
try {
|
|
263943
|
+
const pkg = JSON.parse(readFileSync2(pkgJsonPath, "utf-8"));
|
|
263944
|
+
if (pkg.name)
|
|
263945
|
+
packageMap.set(pkg.name, pkgDir);
|
|
263946
|
+
} catch {
|
|
263947
|
+
}
|
|
263948
|
+
}
|
|
263949
|
+
} catch {
|
|
263950
|
+
}
|
|
263951
|
+
}
|
|
263952
|
+
return packageMap;
|
|
263953
|
+
}
|
|
263954
|
+
function resolveWorkspaceFallback(importSource, workspacePackages, analyzedFiles) {
|
|
263955
|
+
let pkgDir = workspacePackages.get(importSource);
|
|
263956
|
+
let subPath = null;
|
|
263957
|
+
if (!pkgDir) {
|
|
263958
|
+
for (const [pkgName, dir] of workspacePackages) {
|
|
263959
|
+
if (importSource.startsWith(pkgName + "/")) {
|
|
263960
|
+
pkgDir = dir;
|
|
263961
|
+
subPath = importSource.slice(pkgName.length + 1);
|
|
263962
|
+
break;
|
|
263963
|
+
}
|
|
263964
|
+
}
|
|
263965
|
+
}
|
|
263966
|
+
if (!pkgDir)
|
|
263967
|
+
return null;
|
|
263968
|
+
if (subPath) {
|
|
263969
|
+
return resolveRelativeFallback("./" + subPath, join3(pkgDir, "dummy.ts"), analyzedFiles);
|
|
263970
|
+
}
|
|
263971
|
+
const pkgJsonPath = join3(pkgDir, "package.json");
|
|
263972
|
+
if (existsSync4(pkgJsonPath)) {
|
|
263973
|
+
try {
|
|
263974
|
+
const pkg = JSON.parse(readFileSync2(pkgJsonPath, "utf-8"));
|
|
263975
|
+
const mainField = pkg.main || pkg.module;
|
|
263976
|
+
if (mainField) {
|
|
263977
|
+
const mainPath = resolve2(pkgDir, mainField);
|
|
263978
|
+
if (analyzedFiles.has(mainPath))
|
|
263979
|
+
return mainPath;
|
|
263980
|
+
for (const ext2 of FALLBACK_EXTENSIONS) {
|
|
263981
|
+
const candidate = mainPath.endsWith(ext2) ? mainPath : mainPath + ext2;
|
|
263982
|
+
if (analyzedFiles.has(candidate))
|
|
263983
|
+
return candidate;
|
|
263984
|
+
}
|
|
263985
|
+
}
|
|
263986
|
+
} catch {
|
|
263987
|
+
}
|
|
263988
|
+
}
|
|
263989
|
+
for (const indexFile of FALLBACK_INDEX_FILES) {
|
|
263990
|
+
for (const candidate of [join3(pkgDir, "src", indexFile), join3(pkgDir, indexFile)]) {
|
|
263991
|
+
if (analyzedFiles.has(candidate))
|
|
263992
|
+
return candidate;
|
|
263993
|
+
}
|
|
263994
|
+
}
|
|
263995
|
+
return null;
|
|
263996
|
+
}
|
|
263930
263997
|
function buildDependencyGraph(files, rootPath) {
|
|
263931
263998
|
const dependencies = [];
|
|
263932
263999
|
const scoped = rootPath ? buildScopedCompilerOptions(rootPath) : [];
|
|
264000
|
+
const workspacePackages = rootPath ? buildWorkspacePackageMap(rootPath) : /* @__PURE__ */ new Map();
|
|
263933
264001
|
const analyzedFiles = new Set(files.map((f) => f.filePath));
|
|
263934
264002
|
for (const file2 of files) {
|
|
263935
264003
|
const depSources = [];
|
|
@@ -263958,6 +264026,9 @@ function buildDependencyGraph(files, rootPath) {
|
|
|
263958
264026
|
if (!resolved && dep.source.startsWith(".")) {
|
|
263959
264027
|
resolved = resolveRelativeFallback(dep.source, file2.filePath, analyzedFiles);
|
|
263960
264028
|
}
|
|
264029
|
+
if (!resolved && !dep.source.startsWith(".") && workspacePackages.size > 0) {
|
|
264030
|
+
resolved = resolveWorkspaceFallback(dep.source, workspacePackages, analyzedFiles);
|
|
264031
|
+
}
|
|
263961
264032
|
if (resolved && analyzedFiles.has(resolved)) {
|
|
263962
264033
|
dependencies.push({
|
|
263963
264034
|
source: file2.filePath,
|
|
@@ -263981,6 +264052,9 @@ function buildDependencyGraph(files, rootPath) {
|
|
|
263981
264052
|
if (!resolved && specifier.startsWith(".")) {
|
|
263982
264053
|
resolved = resolveRelativeFallback(specifier, file2.filePath, analyzedFiles);
|
|
263983
264054
|
}
|
|
264055
|
+
if (!resolved && !specifier.startsWith(".") && workspacePackages.size > 0) {
|
|
264056
|
+
resolved = resolveWorkspaceFallback(specifier, workspacePackages, analyzedFiles);
|
|
264057
|
+
}
|
|
263984
264058
|
if (resolved && analyzedFiles.has(resolved)) {
|
|
263985
264059
|
dependencies.push({
|
|
263986
264060
|
source: file2.filePath,
|
|
@@ -264013,6 +264087,7 @@ var init_dependency_graph = __esm({
|
|
|
264013
264087
|
"packages/analyzer/dist/dependency-graph.js"() {
|
|
264014
264088
|
"use strict";
|
|
264015
264089
|
init_ts_compiler();
|
|
264090
|
+
init_service_patterns();
|
|
264016
264091
|
FALLBACK_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mts", ".cts"];
|
|
264017
264092
|
FALLBACK_INDEX_FILES = ["index.ts", "index.tsx", "index.js", "index.jsx"];
|
|
264018
264093
|
}
|
|
@@ -266362,8 +266437,8 @@ var init_layer_detector = __esm({
|
|
|
266362
266437
|
});
|
|
266363
266438
|
|
|
266364
266439
|
// packages/analyzer/dist/service-detector.js
|
|
266365
|
-
import { existsSync as
|
|
266366
|
-
import { join as
|
|
266440
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3, readdirSync as readdirSync4, statSync as statSync5 } from "fs";
|
|
266441
|
+
import { join as join4, basename as basename2, dirname as dirname3 } from "path";
|
|
266367
266442
|
function detectServices(rootPath, allFiles) {
|
|
266368
266443
|
const monorepoServices = detectMonorepoServices(rootPath, allFiles);
|
|
266369
266444
|
if (monorepoServices.length > 0) {
|
|
@@ -266388,12 +266463,12 @@ function detectServices(rootPath, allFiles) {
|
|
|
266388
266463
|
function detectMonorepoServices(rootPath, allFiles) {
|
|
266389
266464
|
const services2 = [];
|
|
266390
266465
|
const patterns = serviceDetectionPatterns;
|
|
266391
|
-
const hasMonorepoConfig =
|
|
266466
|
+
const hasMonorepoConfig = existsSync5(join4(rootPath, "pnpm-workspace.yaml")) || existsSync5(join4(rootPath, "lerna.json")) || existsSync5(join4(rootPath, "nx.json")) || existsSync5(join4(rootPath, "turbo.json"));
|
|
266392
266467
|
if (!hasMonorepoConfig) {
|
|
266393
266468
|
let hasPackageDirs = false;
|
|
266394
266469
|
for (const pattern of patterns.monorepoPatterns) {
|
|
266395
|
-
const dirPath =
|
|
266396
|
-
if (
|
|
266470
|
+
const dirPath = join4(rootPath, pattern);
|
|
266471
|
+
if (existsSync5(dirPath) && statSync5(dirPath).isDirectory()) {
|
|
266397
266472
|
hasPackageDirs = true;
|
|
266398
266473
|
break;
|
|
266399
266474
|
}
|
|
@@ -266403,17 +266478,17 @@ function detectMonorepoServices(rootPath, allFiles) {
|
|
|
266403
266478
|
}
|
|
266404
266479
|
}
|
|
266405
266480
|
for (const pattern of patterns.monorepoPatterns) {
|
|
266406
|
-
const dirPath =
|
|
266407
|
-
if (!
|
|
266481
|
+
const dirPath = join4(rootPath, pattern);
|
|
266482
|
+
if (!existsSync5(dirPath))
|
|
266408
266483
|
continue;
|
|
266409
266484
|
try {
|
|
266410
|
-
const entries =
|
|
266485
|
+
const entries = readdirSync4(dirPath);
|
|
266411
266486
|
for (const entry of entries) {
|
|
266412
|
-
const servicePath =
|
|
266413
|
-
const stats =
|
|
266487
|
+
const servicePath = join4(dirPath, entry);
|
|
266488
|
+
const stats = statSync5(servicePath);
|
|
266414
266489
|
if (!stats.isDirectory())
|
|
266415
266490
|
continue;
|
|
266416
|
-
const hasPackageFile =
|
|
266491
|
+
const hasPackageFile = existsSync5(join4(servicePath, "package.json"));
|
|
266417
266492
|
if (hasPackageFile) {
|
|
266418
266493
|
const serviceFiles = allFiles.filter((f) => f.startsWith(servicePath));
|
|
266419
266494
|
if (serviceFiles.length > 0) {
|
|
@@ -266471,8 +266546,8 @@ function detectDockerComposeServices(rootPath, allFiles) {
|
|
|
266471
266546
|
];
|
|
266472
266547
|
let composePath2 = null;
|
|
266473
266548
|
for (const file2 of composeFiles) {
|
|
266474
|
-
const path10 =
|
|
266475
|
-
if (
|
|
266549
|
+
const path10 = join4(rootPath, file2);
|
|
266550
|
+
if (existsSync5(path10)) {
|
|
266476
266551
|
composePath2 = path10;
|
|
266477
266552
|
break;
|
|
266478
266553
|
}
|
|
@@ -266481,7 +266556,7 @@ function detectDockerComposeServices(rootPath, allFiles) {
|
|
|
266481
266556
|
return [];
|
|
266482
266557
|
}
|
|
266483
266558
|
try {
|
|
266484
|
-
const content =
|
|
266559
|
+
const content = readFileSync3(composePath2, "utf-8");
|
|
266485
266560
|
const services2 = [];
|
|
266486
266561
|
const lines = content.split("\n");
|
|
266487
266562
|
let inServices = false;
|
|
@@ -266492,8 +266567,8 @@ function detectDockerComposeServices(rootPath, allFiles) {
|
|
|
266492
266567
|
}
|
|
266493
266568
|
if (inServices && line2.match(/^ \w+:/)) {
|
|
266494
266569
|
const serviceName = line2.trim().replace(":", "");
|
|
266495
|
-
const servicePath =
|
|
266496
|
-
if (
|
|
266570
|
+
const servicePath = join4(rootPath, serviceName);
|
|
266571
|
+
if (existsSync5(servicePath) && statSync5(servicePath).isDirectory()) {
|
|
266497
266572
|
const serviceFiles = allFiles.filter((f) => f.startsWith(servicePath));
|
|
266498
266573
|
if (serviceFiles.length > 0) {
|
|
266499
266574
|
services2.push({
|
|
@@ -266516,10 +266591,10 @@ function detectDockerComposeServices(rootPath, allFiles) {
|
|
|
266516
266591
|
}
|
|
266517
266592
|
function detectServiceType(servicePath, files) {
|
|
266518
266593
|
const patterns = serviceDetectionPatterns;
|
|
266519
|
-
const hasPackageJson =
|
|
266594
|
+
const hasPackageJson = existsSync5(join4(servicePath, "package.json"));
|
|
266520
266595
|
if (hasPackageJson) {
|
|
266521
266596
|
try {
|
|
266522
|
-
const pkg = JSON.parse(
|
|
266597
|
+
const pkg = JSON.parse(readFileSync3(join4(servicePath, "package.json"), "utf-8"));
|
|
266523
266598
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
266524
266599
|
const isFrontend = patterns.frontend.frameworks.some((fw) => deps[fw]);
|
|
266525
266600
|
if (isFrontend) {
|
|
@@ -266538,7 +266613,7 @@ function detectServiceType(servicePath, files) {
|
|
|
266538
266613
|
}
|
|
266539
266614
|
if (hasPackageJson) {
|
|
266540
266615
|
try {
|
|
266541
|
-
const pkg = JSON.parse(
|
|
266616
|
+
const pkg = JSON.parse(readFileSync3(join4(servicePath, "package.json"), "utf-8"));
|
|
266542
266617
|
const hasLibraryIndicators = patterns.library.packageJsonIndicators.some((indicator) => pkg[indicator]);
|
|
266543
266618
|
if (hasLibraryIndicators) {
|
|
266544
266619
|
return "library";
|
|
@@ -266550,10 +266625,10 @@ function detectServiceType(servicePath, files) {
|
|
|
266550
266625
|
}
|
|
266551
266626
|
function detectFramework(servicePath) {
|
|
266552
266627
|
const patterns = serviceDetectionPatterns;
|
|
266553
|
-
const packageJsonPath =
|
|
266554
|
-
if (
|
|
266628
|
+
const packageJsonPath = join4(servicePath, "package.json");
|
|
266629
|
+
if (existsSync5(packageJsonPath)) {
|
|
266555
266630
|
try {
|
|
266556
|
-
const pkg = JSON.parse(
|
|
266631
|
+
const pkg = JSON.parse(readFileSync3(packageJsonPath, "utf-8"));
|
|
266557
266632
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
266558
266633
|
for (const fw of patterns.metaFrameworks) {
|
|
266559
266634
|
if (deps[fw]) {
|
|
@@ -266576,10 +266651,10 @@ function detectFramework(servicePath) {
|
|
|
266576
266651
|
return void 0;
|
|
266577
266652
|
}
|
|
266578
266653
|
function getServiceName(servicePath) {
|
|
266579
|
-
const packageJsonPath =
|
|
266580
|
-
if (
|
|
266654
|
+
const packageJsonPath = join4(servicePath, "package.json");
|
|
266655
|
+
if (existsSync5(packageJsonPath)) {
|
|
266581
266656
|
try {
|
|
266582
|
-
const pkg = JSON.parse(
|
|
266657
|
+
const pkg = JSON.parse(readFileSync3(packageJsonPath, "utf-8"));
|
|
266583
266658
|
if (pkg.name) {
|
|
266584
266659
|
return pkg.name;
|
|
266585
266660
|
}
|
|
@@ -266809,8 +266884,8 @@ var init_drizzle = __esm({
|
|
|
266809
266884
|
});
|
|
266810
266885
|
|
|
266811
266886
|
// packages/analyzer/dist/database-detector.js
|
|
266812
|
-
import { existsSync as
|
|
266813
|
-
import { join as
|
|
266887
|
+
import { existsSync as existsSync6, readFileSync as readFileSync4, readdirSync as readdirSync5 } from "fs";
|
|
266888
|
+
import { join as join5, resolve as resolve3 } from "path";
|
|
266814
266889
|
function detectDatabases(rootPath, analyses2, services2) {
|
|
266815
266890
|
const detections = [];
|
|
266816
266891
|
for (const analysis of analyses2) {
|
|
@@ -266846,7 +266921,7 @@ function detectDatabases(rootPath, analyses2, services2) {
|
|
|
266846
266921
|
const schemaResults = /* @__PURE__ */ new Map();
|
|
266847
266922
|
const prismaFiles = findFiles(rootPath, "schema.prisma", ["node_modules", ".git", "dist"]);
|
|
266848
266923
|
for (const prismaFile of prismaFiles) {
|
|
266849
|
-
const content =
|
|
266924
|
+
const content = readFileSync4(prismaFile, "utf-8");
|
|
266850
266925
|
const result = parsePrismaSchema(content);
|
|
266851
266926
|
let dbType = "postgres";
|
|
266852
266927
|
const providerMatch = content.match(/provider\s*=\s*"(\w+)"/);
|
|
@@ -266884,7 +266959,7 @@ function detectDatabases(rootPath, analyses2, services2) {
|
|
|
266884
266959
|
if (!hasDrizzleImport)
|
|
266885
266960
|
continue;
|
|
266886
266961
|
try {
|
|
266887
|
-
const content =
|
|
266962
|
+
const content = readFileSync4(resolve3(analysis.filePath), "utf-8");
|
|
266888
266963
|
if (!/(?:pgTable|mysqlTable|sqliteTable)\s*\(/.test(content))
|
|
266889
266964
|
continue;
|
|
266890
266965
|
const result = parseDrizzleSchema(content);
|
|
@@ -266934,9 +267009,9 @@ function parseDockerCompose(rootPath) {
|
|
|
266934
267009
|
const composeFiles = ["docker-compose.yml", "docker-compose.yaml", "compose.yml", "compose.yaml"];
|
|
266935
267010
|
let composeContent = null;
|
|
266936
267011
|
for (const file2 of composeFiles) {
|
|
266937
|
-
const filePath =
|
|
266938
|
-
if (
|
|
266939
|
-
composeContent =
|
|
267012
|
+
const filePath = join5(rootPath, file2);
|
|
267013
|
+
if (existsSync6(filePath)) {
|
|
267014
|
+
composeContent = readFileSync4(filePath, "utf-8");
|
|
266940
267015
|
break;
|
|
266941
267016
|
}
|
|
266942
267017
|
}
|
|
@@ -266980,11 +267055,11 @@ function parseDockerCompose(rootPath) {
|
|
|
266980
267055
|
function findFiles(dir, fileName, ignoreDirs) {
|
|
266981
267056
|
const results = [];
|
|
266982
267057
|
try {
|
|
266983
|
-
const entries =
|
|
267058
|
+
const entries = readdirSync5(dir, { withFileTypes: true });
|
|
266984
267059
|
for (const entry of entries) {
|
|
266985
267060
|
if (ignoreDirs.includes(entry.name))
|
|
266986
267061
|
continue;
|
|
266987
|
-
const fullPath =
|
|
267062
|
+
const fullPath = join5(dir, entry.name);
|
|
266988
267063
|
if (entry.isDirectory()) {
|
|
266989
267064
|
results.push(...findFiles(fullPath, fileName, ignoreDirs));
|
|
266990
267065
|
} else if (entry.name === fileName) {
|
|
@@ -307157,7 +307232,7 @@ async function fetcherImpl(args) {
|
|
|
307157
307232
|
};
|
|
307158
307233
|
}
|
|
307159
307234
|
}
|
|
307160
|
-
function
|
|
307235
|
+
function join6(base, ...segments) {
|
|
307161
307236
|
if (!base) {
|
|
307162
307237
|
return "";
|
|
307163
307238
|
}
|
|
@@ -308238,7 +308313,7 @@ var init_dist9 = __esm({
|
|
|
308238
308313
|
};
|
|
308239
308314
|
url_exports = {};
|
|
308240
308315
|
__export4(url_exports, {
|
|
308241
|
-
join: () =>
|
|
308316
|
+
join: () => join6,
|
|
308242
308317
|
toQueryString: () => toQueryString
|
|
308243
308318
|
});
|
|
308244
308319
|
BASIC_AUTH_HEADER_PREFIX = /^Basic /i;
|
|
@@ -325985,7 +326060,7 @@ var init_usage_service = __esm({
|
|
|
325985
326060
|
// apps/server/src/services/llm/cli-provider.ts
|
|
325986
326061
|
import { spawn as spawn2 } from "node:child_process";
|
|
325987
326062
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
325988
|
-
import { join as
|
|
326063
|
+
import { join as join7 } from "node:path";
|
|
325989
326064
|
import { tmpdir } from "node:os";
|
|
325990
326065
|
function log(msg) {
|
|
325991
326066
|
process.stderr.write(`${msg}
|
|
@@ -326046,7 +326121,7 @@ var init_cli_provider = __esm({
|
|
|
326046
326121
|
}
|
|
326047
326122
|
constructor() {
|
|
326048
326123
|
if (process.env.TRUECOURSE_CLI_DEBUG) {
|
|
326049
|
-
this.debugDir =
|
|
326124
|
+
this.debugDir = join7(tmpdir(), "truecourse-cli-debug");
|
|
326050
326125
|
mkdirSync(this.debugDir, { recursive: true });
|
|
326051
326126
|
log(`[CLI] Debug output: ${this.debugDir}`);
|
|
326052
326127
|
}
|
|
@@ -326055,7 +326130,7 @@ var init_cli_provider = __esm({
|
|
|
326055
326130
|
dumpDebug(label, prompt, rawOutput, jsonSchema2) {
|
|
326056
326131
|
if (!this.debugDir) return;
|
|
326057
326132
|
const n = String(++this.callCounter).padStart(2, "0");
|
|
326058
|
-
const prefix =
|
|
326133
|
+
const prefix = join7(this.debugDir, `${n}-${label}`);
|
|
326059
326134
|
writeFileSync(`${prefix}-input.txt`, prompt, "utf-8");
|
|
326060
326135
|
writeFileSync(`${prefix}-output.json`, rawOutput, "utf-8");
|
|
326061
326136
|
if (jsonSchema2) writeFileSync(`${prefix}-schema.json`, jsonSchema2, "utf-8");
|
|
@@ -402004,11 +402079,19 @@ router2.post(
|
|
|
402004
402079
|
}));
|
|
402005
402080
|
const git = simpleGit(repo.path);
|
|
402006
402081
|
const branch = (await git.branch()).current || void 0;
|
|
402082
|
+
const diffTracker = new StepTracker(id, [
|
|
402083
|
+
{ key: "parse", label: "Parsing working tree" },
|
|
402084
|
+
{ key: "detect", label: "Deterministic checks" },
|
|
402085
|
+
{ key: "enrich", label: "Enriching detections" },
|
|
402086
|
+
{ key: "architecture", label: "Architecture analysis" },
|
|
402087
|
+
{ key: "persist", label: "Saving results" }
|
|
402088
|
+
]);
|
|
402089
|
+
diffTracker.start("parse");
|
|
402007
402090
|
const diffAnalysis = await runDiffAnalysis({
|
|
402008
402091
|
repoPath: repo.path,
|
|
402009
402092
|
branch,
|
|
402010
402093
|
onProgress: (progress) => {
|
|
402011
|
-
|
|
402094
|
+
diffTracker.detail("parse", progress.detail ?? "Analyzing...");
|
|
402012
402095
|
}
|
|
402013
402096
|
});
|
|
402014
402097
|
const result = diffAnalysis.analysisResult;
|
|
@@ -402038,6 +402121,7 @@ router2.post(
|
|
|
402038
402121
|
methodName: deterministicViolations.methodName
|
|
402039
402122
|
}).from(deterministicViolations).where(eq(deterministicViolations.analysisId, latestAnalysis.id));
|
|
402040
402123
|
const changedFileSet = new Set(changedFiles.filter((f) => f.status !== "deleted").map((f) => f.path));
|
|
402124
|
+
diffTracker.done("parse", `${result.services.length} services, ${changedFiles.length} changed files`);
|
|
402041
402125
|
const diffProvider = createLLMProvider();
|
|
402042
402126
|
diffProvider.setAnalysisId(diffAnalysisId);
|
|
402043
402127
|
const pipelineResult = await runViolationPipeline({
|
|
@@ -402053,7 +402137,7 @@ router2.post(
|
|
|
402053
402137
|
previousActiveCodeViolations,
|
|
402054
402138
|
previousDeterministicViolations: prevDetViolations,
|
|
402055
402139
|
changedFileSet,
|
|
402056
|
-
|
|
402140
|
+
tracker: diffTracker,
|
|
402057
402141
|
provider: diffProvider
|
|
402058
402142
|
});
|
|
402059
402143
|
try {
|
|
@@ -402157,6 +402241,8 @@ router2.post(
|
|
|
402157
402241
|
}
|
|
402158
402242
|
}).where(eq(analyses.id, diffAnalysisId));
|
|
402159
402243
|
emitAnalysisProgress(id, { step: "complete", percent: 100, detail: "Diff check complete" });
|
|
402244
|
+
const diffMeta = await db.select({ metadata: analyses.metadata }).from(analyses).where(eq(analyses.id, diffAnalysisId)).limit(1);
|
|
402245
|
+
const diffCodeReview = diffMeta[0]?.metadata?.codeReview === true;
|
|
402160
402246
|
res.json({
|
|
402161
402247
|
changedFiles,
|
|
402162
402248
|
resolvedViolations: allResolvedViolations,
|
|
@@ -402164,7 +402250,8 @@ router2.post(
|
|
|
402164
402250
|
affectedNodeIds,
|
|
402165
402251
|
summary,
|
|
402166
402252
|
isStale: false,
|
|
402167
|
-
diffAnalysisId
|
|
402253
|
+
diffAnalysisId,
|
|
402254
|
+
codeReview: diffCodeReview
|
|
402168
402255
|
});
|
|
402169
402256
|
} catch (error40) {
|
|
402170
402257
|
const repoId = req.params.id;
|
|
@@ -402287,7 +402374,8 @@ router2.get(
|
|
|
402287
402374
|
summary: metadata?.summary || { newCount: allNewViolations.length, resolvedCount: allResolvedViolations.length },
|
|
402288
402375
|
changedFiles: metadata?.changedFiles || [],
|
|
402289
402376
|
isStale,
|
|
402290
|
-
diffAnalysisId: diffAnalysis.id
|
|
402377
|
+
diffAnalysisId: diffAnalysis.id,
|
|
402378
|
+
codeReview: metadata?.codeReview === true
|
|
402291
402379
|
});
|
|
402292
402380
|
} catch (error40) {
|
|
402293
402381
|
next(error40);
|