@launchsecure/launch-kit 0.0.14 → 0.0.16
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/dist/chart-client/assets/{index-Dm6IBkiC.js → index-BpQPtTuo.js} +89 -89
- package/dist/chart-client/assets/index-CbZ13AXL.css +1 -0
- package/dist/chart-client/index.html +2 -2
- package/dist/client/assets/index-BCYw64M7.css +32 -0
- package/dist/client/index.html +2 -2
- package/dist/server/chart-serve.js +49 -49
- package/dist/server/cli.js +822 -201
- package/dist/server/graph-mcp-entry.js +687 -103
- package/package.json +1 -1
- package/dist/chart-client/assets/index-l-yyLDX5.css +0 -1
- package/dist/client/assets/index-rlw8dmPR.css +0 -32
- /package/dist/client/assets/{index-CyML1UiJ.js → index-3ENenBk-.js} +0 -0
|
@@ -624,19 +624,26 @@ init_config();
|
|
|
624
624
|
// src/server/graph/core/resolve-paths.ts
|
|
625
625
|
var import_node_fs2 = require("node:fs");
|
|
626
626
|
var import_node_path2 = require("node:path");
|
|
627
|
+
function detectDbDir(rootDir, config) {
|
|
628
|
+
if (config.paths?.dbDir) return (0, import_node_path2.join)(rootDir, config.paths.dbDir);
|
|
629
|
+
const prismaDir = (0, import_node_path2.join)(rootDir, "prisma");
|
|
630
|
+
if ((0, import_node_fs2.existsSync)(prismaDir)) return prismaDir;
|
|
631
|
+
return null;
|
|
632
|
+
}
|
|
627
633
|
function resolveProjectPaths(rootDir, config) {
|
|
634
|
+
const dbDir = detectDbDir(rootDir, config);
|
|
628
635
|
if (config.paths?.appDir) {
|
|
629
636
|
const appDir = (0, import_node_path2.join)(rootDir, config.paths.appDir);
|
|
630
637
|
const srcDir = config.paths.srcDir ? (0, import_node_path2.join)(rootDir, config.paths.srcDir) : (0, import_node_path2.dirname)(appDir);
|
|
631
|
-
return { srcDir, appDir, apiDir: (0, import_node_path2.join)(appDir, "api") };
|
|
638
|
+
return { srcDir, appDir, apiDir: (0, import_node_path2.join)(appDir, "api"), dbDir };
|
|
632
639
|
}
|
|
633
640
|
const srcApp = (0, import_node_path2.join)(rootDir, "src", "app");
|
|
634
641
|
if ((0, import_node_fs2.existsSync)(srcApp)) {
|
|
635
|
-
return { srcDir: (0, import_node_path2.join)(rootDir, "src"), appDir: srcApp, apiDir: (0, import_node_path2.join)(srcApp, "api") };
|
|
642
|
+
return { srcDir: (0, import_node_path2.join)(rootDir, "src"), appDir: srcApp, apiDir: (0, import_node_path2.join)(srcApp, "api"), dbDir };
|
|
636
643
|
}
|
|
637
644
|
const rootApp = (0, import_node_path2.join)(rootDir, "app");
|
|
638
645
|
if ((0, import_node_fs2.existsSync)(rootApp)) {
|
|
639
|
-
return { srcDir: rootDir, appDir: rootApp, apiDir: (0, import_node_path2.join)(rootApp, "api") };
|
|
646
|
+
return { srcDir: rootDir, appDir: rootApp, apiDir: (0, import_node_path2.join)(rootApp, "api"), dbDir };
|
|
640
647
|
}
|
|
641
648
|
return null;
|
|
642
649
|
}
|
|
@@ -2000,6 +2007,7 @@ function resolveUrlPath(urlPath, apiPathMap, apiRoutes) {
|
|
|
2000
2007
|
var fetchResolverParser = {
|
|
2001
2008
|
id: "fetch-resolver",
|
|
2002
2009
|
layer: "crosslayer",
|
|
2010
|
+
concern: "api-binding",
|
|
2003
2011
|
detect(_rootDir) {
|
|
2004
2012
|
return true;
|
|
2005
2013
|
},
|
|
@@ -2113,6 +2121,7 @@ function toNodeId2(srcDir, absPath) {
|
|
|
2113
2121
|
var apiAnnotationsParser = {
|
|
2114
2122
|
id: "api-annotations",
|
|
2115
2123
|
layer: "crosslayer",
|
|
2124
|
+
concern: "api-binding",
|
|
2116
2125
|
detect(rootDir) {
|
|
2117
2126
|
return (0, import_node_fs7.existsSync)((0, import_node_path7.join)(rootDir, "src"));
|
|
2118
2127
|
},
|
|
@@ -2199,6 +2208,7 @@ function toNodeId3(srcDir, absPath) {
|
|
|
2199
2208
|
var urlLiteralScannerParser = {
|
|
2200
2209
|
id: "url-literal-scanner",
|
|
2201
2210
|
layer: "crosslayer",
|
|
2211
|
+
concern: "api-binding",
|
|
2202
2212
|
detect(rootDir) {
|
|
2203
2213
|
const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
|
|
2204
2214
|
return paths !== null;
|
|
@@ -2810,6 +2820,7 @@ function collectStaticRefsRegex(content, valueLookup, allValues) {
|
|
|
2810
2820
|
var staticRefScannerParser = {
|
|
2811
2821
|
id: "static-ref-scanner",
|
|
2812
2822
|
layer: "crosslayer",
|
|
2823
|
+
concern: "static-ref",
|
|
2813
2824
|
detect(rootDir) {
|
|
2814
2825
|
const paths = resolveProjectPaths(rootDir, loadConfig(rootDir));
|
|
2815
2826
|
return paths !== null;
|
|
@@ -2994,6 +3005,9 @@ function loadCustomParsers(registry, config, rootDir, disabled) {
|
|
|
2994
3005
|
`
|
|
2995
3006
|
);
|
|
2996
3007
|
}
|
|
3008
|
+
if (parser.layer === "crosslayer" && entry.concern && !("concern" in parser && parser.concern)) {
|
|
3009
|
+
parser.concern = entry.concern;
|
|
3010
|
+
}
|
|
2997
3011
|
registry.register(parser);
|
|
2998
3012
|
} catch (err) {
|
|
2999
3013
|
process.stderr.write(`[launch-chart] failed to load custom parser from ${entry.path}: ${err}
|
|
@@ -3091,44 +3105,21 @@ function dedupCrossRefs(refs) {
|
|
|
3091
3105
|
}
|
|
3092
3106
|
return result;
|
|
3093
3107
|
}
|
|
3094
|
-
function applyCrossLayerResults(uiOutput, results
|
|
3095
|
-
const allCrossRefs = [...uiOutput.cross_refs];
|
|
3096
|
-
const allFlagged = [...uiOutput.flagged_edges];
|
|
3097
|
-
const allWarnings = [...uiOutput.warnings];
|
|
3098
|
-
const primaryResult = results.find((r) => r.parserId === primaryId);
|
|
3099
|
-
const secondaryResults = results.filter((r) => r.parserId !== primaryId);
|
|
3100
|
-
if (primaryResult) {
|
|
3101
|
-
allCrossRefs.push(...primaryResult.output.cross_refs);
|
|
3102
|
-
allFlagged.push(...primaryResult.output.flagged_edges);
|
|
3103
|
-
allWarnings.push(...primaryResult.output.warnings);
|
|
3104
|
-
}
|
|
3105
|
-
const primarySet = new Set(
|
|
3106
|
-
(primaryResult?.output.cross_refs ?? []).map((r) => `${r.source}|${r.target}|${r.type}`)
|
|
3107
|
-
);
|
|
3108
|
-
for (const sec of secondaryResults) {
|
|
3109
|
-
for (const ref of sec.output.cross_refs) {
|
|
3110
|
-
const key = `${ref.source}|${ref.target}|${ref.type}`;
|
|
3111
|
-
if (primarySet.has(key)) {
|
|
3112
|
-
allCrossRefs.push(ref);
|
|
3113
|
-
} else {
|
|
3114
|
-
allFlagged.push({
|
|
3115
|
-
source: ref.source,
|
|
3116
|
-
target: ref.target,
|
|
3117
|
-
type: "out_of_pattern",
|
|
3118
|
-
label: `API call detected by ${sec.parserId} but not by primary (${primaryId})`,
|
|
3119
|
-
confidence: "medium"
|
|
3120
|
-
});
|
|
3121
|
-
allCrossRefs.push(ref);
|
|
3122
|
-
}
|
|
3123
|
-
}
|
|
3124
|
-
allFlagged.push(...sec.output.flagged_edges);
|
|
3125
|
-
allWarnings.push(...sec.output.warnings);
|
|
3126
|
-
}
|
|
3108
|
+
function applyCrossLayerResults(uiOutput, results) {
|
|
3127
3109
|
return {
|
|
3128
3110
|
...uiOutput,
|
|
3129
|
-
cross_refs: dedupCrossRefs(
|
|
3130
|
-
|
|
3131
|
-
|
|
3111
|
+
cross_refs: dedupCrossRefs([
|
|
3112
|
+
...uiOutput.cross_refs,
|
|
3113
|
+
...results.flatMap((r) => r.output.cross_refs)
|
|
3114
|
+
]),
|
|
3115
|
+
flagged_edges: [
|
|
3116
|
+
...uiOutput.flagged_edges,
|
|
3117
|
+
...results.flatMap((r) => r.output.flagged_edges)
|
|
3118
|
+
],
|
|
3119
|
+
warnings: [
|
|
3120
|
+
...uiOutput.warnings,
|
|
3121
|
+
...results.flatMap((r) => r.output.warnings)
|
|
3122
|
+
]
|
|
3132
3123
|
};
|
|
3133
3124
|
}
|
|
3134
3125
|
|
|
@@ -3167,10 +3158,9 @@ function generateLayer(rootDir, layer) {
|
|
|
3167
3158
|
if (existing) layerOutputs.set(otherLayer, existing);
|
|
3168
3159
|
}
|
|
3169
3160
|
const crossParsers = registry.getCrossLayerParsers();
|
|
3170
|
-
const primaryId = config.parsers?.primary?.crosslayer ?? crossParsers[0]?.id ?? null;
|
|
3171
3161
|
const crossResults = crossParsers.filter((p) => p.detect(rootDir)).map((p) => ({ parserId: p.id, output: p.generate(rootDir, layerOutputs) }));
|
|
3172
3162
|
if (crossResults.length > 0) {
|
|
3173
|
-
merged = applyCrossLayerResults(merged, crossResults
|
|
3163
|
+
merged = applyCrossLayerResults(merged, crossResults);
|
|
3174
3164
|
}
|
|
3175
3165
|
}
|
|
3176
3166
|
return {
|
|
@@ -3217,11 +3207,10 @@ function generateAll(rootDir) {
|
|
|
3217
3207
|
});
|
|
3218
3208
|
}
|
|
3219
3209
|
const crossParsers = registry.getCrossLayerParsers();
|
|
3220
|
-
const primaryId = config.parsers?.primary?.crosslayer ?? crossParsers[0]?.id ?? null;
|
|
3221
3210
|
const crossResults = crossParsers.filter((p) => p.detect(rootDir)).map((p) => ({ parserId: p.id, output: p.generate(rootDir, layerOutputs) }));
|
|
3222
3211
|
if (crossResults.length > 0 && layerOutputs.has("ui")) {
|
|
3223
3212
|
const uiOutput = layerOutputs.get("ui");
|
|
3224
|
-
const merged = applyCrossLayerResults(uiOutput, crossResults
|
|
3213
|
+
const merged = applyCrossLayerResults(uiOutput, crossResults);
|
|
3225
3214
|
layerOutputs.set("ui", merged);
|
|
3226
3215
|
const uiResult = results.find((r) => r.layer === "ui");
|
|
3227
3216
|
if (uiResult) {
|
|
@@ -4386,17 +4375,23 @@ async function startChartServer(opts = {}) {
|
|
|
4386
4375
|
if (req.method === "GET" && url2.pathname === "/api/parser-config") {
|
|
4387
4376
|
const config2 = loadConfig(reqRoot);
|
|
4388
4377
|
const registry = createRegistry(config2, reqRoot);
|
|
4378
|
+
const toLabel = (id) => id.split("-").map((w) => w[0].toUpperCase() + w.slice(1)).join(" ");
|
|
4389
4379
|
const detection = [];
|
|
4390
4380
|
for (const parser of registry.getAll()) {
|
|
4391
4381
|
if ("layers" in parser && Array.isArray(parser.layers)) {
|
|
4392
4382
|
const mp = parser;
|
|
4393
|
-
detection.push({ id: mp.id, layers: mp.layers, detected: mp.detect(reqRoot) });
|
|
4383
|
+
detection.push({ id: mp.id, layers: mp.layers, label: toLabel(mp.id), detected: mp.detect(reqRoot) });
|
|
4394
4384
|
} else if ("layer" in parser && parser.layer !== "crosslayer") {
|
|
4395
4385
|
const sp = parser;
|
|
4396
|
-
detection.push({ id: sp.id, layers: [sp.layer], detected: sp.detect(reqRoot) });
|
|
4386
|
+
detection.push({ id: sp.id, layers: [sp.layer], label: toLabel(sp.id), detected: sp.detect(reqRoot) });
|
|
4397
4387
|
}
|
|
4398
4388
|
}
|
|
4399
|
-
const crosslayerParsers =
|
|
4389
|
+
const crosslayerParsers = {};
|
|
4390
|
+
for (const p of registry.getCrossLayerParsers()) {
|
|
4391
|
+
const concern = p.concern ?? "api-binding";
|
|
4392
|
+
if (!crosslayerParsers[concern]) crosslayerParsers[concern] = [];
|
|
4393
|
+
crosslayerParsers[concern].push({ id: p.id, label: toLabel(p.id) });
|
|
4394
|
+
}
|
|
4400
4395
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
4401
4396
|
res.end(JSON.stringify({ config: config2, detection, crosslayerParsers }));
|
|
4402
4397
|
return;
|
|
@@ -4509,16 +4504,21 @@ async function startChartServer(opts = {}) {
|
|
|
4509
4504
|
if (req.method === "GET" && url2.pathname === "/api/detected-paths") {
|
|
4510
4505
|
const config2 = loadConfig(reqRoot);
|
|
4511
4506
|
const paths = resolveProjectPaths(reqRoot, config2);
|
|
4512
|
-
const
|
|
4507
|
+
const overrides = {
|
|
4508
|
+
appDir: !!config2.paths?.appDir,
|
|
4509
|
+
dbDir: !!config2.paths?.dbDir
|
|
4510
|
+
};
|
|
4513
4511
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
4514
4512
|
res.end(JSON.stringify({
|
|
4515
4513
|
projectRoot: reqRoot,
|
|
4516
4514
|
detected: paths ? {
|
|
4517
4515
|
srcDir: import_node_path19.default.relative(reqRoot, paths.srcDir) || ".",
|
|
4518
4516
|
appDir: import_node_path19.default.relative(reqRoot, paths.appDir),
|
|
4519
|
-
apiDir: import_node_path19.default.relative(reqRoot, paths.apiDir)
|
|
4517
|
+
apiDir: import_node_path19.default.relative(reqRoot, paths.apiDir),
|
|
4518
|
+
dbDir: paths.dbDir ? import_node_path19.default.relative(reqRoot, paths.dbDir) : null
|
|
4520
4519
|
} : null,
|
|
4521
|
-
|
|
4520
|
+
overrides,
|
|
4521
|
+
isOverride: overrides.appDir
|
|
4522
4522
|
}));
|
|
4523
4523
|
return;
|
|
4524
4524
|
}
|